| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | // Copyright (c) 2016-2018 Easy2D - Nomango
 | 
					
						
							|  |  |  | // 
 | 
					
						
							|  |  |  | // Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
					
						
							|  |  |  | // of this software and associated documentation files (the "Software"), to deal
 | 
					
						
							|  |  |  | // in the Software without restriction, including without limitation the rights
 | 
					
						
							|  |  |  | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
					
						
							|  |  |  | // copies of the Software, and to permit persons to whom the Software is
 | 
					
						
							|  |  |  | // furnished to do so, subject to the following conditions:
 | 
					
						
							|  |  |  | // 
 | 
					
						
							|  |  |  | // The above copyright notice and this permission notice shall be included in
 | 
					
						
							|  |  |  | // all copies or substantial portions of the Software.
 | 
					
						
							|  |  |  | // 
 | 
					
						
							|  |  |  | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
					
						
							|  |  |  | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
					
						
							|  |  |  | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
					
						
							|  |  |  | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
					
						
							|  |  |  | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
					
						
							|  |  |  | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
					
						
							|  |  |  | // THE SOFTWARE.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-05 16:06:32 +08:00
										 |  |  | #include "../easy2d-network.h"
 | 
					
						
							| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | #include <thread>
 | 
					
						
							| 
									
										
										
										
											2019-03-31 23:09:49 +08:00
										 |  |  | #include <codecvt>
 | 
					
						
							| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-05 16:06:32 +08:00
										 |  |  | // CURL
 | 
					
						
							|  |  |  | #include "../third-party/curl/curl.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | #pragma comment(lib, "libcurl.lib")
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	using namespace easy2d; | 
					
						
							|  |  |  | 	using namespace easy2d::network; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	size_t write_data(void* buffer, size_t size, size_t nmemb, void* userp) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		std::string* recv_buffer = (std::string*)userp; | 
					
						
							|  |  |  | 		size_t total = size * nmemb; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// add data to the end of recv_buffer
 | 
					
						
							|  |  |  | 		// write data maybe called more than once in a single request
 | 
					
						
							|  |  |  | 		recv_buffer->append((char*)buffer, total); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return  total; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-31 23:09:49 +08:00
										 |  |  | 	std::string convert_to_utf8(String const& str) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv; | 
					
						
							|  |  |  | 		std::string result; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		try | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			result = utf8_conv.to_bytes(str.c_str()); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		catch (std::range_error&) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			// bad conversion
 | 
					
						
							|  |  |  | 			result = str.to_string(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return result; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	String convert_from_utf8(std::string const& str) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv; | 
					
						
							|  |  |  | 		String result; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		try | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			result = utf8_conv.from_bytes(str); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		catch (std::range_error&) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			// bad conversion
 | 
					
						
							|  |  |  | 			result = str; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return result; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | 	class Curl | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	public: | 
					
						
							|  |  |  | 		Curl() | 
					
						
							|  |  |  | 			: curl_(curl_easy_init()) | 
					
						
							|  |  |  | 			, curl_headers_(nullptr) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		~Curl() | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (curl_) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				curl_easy_cleanup(curl_); | 
					
						
							|  |  |  | 				curl_ = nullptr; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (curl_headers_) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				curl_slist_free_all(curl_headers_); | 
					
						
							|  |  |  | 				curl_headers_ = nullptr; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		bool Init(HttpClient* client, Array<std::string> const& headers, std::string const& url, std::string* response_data, std::string* response_header, char* error_buffer) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (!SetOption(CURLOPT_ERRORBUFFER, error_buffer)) | 
					
						
							|  |  |  | 				return false; | 
					
						
							|  |  |  | 			if (!SetOption(CURLOPT_TIMEOUT, client->GetTimeoutForRead())) | 
					
						
							|  |  |  | 				return false; | 
					
						
							|  |  |  | 			if (!SetOption(CURLOPT_CONNECTTIMEOUT, client->GetTimeoutForConnect())) | 
					
						
							|  |  |  | 				return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			const auto ssl_ca_file = client->GetSSLVerification().to_string(); | 
					
						
							|  |  |  | 			if (ssl_ca_file.empty()) { | 
					
						
							|  |  |  | 				if (!SetOption(CURLOPT_SSL_VERIFYPEER, 0L)) | 
					
						
							|  |  |  | 					return false; | 
					
						
							|  |  |  | 				if (!SetOption(CURLOPT_SSL_VERIFYHOST, 0L)) | 
					
						
							|  |  |  | 					return false; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							|  |  |  | 				if (!SetOption(CURLOPT_SSL_VERIFYPEER, 1L)) | 
					
						
							|  |  |  | 					return false; | 
					
						
							|  |  |  | 				if (!SetOption(CURLOPT_SSL_VERIFYHOST, 2L)) | 
					
						
							|  |  |  | 					return false; | 
					
						
							|  |  |  | 				if (!SetOption(CURLOPT_CAINFO, ssl_ca_file.c_str())) | 
					
						
							|  |  |  | 					return false; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (!SetOption(CURLOPT_NOSIGNAL, 1L)) | 
					
						
							|  |  |  | 				return false; | 
					
						
							|  |  |  | 			if (!SetOption(CURLOPT_ACCEPT_ENCODING, "")) | 
					
						
							|  |  |  | 				return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// set request headers
 | 
					
						
							|  |  |  | 			if (!headers.empty()) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				for (const auto& header : headers) | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					curl_headers_ = curl_slist_append(curl_headers_, header.c_str()); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if (!SetOption(CURLOPT_HTTPHEADER, curl_headers_)) | 
					
						
							|  |  |  | 					return false; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return SetOption(CURLOPT_URL, url.c_str()) | 
					
						
							|  |  |  | 				&& SetOption(CURLOPT_WRITEFUNCTION, write_data) | 
					
						
							|  |  |  | 				&& SetOption(CURLOPT_WRITEDATA, response_data) | 
					
						
							|  |  |  | 				&& SetOption(CURLOPT_HEADERFUNCTION, write_data) | 
					
						
							|  |  |  | 				&& SetOption(CURLOPT_HEADERDATA, response_header); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		bool Perform(long* response_code) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (CURLE_OK != curl_easy_perform(curl_)) | 
					
						
							|  |  |  | 				return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			CURLcode code = curl_easy_getinfo(curl_, CURLINFO_RESPONSE_CODE, response_code); | 
					
						
							| 
									
										
										
										
											2019-03-31 13:09:31 +08:00
										 |  |  | 			return code == CURLE_OK && (*response_code >= 200 && *response_code < 300); | 
					
						
							| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		template <typename ..._Args> | 
					
						
							|  |  |  | 		bool SetOption(CURLoption option, _Args&&... args) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			return CURLE_OK == curl_easy_setopt(curl_, option, std::forward<_Args>(args)...); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	public: | 
					
						
							| 
									
										
										
										
											2019-03-31 13:09:31 +08:00
										 |  |  | 		static inline bool GetRequest( | 
					
						
							|  |  |  | 			HttpClient* client, | 
					
						
							|  |  |  | 			Array<std::string> const& headers, | 
					
						
							|  |  |  | 			std::string const& url, | 
					
						
							|  |  |  | 			long* response_code, | 
					
						
							|  |  |  | 			std::string* response_data, | 
					
						
							|  |  |  | 			std::string* response_header, | 
					
						
							|  |  |  | 			char* error_buffer) | 
					
						
							| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			Curl curl; | 
					
						
							| 
									
										
										
										
											2019-03-31 13:09:31 +08:00
										 |  |  | 			return curl.Init(client, headers, url, response_data, response_header, error_buffer) | 
					
						
							| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | 				&& curl.SetOption(CURLOPT_FOLLOWLOCATION, true) | 
					
						
							|  |  |  | 				&& curl.Perform(response_code); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-31 13:09:31 +08:00
										 |  |  | 		static inline bool PostRequest( | 
					
						
							|  |  |  | 			HttpClient* client, | 
					
						
							|  |  |  | 			Array<std::string> const& headers, | 
					
						
							|  |  |  | 			std::string const& url, | 
					
						
							|  |  |  | 			std::string const& request_data, | 
					
						
							|  |  |  | 			long* response_code, | 
					
						
							|  |  |  | 			std::string* response_data, | 
					
						
							|  |  |  | 			std::string* response_header, | 
					
						
							|  |  |  | 			char* error_buffer) | 
					
						
							| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			Curl curl; | 
					
						
							| 
									
										
										
										
											2019-03-31 13:09:31 +08:00
										 |  |  | 			return curl.Init(client, headers, url, response_data, response_header, error_buffer) | 
					
						
							| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | 				&& curl.SetOption(CURLOPT_POST, 1) | 
					
						
							|  |  |  | 				&& curl.SetOption(CURLOPT_POSTFIELDS, request_data.c_str()) | 
					
						
							|  |  |  | 				&& curl.SetOption(CURLOPT_POSTFIELDSIZE, request_data.size()) | 
					
						
							|  |  |  | 				&& curl.Perform(response_code); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-31 13:09:31 +08:00
										 |  |  | 		static inline bool PutRequest( | 
					
						
							|  |  |  | 			HttpClient* client, | 
					
						
							|  |  |  | 			Array<std::string> const& headers, | 
					
						
							|  |  |  | 			std::string const& url, | 
					
						
							|  |  |  | 			std::string const& request_data, | 
					
						
							|  |  |  | 			long* response_code, | 
					
						
							|  |  |  | 			std::string* response_data, | 
					
						
							|  |  |  | 			std::string* response_header, | 
					
						
							|  |  |  | 			char* error_buffer) | 
					
						
							| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			Curl curl; | 
					
						
							| 
									
										
										
										
											2019-03-31 13:09:31 +08:00
										 |  |  | 			return curl.Init(client, headers, url, response_data, response_header, error_buffer) | 
					
						
							| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | 				&& curl.SetOption(CURLOPT_CUSTOMREQUEST, "PUT") | 
					
						
							|  |  |  | 				&& curl.SetOption(CURLOPT_POSTFIELDS, request_data.c_str()) | 
					
						
							|  |  |  | 				&& curl.SetOption(CURLOPT_POSTFIELDSIZE, request_data.size()) | 
					
						
							|  |  |  | 				&& curl.Perform(response_code); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-31 13:09:31 +08:00
										 |  |  | 		static inline bool DeleteRequest( | 
					
						
							|  |  |  | 			HttpClient* client, | 
					
						
							|  |  |  | 			Array<std::string> const& headers, | 
					
						
							|  |  |  | 			std::string const& url, | 
					
						
							|  |  |  | 			long* response_code, | 
					
						
							|  |  |  | 			std::string* response_data, | 
					
						
							|  |  |  | 			std::string* response_header, | 
					
						
							|  |  |  | 			char* error_buffer) | 
					
						
							| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			Curl curl; | 
					
						
							| 
									
										
										
										
											2019-03-31 13:09:31 +08:00
										 |  |  | 			return curl.Init(client, headers, url, response_data, response_header, error_buffer) | 
					
						
							| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | 				&& curl.SetOption(CURLOPT_CUSTOMREQUEST, "DELETE") | 
					
						
							|  |  |  | 				&& curl.SetOption(CURLOPT_FOLLOWLOCATION, true) | 
					
						
							|  |  |  | 				&& curl.Perform(response_code); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	private: | 
					
						
							|  |  |  | 		CURL* curl_; | 
					
						
							|  |  |  | 		curl_slist* curl_headers_; | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace easy2d | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	namespace network | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		HttpClient::HttpClient() | 
					
						
							|  |  |  | 			: app_(nullptr) | 
					
						
							|  |  |  | 			, timeout_for_connect_(30000 /* 30 seconds */) | 
					
						
							|  |  |  | 			, timeout_for_read_(60000 /* 60 seconds */) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		void HttpClient::SetupComponent(Application * app) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			app_ = app; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			::curl_global_init(CURL_GLOBAL_ALL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			std::thread thread(Closure(this, &HttpClient::NetworkThread)); | 
					
						
							|  |  |  | 			thread.detach(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		void HttpClient::DestroyComponent() | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			::curl_global_cleanup(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		void HttpClient::Send(HttpRequestPtr const & request) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (!request) | 
					
						
							|  |  |  | 				return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			request_mutex_.lock(); | 
					
						
							|  |  |  | 			request_queue_.push(request); | 
					
						
							|  |  |  | 			request_mutex_.unlock(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			sleep_condition_.notify_one(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		void HttpClient::NetworkThread() | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			while (true) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				HttpRequestPtr request; | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					std::lock_guard<std::mutex> lock(request_mutex_); | 
					
						
							|  |  |  | 					while (request_queue_.empty()) | 
					
						
							|  |  |  | 					{ | 
					
						
							|  |  |  | 						sleep_condition_.wait(request_mutex_); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					request = request_queue_.front(); | 
					
						
							|  |  |  | 					request_queue_.pop(); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				HttpResponsePtr response = new (std::nothrow) HttpResponse(request); | 
					
						
							|  |  |  | 				Perform(request, response); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				response_mutex_.lock(); | 
					
						
							|  |  |  | 				response_queue_.push(response); | 
					
						
							|  |  |  | 				response_mutex_.unlock(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (app_) | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					app_->PreformFunctionInMainThread(Closure(this, &HttpClient::DispatchResponseCallback)); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		void HttpClient::Perform(HttpRequestPtr const & request, HttpResponsePtr const & response) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			bool ok = false; | 
					
						
							|  |  |  | 			long response_code = 0; | 
					
						
							| 
									
										
										
										
											2019-03-31 13:09:31 +08:00
										 |  |  | 			char error_message[256] = { 0 }; | 
					
						
							|  |  |  | 			std::string response_header; | 
					
						
							|  |  |  | 			std::string response_data; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-31 23:09:49 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			std::string url = convert_to_utf8(request->GetUrl()); | 
					
						
							|  |  |  | 			std::string data = convert_to_utf8(request->GetData()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-31 13:09:31 +08:00
										 |  |  | 			Array<std::string> headers; | 
					
						
							|  |  |  | 			headers.reserve(request->GetHeaders().size()); | 
					
						
							| 
									
										
										
										
											2019-03-31 23:09:49 +08:00
										 |  |  | 			for (const auto& pair : request->GetHeaders()) | 
					
						
							| 
									
										
										
										
											2019-03-31 13:09:31 +08:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2019-03-31 23:09:49 +08:00
										 |  |  | 				headers.push_back(pair.first.to_string() + ":" + pair.second.to_string()); | 
					
						
							| 
									
										
										
										
											2019-03-31 13:09:31 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			switch (request->GetType()) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 			case HttpRequest::Type::Get: | 
					
						
							| 
									
										
										
										
											2019-03-31 13:09:31 +08:00
										 |  |  | 				ok = Curl::GetRequest(this, headers, url, &response_code, &response_data, &response_header, error_message); | 
					
						
							| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 			case HttpRequest::Type::Post: | 
					
						
							| 
									
										
										
										
											2019-03-31 13:09:31 +08:00
										 |  |  | 				ok = Curl::PostRequest(this, headers, url, data, &response_code, &response_data, &response_header, error_message); | 
					
						
							| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 			case HttpRequest::Type::Put: | 
					
						
							| 
									
										
										
										
											2019-03-31 13:09:31 +08:00
										 |  |  | 				ok = Curl::PutRequest(this, headers, url, data, &response_code, &response_data, &response_header, error_message); | 
					
						
							| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 			case HttpRequest::Type::Delete: | 
					
						
							| 
									
										
										
										
											2019-03-31 13:09:31 +08:00
										 |  |  | 				ok = Curl::DeleteRequest(this, headers, url, &response_code, &response_data, &response_header, error_message); | 
					
						
							| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 			default: | 
					
						
							|  |  |  | 				E2D_ERROR_LOG(L"HttpClient: unknown request type, only GET, POST, PUT or DELETE is supported"); | 
					
						
							|  |  |  | 				return; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			response->SetResponseCode(response_code); | 
					
						
							| 
									
										
										
										
											2019-03-31 13:09:31 +08:00
										 |  |  | 			response->SetHeader(response_header); | 
					
						
							| 
									
										
										
										
											2019-03-31 23:09:49 +08:00
										 |  |  | 			response->SetData(convert_from_utf8(response_data)); | 
					
						
							| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | 			if (!ok) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				response->SetSucceed(false); | 
					
						
							|  |  |  | 				response->SetError(error_message); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				response->SetSucceed(true); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		void HttpClient::DispatchResponseCallback() | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			HttpResponsePtr response; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			response_mutex_.lock(); | 
					
						
							|  |  |  | 			if (!response_queue_.empty()) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				response = response_queue_.front(); | 
					
						
							|  |  |  | 				response_queue_.pop(); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			response_mutex_.unlock(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (response) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				HttpRequestPtr request = response->GetRequest(); | 
					
						
							|  |  |  | 				const auto& callback = request->GetResponseCallback(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (callback) | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					callback(request, response); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |