• 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  #include <cstring>
17  #include <iostream>
18  #include <vector>
19  #include <string>
20 
21  #include "net_http.h"
22  #include "netstack_hash_map.h"
23  #include "netstack_log.h"
24  #include "net_http_inner_types.h"
25  #include "http_client_request.h"
26  #include "http_client.h"
27  #include "http_client_constant.h"
28  #include "netstack_common_utils.h"
29 
30 using namespace OHOS::NetStack::HttpClient;
31 
32 std::mutex requestMutex;
33 static std::unordered_map<uint32_t, std::shared_ptr<HttpClientTask>> cppRequestTask;
34 
OH_Http_CreateHeaders(void)35 Http_Headers *OH_Http_CreateHeaders(void)
36 {
37     Http_Headers *headers = (Http_Headers *)malloc(sizeof(Http_Headers));
38     if (headers == nullptr) {
39         NETSTACK_LOGE("failed to alloc for headers");
40         return nullptr;
41     }
42     headers->fields = CreateMap();
43     if (headers->fields == nullptr) {
44         NETSTACK_LOGE("failed to alloc memory for headerMap");
45         free(headers);
46         headers = nullptr;
47     }
48 
49     return headers;
50 }
51 
OH_Http_DestroyHeaderValue(void * value)52 static void OH_Http_DestroyHeaderValue(void *value)
53 {
54     Http_HeaderValue *headerValue = (Http_HeaderValue *)value;
55     Http_HeaderValue *next;
56     while (headerValue != nullptr) {
57         next = headerValue->next;
58         free(headerValue->value);
59         headerValue->value = nullptr;
60         free(headerValue);
61         headerValue = next;
62     }
63 }
64 
OH_Http_DestroyHeaders(Http_Headers ** headers)65 void OH_Http_DestroyHeaders(Http_Headers **headers)
66 {
67     if (headers == nullptr) {
68         return;
69     }
70     if (*headers == nullptr) {
71         return;
72     }
73     if ((*headers)->fields != nullptr) {
74         Netstack_DestroyMapWithValue((*headers)->fields, OH_Http_DestroyHeaderValue);
75         (*headers)->fields = nullptr;
76     }
77     free(*headers);
78 }
79 
OH_Http_ToLowerCase(const char * str)80 static char *OH_Http_ToLowerCase(const char *str)
81 {
82     if (str == nullptr) {
83         return nullptr;
84     }
85     char *lowerStr = strdup(str);
86     if (lowerStr == nullptr) {
87         NETSTACK_LOGE("failed to alloc memory for string");
88         return nullptr;
89     }
90     for (size_t i = 0; i < strlen(lowerStr); i++) {
91         lowerStr[i] = static_cast<char>(tolower(static_cast<int>(lowerStr[i])));
92     }
93     return lowerStr;
94 }
95 
96 // copy both name and value
OH_Http_SetHeaderValue(Http_Headers * headers,const char * name,const char * value)97 uint32_t OH_Http_SetHeaderValue(Http_Headers *headers, const char *name, const char *value)
98 {
99     if (headers == nullptr || headers->fields == nullptr || name == nullptr || value == nullptr) {
100         return OH_HTTP_PARAMETER_ERROR;
101     }
102 
103     char *lowerName = OH_Http_ToLowerCase(name);
104     if (lowerName == nullptr) {
105         return OH_HTTP_OUT_OF_MEMORY;
106     }
107     Http_HeaderValue *existValue = (Http_HeaderValue *)Netstack_GetMapEntry(headers->fields, lowerName);
108     Http_HeaderValue *previous = existValue;
109     while (existValue != nullptr) {
110         if (strcmp(existValue->value, value) == 0) {
111             free(lowerName);
112             return OH_HTTP_RESULT_OK;
113         }
114         previous = existValue;
115         existValue = existValue->next;
116     }
117 
118     Http_HeaderValue *headerValue = (Http_HeaderValue *)calloc(1, sizeof(Http_HeaderValue));
119     if (headerValue == nullptr) {
120         NETSTACK_LOGE("failed to alloc memory for header value");
121         free(lowerName);
122         return OH_HTTP_OUT_OF_MEMORY;
123     }
124     headerValue->value = strdup(value);
125     if (headerValue->value == nullptr) {
126         free(headerValue);
127         free(lowerName);
128         return OH_HTTP_OUT_OF_MEMORY;
129     }
130 
131     if (previous == nullptr) {
132         uint32_t res = Netstack_PutMapEntry(headers->fields, lowerName, headerValue);
133         if (res != OH_HTTP_RESULT_OK) {
134             free(headerValue->value);
135             free(headerValue);
136         }
137         free(lowerName);
138         return res;
139     }
140     previous->next = headerValue;
141     free(lowerName);
142     return OH_HTTP_RESULT_OK;
143 }
144 
OH_Http_GetHeaderValue(Http_Headers * headers,const char * name)145 Http_HeaderValue *OH_Http_GetHeaderValue(Http_Headers *headers, const char *name)
146 {
147     if (headers == nullptr || headers->fields == nullptr || name == nullptr) {
148         return nullptr;
149     }
150     char *lowerName = OH_Http_ToLowerCase(name);
151     if (lowerName == nullptr) {
152         return nullptr;
153     }
154     Http_HeaderValue *value = (Http_HeaderValue *)Netstack_GetMapEntry(headers->fields, lowerName);
155     free(lowerName);
156     return value;
157 }
158 
OH_Http_GetHeaderEntries(Http_Headers * headers)159 Http_HeaderEntry *OH_Http_GetHeaderEntries(Http_Headers *headers)
160 {
161     if (headers == nullptr || headers->fields == nullptr) {
162         NETSTACK_LOGE("OH_Http_GetHeaderEntries headers or headers->fields is null");
163         return nullptr;
164     }
165     Netstack_MapIterator *ite = Netstack_CreateMapIterator(headers->fields);
166     if (ite == nullptr) {
167         NETSTACK_LOGE("OH_Http_GetHeaderEntries ite is null");
168         return nullptr;
169     }
170     Http_HeaderEntry *entry = (Http_HeaderEntry *)calloc(1, sizeof(Http_HeaderEntry));
171     if (entry == nullptr) {
172         Netstack_DestroyMapIterator(ite);
173         return nullptr;
174     }
175     Http_HeaderEntry *head = entry;
176 
177     while (ite->currentEntry != nullptr) {
178         entry->key = ite->currentEntry->key;
179         entry->value = (Http_HeaderValue *)ite->currentEntry->value;
180 
181         Netstack_MapIterateNext(ite);
182         if (ite->currentEntry != nullptr) {
183             entry->next = (Http_HeaderEntry *)calloc(1, sizeof(Http_HeaderEntry));
184             if (entry->next == nullptr) {
185                 OH_Http_DestroyHeaderEntries(&head);
186                 head = nullptr;
187                 break;
188             }
189             entry = entry->next;
190         }
191     }
192     Netstack_DestroyMapIterator(ite);
193     return head;
194 }
195 
OH_Http_DestroyHeaderEntries(Http_HeaderEntry ** entry)196 void OH_Http_DestroyHeaderEntries(Http_HeaderEntry **entry)
197 {
198     if (entry == nullptr || *entry == nullptr) {
199         NETSTACK_LOGE("OH_Http_DestroyHeaderEntries entry or *entry is null");
200         return;
201     }
202     Http_HeaderEntry *next;
203     while (*entry != nullptr) {
204         next = (*entry)->next;
205         free(*entry);
206         *entry = next;
207     }
208 }
209 
OH_Http_CreateRequest(const char * url)210 Http_Request *OH_Http_CreateRequest(const char *url)
211 {
212     NETSTACK_LOGD("liuleimin OH_Http_CreateRequest enter");
213     if (url == nullptr) {
214         NETSTACK_LOGE("create request failed: invalid url");
215         return nullptr;
216     }
217     Http_Request *request = (Http_Request *)calloc(1, sizeof(Http_Request));
218     if (request == nullptr) {
219         NETSTACK_LOGE("failed to alloc memory for request");
220         return nullptr;
221     }
222     request->url = strdup(url);
223     if (request->url == nullptr) {
224         NETSTACK_LOGE("failed strdup url");
225         free(request);
226         return nullptr;
227     }
228     return request;
229 }
230 
OH_Http_ToCHeaders(std::map<std::string,std::string> & map)231 Http_Headers *OH_Http_ToCHeaders(std::map<std::string, std::string> &map)
232 {
233     Http_Headers *cHeaders = OH_Http_CreateHeaders();
234     if (cHeaders == nullptr) {
235         return nullptr;
236     }
237     for (auto it = map.begin(); it != map.end(); ++it) {
238            if (!it->first.empty() && !it->second.empty()) {
239                (void)OH_Http_SetHeaderValue(cHeaders, it->first.c_str(), it->second.c_str());
240            }
241     }
242     return cHeaders;
243 }
244 
OH_Http_SetHeaderData(Http_Headers * headers,HttpClientRequest * httpReq)245 void OH_Http_SetHeaderData(Http_Headers *headers, HttpClientRequest *httpReq)
246 {
247     if (headers == nullptr || httpReq == nullptr) {
248         return;
249     }
250     Http_HeaderEntry *entries = OH_Http_GetHeaderEntries(headers);
251     Http_HeaderValue *headerValue;
252     Http_HeaderEntry *delEntries = entries;
253     while (entries != nullptr) {
254         headerValue = entries->value;
255         while (headerValue != nullptr && entries->key != nullptr) {
256             httpReq->SetHeader(entries->key, headerValue->value);
257             headerValue = headerValue->next;
258         }
259         entries = entries->next;
260     }
261     OH_Http_DestroyHeaderEntries(&delEntries);
262 }
263 
OH_Http_DestroyResponse(Http_Response ** response)264 static void OH_Http_DestroyResponse(Http_Response **response)
265 {
266     NETSTACK_LOGE("OH_Http_DestroyResponse enter");
267     if (response == nullptr || *response == nullptr) {
268         NETSTACK_LOGE("OH_Http_DestroyResponse response is nullptr");
269         return;
270     }
271     if ((*response)->headers != nullptr) {
272         OH_Http_DestroyHeaders(&(*response)->headers);
273     }
274     if ((*response)->cookies != nullptr) {
275         free((*response)->cookies);
276         (*response)->cookies = nullptr;
277     }
278     if ((*response)->performanceTiming != nullptr) {
279         free((*response)->performanceTiming);
280         (*response)->performanceTiming = nullptr;
281     }
282 
283     free((*response));
284     (*response) = nullptr;
285 }
286 
OH_Http_SetOtherOption(HttpClientRequest * httpReq,Http_Request * request)287 void OH_Http_SetOtherOption(HttpClientRequest *httpReq, Http_Request *request)
288 {
289     //clientCert
290     if (request->options->clientCert != nullptr) {
291         HttpClientCert clientCert;
292         if (request->options->clientCert->certPath != nullptr) {
293             clientCert.certPath = request->options->clientCert->certPath;
294         }
295         if (request->options->clientCert->keyPassword != nullptr) {
296             clientCert.keyPassword = request->options->clientCert->keyPassword;
297         }
298         if (request->options->clientCert->keyPath != nullptr) {
299             clientCert.keyPath = request->options->clientCert->keyPath;
300         }
301         if (request->options->clientCert->type == Http_CertType::OH_HTTP_PEM) {
302             clientCert.certType = "PEM";
303         }
304         if (request->options->clientCert->type == Http_CertType::OH_HTTP_DER) {
305             clientCert.certType = "DER";
306         }
307         if (request->options->clientCert->type == Http_CertType::OH_HTTP_P12) {
308             clientCert.certType = "P12";
309         }
310         httpReq->SetClientCert(clientCert);
311     }
312     //Http_AddressFamilyType
313     if (request->options->addressFamily == Http_AddressFamilyType::HTTP_ADDRESS_FAMILY_ONLY_V4) {
314         httpReq->SetAddressFamily("ONLY_V4");
315     }
316     if (request->options->addressFamily == Http_AddressFamilyType::HTTP_ADDRESS_FAMILY_ONLY_V6) {
317         httpReq->SetAddressFamily("ONLY_V6");
318     }
319     if (request->options->addressFamily == Http_AddressFamilyType::HTTP_ADDRESS_FAMILY_DEFAULT) {
320         httpReq->SetAddressFamily("DEFAULT");
321     }
322 }
323 
OH_Http_SetOption(HttpClientRequest * httpReq,Http_Request * request)324 void OH_Http_SetOption(HttpClientRequest *httpReq, Http_Request *request)
325 {
326     if (request->options->method != nullptr) {
327         httpReq->SetMethod(request->options->method);
328     }
329     httpReq->SetPriority(request->options->priority);
330     if (request->options->readTimeout != 0) {
331         httpReq->SetTimeout(request->options->readTimeout);
332     }
333     if (request->options->connectTimeout != 0) {
334         httpReq->SetConnectTimeout(request->options->connectTimeout);
335     }
336     if (request->options->headers != nullptr) {
337         OH_Http_SetHeaderData(request->options->headers, httpReq);
338     }
339     if (request->options->httpProxy != nullptr) {
340         httpReq->SetHttpProxyType(static_cast<HttpProxyType>(request->options->httpProxy->proxyType));
341         if (request->options->httpProxy->customProxy.host != nullptr &&
342             request->options->httpProxy->customProxy.exclusionLists != nullptr) {
343             HttpProxy httpProxy;
344             httpProxy.host = request->options->httpProxy->customProxy.host;
345             httpProxy.port = request->options->httpProxy->customProxy.port;
346             httpProxy.exclusions = request->options->httpProxy->customProxy.exclusionLists;
347             httpReq->SetHttpProxy(httpProxy);
348         }
349     }
350     //httpProtocol
351     httpReq->SetHttpProtocol(static_cast<HttpProtocol>(request->options->httpProtocol));
352     // caPath
353     if (request->options->caPath != nullptr) {
354         httpReq->SetCaPath((std::string)request->options->caPath);
355     }
356     // resumeFrom  resumeTo
357     if ((request->options->method != nullptr && strcmp(request->options->method, HttpConstant::HTTP_METHOD_GET) == 0) ||
358         request->options->method == nullptr) {
359         httpReq->SetResumeFrom(request->options->resumeFrom);
360         httpReq->SetResumeTo(request->options->resumeTo);
361     }
362     OH_Http_SetOtherOption(httpReq, request);
363 }
364 
OH_Http_RequestOnSuccess(std::shared_ptr<HttpClientTask> httpClientTask,Http_ResponseCallback callback,Http_EventsHandler handler)365 void OH_Http_RequestOnSuccess(std::shared_ptr<HttpClientTask> httpClientTask,
366     Http_ResponseCallback callback, Http_EventsHandler handler)
367 {
368     if (httpClientTask == nullptr) {
369         NETSTACK_LOGE("OH_Http_RequestOnSuccess httpClientTask is nullptr");
370         return;
371     }
372     httpClientTask->OnSuccess([callback, handler] (const HttpClientRequest &request,
373         const HttpClientResponse &response) {
374         NETSTACK_LOGI("OnSuccess. code=%{public}d", response.GetResponseCode());
375         Http_Response *resp = (Http_Response *)calloc(1, sizeof(Http_Response));
376         if (resp == nullptr) {
377            callback(nullptr, OH_HTTP_OUT_OF_MEMORY);
378            return OH_HTTP_OUT_OF_MEMORY;
379         }
380         resp->responseCode =  static_cast<Http_ResponseCode>(response.GetResponseCode());
381         resp->cookies = const_cast<char*>(response.GetCookies().data());
382         resp->body.buffer = response.GetResult().data();
383         resp->body.length = response.GetResult().size();
384         Http_PerformanceTiming *performanceTiming = (Http_PerformanceTiming *)calloc(1,
385             sizeof(Http_PerformanceTiming));
386         if (performanceTiming == nullptr) {
387            callback(nullptr, OH_HTTP_OUT_OF_MEMORY);
388            free(resp);
389            return OH_HTTP_OUT_OF_MEMORY;
390         }
391         performanceTiming->dnsTiming = response.GetPerformanceTiming().dnsTiming;
392         performanceTiming->tcpTiming = response.GetPerformanceTiming().connectTiming;
393         performanceTiming->tlsTiming = response.GetPerformanceTiming().tlsTiming;
394         performanceTiming->firstSendTiming = response.GetPerformanceTiming().firstSendTiming;
395         performanceTiming->firstReceiveTiming = response.GetPerformanceTiming().firstReceiveTiming;
396         performanceTiming->totalFinishTiming = response.GetPerformanceTiming().totalTiming;
397         performanceTiming->redirectTiming = response.GetPerformanceTiming().redirectTiming;
398         resp->performanceTiming = performanceTiming;
399 
400         std::map<std::string, std::string> map = response.GetHeaders();
401         Http_Headers *headers = OH_Http_ToCHeaders(map);
402         resp->headers = headers;
403         resp->destroyResponse = OH_Http_DestroyResponse;
404         callback(resp, 0);
405         if (handler.onDataEnd != nullptr) {
406             handler.onDataEnd();
407         }
408         return OH_HTTP_RESULT_OK;
409     });
410 }
411 
OH_Http_RequestOnCancel(std::shared_ptr<HttpClientTask> httpClientTask,Http_EventsHandler handler)412 void OH_Http_RequestOnCancel(std::shared_ptr<HttpClientTask> httpClientTask, Http_EventsHandler handler)
413 {
414     if (httpClientTask == nullptr) {
415         NETSTACK_LOGE("OH_Http_RequestOnCancel httpClientTask is nullptr");
416         return;
417     }
418     httpClientTask->OnCancel([handler] (const HttpClientRequest &request,
419         const HttpClientResponse &response) {
420         NETSTACK_LOGI("OnCancel. code=%{public}d", response.GetResponseCode());
421         if (handler.onCanceled != nullptr) {
422             handler.onCanceled();
423         }
424         return OH_HTTP_RESULT_OK;
425     });
426 }
427 
OH_Http_RequestOnFail(std::shared_ptr<HttpClientTask> httpClientTask,Http_ResponseCallback callback,Http_EventsHandler handler)428 void OH_Http_RequestOnFail(std::shared_ptr<HttpClientTask> httpClientTask,
429     Http_ResponseCallback callback, Http_EventsHandler handler)
430 {
431     if (httpClientTask == nullptr) {
432         NETSTACK_LOGE("OH_Http_RequestOnFail httpClientTask is nullptr");
433         return;
434     }
435     httpClientTask->OnFail([callback, handler] (const HttpClientRequest &request,
436         const HttpClientResponse &response, const HttpClientError &error) {
437         NETSTACK_LOGE("OnFail. responseCode=%{public}d error=%{public}d",
438             response.GetResponseCode(), error.GetErrorCode());
439         Http_Response *resp = (Http_Response *)calloc(1, sizeof(Http_Response));
440         if (resp == nullptr) {
441            callback(nullptr, OH_HTTP_OUT_OF_MEMORY);
442            return OH_HTTP_OUT_OF_MEMORY;
443         }
444         resp->responseCode =  static_cast<Http_ResponseCode>(response.GetResponseCode());
445         resp->destroyResponse = OH_Http_DestroyResponse;
446         callback(resp, static_cast<uint32_t>(error.GetErrorCode()));
447         if (handler.onDataEnd != nullptr) {
448             handler.onDataEnd();
449         }
450         return OH_HTTP_RESULT_OK;
451     });
452 }
453 
OH_Http_RequestOnDataReceive(std::shared_ptr<HttpClientTask> httpClientTask,Http_EventsHandler handler)454 void OH_Http_RequestOnDataReceive(std::shared_ptr<HttpClientTask> httpClientTask, Http_EventsHandler handler)
455 {
456     if (httpClientTask == nullptr) {
457         NETSTACK_LOGE("OH_Http_RequestOnDataReceive httpClientTask is nullptr");
458         return;
459     }
460     httpClientTask->OnDataReceive([handler] (const HttpClientRequest &request,
461         const uint8_t *data, size_t length) {
462         if (handler.onDataReceive != nullptr) {
463             handler.onDataReceive(reinterpret_cast<const char *>(data), length);
464         }
465         return OH_HTTP_RESULT_OK;
466     });
467 }
468 
OH_Http_RequestOnHeadersReceive(std::shared_ptr<HttpClientTask> httpClientTask,Http_EventsHandler handler)469 void OH_Http_RequestOnHeadersReceive(std::shared_ptr<HttpClientTask> httpClientTask, Http_EventsHandler handler)
470 {
471     if (httpClientTask == nullptr) {
472         NETSTACK_LOGE("OH_Http_RequestOnHeadersReceive httpClientTask is nullptr");
473         return;
474     }
475     httpClientTask->OnHeadersReceive([handler] (const HttpClientRequest &request,
476         std::map<std::string, std::string> headerWithSetCookie) {
477         if (handler.onHeadersReceive != nullptr) {
478             Http_Headers *headers = OH_Http_ToCHeaders(headerWithSetCookie);
479             handler.onHeadersReceive(headers);
480         }
481         return OH_HTTP_RESULT_OK;
482     });
483 }
484 
OH_Http_RequestOnProgress(std::shared_ptr<HttpClientTask> httpClientTask,Http_EventsHandler handler)485 void OH_Http_RequestOnProgress(std::shared_ptr<HttpClientTask> httpClientTask, Http_EventsHandler handler)
486 {
487     if (httpClientTask == nullptr) {
488         NETSTACK_LOGE("OH_Http_RequestOnProgress httpClientTask is nullptr");
489         return;
490     }
491     httpClientTask->OnProgress([handler] (const HttpClientRequest &request,
492         u_long dlTotal, u_long dlNow, u_long ulTotal, u_long ulNow) {
493         if (ulTotal != 0 && ulTotal >= ulNow) {
494             if (handler.onUploadProgress != nullptr) {
495                 handler.onUploadProgress(ulTotal, ulNow);
496             }
497         }
498         if (dlTotal != 0) {
499             if (handler.onDownloadProgress != nullptr) {
500                 handler.onDownloadProgress(dlTotal, dlNow);
501             }
502         }
503         return OH_HTTP_RESULT_OK;
504     });
505 }
506 
OH_Http_Request(Http_Request * request,Http_ResponseCallback callback,Http_EventsHandler handler)507 int OH_Http_Request(Http_Request *request, Http_ResponseCallback callback, Http_EventsHandler handler)
508 {
509     NETSTACK_LOGI("OH_Http_Request enter");
510     if (request == nullptr || callback == nullptr) {
511         NETSTACK_LOGE("OH_Http_Request request or callback is nullptr");
512         return OH_HTTP_OUT_OF_MEMORY;
513     }
514     HttpClientRequest httpReq;
515     httpReq.SetURL(request->url);
516     if (request->options != nullptr) {
517         OH_Http_SetOption(&httpReq, request);
518     }
519     HttpSession &session = HttpSession::GetInstance();
520     auto httpClientTask = session.CreateTask(httpReq);
521     if (httpClientTask == nullptr) {
522         NETSTACK_LOGE("OH_Http_Request httpClientTask is nullptr");
523         return OH_HTTP_OUT_OF_MEMORY;
524     }
525     OH_Http_RequestOnSuccess(httpClientTask, callback, handler);
526     OH_Http_RequestOnCancel(httpClientTask, handler);
527     OH_Http_RequestOnFail(httpClientTask, callback, handler);
528     OH_Http_RequestOnDataReceive(httpClientTask, handler);
529     OH_Http_RequestOnHeadersReceive(httpClientTask, handler);
530     OH_Http_RequestOnProgress(httpClientTask, handler);
531     if (!httpClientTask->Start()) {
532         HttpErrorCode error = httpClientTask->GetError().GetErrorCode();
533         NETSTACK_LOGE("OH_Http_Request error:%{public}d", error);
534         return httpClientTask->GetError().GetErrorCode();
535     }
536     request->requestId = httpClientTask->GetTaskId();
537     std::lock_guard<std::mutex> lock(requestMutex);
538     cppRequestTask[request->requestId] = std::move(httpClientTask);
539     return 0;
540 }
541 
OH_Http_Destroy(struct Http_Request ** request)542 void OH_Http_Destroy(struct Http_Request **request)
543 {
544     NETSTACK_LOGI("OH_Http_Destroy enter");
545     if (request == nullptr) {
546         NETSTACK_LOGE("OH_Http_Destroy request is nullptr");
547         return;
548     }
549     if (*request == nullptr) {
550         NETSTACK_LOGE("OH_Http_Destroy *request is nullptr");
551         return;
552     }
553     std::lock_guard<std::mutex> lock(requestMutex);
554     if (cppRequestTask.find((*request)->requestId) != cppRequestTask.end()) {
555         auto httpClientTask = cppRequestTask[(*request)->requestId];
556         if (httpClientTask != nullptr) {
557             httpClientTask->Cancel();
558             NETSTACK_LOGD("OH_Http_Destroy request->requestId:%{public}d", (*request)->requestId);
559         }
560         cppRequestTask.erase((*request)->requestId);
561     }
562     if ((*request)->url != nullptr) {
563         free((*request)->url);
564         (*request)->url = nullptr;
565     }
566     free(*request);
567     *request = nullptr;
568 }