| 
									
										
										
										
											2019-04-11 14:40:54 +08:00
										 |  |  | // Copyright (c) 2016-2018 Kiwano - Nomango
 | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | //
 | 
					
						
							| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | // 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:
 | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | //
 | 
					
						
							| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | // The above copyright notice and this permission notice shall be included in
 | 
					
						
							|  |  |  | // all copies or substantial portions of the Software.
 | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | //
 | 
					
						
							| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | // 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.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-20 13:58:17 +08:00
										 |  |  | #include <chrono>
 | 
					
						
							| 
									
										
										
										
											2020-01-21 11:05:28 +08:00
										 |  |  | #include <thread>
 | 
					
						
							| 
									
										
										
										
											2020-05-24 11:26:21 +08:00
										 |  |  | #include <kiwano/utils/Logger.h>
 | 
					
						
							| 
									
										
										
										
											2019-09-30 10:59:04 +08:00
										 |  |  | #include <kiwano/platform/Application.h>
 | 
					
						
							| 
									
										
										
										
											2020-01-21 11:05:28 +08:00
										 |  |  | #include <kiwano-network/HttpRequest.h>
 | 
					
						
							|  |  |  | #include <kiwano-network/HttpResponse.hpp>
 | 
					
						
							| 
									
										
										
										
											2020-02-14 17:56:50 +08:00
										 |  |  | #include <kiwano-network/HttpModule.h>
 | 
					
						
							| 
									
										
										
										
											2020-04-15 10:12:42 +08:00
										 |  |  | #include <curl/curl.h>  // CURL
 | 
					
						
							| 
									
										
										
										
											2019-04-05 16:06:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | namespace | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | using namespace kiwano; | 
					
						
							|  |  |  | using namespace kiwano::network; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | uint32_t write_data(void* buffer, uint32_t size, uint32_t nmemb, void* userp) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-02-10 13:47:00 +08:00
										 |  |  |     String*  recv_buffer = (String*)userp; | 
					
						
							|  |  |  |     uint32_t total       = size * nmemb; | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // 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; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-19 12:09:50 +08:00
										 |  |  |     bool Init(HttpModule* client, const Vector<String>& headers, const String& url, String* response_data, | 
					
						
							| 
									
										
										
										
											2020-02-10 13:47:00 +08:00
										 |  |  |               String* response_header, char* error_buffer) | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |     { | 
					
						
							|  |  |  |         if (!SetOption(CURLOPT_ERRORBUFFER, error_buffer)) | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         if (!SetOption(CURLOPT_TIMEOUT, client->GetTimeoutForRead())) | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         if (!SetOption(CURLOPT_CONNECTTIMEOUT, client->GetTimeoutForConnect())) | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-10 13:47:00 +08:00
										 |  |  |         const String& ssl_ca_file = client->GetSSLVerification(); | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |         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); | 
					
						
							|  |  |  |         return code == CURLE_OK && (*response_code >= 200 && *response_code < 300); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template <typename... _Args> | 
					
						
							|  |  |  |     bool SetOption(CURLoption option, _Args&&... args) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return CURLE_OK == curl_easy_setopt(curl_, option, std::forward<_Args>(args)...); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2020-02-19 12:09:50 +08:00
										 |  |  |     static inline bool GetRequest(HttpModule* client, const Vector<String>& headers, const String& url, | 
					
						
							| 
									
										
										
										
											2020-02-10 13:47:00 +08:00
										 |  |  |                                   long* response_code, String* response_data, String* response_header, | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |                                   char* error_buffer) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         Curl curl; | 
					
						
							|  |  |  |         return curl.Init(client, headers, url, response_data, response_header, error_buffer) | 
					
						
							|  |  |  |                && curl.SetOption(CURLOPT_FOLLOWLOCATION, true) && curl.Perform(response_code); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-19 12:09:50 +08:00
										 |  |  |     static inline bool PostRequest(HttpModule* client, const Vector<String>& headers, const String& url, | 
					
						
							|  |  |  |                                    const String& request_data, long* response_code, String* response_data, | 
					
						
							| 
									
										
										
										
											2020-02-10 13:47:00 +08:00
										 |  |  |                                    String* response_header, char* error_buffer) | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |     { | 
					
						
							|  |  |  |         Curl curl; | 
					
						
							|  |  |  |         return curl.Init(client, headers, url, response_data, response_header, error_buffer) | 
					
						
							|  |  |  |                && curl.SetOption(CURLOPT_POST, 1) && curl.SetOption(CURLOPT_POSTFIELDS, request_data.c_str()) | 
					
						
							|  |  |  |                && curl.SetOption(CURLOPT_POSTFIELDSIZE, request_data.size()) && curl.Perform(response_code); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-19 12:09:50 +08:00
										 |  |  |     static inline bool PutRequest(HttpModule* client, const Vector<String>& headers, const String& url, | 
					
						
							|  |  |  |                                   const String& request_data, long* response_code, String* response_data, | 
					
						
							| 
									
										
										
										
											2020-02-10 13:47:00 +08:00
										 |  |  |                                   String* response_header, char* error_buffer) | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |     { | 
					
						
							|  |  |  |         Curl curl; | 
					
						
							|  |  |  |         return curl.Init(client, headers, url, response_data, response_header, error_buffer) | 
					
						
							|  |  |  |                && curl.SetOption(CURLOPT_CUSTOMREQUEST, "PUT") | 
					
						
							|  |  |  |                && curl.SetOption(CURLOPT_POSTFIELDS, request_data.c_str()) | 
					
						
							|  |  |  |                && curl.SetOption(CURLOPT_POSTFIELDSIZE, request_data.size()) && curl.Perform(response_code); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-19 12:09:50 +08:00
										 |  |  |     static inline bool DeleteRequest(HttpModule* client, const Vector<String>& headers, const String& url, | 
					
						
							| 
									
										
										
										
											2020-02-10 13:47:00 +08:00
										 |  |  |                                      long* response_code, String* response_data, String* response_header, | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |                                      char* error_buffer) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         Curl curl; | 
					
						
							|  |  |  |         return curl.Init(client, headers, url, response_data, response_header, error_buffer) | 
					
						
							|  |  |  |                && curl.SetOption(CURLOPT_CUSTOMREQUEST, "DELETE") && curl.SetOption(CURLOPT_FOLLOWLOCATION, true) | 
					
						
							|  |  |  |                && curl.Perform(response_code); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     CURL*       curl_; | 
					
						
							|  |  |  |     curl_slist* curl_headers_; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | }  // namespace
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-11 14:40:54 +08:00
										 |  |  | namespace kiwano | 
					
						
							| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | namespace network | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-02-14 17:56:50 +08:00
										 |  |  | HttpModule::HttpModule() | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |     : timeout_for_connect_(30000 /* 30 seconds */) | 
					
						
							|  |  |  |     , timeout_for_read_(60000 /* 60 seconds */) | 
					
						
							| 
									
										
										
										
											2020-02-20 13:58:17 +08:00
										 |  |  |     , quit_flag_(false) | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-14 17:56:50 +08:00
										 |  |  | void HttpModule::SetupModule() | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     ::curl_global_init(CURL_GLOBAL_ALL); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-14 17:56:50 +08:00
										 |  |  |     std::thread thread(Closure(this, &HttpModule::NetworkThread)); | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |     thread.detach(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-14 17:56:50 +08:00
										 |  |  | void HttpModule::DestroyModule() | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-02-20 13:58:17 +08:00
										 |  |  |     // Set quit flag
 | 
					
						
							|  |  |  |     quit_flag_ = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Send a fake request
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         std::unique_lock<std::mutex> lock(request_mutex_); | 
					
						
							|  |  |  |         request_queue_.push(nullptr); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Notify work thread
 | 
					
						
							|  |  |  |     sleep_cond_.notify_one(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Wait for work thread destroyed
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         std::unique_lock<std::mutex> lock(quit_mutex_); | 
					
						
							|  |  |  |         quit_cond_.wait_for(lock, std::chrono::seconds(1)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Clear curl resources
 | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |     ::curl_global_cleanup(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-14 17:56:50 +08:00
										 |  |  | void HttpModule::Send(HttpRequestPtr request) | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     if (!request) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-20 13:58:17 +08:00
										 |  |  |     { | 
					
						
							|  |  |  |         std::unique_lock<std::mutex> lock(request_mutex_); | 
					
						
							|  |  |  |         request_queue_.push(request); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     sleep_cond_.notify_one(); | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-14 17:56:50 +08:00
										 |  |  | void HttpModule::NetworkThread() | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     while (true) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         HttpRequestPtr request; | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2020-02-20 13:58:17 +08:00
										 |  |  |             std::unique_lock<std::mutex> lock(request_mutex_); | 
					
						
							|  |  |  |             sleep_cond_.wait(lock, [&]() { return !request_queue_.empty(); }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |             request = request_queue_.front(); | 
					
						
							|  |  |  |             request_queue_.pop(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-20 13:58:17 +08:00
										 |  |  |         if (quit_flag_) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             quit_cond_.notify_one(); | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |         HttpResponsePtr response = new (std::nothrow) HttpResponse(request); | 
					
						
							|  |  |  |         Perform(request, response); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         response_mutex_.lock(); | 
					
						
							|  |  |  |         response_queue_.push(response); | 
					
						
							|  |  |  |         response_mutex_.unlock(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-14 17:56:50 +08:00
										 |  |  |         Application::GetInstance().PreformInMainThread(Closure(this, &HttpModule::DispatchResponseCallback)); | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-14 17:56:50 +08:00
										 |  |  | void HttpModule::Perform(HttpRequestPtr request, HttpResponsePtr response) | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-02-10 13:47:00 +08:00
										 |  |  |     bool   ok                 = false; | 
					
						
							|  |  |  |     long   response_code      = 0; | 
					
						
							|  |  |  |     char   error_message[256] = { 0 }; | 
					
						
							|  |  |  |     String response_header; | 
					
						
							|  |  |  |     String response_data; | 
					
						
							|  |  |  |     String url  = request->GetUrl(); | 
					
						
							|  |  |  |     String data = request->GetData(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Vector<String> headers; | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |     headers.reserve(request->GetHeaders().size()); | 
					
						
							|  |  |  |     for (const auto& pair : request->GetHeaders()) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-02-10 13:47:00 +08:00
										 |  |  |         headers.push_back(pair.first + ":" + pair.second); | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     switch (request->GetType()) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-02-06 16:54:47 +08:00
										 |  |  |     case HttpType::Get: | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |         ok = Curl::GetRequest(this, headers, url, &response_code, &response_data, &response_header, error_message); | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2020-02-06 16:54:47 +08:00
										 |  |  |     case HttpType::Post: | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |         ok = Curl::PostRequest(this, headers, url, data, &response_code, &response_data, &response_header, | 
					
						
							|  |  |  |                                error_message); | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2020-02-06 16:54:47 +08:00
										 |  |  |     case HttpType::Put: | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |         ok = | 
					
						
							|  |  |  |             Curl::PutRequest(this, headers, url, data, &response_code, &response_data, &response_header, error_message); | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2020-02-06 16:54:47 +08:00
										 |  |  |     case HttpType::Delete: | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |         ok = Curl::DeleteRequest(this, headers, url, &response_code, &response_data, &response_header, error_message); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     default: | 
					
						
							| 
									
										
										
										
											2020-02-14 17:56:50 +08:00
										 |  |  |         KGE_ERROR("HttpModule: unknown request type, only GET, POST, PUT or DELETE is supported"); | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response->SetResponseCode(response_code); | 
					
						
							| 
									
										
										
										
											2020-02-10 13:47:00 +08:00
										 |  |  |     response->SetHeader(response_header); | 
					
						
							|  |  |  |     response->SetData(response_data); | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |     if (!ok) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         response->SetSucceed(false); | 
					
						
							| 
									
										
										
										
											2020-02-10 13:47:00 +08:00
										 |  |  |         response->SetError(error_message); | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         response->SetSucceed(true); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-14 17:56:50 +08:00
										 |  |  | void HttpModule::DispatchResponseCallback() | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     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) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2020-02-15 17:32:32 +08:00
										 |  |  |             callback(request.Get(), response.Get()); | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | }  // namespace network
 | 
					
						
							|  |  |  | }  // namespace kiwano
 |