619 lines
22 KiB
C++
619 lines
22 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set sw=2 ts=8 et tw=80 : */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
// HttpLog.h should generally be included first
|
|
#include "HttpLog.h"
|
|
|
|
// Log on level :5, instead of default :4.
|
|
#undef LOG
|
|
#define LOG(args) LOG5(args)
|
|
#undef LOG_ENABLED
|
|
#define LOG_ENABLED() LOG5_ENABLED()
|
|
|
|
#include "nsHttpConnectionInfo.h"
|
|
|
|
#include "mozilla/net/DNS.h"
|
|
#include "mozilla/net/NeckoChannelParams.h"
|
|
#include "nsComponentManagerUtils.h"
|
|
#include "nsICryptoHash.h"
|
|
#include "nsIDNSByTypeRecord.h"
|
|
#include "nsIProtocolProxyService.h"
|
|
#include "nsHttpHandler.h"
|
|
#include "nsNetCID.h"
|
|
#include "nsProxyInfo.h"
|
|
#include "prnetdb.h"
|
|
|
|
static nsresult SHA256(const char* aPlainText, nsAutoCString& aResult) {
|
|
nsresult rv;
|
|
nsCOMPtr<nsICryptoHash> hasher =
|
|
do_CreateInstance(NS_CRYPTO_HASH_CONTRACTID, &rv);
|
|
if (NS_FAILED(rv)) {
|
|
LOG(("nsHttpDigestAuth: no crypto hash!\n"));
|
|
return rv;
|
|
}
|
|
rv = hasher->Init(nsICryptoHash::SHA256);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
rv = hasher->Update((unsigned char*)aPlainText, strlen(aPlainText));
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
return hasher->Finish(false, aResult);
|
|
}
|
|
|
|
namespace mozilla {
|
|
namespace net {
|
|
|
|
nsHttpConnectionInfo::nsHttpConnectionInfo(
|
|
const nsACString& originHost, int32_t originPort,
|
|
const nsACString& npnToken, const nsACString& username,
|
|
nsProxyInfo* proxyInfo, const OriginAttributes& originAttributes,
|
|
bool endToEndSSL, bool aIsHttp3, bool aWebTransport)
|
|
: mRoutedPort(443), mLessThanTls13(false) {
|
|
Init(originHost, originPort, npnToken, username, proxyInfo, originAttributes,
|
|
endToEndSSL, aIsHttp3, aWebTransport);
|
|
}
|
|
|
|
nsHttpConnectionInfo::nsHttpConnectionInfo(
|
|
const nsACString& originHost, int32_t originPort,
|
|
const nsACString& npnToken, const nsACString& username,
|
|
nsProxyInfo* proxyInfo, const OriginAttributes& originAttributes,
|
|
const nsACString& routedHost, int32_t routedPort, bool aIsHttp3,
|
|
bool aWebTransport)
|
|
: mLessThanTls13(false) {
|
|
mEndToEndSSL = true; // so DefaultPort() works
|
|
mRoutedPort = routedPort == -1 ? DefaultPort() : routedPort;
|
|
|
|
if (!originHost.Equals(routedHost) || (originPort != routedPort) ||
|
|
aIsHttp3) {
|
|
mRoutedHost = routedHost;
|
|
}
|
|
Init(originHost, originPort, npnToken, username, proxyInfo, originAttributes,
|
|
true, aIsHttp3, aWebTransport);
|
|
}
|
|
|
|
// static
|
|
uint64_t nsHttpConnectionInfo::GenerateNewWebTransportId() {
|
|
// Used for generating unique IDSs for dedicated connections, currently used
|
|
// by WebTransport
|
|
MOZ_ASSERT(XRE_IsParentProcess());
|
|
static Atomic<uint64_t> id(0);
|
|
return ++id;
|
|
}
|
|
|
|
void nsHttpConnectionInfo::Init(const nsACString& host, int32_t port,
|
|
const nsACString& npnToken,
|
|
const nsACString& username,
|
|
nsProxyInfo* proxyInfo,
|
|
const OriginAttributes& originAttributes,
|
|
bool e2eSSL, bool aIsHttp3,
|
|
bool aWebTransport) {
|
|
LOG(("Init nsHttpConnectionInfo @%p\n", this));
|
|
|
|
mUsername = username;
|
|
mProxyInfo = proxyInfo;
|
|
mEndToEndSSL = e2eSSL;
|
|
mUsingConnect = false;
|
|
mNPNToken = npnToken;
|
|
mIsHttp3 = aIsHttp3;
|
|
mWebTransport = aWebTransport;
|
|
mOriginAttributes = originAttributes;
|
|
mTlsFlags = 0x0;
|
|
mIsTrrServiceChannel = false;
|
|
mTRRMode = nsIRequest::TRR_DEFAULT_MODE;
|
|
mIPv4Disabled = false;
|
|
mIPv6Disabled = false;
|
|
mHasIPHintAddress = false;
|
|
|
|
mUsingHttpsProxy = (proxyInfo && proxyInfo->IsHTTPS());
|
|
mUsingHttpProxy = mUsingHttpsProxy || (proxyInfo && proxyInfo->IsHTTP());
|
|
|
|
if (mUsingHttpProxy) {
|
|
mUsingConnect = mEndToEndSSL; // SSL always uses CONNECT
|
|
uint32_t resolveFlags = 0;
|
|
if (NS_SUCCEEDED(mProxyInfo->GetResolveFlags(&resolveFlags)) &&
|
|
resolveFlags & nsIProtocolProxyService::RESOLVE_ALWAYS_TUNNEL) {
|
|
mUsingConnect = true;
|
|
}
|
|
}
|
|
|
|
SetOriginServer(host, port);
|
|
}
|
|
|
|
void nsHttpConnectionInfo::BuildHashKey() {
|
|
//
|
|
// build hash key:
|
|
//
|
|
// the hash key uniquely identifies the connection type. two connections
|
|
// are "equal" if they end up talking the same protocol to the same server
|
|
// and are both used for anonymous or non-anonymous connection only;
|
|
// anonymity of the connection is setup later from nsHttpChannel::AsyncOpen
|
|
// where we know we use anonymous connection (LOAD_ANONYMOUS load flag)
|
|
//
|
|
|
|
const char* keyHost;
|
|
int32_t keyPort;
|
|
|
|
if (mUsingHttpProxy && !mUsingConnect) {
|
|
keyHost = ProxyHost();
|
|
keyPort = ProxyPort();
|
|
} else {
|
|
keyHost = Origin();
|
|
keyPort = OriginPort();
|
|
}
|
|
|
|
// The hashkey has 9 fields followed by host connection info
|
|
// byte 0 is P/T/. {P,T} for Plaintext/TLS Proxy over HTTP
|
|
// byte 1 is S/. S is for end to end ssl such as https:// uris
|
|
// byte 2 is A/. A is for an anonymous channel (no cookies, etc..)
|
|
// byte 3 is P/. P is for a private browising channel
|
|
// byte 4 is I/. I is for insecure scheme on TLS for http:// uris
|
|
// byte 5 is X/. X is for disallow_spdy flag
|
|
// byte 6 is C/. C is for be Conservative
|
|
// byte 7 is B/. B is for allowing client certs on an anonymous channel
|
|
// byte 8 is F/. F is for indicating a fallback connection
|
|
// byte 9 is W/. W is for indicating a webTransport
|
|
// Note: when adding/removing fields from this list which do not have
|
|
// corresponding data fields on the object itself, you may also need to
|
|
// modify RebuildHashKey.
|
|
|
|
const auto keyTemplate =
|
|
std::string(UnderlyingIndex(HashKeyIndex::End), '.') +
|
|
std::string("[tlsflags0x00000000]");
|
|
mHashKey.Assign(keyTemplate.c_str());
|
|
|
|
mHashKey.Append(keyHost);
|
|
mHashKey.Append(':');
|
|
mHashKey.AppendInt(keyPort);
|
|
if (!mUsername.IsEmpty()) {
|
|
mHashKey.Append('[');
|
|
mHashKey.Append(mUsername);
|
|
mHashKey.Append(']');
|
|
}
|
|
|
|
if (mUsingHttpsProxy) {
|
|
SetHashCharAt('T', HashKeyIndex::Proxy);
|
|
} else if (mUsingHttpProxy) {
|
|
SetHashCharAt('P', HashKeyIndex::Proxy);
|
|
}
|
|
if (mEndToEndSSL) {
|
|
SetHashCharAt('S', HashKeyIndex::EndToEndSSL);
|
|
}
|
|
|
|
if (mWebTransport) {
|
|
SetHashCharAt('W', HashKeyIndex::WebTransport);
|
|
}
|
|
|
|
// NOTE: for transparent proxies (e.g., SOCKS) we need to encode the proxy
|
|
// info in the hash key (this ensures that we will continue to speak the
|
|
// right protocol even if our proxy preferences change).
|
|
//
|
|
// NOTE: for SSL tunnels add the proxy information to the cache key.
|
|
// We cannot use the proxy as the host parameter (as we do for non SSL)
|
|
// because this is a single host tunnel, but we need to include the proxy
|
|
// information so that a change in proxy config will mean this connection
|
|
// is not reused
|
|
|
|
// NOTE: Adding the username and the password provides a means to isolate
|
|
// keep-alive to the URL bar domain as well: If the username is the URL bar
|
|
// domain, keep-alive connections are not reused by resources bound to
|
|
// different URL bar domains as the respective hash keys are not matching.
|
|
|
|
if ((!mUsingHttpProxy && ProxyHost()) || (mUsingHttpProxy && mUsingConnect)) {
|
|
mHashKey.AppendLiteral(" (");
|
|
mHashKey.Append(ProxyType());
|
|
mHashKey.Append(':');
|
|
mHashKey.Append(ProxyHost());
|
|
mHashKey.Append(':');
|
|
mHashKey.AppendInt(ProxyPort());
|
|
mHashKey.Append(')');
|
|
mHashKey.Append('[');
|
|
mHashKey.Append(ProxyUsername());
|
|
mHashKey.Append(':');
|
|
const char* password = ProxyPassword();
|
|
if (strlen(password) > 0) {
|
|
nsAutoCString digestedPassword;
|
|
nsresult rv = SHA256(password, digestedPassword);
|
|
if (rv == NS_OK) {
|
|
mHashKey.Append(digestedPassword);
|
|
}
|
|
}
|
|
mHashKey.Append(']');
|
|
}
|
|
|
|
if (!mRoutedHost.IsEmpty()) {
|
|
mHashKey.AppendLiteral(" <ROUTE-via ");
|
|
mHashKey.Append(mRoutedHost);
|
|
mHashKey.Append(':');
|
|
mHashKey.AppendInt(mRoutedPort);
|
|
mHashKey.Append('>');
|
|
}
|
|
|
|
if (!mNPNToken.IsEmpty()) {
|
|
mHashKey.AppendLiteral(" {NPN-TOKEN ");
|
|
mHashKey.Append(mNPNToken);
|
|
mHashKey.AppendLiteral("}");
|
|
}
|
|
|
|
if (GetTRRMode() != nsIRequest::TRR_DEFAULT_MODE) {
|
|
// When connecting with another TRR mode, we enforce a separate connection
|
|
// hashkey so that we also can trigger a fresh DNS resolver that then
|
|
// doesn't use TRR as the previous connection might have.
|
|
mHashKey.AppendLiteral("[TRR:");
|
|
mHashKey.AppendInt(GetTRRMode());
|
|
mHashKey.AppendLiteral("]");
|
|
}
|
|
|
|
if (GetIPv4Disabled()) {
|
|
mHashKey.AppendLiteral("[!v4]");
|
|
}
|
|
|
|
if (GetIPv6Disabled()) {
|
|
mHashKey.AppendLiteral("[!v6]");
|
|
}
|
|
|
|
if (mProxyInfo) {
|
|
const nsCString& connectionIsolationKey =
|
|
mProxyInfo->ConnectionIsolationKey();
|
|
if (!connectionIsolationKey.IsEmpty()) {
|
|
mHashKey.AppendLiteral("{CIK ");
|
|
mHashKey.Append(connectionIsolationKey);
|
|
mHashKey.AppendLiteral("}");
|
|
}
|
|
if (mProxyInfo->Flags() & nsIProxyInfo::TRANSPARENT_PROXY_RESOLVES_HOST) {
|
|
mHashKey.AppendLiteral("{TPRH}");
|
|
}
|
|
}
|
|
|
|
if (mWebTransportId) {
|
|
mHashKey.AppendLiteral("{wId");
|
|
mHashKey.AppendInt(mWebTransportId, 16);
|
|
mHashKey.AppendLiteral("}");
|
|
}
|
|
|
|
nsAutoCString originAttributes;
|
|
mOriginAttributes.CreateSuffix(originAttributes);
|
|
mHashKey.Append(originAttributes);
|
|
}
|
|
|
|
void nsHttpConnectionInfo::RebuildHashKey() {
|
|
// Create copies of all properties stored in our hash key.
|
|
bool isAnonymous = GetAnonymous();
|
|
bool isPrivate = GetPrivate();
|
|
bool isInsecureScheme = GetInsecureScheme();
|
|
bool isNoSpdy = GetNoSpdy();
|
|
bool isBeConservative = GetBeConservative();
|
|
bool isAnonymousAllowClientCert = GetAnonymousAllowClientCert();
|
|
bool isFallback = GetFallbackConnection();
|
|
|
|
BuildHashKey();
|
|
|
|
// Restore all of those properties.
|
|
SetAnonymous(isAnonymous);
|
|
SetPrivate(isPrivate);
|
|
SetInsecureScheme(isInsecureScheme);
|
|
SetNoSpdy(isNoSpdy);
|
|
SetBeConservative(isBeConservative);
|
|
SetAnonymousAllowClientCert(isAnonymousAllowClientCert);
|
|
SetFallbackConnection(isFallback);
|
|
SetTlsFlags(mTlsFlags);
|
|
}
|
|
|
|
void nsHttpConnectionInfo::SetOriginServer(const nsACString& host,
|
|
int32_t port) {
|
|
mOrigin = host;
|
|
mOriginPort = port == -1 ? DefaultPort() : port;
|
|
// Use BuildHashKey() since this can only be called when constructing an
|
|
// nsHttpConnectionInfo object.
|
|
MOZ_DIAGNOSTIC_ASSERT(mHashKey.IsEmpty());
|
|
BuildHashKey();
|
|
}
|
|
|
|
// Note that this function needs to be synced with
|
|
// nsHttpConnectionInfo::DeserializeHttpConnectionInfoCloneArgs to make sure
|
|
// nsHttpConnectionInfo can be serialized/deserialized.
|
|
already_AddRefed<nsHttpConnectionInfo> nsHttpConnectionInfo::Clone() const {
|
|
RefPtr<nsHttpConnectionInfo> clone;
|
|
if (mRoutedHost.IsEmpty()) {
|
|
clone = new nsHttpConnectionInfo(mOrigin, mOriginPort, mNPNToken, mUsername,
|
|
mProxyInfo, mOriginAttributes,
|
|
mEndToEndSSL, mIsHttp3, mWebTransport);
|
|
} else {
|
|
MOZ_ASSERT(mEndToEndSSL);
|
|
clone = new nsHttpConnectionInfo(mOrigin, mOriginPort, mNPNToken, mUsername,
|
|
mProxyInfo, mOriginAttributes, mRoutedHost,
|
|
mRoutedPort, mIsHttp3, mWebTransport);
|
|
}
|
|
|
|
// Make sure the anonymous, insecure-scheme, and private flags are transferred
|
|
clone->SetAnonymous(GetAnonymous());
|
|
clone->SetPrivate(GetPrivate());
|
|
clone->SetInsecureScheme(GetInsecureScheme());
|
|
clone->SetNoSpdy(GetNoSpdy());
|
|
clone->SetBeConservative(GetBeConservative());
|
|
clone->SetAnonymousAllowClientCert(GetAnonymousAllowClientCert());
|
|
clone->SetFallbackConnection(GetFallbackConnection());
|
|
clone->SetTlsFlags(GetTlsFlags());
|
|
clone->SetIsTrrServiceChannel(GetIsTrrServiceChannel());
|
|
clone->SetTRRMode(GetTRRMode());
|
|
clone->SetIPv4Disabled(GetIPv4Disabled());
|
|
clone->SetIPv6Disabled(GetIPv6Disabled());
|
|
clone->SetHasIPHintAddress(HasIPHintAddress());
|
|
clone->SetEchConfig(GetEchConfig());
|
|
clone->SetWebTransportId(GetWebTransportId());
|
|
MOZ_ASSERT(clone->Equals(this));
|
|
|
|
return clone.forget();
|
|
}
|
|
|
|
already_AddRefed<nsHttpConnectionInfo>
|
|
nsHttpConnectionInfo::CloneAndAdoptHTTPSSVCRecord(
|
|
nsISVCBRecord* aRecord) const {
|
|
MOZ_ASSERT(aRecord);
|
|
|
|
// Get the domain name of this HTTPS RR. This name will be assigned to
|
|
// mRoutedHost in the new connection info.
|
|
nsAutoCString name;
|
|
aRecord->GetName(name);
|
|
|
|
// Try to get the port and Alpn. If this record has SvcParamKeyPort defined,
|
|
// the new port will be used as mRoutedPort.
|
|
Maybe<uint16_t> port = aRecord->GetPort();
|
|
Maybe<std::tuple<nsCString, SupportedAlpnRank>> alpn = aRecord->GetAlpn();
|
|
|
|
// Let the new conn info learn h3 will be used.
|
|
bool isHttp3 = alpn ? mozilla::net::IsHttp3(std::get<1>(*alpn)) : false;
|
|
|
|
LOG(("HTTPSSVC: use new routed host (%s) and new npnToken (%s)", name.get(),
|
|
alpn ? std::get<0>(*alpn).get() : "None"));
|
|
|
|
RefPtr<nsHttpConnectionInfo> clone;
|
|
if (name.IsEmpty()) {
|
|
clone = new nsHttpConnectionInfo(
|
|
mOrigin, mOriginPort, alpn ? std::get<0>(*alpn) : EmptyCString(),
|
|
mUsername, mProxyInfo, mOriginAttributes, mEndToEndSSL, isHttp3);
|
|
} else {
|
|
MOZ_ASSERT(mEndToEndSSL);
|
|
clone = new nsHttpConnectionInfo(
|
|
mOrigin, mOriginPort, alpn ? std::get<0>(*alpn) : EmptyCString(),
|
|
mUsername, mProxyInfo, mOriginAttributes, name,
|
|
port ? *port : mOriginPort, isHttp3, mWebTransport);
|
|
}
|
|
|
|
// Make sure the anonymous, insecure-scheme, and private flags are transferred
|
|
clone->SetAnonymous(GetAnonymous());
|
|
clone->SetPrivate(GetPrivate());
|
|
clone->SetInsecureScheme(GetInsecureScheme());
|
|
clone->SetNoSpdy(GetNoSpdy());
|
|
clone->SetBeConservative(GetBeConservative());
|
|
clone->SetAnonymousAllowClientCert(GetAnonymousAllowClientCert());
|
|
clone->SetFallbackConnection(GetFallbackConnection());
|
|
clone->SetTlsFlags(GetTlsFlags());
|
|
clone->SetIsTrrServiceChannel(GetIsTrrServiceChannel());
|
|
clone->SetTRRMode(GetTRRMode());
|
|
clone->SetIPv4Disabled(GetIPv4Disabled());
|
|
clone->SetIPv6Disabled(GetIPv6Disabled());
|
|
|
|
bool hasIPHint = false;
|
|
Unused << aRecord->GetHasIPHintAddress(&hasIPHint);
|
|
if (hasIPHint) {
|
|
clone->SetHasIPHintAddress(hasIPHint);
|
|
}
|
|
|
|
nsAutoCString echConfig;
|
|
Unused << aRecord->GetEchConfig(echConfig);
|
|
clone->SetEchConfig(echConfig);
|
|
|
|
return clone.forget();
|
|
}
|
|
|
|
/* static */
|
|
void nsHttpConnectionInfo::SerializeHttpConnectionInfo(
|
|
nsHttpConnectionInfo* aInfo, HttpConnectionInfoCloneArgs& aArgs) {
|
|
aArgs.host() = aInfo->GetOrigin();
|
|
aArgs.port() = aInfo->OriginPort();
|
|
aArgs.npnToken() = aInfo->GetNPNToken();
|
|
aArgs.username() = aInfo->GetUsername();
|
|
aArgs.originAttributes() = aInfo->GetOriginAttributes();
|
|
aArgs.endToEndSSL() = aInfo->EndToEndSSL();
|
|
aArgs.routedHost() = aInfo->GetRoutedHost();
|
|
aArgs.routedPort() = aInfo->RoutedPort();
|
|
aArgs.anonymous() = aInfo->GetAnonymous();
|
|
aArgs.aPrivate() = aInfo->GetPrivate();
|
|
aArgs.insecureScheme() = aInfo->GetInsecureScheme();
|
|
aArgs.noSpdy() = aInfo->GetNoSpdy();
|
|
aArgs.beConservative() = aInfo->GetBeConservative();
|
|
aArgs.anonymousAllowClientCert() = aInfo->GetAnonymousAllowClientCert();
|
|
aArgs.tlsFlags() = aInfo->GetTlsFlags();
|
|
aArgs.isTrrServiceChannel() = aInfo->GetTRRMode();
|
|
aArgs.trrMode() = aInfo->GetTRRMode();
|
|
aArgs.isIPv4Disabled() = aInfo->GetIPv4Disabled();
|
|
aArgs.isIPv6Disabled() = aInfo->GetIPv6Disabled();
|
|
aArgs.isHttp3() = aInfo->IsHttp3();
|
|
aArgs.hasIPHintAddress() = aInfo->HasIPHintAddress();
|
|
aArgs.echConfig() = aInfo->GetEchConfig();
|
|
aArgs.webTransport() = aInfo->GetWebTransport();
|
|
aArgs.webTransportId() = aInfo->GetWebTransportId();
|
|
|
|
if (!aInfo->ProxyInfo()) {
|
|
return;
|
|
}
|
|
|
|
nsTArray<ProxyInfoCloneArgs> proxyInfoArray;
|
|
nsProxyInfo::SerializeProxyInfo(aInfo->ProxyInfo(), proxyInfoArray);
|
|
aArgs.proxyInfo() = std::move(proxyInfoArray);
|
|
}
|
|
|
|
// This function needs to be synced with nsHttpConnectionInfo::Clone.
|
|
/* static */
|
|
already_AddRefed<nsHttpConnectionInfo>
|
|
nsHttpConnectionInfo::DeserializeHttpConnectionInfoCloneArgs(
|
|
const HttpConnectionInfoCloneArgs& aInfoArgs) {
|
|
nsProxyInfo* pi = nsProxyInfo::DeserializeProxyInfo(aInfoArgs.proxyInfo());
|
|
RefPtr<nsHttpConnectionInfo> cinfo;
|
|
if (aInfoArgs.routedHost().IsEmpty()) {
|
|
cinfo = new nsHttpConnectionInfo(
|
|
aInfoArgs.host(), aInfoArgs.port(), aInfoArgs.npnToken(),
|
|
aInfoArgs.username(), pi, aInfoArgs.originAttributes(),
|
|
aInfoArgs.endToEndSSL(), aInfoArgs.isHttp3(), aInfoArgs.webTransport());
|
|
} else {
|
|
MOZ_ASSERT(aInfoArgs.endToEndSSL());
|
|
cinfo = new nsHttpConnectionInfo(
|
|
aInfoArgs.host(), aInfoArgs.port(), aInfoArgs.npnToken(),
|
|
aInfoArgs.username(), pi, aInfoArgs.originAttributes(),
|
|
aInfoArgs.routedHost(), aInfoArgs.routedPort(), aInfoArgs.isHttp3(),
|
|
aInfoArgs.webTransport());
|
|
}
|
|
// Transfer Webtransport ids
|
|
cinfo->SetWebTransportId(aInfoArgs.webTransportId());
|
|
|
|
// Make sure the anonymous, insecure-scheme, and private flags are transferred
|
|
cinfo->SetAnonymous(aInfoArgs.anonymous());
|
|
cinfo->SetPrivate(aInfoArgs.aPrivate());
|
|
cinfo->SetInsecureScheme(aInfoArgs.insecureScheme());
|
|
cinfo->SetNoSpdy(aInfoArgs.noSpdy());
|
|
cinfo->SetBeConservative(aInfoArgs.beConservative());
|
|
cinfo->SetAnonymousAllowClientCert(aInfoArgs.anonymousAllowClientCert());
|
|
cinfo->SetFallbackConnection(aInfoArgs.fallbackConnection());
|
|
cinfo->SetTlsFlags(aInfoArgs.tlsFlags());
|
|
cinfo->SetIsTrrServiceChannel(aInfoArgs.isTrrServiceChannel());
|
|
cinfo->SetTRRMode(static_cast<nsIRequest::TRRMode>(aInfoArgs.trrMode()));
|
|
cinfo->SetIPv4Disabled(aInfoArgs.isIPv4Disabled());
|
|
cinfo->SetIPv6Disabled(aInfoArgs.isIPv6Disabled());
|
|
cinfo->SetHasIPHintAddress(aInfoArgs.hasIPHintAddress());
|
|
cinfo->SetEchConfig(aInfoArgs.echConfig());
|
|
|
|
return cinfo.forget();
|
|
}
|
|
|
|
void nsHttpConnectionInfo::CloneAsDirectRoute(nsHttpConnectionInfo** outCI) {
|
|
// Explicitly use an empty npnToken when |mIsHttp3| is true, since we want to
|
|
// create a non-http3 connection info.
|
|
RefPtr<nsHttpConnectionInfo> clone = new nsHttpConnectionInfo(
|
|
mOrigin, mOriginPort,
|
|
(mRoutedHost.IsEmpty() && !mIsHttp3) ? mNPNToken : ""_ns, mUsername,
|
|
mProxyInfo, mOriginAttributes, mEndToEndSSL, false, mWebTransport);
|
|
// Make sure the anonymous, insecure-scheme, and private flags are transferred
|
|
clone->SetAnonymous(GetAnonymous());
|
|
clone->SetPrivate(GetPrivate());
|
|
clone->SetInsecureScheme(GetInsecureScheme());
|
|
clone->SetNoSpdy(GetNoSpdy());
|
|
clone->SetBeConservative(GetBeConservative());
|
|
clone->SetAnonymousAllowClientCert(GetAnonymousAllowClientCert());
|
|
clone->SetFallbackConnection(GetFallbackConnection());
|
|
clone->SetTlsFlags(GetTlsFlags());
|
|
clone->SetIsTrrServiceChannel(GetIsTrrServiceChannel());
|
|
clone->SetTRRMode(GetTRRMode());
|
|
clone->SetIPv4Disabled(GetIPv4Disabled());
|
|
clone->SetIPv6Disabled(GetIPv6Disabled());
|
|
clone->SetHasIPHintAddress(HasIPHintAddress());
|
|
clone->SetEchConfig(GetEchConfig());
|
|
|
|
clone.forget(outCI);
|
|
}
|
|
|
|
nsresult nsHttpConnectionInfo::CreateWildCard(nsHttpConnectionInfo** outParam) {
|
|
// T???mozilla.org:443 (https:proxy.ducksong.com:3128) [specifc form]
|
|
// TS??*:0 (https:proxy.ducksong.com:3128) [wildcard form]
|
|
|
|
if (!mUsingHttpsProxy) {
|
|
MOZ_ASSERT(false);
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
RefPtr<nsHttpConnectionInfo> clone;
|
|
clone = new nsHttpConnectionInfo("*"_ns, 0, mNPNToken, mUsername, mProxyInfo,
|
|
mOriginAttributes, true, mIsHttp3,
|
|
mWebTransport);
|
|
// Make sure the anonymous and private flags are transferred!
|
|
clone->SetAnonymous(GetAnonymous());
|
|
clone->SetPrivate(GetPrivate());
|
|
clone.forget(outParam);
|
|
return NS_OK;
|
|
}
|
|
|
|
void nsHttpConnectionInfo::SetTRRMode(nsIRequest::TRRMode aTRRMode) {
|
|
if (mTRRMode != aTRRMode) {
|
|
mTRRMode = aTRRMode;
|
|
RebuildHashKey();
|
|
}
|
|
}
|
|
|
|
void nsHttpConnectionInfo::SetIPv4Disabled(bool aNoIPv4) {
|
|
if (mIPv4Disabled != aNoIPv4) {
|
|
mIPv4Disabled = aNoIPv4;
|
|
RebuildHashKey();
|
|
}
|
|
}
|
|
|
|
void nsHttpConnectionInfo::SetIPv6Disabled(bool aNoIPv6) {
|
|
if (mIPv6Disabled != aNoIPv6) {
|
|
mIPv6Disabled = aNoIPv6;
|
|
RebuildHashKey();
|
|
}
|
|
}
|
|
|
|
void nsHttpConnectionInfo::SetWebTransport(bool aWebTransport) {
|
|
if (mWebTransport != aWebTransport) {
|
|
mWebTransport = aWebTransport;
|
|
RebuildHashKey();
|
|
}
|
|
}
|
|
|
|
void nsHttpConnectionInfo::SetWebTransportId(uint64_t id) {
|
|
if (mWebTransportId != id) {
|
|
mWebTransportId = id;
|
|
RebuildHashKey();
|
|
}
|
|
}
|
|
|
|
void nsHttpConnectionInfo::SetTlsFlags(uint32_t aTlsFlags) {
|
|
mTlsFlags = aTlsFlags;
|
|
const uint32_t tlsFlagsLength = 8;
|
|
const uint32_t tlsFlagsIndex =
|
|
UnderlyingIndex(HashKeyIndex::End) + strlen("[tlsflags0x");
|
|
mHashKey.Replace(tlsFlagsIndex, tlsFlagsLength,
|
|
nsPrintfCString("%08x", mTlsFlags));
|
|
}
|
|
|
|
bool nsHttpConnectionInfo::UsingProxy() {
|
|
if (!mProxyInfo) return false;
|
|
return !mProxyInfo->IsDirect();
|
|
}
|
|
|
|
bool nsHttpConnectionInfo::HostIsLocalIPLiteral() const {
|
|
NetAddr netAddr;
|
|
// If the host/proxy host is not an IP address literal, return false.
|
|
nsAutoCString host(ProxyHost() ? ProxyHost() : Origin());
|
|
if (NS_FAILED(netAddr.InitFromString(host))) {
|
|
return false;
|
|
}
|
|
return netAddr.IsIPAddrLocal();
|
|
}
|
|
|
|
// static
|
|
void nsHttpConnectionInfo::BuildOriginFrameHashKey(nsACString& newKey,
|
|
nsHttpConnectionInfo* ci,
|
|
const nsACString& host,
|
|
int32_t port) {
|
|
newKey.Assign(host);
|
|
if (ci->GetAnonymous()) {
|
|
newKey.AppendLiteral("~A:");
|
|
} else {
|
|
newKey.AppendLiteral("~.:");
|
|
}
|
|
if (ci->GetFallbackConnection()) {
|
|
newKey.AppendLiteral("~F:");
|
|
} else {
|
|
newKey.AppendLiteral("~.:");
|
|
}
|
|
newKey.AppendInt(port);
|
|
newKey.AppendLiteral("/[");
|
|
nsAutoCString suffix;
|
|
ci->GetOriginAttributes().CreateSuffix(suffix);
|
|
newKey.Append(suffix);
|
|
newKey.AppendLiteral("]viaORIGIN.FRAME");
|
|
}
|
|
|
|
} // namespace net
|
|
} // namespace mozilla
|