1 /* 2 * Copyright (c) 2023 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 COMMUNICATIONNETSTACK_HTTP_CLIENT_TASK_H 17 #define COMMUNICATIONNETSTACK_HTTP_CLIENT_TASK_H 18 19 #include <atomic> 20 #include <functional> 21 #include <memory> 22 #include <mutex> 23 #include <stdio.h> 24 #include <string.h> 25 #include <string> 26 27 #include "http_client_error.h" 28 #include "http_client_request.h" 29 #include "http_client_response.h" 30 #if HAS_NETMANAGER_BASE 31 #include "netstack_network_profiler.h" 32 #endif 33 34 namespace OHOS { 35 namespace NetStack { 36 namespace HttpClient { 37 enum TaskStatus { 38 IDLE, 39 RUNNING, 40 }; 41 42 enum TaskType { 43 DEFAULT, 44 UPLOAD, 45 }; 46 47 class HttpClientTask : public std::enable_shared_from_this<HttpClientTask> { 48 public: 49 /** 50 * Constructs an HttpClientTask object with the specified request. 51 * @param request The HTTP request object. 52 */ 53 HttpClientTask(const HttpClientRequest &request); 54 55 /** 56 * Constructs an HttpClientTask object with the specified request, type, and file path. 57 * @param request The HTTP request object. 58 * @param type The task type. 59 * @param filePath The file path to save the response content. 60 */ 61 HttpClientTask(const HttpClientRequest &request, TaskType type, const std::string &filePath); 62 63 /** 64 * Destructor that releases any allocated resources. 65 */ 66 ~HttpClientTask(); 67 68 /** 69 * Starts the HTTP request task. 70 * @return Returns true if the task starts successfully, false otherwise. 71 */ 72 bool Start(); 73 74 /** 75 * Cancels the ongoing HTTP request task. 76 */ 77 void Cancel(); 78 79 /** 80 * Gets the status of the HTTP request task. 81 * @return The current status of the task. 82 */ 83 [[nodiscard]] TaskStatus GetStatus(); 84 85 /** 86 * Gets the type of the HTTP request task. 87 * @return The type of the task. 88 */ 89 [[nodiscard]] TaskType GetType(); 90 91 /** 92 * Gets the ID of the HTTP request task. 93 * @return The ID of the task. 94 */ 95 [[nodiscard]] unsigned int GetTaskId(); 96 97 /** 98 * Gets the file path to save the response content. 99 * @return The file path. 100 */ 101 [[nodiscard]] const std::string &GetFilePath(); 102 103 /** 104 * Gets the HTTP request object associated with this task. 105 * @return A reference to the HTTP request object. 106 */ GetRequest()107 [[nodiscard]] HttpClientRequest &GetRequest() 108 { 109 return request_; 110 } 111 112 /** 113 * Gets the HTTP response object associated with this task. 114 * @return A reference to the HTTP response object. 115 */ GetResponse()116 [[nodiscard]] HttpClientResponse &GetResponse() 117 { 118 return response_; 119 } 120 121 /** 122 * Gets the HTTP error object associated with this task. 123 * @return A reference to the HTTP error object. 124 */ GetError()125 [[nodiscard]] HttpClientError &GetError() 126 { 127 return error_; 128 } 129 130 /** 131 * Gets the handle for interacting with the CURL library. 132 * @return The CURL handle. 133 */ GetCurlHandle()134 [[nodiscard]] CURL *GetCurlHandle() 135 { 136 return curlHandle_; 137 } 138 139 /** 140 * Sets a callback function to be called when the HTTP request succeeds. 141 * @param onSucceeded The callback function to be called when the request succeeds. 142 * It takes the HttpClientRequest object and the HttpClientResponse object as parameters. 143 */ 144 void OnSuccess( 145 const std::function<void(const HttpClientRequest &request, const HttpClientResponse &response)> &onSucceeded); 146 147 /** 148 * Sets a callback function to be called when the HTTP request is canceled. 149 * @param onCanceled The callback function to be called when the request is canceled. 150 * It takes the HttpClientRequest object and the HttpClientResponse object as parameters. 151 */ 152 void OnCancel( 153 const std::function<void(const HttpClientRequest &request, const HttpClientResponse &response)> &onCanceled); 154 155 /** 156 * Sets a callback function to be called when the HTTP request fails. 157 * @param onFailed The callback function to be called when the request fails. 158 * It takes the HttpClientRequest object, the HttpClientResponse object, 159 * and the HttpClientError object as parameters. 160 */ 161 void OnFail(const std::function<void(const HttpClientRequest &request, const HttpClientResponse &response, 162 const HttpClientError &error)> &onFailed); 163 164 /** 165 * Sets a callback function to be called when data is received in the HTTP response. 166 * @param onDataReceive The callback function to be called when data is received. 167 * It takes the HttpClientRequest object, a pointer to the received data, 168 * and the length of the received data as parameters. 169 */ 170 void OnDataReceive( 171 const std::function<void(const HttpClientRequest &request, const uint8_t *data, size_t length)> &onDataReceive); 172 173 /** 174 * Sets a callback function to be called to report the progress of the HTTP request. 175 * @param onProgress The callback function to be called to report the progress. 176 * It takes the HttpClientRequest object, the total number of bytes to download, 177 * the number of bytes downloaded, the total number of bytes to upload, 178 * and the number of bytes uploaded as parameters. 179 */ 180 void OnProgress(const std::function<void(const HttpClientRequest &request, u_long dlTotal, u_long dlNow, 181 u_long ulTotal, u_long ulNow)> &onProgress); 182 /** 183 * Sets the response received from the server for this HTTP request. 184 * @param response The HttpClientResponse object representing the response from the server. 185 */ 186 void SetResponse(const HttpClientResponse &response); 187 188 private: 189 friend class HttpSession; 190 191 /** 192 * Sets the status of the HTTP request task. 193 * @param status The status to be set. 194 */ 195 void SetStatus(TaskStatus status); 196 197 /** 198 * Sets the Curl options for the HTTP request. 199 * @return Returns true if the Curl options are set successfully, false otherwise. 200 */ 201 bool SetCurlOptions(); 202 203 /** 204 * Sets other Curl options for the HTTP request. 205 * @param handle The Curl handle. 206 * @return Returns true if the Curl options are set successfully, false otherwise. 207 */ 208 bool SetOtherCurlOption(CURL *handle); 209 210 /** 211 * Sets the server ssl cert options for the HTTP request. 212 * @param handle The Curl handle. 213 * @return Returns true if the set options are set successfully, false otherwise. 214 */ 215 bool SetServerSSLCertOption(CURL *curl); 216 217 /** 218 * Sets the ssl cert options for the HTTP request. 219 * @param handle The Curl handle. 220 * @return Returns true if the set options are set successfully, false otherwise. 221 */ 222 bool SetSSLCertOption(CURL *curl); 223 224 /** 225 * Ssl verify function for the HTTP request. 226 * @param handle The Curl handle. 227 * @param sslCtl The SSL handle. 228 * @return Returns CURLM_OK if the set options are set successfully, error code otherwise. 229 */ 230 CURLcode SslCtxFunction(CURL *curl, void *sslCtx); 231 232 /** 233 * Sets the upload options for the HTTP request. 234 * @param handle The Curl handle. 235 * @return Returns true if the upload options are set successfully, false otherwise. 236 */ 237 bool SetUploadOptions(CURL *handle); 238 239 /** 240 * Converts the HttpProtocol enum value to the corresponding Http version. 241 * @param ptcl The HttpProtocol enum value. 242 * @return The Http version as an unsigned integer. 243 */ 244 uint32_t GetHttpVersion(HttpProtocol ptcl) const; 245 246 /** 247 * Retrieves the HttpProxyInfo including host, port, exclusions, and tunnel flag. 248 * @param host The output string to store the proxy host. 249 * @param port The output integer to store the proxy port. 250 * @param exclusions The output string to store the proxy exclusions. 251 * @param tunnel The output bool to indicate if the proxy uses tunneling. 252 */ 253 void GetHttpProxyInfo(std::string &host, int32_t &port, std::string &exclusions, 254 bool &tunnel); 255 256 /** 257 * Callback function used to report the progress of the HTTP request. 258 * @param userData User-defined data passed to the callback function. 259 * @param dltotal The total number of bytes to download. 260 * @param dlnow The number of bytes downloaded so far. 261 * @param ultotal The total number of bytes to upload. 262 * @param ulnow The number of bytes uploaded so far. 263 * @return Returns 0 to continue the transfer, or a non-zero value to abort the transfer. 264 */ 265 static int ProgressCallback(void *userData, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, 266 curl_off_t ulnow); 267 268 /** 269 * Callback function used to receive data in the HTTP response. 270 * @param data Pointer to the received data. 271 * @param size Size of each element in the data buffer. 272 * @param memBytes Number of elements in the data buffer. 273 * @param userData User-defined data passed to the callback function. 274 * @return The number of bytes processed by the callback function. 275 */ 276 static size_t DataReceiveCallback(const void *data, size_t size, size_t memBytes, void *userData); 277 278 /** 279 * Callback function used to receive header data in the HTTP response. 280 * @param data Pointer to the received header data. 281 * @param size Size of each element in the data buffer. 282 * @param memBytes Number of elements in the data buffer. 283 * @param userData User-defined data passed to the callback function. 284 * @return The number of bytes processed by the callback function. 285 */ 286 static size_t HeaderReceiveCallback(const void *data, size_t size, size_t memBytes, void *userData); 287 288 /** 289 * Processes the Curl response message and updates the task status. 290 * @param msg The Curl message. 291 */ 292 void ProcessResponse(CURLMsg *msg); 293 294 /** 295 * Processes the response code in the HTTP response. 296 * @return Returns true if the response code is processed successfully, false otherwise. 297 */ 298 bool ProcessResponseCode(); 299 300 /** 301 * Get the timing from curl handle 302 * @return Returns timing, unit is seconds. 303 */ 304 double GetTimingFromCurl(CURL *handle, CURLINFO info) const; 305 306 /** 307 * Processes the cookie in the HTTP response. 308 * @param handle The Curl handle. 309 */ 310 void ProcessCookie(CURL *handle); 311 312 /** 313 * Get download or uploader size from curl handle 314 * @return Returns size, unit is bytes. 315 */ 316 curl_off_t GetSizeFromCurl(CURL *handle) const; 317 318 /** 319 * dump http informations from curl 320 */ 321 void DumpHttpPerformance() const; 322 323 std::function<void(const HttpClientRequest &request, const HttpClientResponse &response)> onSucceeded_; 324 std::function<void(const HttpClientRequest &request, const HttpClientResponse &response)> onCanceled_; 325 std::function<void(const HttpClientRequest &request, const HttpClientResponse &response, 326 const HttpClientError &error)> 327 onFailed_; 328 std::function<void(const HttpClientRequest &request, const uint8_t *data, size_t length)> onDataReceive_; 329 std::function<void(const HttpClientRequest &request, u_long dlTotal, u_long dlNow, u_long ulTotal, u_long ulNow)> 330 onProgress_; 331 332 HttpClientRequest request_; 333 HttpClientResponse response_; 334 HttpClientError error_; 335 336 TaskType type_; 337 TaskStatus status_; 338 unsigned int taskId_; 339 struct curl_slist *curlHeaderList_; 340 bool canceled_; 341 342 std::mutex mutex_; 343 CURL *curlHandle_; 344 static std::atomic<unsigned int> nextTaskId_; 345 std::string filePath_; 346 FILE *file_ = nullptr; 347 #if HAS_NETMANAGER_BASE 348 std::unique_ptr<NetworkProfilerUtils> networkProfilerUtils_; 349 #endif 350 }; 351 352 } // namespace HttpClient 353 } // namespace NetStack 354 } // namespace OHOS 355 356 #endif // COMMUNICATIONNETSTACK_HTTP_CLIENT_TASK_H