• 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 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