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 /** 187 * Sets a callback function to be called when headers is received in the HTTP response. 188 * @param onHeadersReceive The callback function to be called when headers is received. 189 */ 190 void OnHeadersReceive(const std::function<void(const HttpClientRequest &request, 191 std::map<std::string, std::string> headersWithSetCookie)> &onHeadersReceive); 192 193 /** 194 * Sets the response received from the server for this HTTP request. 195 * @param response The HttpClientResponse object representing the response from the server. 196 */ 197 void SetResponse(const HttpClientResponse &response); 198 199 RequestTracer::Trace &GetTrace(); 200 private: 201 friend class HttpSession; 202 203 /** 204 * Sets the status of the HTTP request task. 205 * @param status The status to be set. 206 */ 207 void SetStatus(TaskStatus status); 208 209 /** 210 * Sets the Curl options for the HTTP request. 211 * @return Returns true if the Curl options are set successfully, false otherwise. 212 */ 213 bool SetCurlOptions(); 214 215 /** 216 * Sets the Curl options for the tracing stages. 217 * @return Returns true if the trace options are set successfully, false otherwise. 218 */ 219 bool SetTraceOptions(CURL *handle); 220 221 /** 222 * Sets other Curl options for the HTTP request. 223 * @param handle The Curl handle. 224 * @return Returns true if the Curl options are set successfully, false otherwise. 225 */ 226 bool SetOtherCurlOption(CURL *handle); 227 228 /** 229 * Sets the range options for the HTTP request. 230 * @param handle The Curl handle. 231 * @return Returns true if the request options are set successfully, false otherwise. 232 */ 233 bool SetRequestOption(CURL *handle); 234 235 /** 236 * Sets the server ssl cert options for the HTTP request. 237 * @param handle The Curl handle. 238 * @return Returns true if the set options are set successfully, false otherwise. 239 */ 240 bool SetServerSSLCertOption(CURL *curl); 241 242 /** 243 * Sets the ssl cert options for the HTTP request. 244 * @param handle The Curl handle. 245 * @return Returns true if the set options are set successfully, false otherwise. 246 */ 247 bool SetSSLCertOption(CURL *curl); 248 249 /** 250 * Ssl verify function for the HTTP request. 251 * @param handle The Curl handle. 252 * @param sslCtl The SSL handle. 253 * @return Returns CURLM_OK if the set options are set successfully, error code otherwise. 254 */ 255 CURLcode SslCtxFunction(CURL *curl, void *sslCtx); 256 257 /** 258 * Sets the upload options for the HTTP request. 259 * @param handle The Curl handle. 260 * @return Returns true if the upload options are set successfully, false otherwise. 261 */ 262 bool SetUploadOptions(CURL *handle); 263 264 /** 265 * Converts the HttpProtocol enum value to the corresponding Http version. 266 * @param ptcl The HttpProtocol enum value. 267 * @return The Http version as an unsigned integer. 268 */ 269 uint32_t GetHttpVersion(HttpProtocol ptcl) const; 270 271 /** 272 * Retrieves the HttpProxyInfo including host, port, exclusions, and tunnel flag. 273 * @param host The output string to store the proxy host. 274 * @param port The output integer to store the proxy port. 275 * @param exclusions The output string to store the proxy exclusions. 276 * @param tunnel The output bool to indicate if the proxy uses tunneling. 277 */ 278 void GetHttpProxyInfo(std::string &host, int32_t &port, std::string &exclusions, 279 bool &tunnel); 280 281 /** 282 * Callback function used to report the progress of the HTTP request. 283 * @param userData User-defined data passed to the callback function. 284 * @param dltotal The total number of bytes to download. 285 * @param dlnow The number of bytes downloaded so far. 286 * @param ultotal The total number of bytes to upload. 287 * @param ulnow The number of bytes uploaded so far. 288 * @return Returns 0 to continue the transfer, or a non-zero value to abort the transfer. 289 */ 290 static int ProgressCallback(void *userData, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, 291 curl_off_t ulnow); 292 293 /** 294 * Callback function used to receive data in the HTTP response. 295 * @param data Pointer to the received data. 296 * @param size Size of each element in the data buffer. 297 * @param memBytes Number of elements in the data buffer. 298 * @param userData User-defined data passed to the callback function. 299 * @return The number of bytes processed by the callback function. 300 */ 301 static size_t DataReceiveCallback(const void *data, size_t size, size_t memBytes, void *userData); 302 303 /** 304 * Callback function used to receive header data in the HTTP response. 305 * @param data Pointer to the received header data. 306 * @param size Size of each element in the data buffer. 307 * @param memBytes Number of elements in the data buffer. 308 * @param userData User-defined data passed to the callback function. 309 * @return The number of bytes processed by the callback function. 310 */ 311 static size_t HeaderReceiveCallback(const void *data, size_t size, size_t memBytes, void *userData); 312 313 /** 314 * Processes the Curl response message and updates the task status. 315 * @param msg The Curl message. 316 */ 317 void ProcessResponse(CURLMsg *msg); 318 319 /** 320 * Processes the response code in the HTTP response. 321 * @return Returns true if the response code is processed successfully, false otherwise. 322 */ 323 bool ProcessResponseCode(); 324 325 /** 326 * Get the timing from curl handle 327 * @return Returns timing, unit is seconds. 328 */ 329 double GetTimingFromCurl(CURL *handle, CURLINFO info) const; 330 331 /** 332 * Processes the cookie in the HTTP response. 333 * @param handle The Curl handle. 334 */ 335 void ProcessCookie(CURL *handle); 336 337 /** 338 * Get download or uploader size from curl handle 339 * @return Returns size, unit is bytes. 340 */ 341 curl_off_t GetSizeFromCurl(CURL *handle) const; 342 343 /** 344 * dump http informations from curl 345 */ 346 void DumpHttpPerformance(); 347 348 /** 349 * Sets the DNS cache options for the HTTP request. 350 * @return Returns true if the Curl options are set successfully, false otherwise. 351 */ 352 bool SetDnsCacheOption(CURL *handle); 353 354 /** 355 * Sets the addressFamily for the HTTP request. 356 * @return Returns the string of addressFamily. 357 */ 358 bool SetIpResolve(CURL *handle); 359 360 #ifdef HTTP_HANDOVER_FEATURE 361 /** 362 * Get the flag which indicating whether the request is success. 363 * @return Return flag indicating the request whether is success. 364 */ IsSuccess()365 bool IsSuccess() 366 { 367 return isSuccess_; 368 } 369 370 /** 371 * Set the request whether is success. 372 */ 373 void SetSuccess(bool isSuccess); 374 375 /** 376 * Get network switch information. 377 * @return Return String format for obtaining network sswitching information. 378 */ 379 std::string GetRequestHandoverInfo(); 380 381 /** 382 * Set the request information and print it to the log. 383 */ 384 void SetRequestHandoverInfo(int32_t handoverNum, int32_t handoverReason, double flowControlTime, 385 int32_t readFlag); 386 #endif 387 388 /** 389 * Gets the start and end download position for the HTTP request. 390 * @return Returns the string of range. If the position is invallid, the string is empty. 391 */ 392 std::string GetRangeString() const; 393 394 std::function<void(const HttpClientRequest &request, const HttpClientResponse &response)> onSucceeded_; 395 std::function<void(const HttpClientRequest &request, const HttpClientResponse &response)> onCanceled_; 396 std::function<void(const HttpClientRequest &request, const HttpClientResponse &response, 397 const HttpClientError &error)> 398 onFailed_; 399 std::function<void(const HttpClientRequest &request, const uint8_t *data, size_t length)> onDataReceive_; 400 std::function<void(const HttpClientRequest &request, u_long dlTotal, u_long dlNow, u_long ulTotal, u_long ulNow)> 401 onProgress_; 402 std::function<void(const HttpClientRequest &request, std::map<std::string, std::string> headerWithSetCookie)> 403 onHeadersReceive_; 404 405 HttpClientRequest request_; 406 HttpClientResponse response_; 407 HttpClientError error_; 408 #ifdef HTTP_HANDOVER_FEATURE 409 bool isSuccess_ = false; 410 int32_t handoverNum_ = -1; 411 int32_t handoverReason_ = -1; 412 double flowControlTime_ = 0.0; 413 int32_t readFlag_ = -1; 414 #endif 415 416 TaskType type_; 417 TaskStatus status_; 418 unsigned int taskId_; 419 struct curl_slist *curlHeaderList_; 420 bool canceled_; 421 422 std::mutex mutex_; 423 CURL *curlHandle_; 424 static std::atomic<unsigned int> nextTaskId_; 425 std::string filePath_; 426 FILE *file_ = nullptr; 427 #if HAS_NETMANAGER_BASE 428 std::unique_ptr<NetworkProfilerUtils> networkProfilerUtils_; 429 #endif 430 std::unique_ptr<RequestTracer::Trace> trace_; 431 }; 432 433 } // namespace HttpClient 434 } // namespace NetStack 435 } // namespace OHOS 436 437 #endif // COMMUNICATIONNETSTACK_HTTP_CLIENT_TASK_H