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 }