• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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