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 upload options for the HTTP request. 209 * @param handle The Curl handle. 210 * @return Returns true if the upload options are set successfully, false otherwise. 211 */ 212 bool SetUploadOptions(CURL *handle); 213 214 /** 215 * Converts the HttpProtocol enum value to the corresponding Http version. 216 * @param ptcl The HttpProtocol enum value. 217 * @return The Http version as an unsigned integer. 218 */ 219 uint32_t GetHttpVersion(HttpProtocol ptcl) const; 220 221 /** 222 * Retrieves the HttpProxyInfo including host, port, exclusions, userpwd, and tunnel flag. 223 * @param host The output string to store the proxy host. 224 * @param port The output integer to store the proxy port. 225 * @param exclusions The output string to store the proxy exclusions. 226 * @param userpwd The output string to store the proxy username and password. 227 * @param tunnel The output bool to indicate if the proxy uses tunneling. 228 */ 229 void GetHttpProxyInfo(std::string &host, int32_t &port, std::string &exclusions, std::string &userpwd, 230 bool &tunnel); 231 232 /** 233 * Callback function used to report the progress of the HTTP request. 234 * @param userData User-defined data passed to the callback function. 235 * @param dltotal The total number of bytes to download. 236 * @param dlnow The number of bytes downloaded so far. 237 * @param ultotal The total number of bytes to upload. 238 * @param ulnow The number of bytes uploaded so far. 239 * @return Returns 0 to continue the transfer, or a non-zero value to abort the transfer. 240 */ 241 static int ProgressCallback(void *userData, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, 242 curl_off_t ulnow); 243 244 /** 245 * Callback function used to receive data in the HTTP response. 246 * @param data Pointer to the received data. 247 * @param size Size of each element in the data buffer. 248 * @param memBytes Number of elements in the data buffer. 249 * @param userData User-defined data passed to the callback function. 250 * @return The number of bytes processed by the callback function. 251 */ 252 static size_t DataReceiveCallback(const void *data, size_t size, size_t memBytes, void *userData); 253 254 /** 255 * Callback function used to receive header data in the HTTP response. 256 * @param data Pointer to the received header data. 257 * @param size Size of each element in the data buffer. 258 * @param memBytes Number of elements in the data buffer. 259 * @param userData User-defined data passed to the callback function. 260 * @return The number of bytes processed by the callback function. 261 */ 262 static size_t HeaderReceiveCallback(const void *data, size_t size, size_t memBytes, void *userData); 263 264 /** 265 * Processes the Curl response message and updates the task status. 266 * @param msg The Curl message. 267 */ 268 void ProcessResponse(CURLMsg *msg); 269 270 /** 271 * Processes the response code in the HTTP response. 272 * @return Returns true if the response code is processed successfully, false otherwise. 273 */ 274 bool ProcessResponseCode(); 275 276 /** 277 * Processes the cookie in the HTTP response. 278 * @param handle The Curl handle. 279 */ 280 void ProcessCookie(CURL *handle); 281 282 std::function<void(const HttpClientRequest &request, const HttpClientResponse &response)> onSucceeded_; 283 std::function<void(const HttpClientRequest &request, const HttpClientResponse &response)> onCanceled_; 284 std::function<void(const HttpClientRequest &request, const HttpClientResponse &response, 285 const HttpClientError &error)> 286 onFailed_; 287 std::function<void(const HttpClientRequest &request, const uint8_t *data, size_t length)> onDataReceive_; 288 std::function<void(const HttpClientRequest &request, u_long dlTotal, u_long dlNow, u_long ulTotal, u_long ulNow)> 289 onProgress_; 290 291 HttpClientRequest request_; 292 HttpClientResponse response_; 293 HttpClientError error_; 294 295 TaskType type_; 296 TaskStatus status_; 297 unsigned int taskId_; 298 struct curl_slist *curlHeaderList_; 299 bool canceled_; 300 301 std::mutex mutex_; 302 CURL *curlHandle_; 303 static std::atomic<unsigned int> nextTaskId_; 304 std::string filePath_; 305 FILE *file_ = nullptr; 306 }; 307 308 } // namespace HttpClient 309 } // namespace NetStack 310 } // namespace OHOS 311 312 #endif // COMMUNICATIONNETSTACK_HTTP_CLIENT_TASK_H 313