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