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