1 /* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef NET_HTTP_CLIENT_EXEC_H 17 #define NET_HTTP_CLIENT_EXEC_H 18 19 #include <atomic> 20 #include <condition_variable> 21 #include <functional> 22 #include <mutex> 23 #include <queue> 24 #include <thread> 25 #include <utility> 26 #include <vector> 27 #include <set> 28 29 #include "curl/curl.h" 30 #include "net_http_request_context.h" 31 32 namespace OHOS::NetStack::Http { 33 class NetHttpClientExec final { 34 public: 35 NetHttpClientExec() = default; 36 37 ~NetHttpClientExec() = default; 38 39 static bool RequestWithoutCache(RequestContext *context); 40 41 static void ExecRequest(RequestContext *context); 42 43 static std::string MakeUrl(const std::string &url, std::string param, const std::string &extraParam); 44 45 static bool MethodForGet(const std::string &method); 46 47 static bool MethodForPost(const std::string &method); 48 49 static bool EncodeUrlParam(std::string &str); 50 51 static bool Initialize(); 52 53 static bool IsInitialized(); 54 55 static void DeInitialize(); 56 57 struct StaticContextVec { 58 StaticContextVec() = default; 59 ~StaticContextVec() = default; 60 std::mutex mutexForContextVec; 61 std::set<RequestContext *> contextSet; 62 }; 63 static StaticContextVec staticContextSet_; 64 65 private: 66 static bool SetOption(CURL *curl, RequestContext *context, struct curl_slist *requestHeader); 67 68 static bool SetOtherOption(CURL *curl, RequestContext *context); 69 70 static bool SetRequestOption(CURL *curl, RequestContext *context); 71 72 static bool SetServerSSLCertOption(CURL *curl, OHOS::NetStack::Http::RequestContext *context); 73 74 static bool SetSSLCertOption(CURL *curl, RequestContext *context); 75 76 static bool SetDnsOption(CURL *curl, RequestContext *context); 77 78 static size_t OnWritingMemoryBody(const void *data, size_t size, size_t memBytes, void *userData); 79 80 static size_t OnWritingMemoryHeader(const void *data, size_t size, size_t memBytes, void *userData); 81 82 static struct curl_slist *MakeHeaders(const std::vector<std::string> &vec); 83 84 static bool IsUnReserved(unsigned char in); 85 86 static bool AddCurlHandle(CURL *handle, RequestContext *context); 87 88 static void HandleCurlData(CURLMsg *msg); 89 90 static bool GetCurlDataFromHandle(CURL *handle, RequestContext *context, CURLMSG curlMsg, CURLcode result); 91 92 static double GetTimingFromCurl(CURL *handle, CURLINFO info); 93 94 static void CacheCurlPerformanceTiming(CURL *handle, RequestContext *context); 95 96 static void RunThread(); 97 98 static void SendRequest(); 99 100 static void ReadResponse(); 101 102 static void GetGlobalHttpProxyInfo(std::string &host, int32_t &port, std::string &exclusions); 103 104 static void GetHttpProxyInfo(RequestContext *context, std::string &host, int32_t &port, std::string &exclusions); 105 106 static int ProgressCallback(void *userData, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, 107 curl_off_t ulnow); 108 109 static bool SetMultiPartOption(CURL *curl, RequestContext *context); 110 111 static void SetFormDataOption(MultiFormData &multiFormData, curl_mimepart *part, 112 CURL *curl, RequestContext *context); 113 114 static void AddRequestInfo(); 115 116 static bool IsContextDeleted(RequestContext *context); 117 118 struct RequestInfo { 119 RequestInfo() = delete; 120 ~RequestInfo() = default; 121 RequestInfoRequestInfo122 RequestInfo(RequestContext *c, CURL *h) : context(c), handle(h) {}; 123 124 RequestContext *context; 125 CURL *handle; 126 127 bool operator<(const RequestInfo &info) const 128 { 129 return context->options.GetPriority() < info.context->options.GetPriority(); 130 } 131 132 bool operator>(const RequestInfo &info) const 133 { 134 return context->options.GetPriority() > info.context->options.GetPriority(); 135 } 136 }; 137 138 struct StaticVariable { StaticVariableStaticVariable139 StaticVariable() : curlMulti(nullptr), initialized(false), runThread(true) {} 140 ~StaticVariableStaticVariable141 ~StaticVariable() 142 { 143 if (NetHttpClientExec::IsInitialized()) { 144 NetHttpClientExec::DeInitialize(); 145 } 146 } 147 148 std::mutex curlMultiMutex; 149 std::mutex mutexForInitialize; 150 CURLM *curlMulti; 151 std::map<CURL *, RequestContext *> contextMap; 152 std::thread workThread; 153 std::condition_variable conditionVariable; 154 std::priority_queue<RequestInfo> infoQueue; 155 156 #ifndef MAC_PLATFORM 157 std::atomic_bool initialized; 158 std::atomic_bool runThread; 159 #else 160 bool initialized; 161 bool runThread; 162 #endif 163 }; 164 static StaticVariable staticVariable_; 165 }; 166 } 167 #endif