1 /*
2 * Copyright (c) 2021-2024 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 "request_context.h"
17
18 #include <algorithm>
19 #include <atomic>
20 #include <limits>
21 #include <string>
22 #include <utility>
23 #include <sstream>
24
25 #include "constant.h"
26 #include "http_exec.h"
27 #include "http_tls_config.h"
28 #include "napi_utils.h"
29 #include "netstack_common_utils.h"
30 #include "netstack_log.h"
31 #include "request_tracer.h"
32 #include "secure_char.h"
33 #include "timing.h"
34 #if HAS_NETMANAGER_BASE
35 #include "http_network_message.h"
36 #endif
37
38 static constexpr const int PARAM_JUST_URL = 1;
39
40 static constexpr const int PARAM_JUST_URL_OR_CALLBACK = 1;
41
42 static constexpr const int PARAM_URL_AND_OPTIONS_OR_CALLBACK = 2;
43
44 static constexpr const int PARAM_URL_AND_OPTIONS_AND_CALLBACK = 3;
45
46 static constexpr const uint32_t DNS_SERVER_SIZE = 3;
47 namespace OHOS::NetStack::Http {
48 static const std::map<int32_t, const char *> HTTP_ERR_MAP = {
49 {HTTP_UNSUPPORTED_PROTOCOL, "Unsupported protocol"},
50 {HTTP_URL_MALFORMAT, "URL using bad/illegal format or missing URL"},
51 {HTTP_COULDNT_RESOLVE_PROXY, "Couldn't resolve proxy name"},
52 {HTTP_COULDNT_RESOLVE_HOST, "Couldn't resolve host name"},
53 {HTTP_COULDNT_CONNECT, "Couldn't connect to server"},
54 {HTTP_WEIRD_SERVER_REPLY, "Weird server reply"},
55 {HTTP_REMOTE_ACCESS_DENIED, "Access denied to remote resource"},
56 {HTTP_HTTP2_ERROR, "Error in the HTTP2 framing layer"},
57 {HTTP_PARTIAL_FILE, "Transferred a partial file"},
58 {HTTP_WRITE_ERROR, "Failed writing received data to disk/application"},
59 {HTTP_UPLOAD_FAILED, "Upload failed"},
60 {HTTP_READ_ERROR, "Failed to open/read local data from file/application"},
61 {HTTP_OUT_OF_MEMORY, "Out of memory"},
62 {HTTP_OPERATION_TIMEDOUT, "Timeout was reached"},
63 {HTTP_TOO_MANY_REDIRECTS, "Number of redirects hit maximum amount"},
64 {HTTP_GOT_NOTHING, "Server returned nothing (no headers, no data)"},
65 {HTTP_SEND_ERROR, "Failed sending data to the peer"},
66 {HTTP_RECV_ERROR, "Failure when receiving data from the peer"},
67 {HTTP_SSL_CERTPROBLEM, "Problem with the local SSL certificate"},
68 {HTTP_SSL_CIPHER, "Couldn't use specified SSL cipher"},
69 {HTTP_PEER_FAILED_VERIFICATION, "SSL peer certificate or SSH remote key was not OK"},
70 {HTTP_BAD_CONTENT_ENCODING, "Unrecognized or bad HTTP Content or Transfer-Encoding"},
71 {HTTP_FILESIZE_EXCEEDED, "Maximum file size exceeded"},
72 {HTTP_REMOTE_DISK_FULL, "Disk full or allocation exceeded"},
73 {HTTP_REMOTE_FILE_EXISTS, "Remote file already exists"},
74 {HTTP_SSL_CACERT_BADFILE, "Problem with the SSL CA cert (path? access rights?)"},
75 {HTTP_REMOTE_FILE_NOT_FOUND, "Remote file not found"},
76 {HTTP_AUTH_ERROR, "An authentication function returned an error"},
77 {HTTP_SSL_PINNEDPUBKEYNOTMATCH, "Specified pinned public key did not match"},
78 {HTTP_CLEARTEXT_NOT_PERMITTED, "Cleartext traffic is not permitted"},
79 {HTTP_NOT_ALLOWED_HOST, "It is not allowed to access this domain"},
80 {HTTP_UNKNOWN_OTHER_ERROR, "Unknown Other Error"},
81 };
82 static std::atomic<int32_t> g_currentTaskId = std::numeric_limits<int32_t>::min();
RequestContext(napi_env env,const std::shared_ptr<EventManager> & manager)83 RequestContext::RequestContext(napi_env env, const std::shared_ptr<EventManager> &manager)
84 : BaseContext(env, manager),
85 taskId_(g_currentTaskId++),
86 usingCache_(true),
87 requestInStream_(false),
88 curlHeaderList_(nullptr),
89 multipart_(nullptr),
90 curlHostList_(nullptr),
91 isAtomicService_(false),
92 bundleName_(""),
93 trace_("HttpRequest_" + std::to_string(taskId_))
94 {
95 StartTiming();
96 #if HAS_NETMANAGER_BASE
97 networkProfilerUtils_ = std::make_unique<NetworkProfilerUtils>();
98 #endif
99 }
100
StartTiming()101 void RequestContext::StartTiming()
102 {
103 time_t startTime = Timing::TimeUtils::GetNowTimeMicroseconds();
104 timerMap_.RecieveTimer(HttpConstant::RESPONSE_HEADER_TIMING).Start(startTime);
105 timerMap_.RecieveTimer(HttpConstant::RESPONSE_BODY_TIMING).Start(startTime);
106 timerMap_.RecieveTimer(HttpConstant::RESPONSE_TOTAL_TIMING).Start(startTime);
107
108 // init RESPONSE_HEADER_TIMING and RESPONSE_BODY_TIMING
109 performanceTimingMap_[HttpConstant::RESPONSE_HEADER_TIMING] = 0.0;
110 performanceTimingMap_[HttpConstant::RESPONSE_BODY_TIMING] = 0.0;
111 }
112
ParseParams(napi_value * params,size_t paramsCount)113 void RequestContext::ParseParams(napi_value *params, size_t paramsCount)
114 {
115 bool valid = CheckParamsType(params, paramsCount);
116 if (!valid) {
117 if (paramsCount == PARAM_JUST_URL_OR_CALLBACK) {
118 if (NapiUtils::GetValueType(GetEnv(), params[0]) == napi_function) {
119 SetCallback(params[0]);
120 }
121 return;
122 }
123 if (paramsCount == PARAM_URL_AND_OPTIONS_OR_CALLBACK) {
124 if (NapiUtils::GetValueType(GetEnv(), params[1]) == napi_function) {
125 SetCallback(params[1]);
126 }
127 return;
128 }
129 if (paramsCount == PARAM_URL_AND_OPTIONS_AND_CALLBACK) {
130 if (NapiUtils::GetValueType(GetEnv(), params[PARAM_URL_AND_OPTIONS_AND_CALLBACK - 1]) == napi_function) {
131 SetCallback(params[PARAM_URL_AND_OPTIONS_AND_CALLBACK - 1]);
132 }
133 return;
134 }
135 return;
136 }
137
138 if (paramsCount == PARAM_JUST_URL) {
139 options.SetUrl(NapiUtils::GetStringFromValueUtf8(GetEnv(), params[0]));
140 SetParseOK(true);
141 return;
142 }
143
144 if (paramsCount == PARAM_URL_AND_OPTIONS_OR_CALLBACK) {
145 napi_valuetype type = NapiUtils::GetValueType(GetEnv(), params[1]);
146 if (type == napi_function) {
147 options.SetUrl(NapiUtils::GetStringFromValueUtf8(GetEnv(), params[0]));
148 SetParseOK(SetCallback(params[1]) == napi_ok);
149 return;
150 }
151 if (type == napi_object) {
152 UrlAndOptions(params[0], params[1]);
153 return;
154 }
155 return;
156 }
157
158 if (paramsCount == PARAM_URL_AND_OPTIONS_AND_CALLBACK) {
159 if (SetCallback(params[PARAM_URL_AND_OPTIONS_AND_CALLBACK - 1]) != napi_ok) {
160 return;
161 }
162 UrlAndOptions(params[0], params[1]);
163 }
164 }
165
CheckParamsType(napi_value * params,size_t paramsCount)166 bool RequestContext::CheckParamsType(napi_value *params, size_t paramsCount)
167 {
168 if (paramsCount == PARAM_JUST_URL) {
169 // just url
170 return NapiUtils::GetValueType(GetEnv(), params[0]) == napi_string;
171 }
172 if (paramsCount == PARAM_URL_AND_OPTIONS_OR_CALLBACK) {
173 // should be url, callback or url, options
174 napi_valuetype type = NapiUtils::GetValueType(GetEnv(), params[1]);
175 return NapiUtils::GetValueType(GetEnv(), params[0]) == napi_string &&
176 (type == napi_function || type == napi_object);
177 }
178 if (paramsCount == PARAM_URL_AND_OPTIONS_AND_CALLBACK) {
179 // should be url options and callback
180 return NapiUtils::GetValueType(GetEnv(), params[0]) == napi_string &&
181 NapiUtils::GetValueType(GetEnv(), params[1]) == napi_object &&
182 NapiUtils::GetValueType(GetEnv(), params[PARAM_URL_AND_OPTIONS_AND_CALLBACK - 1]) == napi_function;
183 }
184 return false;
185 }
186
ParseNumberOptions(napi_value optionsValue)187 void RequestContext::ParseNumberOptions(napi_value optionsValue)
188 {
189 if (NapiUtils::HasNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_READ_TIMEOUT)) {
190 options.SetReadTimeout(
191 NapiUtils::GetUint32Property(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_READ_TIMEOUT));
192 }
193
194 if (NapiUtils::HasNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_MAX_LIMIT)) {
195 options.SetMaxLimit(NapiUtils::GetUint32Property(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_MAX_LIMIT));
196 }
197
198 if (NapiUtils::HasNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_CONNECT_TIMEOUT)) {
199 options.SetConnectTimeout(
200 NapiUtils::GetUint32Property(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_CONNECT_TIMEOUT));
201 }
202
203 if (NapiUtils::HasNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_USING_CACHE)) {
204 napi_value value = NapiUtils::GetNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_USING_CACHE);
205 if (NapiUtils::GetValueType(GetEnv(), value) == napi_boolean) {
206 usingCache_ = NapiUtils::GetBooleanFromValue(GetEnv(), value);
207 }
208 }
209
210 if (NapiUtils::HasNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_USING_PROTOCOL)) {
211 napi_value value = NapiUtils::GetNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_USING_PROTOCOL);
212 if (NapiUtils::GetValueType(GetEnv(), value) == napi_number) {
213 uint32_t number = NapiUtils::GetUint32FromValue(GetEnv(), value);
214 if (number == static_cast<uint32_t>(HttpProtocol::HTTP1_1) ||
215 number == static_cast<uint32_t>(HttpProtocol::HTTP2) ||
216 number == static_cast<uint32_t>(HttpProtocol::HTTP3)) {
217 options.SetUsingProtocol(static_cast<HttpProtocol>(number));
218 }
219 }
220 }
221 if (NapiUtils::HasNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_EXPECT_DATA_TYPE)) {
222 napi_value value =
223 NapiUtils::GetNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_EXPECT_DATA_TYPE);
224 if (NapiUtils::GetValueType(GetEnv(), value) == napi_number) {
225 uint32_t type = NapiUtils::GetUint32FromValue(GetEnv(), value);
226 options.SetHttpDataType(static_cast<HttpDataType>(type));
227 }
228 }
229
230 if (NapiUtils::HasNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_PRIORITY)) {
231 napi_value value = NapiUtils::GetNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_PRIORITY);
232 if (NapiUtils::GetValueType(GetEnv(), value) == napi_number) {
233 uint32_t priority = NapiUtils::GetUint32FromValue(GetEnv(), value);
234 options.SetPriority(priority);
235 }
236 }
237 }
238
ParseRemoteValidationMode(napi_value optionsValue)239 void RequestContext::ParseRemoteValidationMode(napi_value optionsValue)
240 {
241 if (!NapiUtils::HasNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_REMOTE_VALIDATION)) {
242 NETSTACK_LOGD("no remote validation mode config");
243 return;
244 }
245 napi_value value = NapiUtils::GetNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_REMOTE_VALIDATION);
246 if (NapiUtils::GetValueType(GetEnv(), value) == napi_string) {
247 auto remoteValidationMode = NapiUtils::GetStringFromValueUtf8(GetEnv(), value);
248 if (remoteValidationMode == "skip") {
249 NETSTACK_LOGI("ParseRemoteValidationMode remoteValidationMode skip");
250 options.SetCanSkipCertVerifyFlag(true);
251 } else if (remoteValidationMode != "system") {
252 NETSTACK_LOGE("RemoteValidationMode config error");
253 }
254 }
255 }
256
ParseTlsOption(napi_value optionsValue)257 void RequestContext::ParseTlsOption(napi_value optionsValue)
258 {
259 if (!NapiUtils::HasNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_TLS_OPTION)) {
260 NETSTACK_LOGD("no tls config");
261 return;
262 }
263 napi_value tlsVersionValue = NapiUtils::GetNamedProperty(
264 GetEnv(), optionsValue, HttpConstant::PARAM_KEY_TLS_OPTION);
265 napi_valuetype type = NapiUtils::GetValueType(GetEnv(), tlsVersionValue);
266 if (type != napi_object && type != napi_string) {
267 NETSTACK_LOGE("tlsVersionValue type error");
268 return;
269 }
270 uint32_t tlsVersionMin = NapiUtils::GetUint32Property(GetEnv(), tlsVersionValue, "tlsVersionMin");
271 uint32_t tlsVersionMax = NapiUtils::GetUint32Property(GetEnv(), tlsVersionValue, "tlsVersionMax");
272 NETSTACK_LOGD("tlsVersionMin = %{public}d, tlsVersionMax = %{public}d", tlsVersionMin, tlsVersionMax);
273 TlsOption tlsOption;
274 tlsOption.tlsVersionMin = static_cast<TlsVersion>(tlsVersionMin);
275 tlsOption.tlsVersionMax = static_cast<TlsVersion>(tlsVersionMax);
276 if (!NapiUtils::HasNamedProperty(GetEnv(), tlsVersionValue, "cipherSuites")) {
277 NETSTACK_LOGD("no cipherSuites");
278 options.SetTlsOption(tlsOption);
279 return;
280 }
281 auto cipherSuiteNapi = NapiUtils::GetNamedProperty(GetEnv(), tlsVersionValue, "cipherSuites");
282 if (!NapiUtils::IsArray(GetEnv(), cipherSuiteNapi)) {
283 options.SetTlsOption(tlsOption);
284 return;
285 }
286 auto length = NapiUtils::GetArrayLength(GetEnv(), cipherSuiteNapi);
287 for (uint32_t i = 0; i < length; ++i) {
288 auto standardNameNapi = NapiUtils::GetArrayElement(GetEnv(), cipherSuiteNapi, i);
289 auto cipherSuite = GetTlsCipherSuiteFromStandardName(
290 NapiUtils::GetStringFromValueUtf8(GetEnv(), standardNameNapi));
291 if (cipherSuite != CipherSuite::INVALID) {
292 tlsOption.cipherSuite.emplace(cipherSuite);
293 }
294 }
295
296 options.SetTlsOption(tlsOption);
297 }
298
ParseServerAuthentication(napi_value optionsValue)299 void RequestContext::ParseServerAuthentication(napi_value optionsValue)
300 {
301 if (!NapiUtils::HasNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_SERVER_AUTH)) {
302 NETSTACK_LOGD("no server authentication config");
303 return;
304 }
305 napi_value serverAuthenticationValue = NapiUtils::GetNamedProperty(
306 GetEnv(), optionsValue, HttpConstant::PARAM_KEY_SERVER_AUTH);
307 napi_valuetype type = NapiUtils::GetValueType(GetEnv(), serverAuthenticationValue);
308 if (type != napi_object) {
309 NETSTACK_LOGE("server authentication type error");
310 return;
311 }
312 ServerAuthentication serverAuthentication;
313 auto credentialNapi = NapiUtils::GetNamedProperty(GetEnv(), serverAuthenticationValue, "credential");
314 NapiUtils::GetSecureDataPropertyUtf8(GetEnv(),
315 credentialNapi, "username", serverAuthentication.credential.username);
316 NapiUtils::GetSecureDataPropertyUtf8(GetEnv(),
317 credentialNapi, "password", serverAuthentication.credential.password);
318 auto authenticationType = NapiUtils::GetStringPropertyUtf8(GetEnv(),
319 serverAuthenticationValue, "authenticationType");
320 if (authenticationType == "basic") {
321 serverAuthentication.authenticationType = AuthenticationType::BASIC;
322 } else if (authenticationType == "ntlm") {
323 serverAuthentication.authenticationType = AuthenticationType::NTLM;
324 } else if (authenticationType == "digest") {
325 serverAuthentication.authenticationType = AuthenticationType::DIGEST;
326 }
327 options.SetServerAuthentication(serverAuthentication);
328 }
329
ParseHeader(napi_value optionsValue)330 void RequestContext::ParseHeader(napi_value optionsValue)
331 {
332 if (!NapiUtils::HasNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_HEADER)) {
333 return;
334 }
335 napi_value header = NapiUtils::GetNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_HEADER);
336 if (NapiUtils::GetValueType(GetEnv(), header) != napi_object) {
337 return;
338 }
339 if (HttpExec::MethodForPost(options.GetMethod())) {
340 options.SetHeader(CommonUtils::ToLower(HttpConstant::HTTP_CONTENT_TYPE),
341 HttpConstant::HTTP_CONTENT_TYPE_JSON); // default
342 }
343 auto names = NapiUtils::GetPropertyNames(GetEnv(), header);
344 std::for_each(names.begin(), names.end(), [header, this](const std::string &name) {
345 napi_value value = NapiUtils::GetNamedProperty(GetEnv(), header, name);
346 std::string valueStr = NapiUtils::NapiValueToString(GetEnv(), value);
347 options.SetHeader(CommonUtils::ToLower(name), valueStr);
348 });
349 }
350
HandleMethodForGet(napi_value extraData)351 bool RequestContext::HandleMethodForGet(napi_value extraData)
352 {
353 std::string url = options.GetUrl();
354 std::string param;
355 auto index = url.find(HttpConstant::HTTP_URL_PARAM_START);
356 if (index != std::string::npos) {
357 param = url.substr(index + 1);
358 url.resize(index);
359 }
360
361 napi_valuetype type = NapiUtils::GetValueType(GetEnv(), extraData);
362 if (type == napi_string) {
363 std::string extraParam = NapiUtils::GetStringFromValueUtf8(GetEnv(), extraData);
364
365 options.SetUrl(HttpExec::MakeUrl(url, param, extraParam));
366 return true;
367 }
368 if (type != napi_object) {
369 return true;
370 }
371
372 std::string extraParam;
373 auto names = NapiUtils::GetPropertyNames(GetEnv(), extraData);
374 std::for_each(names.begin(), names.end(), [this, extraData, &extraParam](std::string name) {
375 auto value = NapiUtils::GetStringPropertyUtf8(GetEnv(), extraData, name);
376 if (!name.empty() && !value.empty()) {
377 bool encodeName = HttpExec::EncodeUrlParam(name);
378 bool encodeValue = HttpExec::EncodeUrlParam(value);
379 if (encodeName || encodeValue) {
380 options.SetHeader(CommonUtils::ToLower(HttpConstant::HTTP_CONTENT_TYPE),
381 HttpConstant::HTTP_CONTENT_TYPE_URL_ENCODE);
382 }
383 extraParam +=
384 name + HttpConstant::HTTP_URL_NAME_VALUE_SEPARATOR + value + HttpConstant::HTTP_URL_PARAM_SEPARATOR;
385 }
386 });
387 if (!extraParam.empty()) {
388 extraParam.pop_back(); // remove the last &
389 }
390
391 options.SetUrl(HttpExec::MakeUrl(url, param, extraParam));
392 return true;
393 }
394
ParseExtraData(napi_value optionsValue)395 bool RequestContext::ParseExtraData(napi_value optionsValue)
396 {
397 if (!NapiUtils::HasNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_EXTRA_DATA)) {
398 NETSTACK_LOGD("no extraData");
399 return true;
400 }
401
402 napi_value extraData = NapiUtils::GetNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_EXTRA_DATA);
403 if (NapiUtils::GetValueType(GetEnv(), extraData) == napi_undefined ||
404 NapiUtils::GetValueType(GetEnv(), extraData) == napi_null) {
405 NETSTACK_LOGD("extraData is undefined or null");
406 return true;
407 }
408
409 if (HttpExec::MethodForGet(options.GetMethod())) {
410 return HandleMethodForGet(extraData);
411 }
412
413 if (HttpExec::MethodForPost(options.GetMethod())) {
414 return GetRequestBody(extraData);
415 }
416 return false;
417 }
418
ParseUsingHttpProxy(napi_value optionsValue)419 void RequestContext::ParseUsingHttpProxy(napi_value optionsValue)
420 {
421 if (!NapiUtils::HasNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_USING_HTTP_PROXY)) {
422 NETSTACK_LOGD("Use default proxy");
423 return;
424 }
425 napi_value httpProxyValue =
426 NapiUtils::GetNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_USING_HTTP_PROXY);
427 napi_valuetype type = NapiUtils::GetValueType(GetEnv(), httpProxyValue);
428 if (type == napi_boolean) {
429 bool usingProxy = NapiUtils::GetBooleanFromValue(GetEnv(), httpProxyValue);
430 UsingHttpProxyType usingType = usingProxy ? UsingHttpProxyType::USE_DEFAULT : UsingHttpProxyType::NOT_USE;
431 options.SetUsingHttpProxyType(usingType);
432 return;
433 }
434 if (type != napi_object) {
435 return;
436 }
437 std::string host = NapiUtils::GetStringPropertyUtf8(GetEnv(), httpProxyValue, HttpConstant::HTTP_PROXY_KEY_HOST);
438 int32_t port = NapiUtils::GetInt32Property(GetEnv(), httpProxyValue, HttpConstant::HTTP_PROXY_KEY_PORT);
439 std::string exclusionList;
440 if (NapiUtils::HasNamedProperty(GetEnv(), httpProxyValue, HttpConstant::HTTP_PROXY_KEY_EXCLUSION_LIST)) {
441 napi_value exclusionListValue =
442 NapiUtils::GetNamedProperty(GetEnv(), httpProxyValue, HttpConstant::HTTP_PROXY_KEY_EXCLUSION_LIST);
443 uint32_t listLength = NapiUtils::GetArrayLength(GetEnv(), exclusionListValue);
444 for (uint32_t index = 0; index < listLength; ++index) {
445 napi_value exclusionValue = NapiUtils::GetArrayElement(GetEnv(), exclusionListValue, index);
446 std::string exclusion = NapiUtils::GetStringFromValueUtf8(GetEnv(), exclusionValue);
447 if (index != 0) {
448 exclusionList = exclusionList + HttpConstant::HTTP_PROXY_EXCLUSIONS_SEPARATOR;
449 }
450 exclusionList += exclusion;
451 }
452 }
453 options.SetSpecifiedHttpProxy(host, port, exclusionList);
454 options.SetUsingHttpProxyType(UsingHttpProxyType::USE_SPECIFIED);
455 }
456
GetRequestBody(napi_value extraData)457 bool RequestContext::GetRequestBody(napi_value extraData)
458 {
459 /* if body is empty, return false, or curl will wait for body */
460
461 napi_valuetype type = NapiUtils::GetValueType(GetEnv(), extraData);
462 if (type == napi_string) {
463 auto body = NapiUtils::GetStringFromValueUtf8(GetEnv(), extraData);
464 if (body.empty()) {
465 return false;
466 }
467 options.SetBody(body.c_str(), body.size());
468 return true;
469 }
470
471 if (NapiUtils::ValueIsArrayBuffer(GetEnv(), extraData)) {
472 size_t length = 0;
473 void *data = NapiUtils::GetInfoFromArrayBufferValue(GetEnv(), extraData, &length);
474 if (data == nullptr) {
475 return false;
476 }
477 options.SetBody(data, length);
478 return true;
479 }
480
481 if (type == napi_object) {
482 std::string body = NapiUtils::GetStringFromValueUtf8(GetEnv(), NapiUtils::JsonStringify(GetEnv(), extraData));
483 if (body.empty()) {
484 return false;
485 }
486 options.SetBody(body.c_str(), body.length());
487 return true;
488 }
489
490 NETSTACK_LOGE("only support string arraybuffer and object");
491 return false;
492 }
493
ParseCaPath(napi_value optionsValue)494 void RequestContext::ParseCaPath(napi_value optionsValue)
495 {
496 std::string caPath = NapiUtils::GetStringPropertyUtf8(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_CA_PATH);
497 if (!caPath.empty()) {
498 options.SetCaPath(caPath);
499 }
500 }
501
ParseDohUrl(napi_value optionsValue)502 void RequestContext::ParseDohUrl(napi_value optionsValue)
503 {
504 std::string dohUrl = NapiUtils::GetStringPropertyUtf8(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_DOH_URL);
505 if (!dohUrl.empty()) {
506 options.SetDohUrl(dohUrl);
507 }
508 }
509
ParseResumeFromToNumber(napi_value optionsValue)510 void RequestContext::ParseResumeFromToNumber(napi_value optionsValue)
511 {
512 napi_env env = GetEnv();
513 int64_t from = NapiUtils::GetInt64Property(env, optionsValue, HttpConstant::PARAM_KEY_RESUME_FROM);
514 int64_t to = NapiUtils::GetInt64Property(env, optionsValue, HttpConstant::PARAM_KEY_RESUME_TO);
515 options.SetRangeNumber(from, to);
516 }
517
UrlAndOptions(napi_value urlValue,napi_value optionsValue)518 void RequestContext::UrlAndOptions(napi_value urlValue, napi_value optionsValue)
519 {
520 options.SetUrl(NapiUtils::GetStringFromValueUtf8(GetEnv(), urlValue));
521
522 if (NapiUtils::HasNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_METHOD)) {
523 napi_value requestMethod = NapiUtils::GetNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_METHOD);
524 if (NapiUtils::GetValueType(GetEnv(), requestMethod) == napi_string) {
525 options.SetMethod(NapiUtils::GetStringPropertyUtf8(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_METHOD));
526 }
527 }
528
529 ParseNumberOptions(optionsValue);
530 ParseUsingHttpProxy(optionsValue);
531 ParseClientCert(optionsValue);
532
533 /* parse extra data here to recover header */
534 if (!ParseExtraData(optionsValue)) {
535 return;
536 }
537
538 ParseHeader(optionsValue);
539 ParseCaPath(optionsValue);
540 ParseDohUrl(optionsValue);
541 ParseResumeFromToNumber(optionsValue);
542 ParseDnsServers(optionsValue);
543 ParseMultiFormData(optionsValue);
544 ParseCertificatePinning(optionsValue);
545 ParseRemoteValidationMode(optionsValue);
546 ParseTlsOption(optionsValue);
547 ParseServerAuthentication(optionsValue);
548 SetParseOK(true);
549 ParseAddressFamily(optionsValue);
550 }
551
IsUsingCache() const552 bool RequestContext::IsUsingCache() const
553 {
554 return usingCache_;
555 }
556
SetCurlHeaderList(curl_slist * curlHeaderList)557 void RequestContext::SetCurlHeaderList(curl_slist *curlHeaderList)
558 {
559 curlHeaderList_ = curlHeaderList;
560 }
561
GetCurlHeaderList()562 curl_slist *RequestContext::GetCurlHeaderList()
563 {
564 return curlHeaderList_;
565 }
566
SetCurlHostList(curl_slist * curlHostList)567 void RequestContext::SetCurlHostList(curl_slist *curlHostList)
568 {
569 curlHostList_ = curlHostList;
570 }
571
GetCurlHostList()572 curl_slist *RequestContext::GetCurlHostList()
573 {
574 return curlHostList_;
575 }
576
~RequestContext()577 RequestContext::~RequestContext()
578 {
579 trace_.Finish();
580 if (curlHeaderList_ != nullptr) {
581 curl_slist_free_all(curlHeaderList_);
582 }
583 if (curlHostList_ != nullptr) {
584 curl_slist_free_all(curlHostList_);
585 }
586 if (multipart_ != nullptr) {
587 curl_mime_free(multipart_);
588 multipart_ = nullptr;
589 }
590 NETSTACK_LOGD("the destructor of request context is invoked");
591 }
592
SetCacheResponse(const HttpResponse & cacheResponse)593 void RequestContext::SetCacheResponse(const HttpResponse &cacheResponse)
594 {
595 cacheResponse_ = cacheResponse;
596 }
SetResponseByCache()597 void RequestContext::SetResponseByCache()
598 {
599 response = cacheResponse_;
600 }
601
GetErrorCode() const602 int32_t RequestContext::GetErrorCode() const
603 {
604 auto err = BaseContext::GetErrorCode();
605 if (err == PARSE_ERROR_CODE) {
606 return PARSE_ERROR_CODE;
607 }
608
609 if (BaseContext::IsPermissionDenied()) {
610 return PERMISSION_DENIED_CODE;
611 }
612
613 if (BaseContext::IsNoAllowedHost()) {
614 return HTTP_NOT_ALLOWED_HOST;
615 }
616
617 if (BaseContext::IsCleartextNotPermitted()) {
618 return HTTP_CLEARTEXT_NOT_PERMITTED;
619 }
620
621 if (HTTP_ERR_MAP.find(err + HTTP_ERROR_CODE_BASE) != HTTP_ERR_MAP.end()) {
622 return err + HTTP_ERROR_CODE_BASE;
623 }
624 return HTTP_UNKNOWN_OTHER_ERROR;
625 }
626
GetErrorMessage() const627 std::string RequestContext::GetErrorMessage() const
628 {
629 auto err = BaseContext::GetErrorCode();
630 if (err == PARSE_ERROR_CODE) {
631 return PARSE_ERROR_MSG;
632 }
633
634 if (BaseContext::IsPermissionDenied()) {
635 return PERMISSION_DENIED_MSG;
636 }
637
638 if (BaseContext::IsNoAllowedHost()) {
639 return HTTP_ERR_MAP.at(HTTP_NOT_ALLOWED_HOST);
640 }
641
642 if (BaseContext::IsCleartextNotPermitted()) {
643 return HTTP_ERR_MAP.at(HTTP_CLEARTEXT_NOT_PERMITTED);
644 }
645
646 auto pos = HTTP_ERR_MAP.find(err + HTTP_ERROR_CODE_BASE);
647 if (pos != HTTP_ERR_MAP.end()) {
648 return pos->second;
649 }
650 return HTTP_ERR_MAP.at(HTTP_UNKNOWN_OTHER_ERROR);
651 }
652
EnableRequestInStream()653 void RequestContext::EnableRequestInStream()
654 {
655 requestInStream_ = true;
656 }
657
IsRequestInStream() const658 bool RequestContext::IsRequestInStream() const
659 {
660 return requestInStream_;
661 }
662
SetDlLen(curl_off_t nowLen,curl_off_t totalLen)663 void RequestContext::SetDlLen(curl_off_t nowLen, curl_off_t totalLen)
664 {
665 std::lock_guard<std::mutex> lock(dlLenLock_);
666 LoadBytes dlBytes{nowLen, totalLen};
667 dlBytes_.push(dlBytes);
668 }
669
SetCertsPath(std::vector<std::string> && certPathList,const std::string & certFile)670 void RequestContext::SetCertsPath(std::vector<std::string> &&certPathList, const std::string &certFile)
671 {
672 certsPath_.certPathList = std::move(certPathList);
673 certsPath_.certFile = certFile;
674 }
675
GetCertsPath()676 const CertsPath &RequestContext::GetCertsPath()
677 {
678 return certsPath_;
679 }
680
GetDlLen()681 LoadBytes RequestContext::GetDlLen()
682 {
683 std::lock_guard<std::mutex> lock(dlLenLock_);
684 LoadBytes dlBytes;
685 if (!dlBytes_.empty()) {
686 dlBytes.nLen = dlBytes_.front().nLen;
687 dlBytes.tLen = dlBytes_.front().tLen;
688 dlBytes_.pop();
689 }
690 return dlBytes;
691 }
692
SetUlLen(curl_off_t nowLen,curl_off_t totalLen)693 void RequestContext::SetUlLen(curl_off_t nowLen, curl_off_t totalLen)
694 {
695 std::lock_guard<std::mutex> lock(ulLenLock_);
696 if (!ulBytes_.empty()) {
697 ulBytes_.pop();
698 }
699 LoadBytes ulBytes{nowLen, totalLen};
700 ulBytes_.push(ulBytes);
701 }
702
GetUlLen()703 LoadBytes RequestContext::GetUlLen()
704 {
705 std::lock_guard<std::mutex> lock(ulLenLock_);
706 LoadBytes ulBytes;
707 if (!ulBytes_.empty()) {
708 ulBytes.nLen = ulBytes_.back().nLen;
709 ulBytes.tLen = ulBytes_.back().tLen;
710 }
711 return ulBytes;
712 }
713
CompareWithLastElement(curl_off_t nowLen,curl_off_t totalLen)714 bool RequestContext::CompareWithLastElement(curl_off_t nowLen, curl_off_t totalLen)
715 {
716 std::lock_guard<std::mutex> lock(ulLenLock_);
717 if (ulBytes_.empty()) {
718 return false;
719 }
720 const LoadBytes &lastElement = ulBytes_.back();
721 return nowLen == lastElement.nLen && totalLen == lastElement.tLen;
722 }
723
SetTempData(const void * data,size_t size)724 void RequestContext::SetTempData(const void *data, size_t size)
725 {
726 std::lock_guard<std::mutex> lock(tempDataLock_);
727 std::string tempString;
728 tempString.append(reinterpret_cast<const char *>(data), size);
729 tempData_.push(tempString);
730 }
731
GetTempData()732 std::string RequestContext::GetTempData()
733 {
734 std::lock_guard<std::mutex> lock(tempDataLock_);
735 if (!tempData_.empty()) {
736 return tempData_.front();
737 }
738 return {};
739 }
740
PopTempData()741 void RequestContext::PopTempData()
742 {
743 std::lock_guard<std::mutex> lock(tempDataLock_);
744 if (!tempData_.empty()) {
745 tempData_.pop();
746 }
747 }
748
ParseDnsServers(napi_value optionsValue)749 void RequestContext::ParseDnsServers(napi_value optionsValue)
750 {
751 napi_env env = GetEnv();
752 if (!NapiUtils::HasNamedProperty(env, optionsValue, HttpConstant::PARAM_KEY_DNS_SERVERS)) {
753 NETSTACK_LOGD("ParseDnsServers no data");
754 return;
755 }
756 napi_value dnsServerValue = NapiUtils::GetNamedProperty(env, optionsValue, HttpConstant::PARAM_KEY_DNS_SERVERS);
757 if (NapiUtils::GetValueType(env, dnsServerValue) != napi_object) {
758 return;
759 }
760 uint32_t dnsLength = NapiUtils::GetArrayLength(env, dnsServerValue);
761 if (dnsLength == 0) {
762 return;
763 }
764 std::vector<std::string> dnsServers;
765 uint32_t dnsSize = 0;
766 for (uint32_t i = 0; i < dnsLength && dnsSize < DNS_SERVER_SIZE; i++) {
767 napi_value element = NapiUtils::GetArrayElement(env, dnsServerValue, i);
768 std::string dnsServer = NapiUtils::GetStringFromValueUtf8(env, element);
769 if (dnsServer.length() == 0) {
770 continue;
771 }
772 if (!CommonUtils::IsValidIPV4(dnsServer) && !CommonUtils::IsValidIPV6(dnsServer)) {
773 continue;
774 }
775 dnsServers.push_back(dnsServer);
776 dnsSize++;
777 }
778 if (dnsSize == 0 || dnsServers.data() == nullptr || dnsServers.empty()) {
779 NETSTACK_LOGD("dnsServersArray is empty.");
780 return;
781 }
782 options.SetDnsServers(dnsServers);
783 NETSTACK_LOGD("SetDnsServers success");
784 }
785
CachePerformanceTimingItem(const std::string & key,double value)786 void RequestContext::CachePerformanceTimingItem(const std::string &key, double value)
787 {
788 performanceTimingMap_[key] = value;
789 }
790
StopAndCacheNapiPerformanceTiming(const char * key)791 void RequestContext::StopAndCacheNapiPerformanceTiming(const char *key)
792 {
793 Timing::Timer &timer = timerMap_.RecieveTimer(key);
794 timer.Stop();
795 CachePerformanceTimingItem(key, timer.Elapsed());
796 }
797
SetPerformanceTimingToResult(napi_value result)798 void RequestContext::SetPerformanceTimingToResult(napi_value result)
799 {
800 if (performanceTimingMap_.empty()) {
801 NETSTACK_LOGD("Get performanceTiming data is empty.");
802 return;
803 }
804 napi_value performanceTimingValue;
805 napi_env env = GetEnv();
806 napi_create_object(env, &performanceTimingValue);
807 for (const auto &pair : performanceTimingMap_) {
808 NapiUtils::SetDoubleProperty(env, performanceTimingValue, pair.first, pair.second);
809 }
810 NapiUtils::SetNamedProperty(env, result, HttpConstant::RESPONSE_PERFORMANCE_TIMING, performanceTimingValue);
811 }
812
ParseClientCert(napi_value optionsValue)813 void RequestContext::ParseClientCert(napi_value optionsValue)
814 {
815 if (!NapiUtils::HasNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_CLIENT_CERT)) {
816 return;
817 }
818 napi_value clientCertValue =
819 NapiUtils::GetNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_CLIENT_CERT);
820 napi_valuetype type = NapiUtils::GetValueType(GetEnv(), clientCertValue);
821 if (type != napi_object) {
822 return;
823 }
824 std::string cert = NapiUtils::GetStringPropertyUtf8(GetEnv(), clientCertValue, HttpConstant::HTTP_CLIENT_CERT);
825 std::string certType =
826 NapiUtils::GetStringPropertyUtf8(GetEnv(), clientCertValue, HttpConstant::HTTP_CLIENT_CERT_TYPE);
827 std::string key = NapiUtils::GetStringPropertyUtf8(GetEnv(), clientCertValue, HttpConstant::HTTP_CLIENT_KEY);
828 Secure::SecureChar keyPasswd = Secure::SecureChar(
829 NapiUtils::GetStringPropertyUtf8(GetEnv(), clientCertValue, HttpConstant::HTTP_CLIENT_KEY_PASSWD));
830 options.SetClientCert(cert, certType, key, keyPasswd);
831 }
832
ParseMultiFormData(napi_value optionsValue)833 void RequestContext::ParseMultiFormData(napi_value optionsValue)
834 {
835 napi_env env = GetEnv();
836 if (!NapiUtils::HasNamedProperty(env, optionsValue, HttpConstant::PARAM_KEY_MULTI_FORM_DATA_LIST)) {
837 NETSTACK_LOGD("ParseMultiFormData multiFormDataList is null.");
838 return;
839 }
840 napi_value multiFormDataListValue =
841 NapiUtils::GetNamedProperty(env, optionsValue, HttpConstant::PARAM_KEY_MULTI_FORM_DATA_LIST);
842 if (NapiUtils::GetValueType(env, multiFormDataListValue) != napi_object) {
843 NETSTACK_LOGE("ParseMultiFormData multiFormDataList type is not object.");
844 return;
845 }
846 uint32_t dataLength = NapiUtils::GetArrayLength(env, multiFormDataListValue);
847 if (dataLength == 0) {
848 NETSTACK_LOGD("ParseMultiFormData multiFormDataList length is 0.");
849 return;
850 }
851 for (uint32_t i = 0; i < dataLength; i++) {
852 napi_value formDataValue = NapiUtils::GetArrayElement(env, multiFormDataListValue, i);
853 MultiFormData multiFormData = NapiValue2FormData(formDataValue);
854 options.AddMultiFormData(multiFormData);
855 }
856 }
857
NapiValue2FormData(napi_value formDataValue)858 MultiFormData RequestContext::NapiValue2FormData(napi_value formDataValue)
859 {
860 napi_env env = GetEnv();
861 MultiFormData multiFormData;
862 multiFormData.name = NapiUtils::GetStringPropertyUtf8(env, formDataValue, HttpConstant::HTTP_MULTI_FORM_DATA_NAME);
863 multiFormData.contentType =
864 NapiUtils::GetStringPropertyUtf8(env, formDataValue, HttpConstant::HTTP_MULTI_FORM_DATA_CONTENT_TYPE);
865 multiFormData.remoteFileName =
866 NapiUtils::GetStringPropertyUtf8(env, formDataValue, HttpConstant::HTTP_MULTI_FORM_DATA_REMOTE_FILE_NAME);
867 RequestContext::SaveFormData(
868 env, NapiUtils::GetNamedProperty(env, formDataValue, HttpConstant::HTTP_MULTI_FORM_DATA_DATA), multiFormData);
869 multiFormData.filePath =
870 NapiUtils::GetStringPropertyUtf8(env, formDataValue, HttpConstant::HTTP_MULTI_FORM_DATA_FILE_PATH);
871 return multiFormData;
872 }
873
NapiValue2CertPinning(napi_value certPIN)874 CertificatePinning RequestContext::NapiValue2CertPinning(napi_value certPIN)
875 {
876 napi_env env = GetEnv();
877 CertificatePinning singleCertPIN;
878 auto algorithm = NapiUtils::GetStringPropertyUtf8(env, certPIN, HttpConstant::HTTP_HASH_ALGORITHM);
879 if (algorithm == "SHA-256") {
880 singleCertPIN.hashAlgorithm = HashAlgorithm::SHA256;
881 } else {
882 singleCertPIN.hashAlgorithm = HashAlgorithm::INVALID;
883 }
884
885 singleCertPIN.publicKeyHash = NapiUtils::GetStringPropertyUtf8(env, certPIN, HttpConstant::HTTP_PUBLIC_KEY_HASH);
886 return singleCertPIN;
887 }
888
SaveFormData(napi_env env,napi_value dataValue,MultiFormData & multiFormData)889 void RequestContext::SaveFormData(napi_env env, napi_value dataValue, MultiFormData &multiFormData)
890 {
891 napi_valuetype type = NapiUtils::GetValueType(env, dataValue);
892 if (type == napi_string) {
893 multiFormData.data = NapiUtils::GetStringFromValueUtf8(GetEnv(), dataValue);
894 NETSTACK_LOGD("SaveFormData string");
895 } else if (NapiUtils::ValueIsArrayBuffer(GetEnv(), dataValue)) {
896 size_t length = 0;
897 void *data = NapiUtils::GetInfoFromArrayBufferValue(GetEnv(), dataValue, &length);
898 if (data == nullptr) {
899 return;
900 }
901 multiFormData.data = std::string(static_cast<const char *>(data), length);
902 NETSTACK_LOGD("SaveFormData ArrayBuffer");
903 } else if (type == napi_object) {
904 multiFormData.data = NapiUtils::GetStringFromValueUtf8(GetEnv(), NapiUtils::JsonStringify(GetEnv(), dataValue));
905 NETSTACK_LOGD("SaveFormData Object");
906 } else {
907 NETSTACK_LOGD("only support string, ArrayBuffer and Object");
908 }
909 }
910
ParseCertificatePinning(napi_value optionsValue)911 void RequestContext::ParseCertificatePinning(napi_value optionsValue)
912 {
913 auto env = GetEnv();
914 if (!NapiUtils::HasNamedProperty(env, optionsValue, HttpConstant::PARAM_KEY_CERTIFICATE_PINNING)) {
915 NETSTACK_LOGD("NO CertificatePinning option");
916 return;
917 }
918 napi_value certificatePin =
919 NapiUtils::GetNamedProperty(env, optionsValue, HttpConstant::PARAM_KEY_CERTIFICATE_PINNING);
920 std::stringstream certPinBuilder;
921
922 if (NapiUtils::IsArray(env, certificatePin)) {
923 auto arrayLen = NapiUtils::GetArrayLength(env, certificatePin);
924 for (uint32_t i = 0; i < arrayLen; i++) {
925 napi_value certPIN = NapiUtils::GetArrayElement(env, certificatePin, i);
926 CertificatePinning singleCertPIN = NapiValue2CertPinning(certPIN);
927 if (singleCertPIN.hashAlgorithm == HashAlgorithm::SHA256) {
928 certPinBuilder << "sha256//" << singleCertPIN.publicKeyHash << ';';
929 }
930 }
931 } else {
932 CertificatePinning singleCertPIN = NapiValue2CertPinning(certificatePin);
933 if (singleCertPIN.hashAlgorithm == HashAlgorithm::SHA256) {
934 certPinBuilder << "sha256//" << singleCertPIN.publicKeyHash << ';';
935 }
936 }
937
938 std::string pinRes = certPinBuilder.str();
939 if (!pinRes.empty()) {
940 pinRes.pop_back();
941 options.SetCertificatePinning(pinRes);
942 }
943 }
944
SetMultipart(curl_mime * multipart)945 void RequestContext::SetMultipart(curl_mime *multipart)
946 {
947 multipart_ = multipart;
948 }
949
GetTaskId() const950 int32_t RequestContext::GetTaskId() const
951 {
952 return taskId_;
953 }
954
SetModuleId(uint64_t moduleId)955 void RequestContext::SetModuleId(uint64_t moduleId)
956 {
957 moduleId_ = moduleId;
958 }
959
GetModuleId() const960 uint64_t RequestContext::GetModuleId() const
961 {
962 return moduleId_;
963 }
964
IsAtomicService() const965 bool RequestContext::IsAtomicService() const
966 {
967 return isAtomicService_;
968 }
969
SetAtomicService(bool isAtomicService)970 void RequestContext::SetAtomicService(bool isAtomicService)
971 {
972 isAtomicService_ = isAtomicService;
973 }
974
SetBundleName(const std::string & bundleName)975 void RequestContext::SetBundleName(const std::string &bundleName)
976 {
977 bundleName_ = bundleName;
978 }
979
GetBundleName() const980 std::string RequestContext::GetBundleName() const
981 {
982 return bundleName_;
983 }
984
SetCurlHandle(CURL * handle)985 void RequestContext::SetCurlHandle(CURL *handle)
986 {
987 curlHandle_ = handle;
988 }
989
SendNetworkProfiler()990 void RequestContext::SendNetworkProfiler()
991 {
992 #if HAS_NETMANAGER_BASE
993 HttpNetworkMessage networkMessage(std::to_string(GetTaskId()), options, response, curlHandle_);
994 networkProfilerUtils_->NetworkProfiling(networkMessage);
995 #endif
996 }
997
GetTrace()998 RequestTracer::Trace &RequestContext::GetTrace()
999 {
1000 return trace_;
1001 }
1002
IsRootCaVerified() const1003 bool RequestContext::IsRootCaVerified() const
1004 {
1005 return isRootCaVerified_;
1006 }
1007
SetRootCaVerified()1008 void RequestContext::SetRootCaVerified()
1009 {
1010 isRootCaVerified_ = true;
1011 }
1012
IsRootCaVerifiedOk() const1013 bool RequestContext::IsRootCaVerifiedOk() const
1014 {
1015 return isRootCaVerifiedOk_;
1016 }
1017
SetRootCaVerifiedOk(bool ok)1018 void RequestContext::SetRootCaVerifiedOk(bool ok)
1019 {
1020 isRootCaVerifiedOk_ = ok;
1021 }
1022
SetPinnedPubkey(std::string & pubkey)1023 void RequestContext::SetPinnedPubkey(std::string &pubkey)
1024 {
1025 pinnedPubkey_ = pubkey;
1026 }
1027
GetPinnedPubkey() const1028 std::string RequestContext::GetPinnedPubkey() const
1029 {
1030 return pinnedPubkey_;
1031 }
1032
ParseAddressFamily(napi_value optionsValue)1033 void RequestContext::ParseAddressFamily(napi_value optionsValue)
1034 {
1035 std::string addressFamily = NapiUtils::GetStringPropertyUtf8(GetEnv(), optionsValue,
1036 HttpConstant::PARAM_KEY_ADDRESS_FAMILY);
1037 if (!addressFamily.empty()) {
1038 options.SetAddressFamily(addressFamily);
1039 }
1040 }
1041 } // namespace OHOS::NetStack::Http
1042