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