Пример #1
0
	bool
	Client::create_directory(std::string remote_directory, bool recursive) noexcept
	{
		auto clientImpl = GetImpl(this);
		bool is_existed = this->check(remote_directory);
		if (is_existed) return true;

		bool resource_is_dir = true;
		Urn directory_urn(remote_directory, resource_is_dir);

		if (recursive) {
			auto remote_parent_directory = directory_urn.parent();
			bool is_created = this->create_directory(remote_parent_directory, true);
			if (!is_created) return false;
		}

		Header header = {
				"Accept: */*",
				"Connection: Keep-Alive"
		};
		
		auto target_urn = Urn(clientImpl->webdav_root, true) + remote_directory;
		target_urn = Urn(target_urn.path(), true);

		Request request(clientImpl->options());

		auto url = clientImpl->webdav_hostname + target_urn.quote(request.handle);

		request.set(CURLOPT_CUSTOMREQUEST, "MKCOL");
		request.set(CURLOPT_URL, url.c_str());
		request.set(CURLOPT_HTTPHEADER, (struct curl_slist *)header.handle);

		return request.perform();
	}
Пример #2
0
	strings_t
	Client::list(std::string remote_directory) noexcept
	{
		auto clientImpl = GetImpl(this);
		bool is_existed = this->check(remote_directory);
		if (!is_existed) return strings_t();

		bool is_directory = this->is_dir(remote_directory);
		if (!is_directory) return strings_t();
		auto target_urn = Urn(clientImpl->webdav_root, true) + remote_directory;
		target_urn = Urn(target_urn.path(), true);

		Header header = {
				"Accept: */*",
				"Depth: 1"
		};

		Data data = { 0, 0, 0 };

		Request request(clientImpl->options());

		auto url = clientImpl->webdav_hostname + target_urn.quote(request.handle);

		request.set(CURLOPT_CUSTOMREQUEST, "PROPFIND");
		request.set(CURLOPT_URL, url.c_str());
		request.set(CURLOPT_HTTPHEADER, (struct curl_slist *)header.handle);
		request.set(CURLOPT_HEADER, 0);
		request.set(CURLOPT_WRITEDATA, (size_t)&data);
		request.set(CURLOPT_WRITEFUNCTION, (size_t)Callback::Append::buffer);

		bool is_performed = request.perform();

		if (!is_performed) return strings_t();

		strings_t resources;

		pugi::xml_document document;
		document.load_buffer(data.buffer, (size_t)data.size);
		auto multistatus = document.select_single_node("d:multistatus").node();
		auto responses = multistatus.select_nodes("d:response");
		for(auto response : responses)
		{
			pugi::xml_node href = response.node().select_single_node("d:href").node();
			std::string encode_file_name = href.first_child().value();
			std::string resource_path = curl_unescape(encode_file_name.c_str(), (int) encode_file_name.length());
			auto target_path = target_urn.path();
			if (resource_path == target_path) continue;
			Urn resource_urn(resource_path);
			resources.push_back(resource_urn.name());
		}

		return resources;
	}
Пример #3
0
	Urn Urn::operator+(std::string resource_path) {
		bool is_directory = this->is_dir();
		if (!is_directory) return *this;
		auto directory_path = this->path();
		resource_path = directory_path + resource_path;
		return Urn(resource_path);
	}
Пример #4
0
	bool
	Client::clean(std::string remote_resource) noexcept
	{
		auto clientImpl = GetImpl(this);
		bool is_existed = this->check(remote_resource);
		if (!is_existed) return true;

		auto root_urn = Urn(clientImpl->webdav_root, true);
		auto resource_urn = root_urn + remote_resource;

		Header header = {
				"Accept: */*",
				"Connection: Keep-Alive"
		};

		Request request(clientImpl->options());

		auto url = clientImpl->webdav_hostname + resource_urn.quote(request.handle);

		request.set(CURLOPT_CUSTOMREQUEST, "DELETE");
		request.set(CURLOPT_URL, url.c_str());
		request.set(CURLOPT_HTTPHEADER, (struct curl_slist *)header.handle);

		return request.perform();
	}
Пример #5
0
	bool
	ClientImpl::sync_download_to(
		std::string remote_file, 
		std::ostream & stream, 
		callback_t callback, 
		progress_t progress
	) noexcept
	{
		bool is_existed = this->check(remote_file);
		if (!is_existed) return false;

		auto root_urn = Urn(this->webdav_root, true);
		auto file_urn = root_urn + remote_file;

		Request request(this->options());

		auto url = this->webdav_hostname + file_urn.quote(request.handle);

		request.set(CURLOPT_CUSTOMREQUEST, "GET");
		request.set(CURLOPT_URL, url.c_str());
		request.set(CURLOPT_HEADER, 0L);
		request.set(CURLOPT_WRITEDATA, (size_t)&stream);
		request.set(CURLOPT_WRITEFUNCTION, (size_t)Callback::Write::stream);
		if (progress != nullptr) {
			request.set(CURLOPT_XFERINFOFUNCTION, (size_t)progress.target<progress_funptr>());
			request.set(CURLOPT_NOPROGRESS, 0L);
		}

		bool is_performed = request.perform();
		if (callback != nullptr) callback(is_performed);
		if (!is_performed) return false;

		return true;
	}
Пример #6
0
	bool
	Client::check(std::string remote_resource) noexcept
	{
		auto clientImpl = GetImpl(this);
		auto root_urn = Urn(clientImpl->webdav_root, true);
		auto resource_urn = root_urn + remote_resource;

		Header header = {
				"Accept: */*",
				"Depth: 1"
		};

		Data data = { 0, 0, 0 };

		Request request(clientImpl->options());

		auto url = clientImpl->webdav_hostname + resource_urn.quote(request.handle);

		request.set(CURLOPT_CUSTOMREQUEST, "PROPFIND");
		request.set(CURLOPT_URL, url.c_str());
		request.set(CURLOPT_HTTPHEADER, (struct curl_slist *)header.handle);
		request.set(CURLOPT_WRITEDATA, (size_t)&data);
		request.set(CURLOPT_WRITEFUNCTION, (size_t)Callback::Append::buffer);

		return request.perform();
	}
Пример #7
0
	strings_t
	Client::list(std::string remote_directory) noexcept
	{
		auto clientImpl = GetImpl(this);
		bool is_existed = this->check(remote_directory);
		if (!is_existed) return strings_t();

		bool is_directory = this->is_dir(remote_directory);
		if (!is_directory) return strings_t();
		auto target_urn = Urn(clientImpl->ftps_root, true) + remote_directory;
		target_urn = Urn(target_urn.path(), true);

		Header header = {
				"Accept: */*",
				"Depth: 1"
		};

		Data data = { 0, 0, 0 };

		Request request(clientImpl->options());

		auto url = clientImpl->ftps_hostname + target_urn.quote(request.handle);

		request.set(CURLOPT_CUSTOMREQUEST, "PROPFIND");
		request.set(CURLOPT_URL, url.c_str());
		request.set(CURLOPT_HTTPHEADER, (struct curl_slist *)header.handle);
		request.set(CURLOPT_HEADER, 0);
		request.set(CURLOPT_WRITEDATA, (size_t)&data);
		request.set(CURLOPT_WRITEFUNCTION, (size_t)Callback::Append::buffer);

		bool is_performed = request.perform();

		if (!is_performed) return strings_t();

		strings_t resources;

		// TODO

		return resources;
	}
Пример #8
0
	bool
	ClientImpl::sync_upload(
		std::string remote_file, 
		std::string local_file, 
		callback_t callback, 
		progress_t progress
	) noexcept
	{
		bool is_existed = FileInfo::exists(local_file);
		if (!is_existed) return false;

		auto root_urn = Urn(this->webdav_root, true);
		auto file_urn = root_urn + remote_file;

		std::ifstream file_stream(local_file, std::ios::binary);
		auto size = FileInfo::size(local_file);

		Request request(this->options());

		auto url = this->webdav_hostname + file_urn.quote(request.handle);

		Data response = { 0, 0, 0 };

		request.set(CURLOPT_UPLOAD, 1L);
		request.set(CURLOPT_URL, url.c_str());
		request.set(CURLOPT_READDATA, (size_t)&file_stream);
		request.set(CURLOPT_READFUNCTION, (size_t)Callback::Read::stream);
		request.set(CURLOPT_INFILESIZE_LARGE, (curl_off_t)size);
		request.set(CURLOPT_BUFFERSIZE, (long)Client::buffer_size);
		request.set(CURLOPT_WRITEDATA, (size_t)&response);
		request.set(CURLOPT_WRITEFUNCTION, (size_t)Callback::Append::buffer);
		if (progress != nullptr) {
			request.set(CURLOPT_XFERINFOFUNCTION, (size_t)progress.target<progress_funptr>());
			request.set(CURLOPT_NOPROGRESS, 0L);
		}

		bool is_performed = request.perform();

		if (callback != nullptr) callback(is_performed);
		return is_performed;
	}
Пример #9
0
	bool
	ClientImpl::sync_download_to(
		std::string remote_file, 
		char * & buffer_ptr, 
		unsigned long long int & buffer_size, 
		callback_t callback, 
		progress_t progress
	) noexcept
	{
		bool is_existed = this->check(remote_file);
		if (!is_existed) return false;

		auto root_urn = Urn(this->webdav_root, true);
		auto file_urn = root_urn + remote_file;

		Data data = { 0, 0, 0 };

		Request request(this->options());

		auto url = this->webdav_hostname + file_urn.quote(request.handle);

		request.set(CURLOPT_CUSTOMREQUEST, "GET");
		request.set(CURLOPT_URL, url.c_str());
		request.set(CURLOPT_HEADER, 0L);
		request.set(CURLOPT_WRITEDATA, (size_t)&data);
		request.set(CURLOPT_WRITEFUNCTION, (size_t)Callback::Append::buffer);
		if (progress != nullptr) {
			request.set(CURLOPT_XFERINFOFUNCTION, (size_t)progress.target<progress_funptr>());
			request.set(CURLOPT_NOPROGRESS, 0L);
		}

		bool is_performed = request.perform();
		if (callback != nullptr) callback(is_performed);
		if (!is_performed) return false;

		buffer_ptr = data.buffer;
		buffer_size = data.size;
		return true;
	}
Пример #10
0
	bool
	ClientImpl::sync_upload_from(
		std::string remote_file, 
		char * buffer, 
		unsigned long long int buffer_size, 
		callback_t callback, 
		progress_t progress
	) noexcept
	{
		auto root_urn = Urn(this->webdav_root, true);
		auto file_urn = root_urn + remote_file;

		Data data = { buffer, 0, buffer_size };

		Request request(this->options());

		auto url = this->webdav_hostname + file_urn.quote(request.handle);

		Data response = { 0, 0, 0 };

		request.set(CURLOPT_UPLOAD, 1L);
		request.set(CURLOPT_URL, url.c_str());
		request.set(CURLOPT_READDATA, (size_t)&data);
		request.set(CURLOPT_READFUNCTION, (size_t)Callback::Read::buffer);
		request.set(CURLOPT_INFILESIZE_LARGE, (curl_off_t)buffer_size);
		request.set(CURLOPT_BUFFERSIZE, (long)Client::buffer_size);
		request.set(CURLOPT_WRITEDATA, (size_t)&response);
		request.set(CURLOPT_WRITEFUNCTION, (size_t)Callback::Append::buffer);
		if (progress != nullptr) {
			request.set(CURLOPT_XFERINFOFUNCTION, (size_t)progress.target<progress_funptr>());
			request.set(CURLOPT_NOPROGRESS, 0L);
		}
	
		bool is_performed = request.perform();

		if (callback != nullptr) callback(is_performed);
		return is_performed;
	}
Пример #11
0
	bool
	ClientImpl::sync_upload_from(
		std::string remote_file, 
		std::istream & stream, 
		callback_t callback, 
		progress_t progress
	) noexcept
	{
		auto root_urn = Urn(this->ftps_root, true);
		auto file_urn = root_urn + remote_file;

		Request request(this->options());

		auto url = this->ftps_hostname + file_urn.quote(request.handle);
		stream.seekg(0, std::ios::end);
		size_t stream_size = stream.tellg();
		stream.seekg(0, std::ios::beg);

		Data response = { 0, 0, 0 };

		request.set(CURLOPT_UPLOAD, 1L);
		request.set(CURLOPT_URL, url.c_str());
		request.set(CURLOPT_READDATA, (size_t)&stream);
		request.set(CURLOPT_READFUNCTION, (size_t)Callback::Read::stream);
		request.set(CURLOPT_INFILESIZE_LARGE, (curl_off_t)stream_size);
		request.set(CURLOPT_BUFFERSIZE, (long)Client::buffer_size);
		request.set(CURLOPT_WRITEDATA, (size_t)&response);
		request.set(CURLOPT_WRITEFUNCTION, (size_t)Callback::Append::buffer);
		if (progress != nullptr) {
			request.set(CURLOPT_XFERINFOFUNCTION, (size_t)progress.target<progress_funptr>());
			request.set(CURLOPT_NOPROGRESS, 0L);
		}
	
		bool is_performed = request.perform();

		if (callback != nullptr) callback(is_performed);
		return is_performed;
	}
Пример #12
0
	dict_t
	Client::info(std::string remote_resource) noexcept
	{
		auto clientImpl = GetImpl(this);
		auto root_urn = Urn(clientImpl->webdav_root, true);
		auto target_urn = root_urn + remote_resource;

		Header header = {
				"Accept: */*",
				"Depth: 1"
		};

		Data data = { 0, 0, 0 };

		Request request(clientImpl->options());

		auto url = clientImpl->webdav_hostname + target_urn.quote(request.handle);

		request.set(CURLOPT_CUSTOMREQUEST, "PROPFIND");
		request.set(CURLOPT_URL, url.c_str());
		request.set(CURLOPT_HTTPHEADER, (struct curl_slist *)header.handle);
		request.set(CURLOPT_WRITEDATA, (size_t)&data);
		request.set(CURLOPT_WRITEFUNCTION, (size_t)Callback::Append::buffer);

		bool is_performed = request.perform();

		if (!is_performed) return dict_t();

		pugi::xml_document document;
		document.load_buffer(data.buffer, (size_t)data.size);
		auto multistatus = document.select_single_node("d:multistatus").node();
		auto responses = multistatus.select_nodes("d:response");
		for (auto response : responses)
		{
			pugi::xml_node href = response.node().select_single_node("d:href").node();
			std::string encode_file_name = href.first_child().value();
			std::string resource_path = curl_unescape(encode_file_name.c_str(), (int)encode_file_name.length());
			auto target_path = target_urn.path();
			auto target_path_without_sep = std::string(target_path, 0, target_path.rfind("/")+1);
			auto resource_path_without_sep = std::string(resource_path, 0, resource_path.rfind("/")+1);
			if (resource_path_without_sep.compare(target_path_without_sep) == 0) {
				auto propstat = response.node().select_single_node("d:propstat").node();
				auto prop = propstat.select_single_node("d:prop").node();
				auto creation_date = prop.select_single_node("d:creationdate").node();
				auto display_name = prop.select_single_node("d:displayname").node();
				auto content_length = prop.select_single_node("d:getcontentlength").node();
				auto modified_date = prop.select_single_node("d:getlastmodified").node();
				auto resource_type = prop.select_single_node("d:resourcetype").node();

				dict_t information = {
						{"created", creation_date.first_child().value()},
						{"name", display_name.first_child().value()},
						{"size", content_length.first_child().value()},
						{"modified", modified_date.first_child().value()},
						{"type", resource_type.first_child().name()}
				};

				return information;
			}
		}

		return dict_t();
	}