nsHttpConnectionInfo.cpp (22941B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set sw=2 ts=8 et tw=80 : */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 // HttpLog.h should generally be included first 8 #include "HttpLog.h" 9 10 // Log on level :5, instead of default :4. 11 #undef LOG 12 #define LOG(args) LOG5(args) 13 #undef LOG_ENABLED 14 #define LOG_ENABLED() LOG5_ENABLED() 15 16 #include "nsHttpConnectionInfo.h" 17 18 #include "mozilla/net/DNS.h" 19 #include "mozilla/net/NeckoChannelParams.h" 20 #include "nsComponentManagerUtils.h" 21 #include "nsICryptoHash.h" 22 #include "nsIDNSByTypeRecord.h" 23 #include "nsIProtocolProxyService.h" 24 #include "nsHttpHandler.h" 25 #include "nsNetCID.h" 26 #include "nsProxyInfo.h" 27 #include "prnetdb.h" 28 29 static nsresult SHA256(const char* aPlainText, nsAutoCString& aResult) { 30 nsresult rv; 31 nsCOMPtr<nsICryptoHash> hasher = 32 do_CreateInstance(NS_CRYPTO_HASH_CONTRACTID, &rv); 33 if (NS_FAILED(rv)) { 34 LOG(("nsHttpDigestAuth: no crypto hash!\n")); 35 return rv; 36 } 37 rv = hasher->Init(nsICryptoHash::SHA256); 38 NS_ENSURE_SUCCESS(rv, rv); 39 rv = hasher->Update((unsigned char*)aPlainText, strlen(aPlainText)); 40 NS_ENSURE_SUCCESS(rv, rv); 41 return hasher->Finish(false, aResult); 42 } 43 44 namespace mozilla { 45 namespace net { 46 47 nsHttpConnectionInfo::nsHttpConnectionInfo( 48 const nsACString& originHost, int32_t originPort, 49 const nsACString& npnToken, const nsACString& username, 50 nsProxyInfo* proxyInfo, const OriginAttributes& originAttributes, 51 bool endToEndSSL, bool aIsHttp3, bool aWebTransport) 52 : mRoutedPort(443), mLessThanTls13(false) { 53 Init(originHost, originPort, npnToken, username, proxyInfo, originAttributes, 54 endToEndSSL, aIsHttp3, aWebTransport); 55 } 56 57 nsHttpConnectionInfo::nsHttpConnectionInfo( 58 const nsACString& originHost, int32_t originPort, 59 const nsACString& npnToken, const nsACString& username, 60 nsProxyInfo* proxyInfo, const OriginAttributes& originAttributes, 61 const nsACString& routedHost, int32_t routedPort, bool aIsHttp3, 62 bool aWebTransport) 63 : mLessThanTls13(false) { 64 mEndToEndSSL = true; // so DefaultPort() works 65 mRoutedPort = routedPort == -1 ? DefaultPort() : routedPort; 66 67 if (!originHost.Equals(routedHost) || (originPort != routedPort) || 68 aIsHttp3) { 69 mRoutedHost = routedHost; 70 } 71 Init(originHost, originPort, npnToken, username, proxyInfo, originAttributes, 72 true, aIsHttp3, aWebTransport); 73 } 74 75 // static 76 uint64_t nsHttpConnectionInfo::GenerateNewWebTransportId() { 77 // Used for generating unique IDSs for dedicated connections, currently used 78 // by WebTransport 79 MOZ_ASSERT(XRE_IsParentProcess()); 80 static Atomic<uint64_t> id(0); 81 return ++id; 82 } 83 84 void nsHttpConnectionInfo::Init(const nsACString& host, int32_t port, 85 const nsACString& npnToken, 86 const nsACString& username, 87 nsProxyInfo* proxyInfo, 88 const OriginAttributes& originAttributes, 89 bool e2eSSL, bool aIsHttp3, 90 bool aWebTransport) { 91 LOG(("Init nsHttpConnectionInfo @%p\n", this)); 92 93 mUsername = username; 94 mProxyInfo = proxyInfo; 95 mEndToEndSSL = e2eSSL; 96 mUsingConnect = false; 97 mNPNToken = npnToken; 98 mIsHttp3 = aIsHttp3; 99 mWebTransport = aWebTransport; 100 mOriginAttributes = originAttributes; 101 mTlsFlags = 0x0; 102 mIsTrrServiceChannel = false; 103 mTRRMode = nsIRequest::TRR_DEFAULT_MODE; 104 mIPv4Disabled = false; 105 mIPv6Disabled = false; 106 mHasIPHintAddress = false; 107 108 mUsingHttpsProxy = (proxyInfo && proxyInfo->IsHTTPS()); 109 mUsingHttpProxy = mUsingHttpsProxy || (proxyInfo && proxyInfo->IsHTTP()); 110 111 if (mUsingHttpProxy) { 112 mUsingConnect = mEndToEndSSL || proxyInfo->IsHttp3Proxy(); 113 if (!mUsingConnect) { 114 uint32_t resolveFlags = 0; 115 if (NS_SUCCEEDED(mProxyInfo->GetResolveFlags(&resolveFlags)) && 116 resolveFlags & nsIProtocolProxyService::RESOLVE_ALWAYS_TUNNEL) { 117 mUsingConnect = true; 118 } 119 } 120 } 121 122 if (mUsingHttpsProxy) { 123 mIsHttp3ProxyConnection = "masque"_ns.Equals(proxyInfo->Type()); 124 if (mIsHttp3ProxyConnection) { 125 mProxyNPNToken = "h3"_ns; 126 } 127 } 128 129 SetOriginServer(host, port); 130 } 131 132 void nsHttpConnectionInfo::BuildHashKey() { 133 // 134 // build hash key: 135 // 136 // the hash key uniquely identifies the connection type. two connections 137 // are "equal" if they end up talking the same protocol to the same server 138 // and are both used for anonymous or non-anonymous connection only; 139 // anonymity of the connection is setup later from nsHttpChannel::AsyncOpen 140 // where we know we use anonymous connection (LOAD_ANONYMOUS load flag) 141 // 142 143 const char* keyHost; 144 int32_t keyPort; 145 146 if (mUsingHttpProxy && !mUsingConnect) { 147 keyHost = ProxyHost(); 148 keyPort = ProxyPort(); 149 } else { 150 keyHost = Origin(); 151 keyPort = OriginPort(); 152 } 153 154 // The hashkey has 9 fields followed by host connection info 155 // byte 0 is P/T/. {P,T} for Plaintext/TLS Proxy over HTTP 156 // byte 1 is S/. S is for end to end ssl such as https:// uris 157 // byte 2 is A/. A is for an anonymous channel (no cookies, etc..) 158 // byte 3 is P/. P is for a private browising channel 159 // byte 4 is I/. I is for insecure scheme on TLS for http:// uris 160 // byte 5 is X/. X is for disallow_spdy flag 161 // byte 6 is C/. C is for be Conservative 162 // byte 7 is B/. B is for allowing client certs on an anonymous channel 163 // byte 8 is F/. F is for indicating a fallback connection 164 // byte 9 is W/. W is for indicating a webTransport 165 // Note: when adding/removing fields from this list which do not have 166 // corresponding data fields on the object itself, you may also need to 167 // modify RebuildHashKey. 168 169 const auto keyTemplate = 170 std::string(UnderlyingIndex(HashKeyIndex::End), '.') + 171 std::string("[tlsflags0x00000000]"); 172 mHashKey.Assign(keyTemplate.c_str()); 173 174 mHashKey.Append(keyHost); 175 mHashKey.Append(':'); 176 mHashKey.AppendInt(keyPort); 177 if (!mUsername.IsEmpty()) { 178 mHashKey.Append('['); 179 mHashKey.Append(mUsername); 180 mHashKey.Append(']'); 181 } 182 183 if (mUsingHttpsProxy) { 184 SetHashCharAt('T', HashKeyIndex::Proxy); 185 } else if (mUsingHttpProxy) { 186 SetHashCharAt('P', HashKeyIndex::Proxy); 187 } 188 if (mEndToEndSSL) { 189 SetHashCharAt('S', HashKeyIndex::EndToEndSSL); 190 } 191 192 if (mWebTransport) { 193 SetHashCharAt('W', HashKeyIndex::WebTransport); 194 } 195 196 // NOTE: for transparent proxies (e.g., SOCKS) we need to encode the proxy 197 // info in the hash key (this ensures that we will continue to speak the 198 // right protocol even if our proxy preferences change). 199 // 200 // NOTE: for SSL tunnels add the proxy information to the cache key. 201 // We cannot use the proxy as the host parameter (as we do for non SSL) 202 // because this is a single host tunnel, but we need to include the proxy 203 // information so that a change in proxy config will mean this connection 204 // is not reused 205 206 // NOTE: Adding the username and the password provides a means to isolate 207 // keep-alive to the URL bar domain as well: If the username is the URL bar 208 // domain, keep-alive connections are not reused by resources bound to 209 // different URL bar domains as the respective hash keys are not matching. 210 211 if ((!mUsingHttpProxy && ProxyHost()) || (mUsingHttpProxy && mUsingConnect)) { 212 mHashKey.AppendLiteral(" ("); 213 mHashKey.Append(ProxyType()); 214 mHashKey.Append(':'); 215 mHashKey.Append(ProxyHost()); 216 mHashKey.Append(':'); 217 mHashKey.AppendInt(ProxyPort()); 218 mHashKey.Append(')'); 219 mHashKey.Append('['); 220 mHashKey.Append(ProxyUsername()); 221 mHashKey.Append(':'); 222 const char* password = ProxyPassword(); 223 if (strlen(password) > 0) { 224 nsAutoCString digestedPassword; 225 nsresult rv = SHA256(password, digestedPassword); 226 if (rv == NS_OK) { 227 mHashKey.Append(digestedPassword); 228 } 229 } 230 mHashKey.Append(']'); 231 } 232 233 if (!mRoutedHost.IsEmpty()) { 234 mHashKey.AppendLiteral(" <ROUTE-via "); 235 mHashKey.Append(mRoutedHost); 236 mHashKey.Append(':'); 237 mHashKey.AppendInt(mRoutedPort); 238 mHashKey.Append('>'); 239 } 240 241 if (!mNPNToken.IsEmpty()) { 242 mHashKey.AppendLiteral(" {NPN-TOKEN "); 243 mHashKey.Append(mNPNToken); 244 mHashKey.AppendLiteral("}"); 245 } 246 247 if (GetTRRMode() != nsIRequest::TRR_DEFAULT_MODE) { 248 // When connecting with another TRR mode, we enforce a separate connection 249 // hashkey so that we also can trigger a fresh DNS resolver that then 250 // doesn't use TRR as the previous connection might have. 251 mHashKey.AppendLiteral("[TRR:"); 252 mHashKey.AppendInt(GetTRRMode()); 253 mHashKey.AppendLiteral("]"); 254 } 255 256 if (GetIPv4Disabled()) { 257 mHashKey.AppendLiteral("[!v4]"); 258 } 259 260 if (GetIPv6Disabled()) { 261 mHashKey.AppendLiteral("[!v6]"); 262 } 263 264 if (mProxyInfo) { 265 const nsCString& connectionIsolationKey = 266 mProxyInfo->ConnectionIsolationKey(); 267 if (!connectionIsolationKey.IsEmpty()) { 268 mHashKey.AppendLiteral("{CIK "); 269 mHashKey.Append(connectionIsolationKey); 270 mHashKey.AppendLiteral("}"); 271 } 272 if (mProxyInfo->Flags() & nsIProxyInfo::TRANSPARENT_PROXY_RESOLVES_HOST) { 273 mHashKey.AppendLiteral("{TPRH}"); 274 } 275 } 276 277 if (mWebTransportId) { 278 mHashKey.AppendLiteral("{wId"); 279 mHashKey.AppendInt(mWebTransportId, 16); 280 mHashKey.AppendLiteral("}"); 281 } 282 283 nsAutoCString originAttributes; 284 mOriginAttributes.CreateSuffix(originAttributes); 285 mHashKey.Append(originAttributes); 286 } 287 288 void nsHttpConnectionInfo::RebuildHashKey() { 289 // Create copies of all properties stored in our hash key. 290 bool isAnonymous = GetAnonymous(); 291 bool isPrivate = GetPrivate(); 292 bool isInsecureScheme = GetInsecureScheme(); 293 bool isNoSpdy = GetNoSpdy(); 294 bool isBeConservative = GetBeConservative(); 295 bool isAnonymousAllowClientCert = GetAnonymousAllowClientCert(); 296 bool isFallback = GetFallbackConnection(); 297 298 BuildHashKey(); 299 300 // Restore all of those properties. 301 SetAnonymous(isAnonymous); 302 SetPrivate(isPrivate); 303 SetInsecureScheme(isInsecureScheme); 304 SetNoSpdy(isNoSpdy); 305 SetBeConservative(isBeConservative); 306 SetAnonymousAllowClientCert(isAnonymousAllowClientCert); 307 SetFallbackConnection(isFallback); 308 SetTlsFlags(mTlsFlags); 309 } 310 311 void nsHttpConnectionInfo::SetOriginServer(const nsACString& host, 312 int32_t port) { 313 mOrigin = host; 314 mOriginPort = port == -1 ? DefaultPort() : port; 315 // Use BuildHashKey() since this can only be called when constructing an 316 // nsHttpConnectionInfo object. 317 MOZ_DIAGNOSTIC_ASSERT(mHashKey.IsEmpty()); 318 BuildHashKey(); 319 } 320 321 // Note that this function needs to be synced with 322 // nsHttpConnectionInfo::DeserializeHttpConnectionInfoCloneArgs to make sure 323 // nsHttpConnectionInfo can be serialized/deserialized. 324 already_AddRefed<nsHttpConnectionInfo> nsHttpConnectionInfo::Clone() const { 325 RefPtr<nsHttpConnectionInfo> clone; 326 if (mRoutedHost.IsEmpty()) { 327 clone = new nsHttpConnectionInfo(mOrigin, mOriginPort, mNPNToken, mUsername, 328 mProxyInfo, mOriginAttributes, 329 mEndToEndSSL, mIsHttp3, mWebTransport); 330 } else { 331 MOZ_ASSERT(mEndToEndSSL); 332 clone = new nsHttpConnectionInfo(mOrigin, mOriginPort, mNPNToken, mUsername, 333 mProxyInfo, mOriginAttributes, mRoutedHost, 334 mRoutedPort, mIsHttp3, mWebTransport); 335 } 336 337 // Make sure the anonymous, insecure-scheme, and private flags are transferred 338 clone->SetAnonymous(GetAnonymous()); 339 clone->SetPrivate(GetPrivate()); 340 clone->SetInsecureScheme(GetInsecureScheme()); 341 clone->SetNoSpdy(GetNoSpdy()); 342 clone->SetBeConservative(GetBeConservative()); 343 clone->SetAnonymousAllowClientCert(GetAnonymousAllowClientCert()); 344 clone->SetFallbackConnection(GetFallbackConnection()); 345 clone->SetTlsFlags(GetTlsFlags()); 346 clone->SetIsTrrServiceChannel(GetIsTrrServiceChannel()); 347 clone->SetTRRMode(GetTRRMode()); 348 clone->SetIPv4Disabled(GetIPv4Disabled()); 349 clone->SetIPv6Disabled(GetIPv6Disabled()); 350 clone->SetHasIPHintAddress(HasIPHintAddress()); 351 clone->SetEchConfig(GetEchConfig()); 352 clone->SetWebTransportId(GetWebTransportId()); 353 MOZ_ASSERT(clone->Equals(this)); 354 355 return clone.forget(); 356 } 357 358 already_AddRefed<nsHttpConnectionInfo> 359 nsHttpConnectionInfo::CloneAndAdoptHTTPSSVCRecord( 360 nsISVCBRecord* aRecord) const { 361 MOZ_ASSERT(aRecord); 362 363 // Get the domain name of this HTTPS RR. This name will be assigned to 364 // mRoutedHost in the new connection info. 365 nsAutoCString name; 366 aRecord->GetName(name); 367 368 // Try to get the port and Alpn. If this record has SvcParamKeyPort defined, 369 // the new port will be used as mRoutedPort. 370 Maybe<uint16_t> port = aRecord->GetPort(); 371 Maybe<std::tuple<nsCString, SupportedAlpnRank>> alpn = aRecord->GetAlpn(); 372 373 // Let the new conn info learn h3 will be used. 374 bool isHttp3 = alpn ? mozilla::net::IsHttp3(std::get<1>(*alpn)) : false; 375 376 LOG(("HTTPSSVC: use new routed host (%s) and new npnToken (%s)", name.get(), 377 alpn ? std::get<0>(*alpn).get() : "None")); 378 379 RefPtr<nsHttpConnectionInfo> clone; 380 if (name.IsEmpty()) { 381 clone = new nsHttpConnectionInfo( 382 mOrigin, mOriginPort, alpn ? std::get<0>(*alpn) : EmptyCString(), 383 mUsername, mProxyInfo, mOriginAttributes, mEndToEndSSL, isHttp3); 384 } else { 385 MOZ_ASSERT(mEndToEndSSL); 386 clone = new nsHttpConnectionInfo( 387 mOrigin, mOriginPort, alpn ? std::get<0>(*alpn) : EmptyCString(), 388 mUsername, mProxyInfo, mOriginAttributes, name, 389 port ? *port : mOriginPort, isHttp3, mWebTransport); 390 } 391 392 // Make sure the anonymous, insecure-scheme, and private flags are transferred 393 clone->SetAnonymous(GetAnonymous()); 394 clone->SetPrivate(GetPrivate()); 395 clone->SetInsecureScheme(GetInsecureScheme()); 396 clone->SetNoSpdy(GetNoSpdy()); 397 clone->SetBeConservative(GetBeConservative()); 398 clone->SetAnonymousAllowClientCert(GetAnonymousAllowClientCert()); 399 clone->SetFallbackConnection(GetFallbackConnection()); 400 clone->SetTlsFlags(GetTlsFlags()); 401 clone->SetIsTrrServiceChannel(GetIsTrrServiceChannel()); 402 clone->SetTRRMode(GetTRRMode()); 403 clone->SetIPv4Disabled(GetIPv4Disabled()); 404 clone->SetIPv6Disabled(GetIPv6Disabled()); 405 406 bool hasIPHint = false; 407 (void)aRecord->GetHasIPHintAddress(&hasIPHint); 408 if (hasIPHint) { 409 clone->SetHasIPHintAddress(hasIPHint); 410 } 411 412 nsAutoCString echConfig; 413 (void)aRecord->GetEchConfig(echConfig); 414 clone->SetEchConfig(echConfig); 415 416 return clone.forget(); 417 } 418 419 /* static */ 420 void nsHttpConnectionInfo::SerializeHttpConnectionInfo( 421 nsHttpConnectionInfo* aInfo, HttpConnectionInfoCloneArgs& aArgs) { 422 aArgs.host() = aInfo->GetOrigin(); 423 aArgs.port() = aInfo->OriginPort(); 424 aArgs.npnToken() = aInfo->GetNPNToken(); 425 aArgs.username() = aInfo->GetUsername(); 426 aArgs.originAttributes() = aInfo->GetOriginAttributes(); 427 aArgs.endToEndSSL() = aInfo->EndToEndSSL(); 428 aArgs.routedHost() = aInfo->GetRoutedHost(); 429 aArgs.routedPort() = aInfo->RoutedPort(); 430 aArgs.anonymous() = aInfo->GetAnonymous(); 431 aArgs.aPrivate() = aInfo->GetPrivate(); 432 aArgs.insecureScheme() = aInfo->GetInsecureScheme(); 433 aArgs.noSpdy() = aInfo->GetNoSpdy(); 434 aArgs.beConservative() = aInfo->GetBeConservative(); 435 aArgs.anonymousAllowClientCert() = aInfo->GetAnonymousAllowClientCert(); 436 aArgs.tlsFlags() = aInfo->GetTlsFlags(); 437 aArgs.isTrrServiceChannel() = aInfo->GetTRRMode(); 438 aArgs.trrMode() = aInfo->GetTRRMode(); 439 aArgs.isIPv4Disabled() = aInfo->GetIPv4Disabled(); 440 aArgs.isIPv6Disabled() = aInfo->GetIPv6Disabled(); 441 aArgs.isHttp3() = aInfo->IsHttp3(); 442 aArgs.hasIPHintAddress() = aInfo->HasIPHintAddress(); 443 aArgs.echConfig() = aInfo->GetEchConfig(); 444 aArgs.webTransport() = aInfo->GetWebTransport(); 445 aArgs.webTransportId() = aInfo->GetWebTransportId(); 446 447 if (!aInfo->ProxyInfo()) { 448 return; 449 } 450 451 nsTArray<ProxyInfoCloneArgs> proxyInfoArray; 452 nsProxyInfo::SerializeProxyInfo(aInfo->ProxyInfo(), proxyInfoArray); 453 aArgs.proxyInfo() = std::move(proxyInfoArray); 454 } 455 456 // This function needs to be synced with nsHttpConnectionInfo::Clone. 457 /* static */ 458 already_AddRefed<nsHttpConnectionInfo> 459 nsHttpConnectionInfo::DeserializeHttpConnectionInfoCloneArgs( 460 const HttpConnectionInfoCloneArgs& aInfoArgs) { 461 nsProxyInfo* pi = nsProxyInfo::DeserializeProxyInfo(aInfoArgs.proxyInfo()); 462 RefPtr<nsHttpConnectionInfo> cinfo; 463 if (aInfoArgs.routedHost().IsEmpty()) { 464 cinfo = new nsHttpConnectionInfo( 465 aInfoArgs.host(), aInfoArgs.port(), aInfoArgs.npnToken(), 466 aInfoArgs.username(), pi, aInfoArgs.originAttributes(), 467 aInfoArgs.endToEndSSL(), aInfoArgs.isHttp3(), aInfoArgs.webTransport()); 468 } else { 469 MOZ_ASSERT(aInfoArgs.endToEndSSL()); 470 cinfo = new nsHttpConnectionInfo( 471 aInfoArgs.host(), aInfoArgs.port(), aInfoArgs.npnToken(), 472 aInfoArgs.username(), pi, aInfoArgs.originAttributes(), 473 aInfoArgs.routedHost(), aInfoArgs.routedPort(), aInfoArgs.isHttp3(), 474 aInfoArgs.webTransport()); 475 } 476 // Transfer Webtransport ids 477 cinfo->SetWebTransportId(aInfoArgs.webTransportId()); 478 479 // Make sure the anonymous, insecure-scheme, and private flags are transferred 480 cinfo->SetAnonymous(aInfoArgs.anonymous()); 481 cinfo->SetPrivate(aInfoArgs.aPrivate()); 482 cinfo->SetInsecureScheme(aInfoArgs.insecureScheme()); 483 cinfo->SetNoSpdy(aInfoArgs.noSpdy()); 484 cinfo->SetBeConservative(aInfoArgs.beConservative()); 485 cinfo->SetAnonymousAllowClientCert(aInfoArgs.anonymousAllowClientCert()); 486 cinfo->SetFallbackConnection(aInfoArgs.fallbackConnection()); 487 cinfo->SetTlsFlags(aInfoArgs.tlsFlags()); 488 cinfo->SetIsTrrServiceChannel(aInfoArgs.isTrrServiceChannel()); 489 cinfo->SetTRRMode(static_cast<nsIRequest::TRRMode>(aInfoArgs.trrMode())); 490 cinfo->SetIPv4Disabled(aInfoArgs.isIPv4Disabled()); 491 cinfo->SetIPv6Disabled(aInfoArgs.isIPv6Disabled()); 492 cinfo->SetHasIPHintAddress(aInfoArgs.hasIPHintAddress()); 493 cinfo->SetEchConfig(aInfoArgs.echConfig()); 494 495 return cinfo.forget(); 496 } 497 498 void nsHttpConnectionInfo::CloneAsDirectRoute(nsHttpConnectionInfo** outCI, 499 nsProxyInfo* aProxyInfo) { 500 // Explicitly use an empty npnToken when |mIsHttp3| is true, since we want to 501 // create a non-http3 connection info. 502 RefPtr<nsHttpConnectionInfo> clone = new nsHttpConnectionInfo( 503 mOrigin, mOriginPort, 504 (mRoutedHost.IsEmpty() && !mIsHttp3) ? mNPNToken : ""_ns, mUsername, 505 aProxyInfo ? aProxyInfo : mProxyInfo.get(), mOriginAttributes, 506 mEndToEndSSL, false, mWebTransport); 507 // Make sure the anonymous, insecure-scheme, and private flags are transferred 508 clone->SetAnonymous(GetAnonymous()); 509 clone->SetPrivate(GetPrivate()); 510 clone->SetInsecureScheme(GetInsecureScheme()); 511 clone->SetNoSpdy(GetNoSpdy()); 512 clone->SetBeConservative(GetBeConservative()); 513 clone->SetAnonymousAllowClientCert(GetAnonymousAllowClientCert()); 514 clone->SetFallbackConnection(GetFallbackConnection()); 515 clone->SetTlsFlags(GetTlsFlags()); 516 clone->SetIsTrrServiceChannel(GetIsTrrServiceChannel()); 517 clone->SetTRRMode(GetTRRMode()); 518 clone->SetIPv4Disabled(GetIPv4Disabled()); 519 clone->SetIPv6Disabled(GetIPv6Disabled()); 520 clone->SetHasIPHintAddress(HasIPHintAddress()); 521 clone->SetEchConfig(GetEchConfig()); 522 523 clone.forget(outCI); 524 } 525 526 already_AddRefed<nsHttpConnectionInfo> 527 nsHttpConnectionInfo::CreateConnectUDPFallbackConnInfo() { 528 if (!mProxyInfo || !mProxyInfo->IsHttp3Proxy()) { 529 return nullptr; 530 } 531 532 RefPtr<nsProxyInfo> proxyInfo = mProxyInfo->CreateFallbackProxyInfo(); 533 RefPtr<nsHttpConnectionInfo> clone; 534 CloneAsDirectRoute(getter_AddRefs(clone), proxyInfo); 535 return clone.forget(); 536 } 537 538 nsresult nsHttpConnectionInfo::CreateWildCard(nsHttpConnectionInfo** outParam) { 539 // T???mozilla.org:443 (https:proxy.ducksong.com:3128) [specifc form] 540 // TS??*:0 (https:proxy.ducksong.com:3128) [wildcard form] 541 542 if (!mUsingHttpsProxy) { 543 MOZ_ASSERT(false); 544 return NS_ERROR_NOT_IMPLEMENTED; 545 } 546 547 RefPtr<nsHttpConnectionInfo> clone; 548 clone = new nsHttpConnectionInfo("*"_ns, 0, mNPNToken, mUsername, mProxyInfo, 549 mOriginAttributes, true, mIsHttp3, 550 mWebTransport); 551 // Make sure the anonymous and private flags are transferred! 552 clone->SetAnonymous(GetAnonymous()); 553 clone->SetPrivate(GetPrivate()); 554 clone->SetFallbackConnection(GetFallbackConnection()); 555 clone.forget(outParam); 556 return NS_OK; 557 } 558 559 void nsHttpConnectionInfo::SetTRRMode(nsIRequest::TRRMode aTRRMode) { 560 if (mTRRMode != aTRRMode) { 561 mTRRMode = aTRRMode; 562 RebuildHashKey(); 563 } 564 } 565 566 void nsHttpConnectionInfo::SetIPv4Disabled(bool aNoIPv4) { 567 if (mIPv4Disabled != aNoIPv4) { 568 mIPv4Disabled = aNoIPv4; 569 RebuildHashKey(); 570 } 571 } 572 573 void nsHttpConnectionInfo::SetIPv6Disabled(bool aNoIPv6) { 574 if (mIPv6Disabled != aNoIPv6) { 575 mIPv6Disabled = aNoIPv6; 576 RebuildHashKey(); 577 } 578 } 579 580 void nsHttpConnectionInfo::SetWebTransport(bool aWebTransport) { 581 if (mWebTransport != aWebTransport) { 582 mWebTransport = aWebTransport; 583 RebuildHashKey(); 584 } 585 } 586 587 void nsHttpConnectionInfo::SetWebTransportId(uint64_t id) { 588 if (mWebTransportId != id) { 589 mWebTransportId = id; 590 RebuildHashKey(); 591 } 592 } 593 594 void nsHttpConnectionInfo::SetTlsFlags(uint32_t aTlsFlags) { 595 mTlsFlags = aTlsFlags; 596 const uint32_t tlsFlagsLength = 8; 597 const uint32_t tlsFlagsIndex = 598 UnderlyingIndex(HashKeyIndex::End) + strlen("[tlsflags0x"); 599 mHashKey.Replace(tlsFlagsIndex, tlsFlagsLength, 600 nsPrintfCString("%08x", mTlsFlags)); 601 } 602 603 bool nsHttpConnectionInfo::UsingProxy() { 604 if (!mProxyInfo) return false; 605 return !mProxyInfo->IsDirect(); 606 } 607 608 bool nsHttpConnectionInfo::HostIsLocalIPLiteral() const { 609 NetAddr netAddr; 610 // If the host/proxy host is not an IP address literal, return false. 611 nsAutoCString host(ProxyHost() ? ProxyHost() : Origin()); 612 if (NS_FAILED(netAddr.InitFromString(host))) { 613 return false; 614 } 615 return netAddr.IsIPAddrLocal(); 616 } 617 618 // static 619 void nsHttpConnectionInfo::BuildOriginFrameHashKey(nsACString& newKey, 620 nsHttpConnectionInfo* ci, 621 const nsACString& host, 622 int32_t port) { 623 newKey.Assign(host); 624 if (ci->GetAnonymous()) { 625 newKey.AppendLiteral("~A:"); 626 } else { 627 newKey.AppendLiteral("~.:"); 628 } 629 if (ci->GetFallbackConnection()) { 630 newKey.AppendLiteral("~F:"); 631 } else { 632 newKey.AppendLiteral("~.:"); 633 } 634 newKey.AppendInt(port); 635 newKey.AppendLiteral("/["); 636 nsAutoCString suffix; 637 ci->GetOriginAttributes().CreateSuffix(suffix); 638 newKey.Append(suffix); 639 newKey.AppendLiteral("]viaORIGIN.FRAME"); 640 } 641 642 } // namespace net 643 } // namespace mozilla