зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1618849 - Add separate AltSvc for http2 and http3 and prefer http3 if allowed. r=necko-reviewers,valentin
Differential Revision: https://phabricator.services.mozilla.com/D86934
This commit is contained in:
Родитель
7c12fdbba9
Коммит
821dfeec6a
|
@ -165,7 +165,9 @@ void AltSvcMapping::ProcessHeader(
|
|||
continue;
|
||||
}
|
||||
|
||||
http3Found = true;
|
||||
if (isHttp3) {
|
||||
http3Found = true;
|
||||
}
|
||||
|
||||
RefPtr<AltSvcMapping> mapping = new AltSvcMapping(
|
||||
gHttpHandler->AltServiceCache()->GetStoragePtr(),
|
||||
|
@ -255,7 +257,7 @@ AltSvcMapping::AltSvcMapping(
|
|||
|
||||
if (mExpiresAt) {
|
||||
MakeHashKey(mHashKey, originScheme, mOriginHost, mOriginPort, mPrivate,
|
||||
mIsolated, mTopWindowOrigin, mOriginAttributes);
|
||||
mIsolated, mTopWindowOrigin, mOriginAttributes, mIsHttp3);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -265,7 +267,8 @@ void AltSvcMapping::MakeHashKey(nsCString& outKey,
|
|||
int32_t originPort, bool privateBrowsing,
|
||||
bool isolated,
|
||||
const nsACString& topWindowOrigin,
|
||||
const OriginAttributes& originAttributes) {
|
||||
const OriginAttributes& originAttributes,
|
||||
bool aHttp3) {
|
||||
outKey.Truncate();
|
||||
|
||||
if (originPort == -1) {
|
||||
|
@ -284,15 +287,16 @@ void AltSvcMapping::MakeHashKey(nsCString& outKey,
|
|||
nsAutoCString suffix;
|
||||
originAttributes.CreateSuffix(suffix);
|
||||
outKey.Append(suffix);
|
||||
outKey.Append(':');
|
||||
|
||||
if (isolated) {
|
||||
outKey.Append(':');
|
||||
outKey.Append('I');
|
||||
outKey.Append(':');
|
||||
outKey.Append(topWindowOrigin);
|
||||
outKey.Append(
|
||||
'|'); // Be careful, the top window origin may contain colons!
|
||||
}
|
||||
outKey.Append(aHttp3 ? '3' : '.');
|
||||
}
|
||||
|
||||
int32_t AltSvcMapping::TTL() { return mExpiresAt - NowInSeconds(); }
|
||||
|
@ -479,7 +483,7 @@ AltSvcMapping::AltSvcMapping(DataStorage* storage, int32_t epoch,
|
|||
|
||||
MakeHashKey(mHashKey, mHttps ? "https"_ns : "http"_ns, mOriginHost,
|
||||
mOriginPort, mPrivate, mIsolated, mTopWindowOrigin,
|
||||
mOriginAttributes);
|
||||
mOriginAttributes, mIsHttp3);
|
||||
} while (false);
|
||||
}
|
||||
|
||||
|
@ -1132,7 +1136,8 @@ void AltSvcCache::UpdateAltServiceMapping(
|
|||
already_AddRefed<AltSvcMapping> AltSvcCache::GetAltServiceMapping(
|
||||
const nsACString& scheme, const nsACString& host, int32_t port,
|
||||
bool privateBrowsing, bool isolated, const nsACString& topWindowOrigin,
|
||||
const OriginAttributes& originAttributes, bool aHttp3Allowed) {
|
||||
const OriginAttributes& originAttributes, bool aHttp2Allowed,
|
||||
bool aHttp3Allowed) {
|
||||
EnsureStorageInited();
|
||||
|
||||
bool isHTTPS;
|
||||
|
@ -1146,24 +1151,39 @@ already_AddRefed<AltSvcMapping> AltSvcCache::GetAltServiceMapping(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
nsAutoCString key;
|
||||
AltSvcMapping::MakeHashKey(key, scheme, host, port, privateBrowsing, isolated,
|
||||
topWindowOrigin, originAttributes);
|
||||
RefPtr<AltSvcMapping> existing = LookupMapping(key, privateBrowsing);
|
||||
LOG(
|
||||
("AltSvcCache::GetAltServiceMapping %p key=%s "
|
||||
"existing=%p validated=%d ttl=%d",
|
||||
this, key.get(), existing.get(), existing ? existing->Validated() : 0,
|
||||
existing ? existing->TTL() : 0));
|
||||
if (existing && !existing->Validated()) {
|
||||
existing = nullptr;
|
||||
// First look for HTTP3
|
||||
if (aHttp3Allowed) {
|
||||
nsAutoCString key;
|
||||
AltSvcMapping::MakeHashKey(key, scheme, host, port, privateBrowsing, isolated,
|
||||
topWindowOrigin, originAttributes, true);
|
||||
RefPtr<AltSvcMapping> existing = LookupMapping(key, privateBrowsing);
|
||||
LOG(
|
||||
("AltSvcCache::GetAltServiceMapping %p key=%s "
|
||||
"existing=%p validated=%d ttl=%d",
|
||||
this, key.get(), existing.get(), existing ? existing->Validated() : 0,
|
||||
existing ? existing->TTL() : 0));
|
||||
if (existing && existing->Validated()) {
|
||||
return existing.forget();
|
||||
}
|
||||
}
|
||||
|
||||
if (existing && existing->IsHttp3() && !aHttp3Allowed) {
|
||||
existing = nullptr;
|
||||
// Now look for HTTP2.
|
||||
if (aHttp2Allowed) {
|
||||
nsAutoCString key;
|
||||
AltSvcMapping::MakeHashKey(key, scheme, host, port, privateBrowsing, isolated,
|
||||
topWindowOrigin, originAttributes, false);
|
||||
RefPtr<AltSvcMapping> existing = LookupMapping(key, privateBrowsing);
|
||||
LOG(
|
||||
("AltSvcCache::GetAltServiceMapping %p key=%s "
|
||||
"existing=%p validated=%d ttl=%d",
|
||||
this, key.get(), existing.get(), existing ? existing->Validated() : 0,
|
||||
existing ? existing->TTL() : 0));
|
||||
if (existing && existing->Validated()) {
|
||||
return existing.forget();
|
||||
}
|
||||
}
|
||||
|
||||
return existing.forget();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
class ProxyClearHostMapping : public Runnable {
|
||||
|
@ -1213,11 +1233,18 @@ void AltSvcCache::ClearHostMapping(const nsACString& host, int32_t port,
|
|||
for (int isolate = 0; isolate < 2; ++isolate) {
|
||||
AltSvcMapping::MakeHashKey(key, scheme, host, port, bool(pb),
|
||||
bool(isolate), topWindowOrigin,
|
||||
originAttributes);
|
||||
originAttributes, false);
|
||||
RefPtr<AltSvcMapping> existing = LookupMapping(key, bool(pb));
|
||||
if (existing) {
|
||||
existing->SetExpired();
|
||||
}
|
||||
AltSvcMapping::MakeHashKey(key, scheme, host, port, bool(pb),
|
||||
bool(isolate), topWindowOrigin,
|
||||
originAttributes, true);
|
||||
existing = LookupMapping(key, bool(pb));
|
||||
if (existing) {
|
||||
existing->SetExpired();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,7 +102,7 @@ class AltSvcMapping {
|
|||
const nsACString& originHost, int32_t originPort,
|
||||
bool privateBrowsing, bool isolated,
|
||||
const nsACString& topWindowOrigin,
|
||||
const OriginAttributes& originAttributes);
|
||||
const OriginAttributes& originAttributes, bool aIsHttp3);
|
||||
|
||||
bool IsHttp3() { return mIsHttp3; }
|
||||
const nsCString& NPNToken() const { return mNPNToken; }
|
||||
|
@ -198,7 +198,8 @@ class AltSvcCache {
|
|||
already_AddRefed<AltSvcMapping> GetAltServiceMapping(
|
||||
const nsACString& scheme, const nsACString& host, int32_t port, bool pb,
|
||||
bool isolated, const nsACString& topWindowOrigin,
|
||||
const OriginAttributes& originAttributes, bool aHttp3Allowed);
|
||||
const OriginAttributes& originAttributes, bool aHttp2Allowed,
|
||||
bool aHttp3Allowed);
|
||||
void ClearAltServiceMappings();
|
||||
void ClearHostMapping(const nsACString& host, int32_t port,
|
||||
const OriginAttributes& originAttributes,
|
||||
|
|
|
@ -3118,7 +3118,7 @@ nsresult Http2Session::WriteSegmentsAgain(nsAHttpSegmentWriter* writer,
|
|||
// Don't allow any more h2 connections to this host
|
||||
RefPtr<nsHttpConnectionInfo> ci = ConnectionInfo();
|
||||
if (ci) {
|
||||
gHttpHandler->BlacklistSpdy(ci);
|
||||
gHttpHandler->ExcludeHttp2(ci);
|
||||
}
|
||||
|
||||
// Go through and re-start all of our transactions with h2 disabled.
|
||||
|
|
|
@ -241,8 +241,12 @@ nsresult HttpConnectionMgrParent::VerifyTraffic() {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void HttpConnectionMgrParent::BlacklistSpdy(const nsHttpConnectionInfo* ci) {
|
||||
MOZ_ASSERT_UNREACHABLE("BlacklistSpdy should not be called");
|
||||
void HttpConnectionMgrParent::ExcludeHttp2(const nsHttpConnectionInfo* ci) {
|
||||
MOZ_ASSERT_UNREACHABLE("ExcludeHttp2 should not be called");
|
||||
}
|
||||
|
||||
void HttpConnectionMgrParent::ExcludeHttp3(const nsHttpConnectionInfo* ci) {
|
||||
MOZ_ASSERT_UNREACHABLE("ExcludeHttp3 should not be called");
|
||||
}
|
||||
|
||||
nsresult HttpConnectionMgrParent::ClearConnectionHistory() {
|
||||
|
|
|
@ -153,7 +153,8 @@ class HttpConnectionMgrShell : public nsISupports {
|
|||
// that connection.
|
||||
[[nodiscard]] virtual nsresult VerifyTraffic() = 0;
|
||||
|
||||
virtual void BlacklistSpdy(const nsHttpConnectionInfo* ci) = 0;
|
||||
virtual void ExcludeHttp2(const nsHttpConnectionInfo* ci) = 0;
|
||||
virtual void ExcludeHttp3(const nsHttpConnectionInfo* ci) = 0;
|
||||
|
||||
// clears the connection history mCT
|
||||
[[nodiscard]] virtual nsresult ClearConnectionHistory() = 0;
|
||||
|
@ -216,7 +217,8 @@ NS_DEFINE_STATIC_IID_ACCESSOR(HttpConnectionMgrShell,
|
|||
nsHttpConnectionInfo*, nsIInterfaceRequestor*, uint32_t caps = 0, \
|
||||
NullHttpTransaction* = nullptr) override; \
|
||||
virtual nsresult VerifyTraffic() override; \
|
||||
virtual void BlacklistSpdy(const nsHttpConnectionInfo* ci) override; \
|
||||
virtual void ExcludeHttp2(const nsHttpConnectionInfo* ci) override; \
|
||||
virtual void ExcludeHttp3(const nsHttpConnectionInfo* ci) override; \
|
||||
virtual nsresult ClearConnectionHistory() override; \
|
||||
virtual nsresult CompleteUpgrade(HttpTransactionShell* aTrans, \
|
||||
nsIHttpUpgradeListener* aUpgradeListener) \
|
||||
|
|
|
@ -392,17 +392,21 @@ nsresult TRRServiceChannel::BeginConnect() {
|
|||
host, port, EmptyCString(), mUsername, GetTopWindowOrigin(), proxyInfo,
|
||||
OriginAttributes(), isHttps);
|
||||
// TODO: Bug 1622778 for using AltService in socket process.
|
||||
mAllowAltSvc = XRE_IsParentProcess() &&
|
||||
(mAllowAltSvc && !gHttpHandler->IsSpdyBlacklisted(connInfo));
|
||||
mAllowAltSvc = XRE_IsParentProcess() && mAllowAltSvc;
|
||||
bool http2Allowed = !gHttpHandler->IsHttp2Excluded(connInfo);
|
||||
bool http3Allowed = !mUpgradeProtocolCallback && !mProxyInfo &&
|
||||
!(mCaps & NS_HTTP_BE_CONSERVATIVE) && !mBeConservative &&
|
||||
!gHttpHandler->IsHttp3Excluded(connInfo);
|
||||
|
||||
RefPtr<AltSvcMapping> mapping;
|
||||
if (!mConnectionInfo && mAllowAltSvc && // per channel
|
||||
(http2Allowed || http3Allowed) &&
|
||||
!(mLoadFlags & LOAD_FRESH_CONNECTION) &&
|
||||
AltSvcMapping::AcceptableProxy(proxyInfo) &&
|
||||
(scheme.EqualsLiteral("http") || scheme.EqualsLiteral("https")) &&
|
||||
(mapping = gHttpHandler->GetAltServiceMapping(
|
||||
scheme, host, port, mPrivateBrowsing, IsIsolated(),
|
||||
GetTopWindowOrigin(), OriginAttributes(), false))) {
|
||||
GetTopWindowOrigin(), OriginAttributes(), http2Allowed, http3Allowed))) {
|
||||
LOG(("TRRServiceChannel %p Alt Service Mapping Found %s://%s:%d [%s]\n",
|
||||
this, scheme.get(), mapping->AlternateHost().get(),
|
||||
mapping->AlternatePort(), mapping->HashKey().get()));
|
||||
|
@ -438,7 +442,7 @@ nsresult TRRServiceChannel::BeginConnect() {
|
|||
|
||||
// Need to re-ask the handler, since mConnectionInfo may not be the connInfo
|
||||
// we used earlier
|
||||
if (gHttpHandler->IsSpdyBlacklisted(mConnectionInfo)) {
|
||||
if (gHttpHandler->IsHttp2Excluded(mConnectionInfo)) {
|
||||
mAllowSpdy = 0;
|
||||
mCaps |= NS_HTTP_DISALLOW_SPDY;
|
||||
mConnectionInfo->SetNoSpdy(true);
|
||||
|
|
|
@ -6895,9 +6895,10 @@ nsresult nsHttpChannel::BeginConnect() {
|
|||
RefPtr<nsHttpConnectionInfo> connInfo = new nsHttpConnectionInfo(
|
||||
host, port, EmptyCString(), mUsername, GetTopWindowOrigin(), proxyInfo,
|
||||
originAttributes, isHttps);
|
||||
mAllowAltSvc = (mAllowAltSvc && !gHttpHandler->IsSpdyBlacklisted(connInfo));
|
||||
bool http2Allowed = !gHttpHandler->IsHttp2Excluded(connInfo);
|
||||
bool http3Allowed = !mUpgradeProtocolCallback && !mProxyInfo &&
|
||||
!(mCaps & NS_HTTP_BE_CONSERVATIVE) && !mBeConservative;
|
||||
!(mCaps & NS_HTTP_BE_CONSERVATIVE) && !mBeConservative &&
|
||||
!gHttpHandler->IsHttp3Excluded(connInfo);
|
||||
|
||||
// No need to lookup HTTPSSVC record if we already have one.
|
||||
mUseHTTPSSVC =
|
||||
|
@ -6905,12 +6906,13 @@ nsresult nsHttpChannel::BeginConnect() {
|
|||
|
||||
RefPtr<AltSvcMapping> mapping;
|
||||
if (!mConnectionInfo && mAllowAltSvc && // per channel
|
||||
(http2Allowed || http3Allowed) &&
|
||||
!(mLoadFlags & LOAD_FRESH_CONNECTION) &&
|
||||
AltSvcMapping::AcceptableProxy(proxyInfo) &&
|
||||
(scheme.EqualsLiteral("http") || scheme.EqualsLiteral("https")) &&
|
||||
(mapping = gHttpHandler->GetAltServiceMapping(
|
||||
scheme, host, port, mPrivateBrowsing, IsIsolated(),
|
||||
GetTopWindowOrigin(), originAttributes, http3Allowed))) {
|
||||
GetTopWindowOrigin(), originAttributes, http2Allowed, http3Allowed))) {
|
||||
LOG(("nsHttpChannel %p Alt Service Mapping Found %s://%s:%d [%s]\n", this,
|
||||
scheme.get(), mapping->AlternateHost().get(), mapping->AlternatePort(),
|
||||
mapping->HashKey().get()));
|
||||
|
@ -6966,7 +6968,7 @@ nsresult nsHttpChannel::BeginConnect() {
|
|||
|
||||
// Need to re-ask the handler, since mConnectionInfo may not be the connInfo
|
||||
// we used earlier
|
||||
if (gHttpHandler->IsSpdyBlacklisted(mConnectionInfo)) {
|
||||
if (gHttpHandler->IsHttp2Excluded(mConnectionInfo)) {
|
||||
mAllowSpdy = 0;
|
||||
mCaps |= NS_HTTP_DISALLOW_SPDY;
|
||||
mConnectionInfo->SetNoSpdy(true);
|
||||
|
|
|
@ -2060,7 +2060,7 @@ nsresult nsHttpConnectionMgr::ProcessNewTransaction(nsHttpTransaction* trans) {
|
|||
trans->SetConnection(nullptr);
|
||||
rv = DispatchTransaction(ent, trans, conn);
|
||||
} else {
|
||||
if (!ent->AllowSpdy()) {
|
||||
if (!ent->AllowHttp2()) {
|
||||
trans->DisableSpdy();
|
||||
}
|
||||
pendingTransInfo = new PendingTransactionInfo(trans);
|
||||
|
@ -5263,7 +5263,7 @@ nsHttpConnectionMgr::nsHalfOpenSocket::OnTransportStatus(nsITransport* trans,
|
|||
|
||||
if (status == NS_NET_STATUS_CONNECTING_TO && gHttpHandler->IsSpdyEnabled() &&
|
||||
gHttpHandler->CoalesceSpdy() && mEnt && mEnt->mConnInfo &&
|
||||
mEnt->mConnInfo->EndToEndSSL() && mEnt->AllowSpdy() &&
|
||||
mEnt->mConnInfo->EndToEndSSL() && mEnt->AllowHttp2() &&
|
||||
!mEnt->mConnInfo->UsingProxy() && mEnt->mCoalescingKeys.IsEmpty()) {
|
||||
nsCOMPtr<nsIDNSAddrRecord> dnsRecord(do_GetInterface(mSocketTransport));
|
||||
nsTArray<NetAddr> addressSet;
|
||||
|
@ -5544,19 +5544,31 @@ void nsHttpConnectionMgr::nsConnectionEntry::RemoveHalfOpen(
|
|||
}
|
||||
}
|
||||
|
||||
void nsHttpConnectionMgr::BlacklistSpdy(const nsHttpConnectionInfo* ci) {
|
||||
LOG(("nsHttpConnectionMgr::BlacklistSpdy blacklisting ci %s",
|
||||
void nsHttpConnectionMgr::ExcludeHttp2(const nsHttpConnectionInfo* ci) {
|
||||
LOG(("nsHttpConnectionMgr::ExcludeHttp2 excluding ci %s",
|
||||
ci->HashKey().BeginReading()));
|
||||
nsConnectionEntry* ent = mCT.GetWeak(ci->HashKey());
|
||||
if (!ent) {
|
||||
LOG(("nsHttpConnectionMgr::BlacklistSpdy no entry found?!"));
|
||||
LOG(("nsHttpConnectionMgr::ExcludeHttp2 no entry found?!"));
|
||||
return;
|
||||
}
|
||||
|
||||
ent->DisallowSpdy();
|
||||
ent->DisallowHttp2();
|
||||
}
|
||||
|
||||
void nsHttpConnectionMgr::nsConnectionEntry::DisallowSpdy() {
|
||||
void nsHttpConnectionMgr::ExcludeHttp3(const nsHttpConnectionInfo* ci) {
|
||||
LOG(("nsHttpConnectionMgr::ExcludeHttp3 exclude ci %s",
|
||||
ci->HashKey().BeginReading()));
|
||||
nsConnectionEntry* ent = mCT.GetWeak(ci->HashKey());
|
||||
if (!ent) {
|
||||
LOG(("nsHttpConnectionMgr::ExcludeHttp3 no entry found?!"));
|
||||
return;
|
||||
}
|
||||
|
||||
ent->DontReuseHttp3Conn();
|
||||
}
|
||||
|
||||
void nsHttpConnectionMgr::nsConnectionEntry::DisallowHttp2() {
|
||||
mCanUseSpdy = false;
|
||||
|
||||
// If we have any spdy connections, we want to go ahead and close them when
|
||||
|
@ -5576,6 +5588,19 @@ void nsHttpConnectionMgr::nsConnectionEntry::DisallowSpdy() {
|
|||
mCoalescingKeys.Clear();
|
||||
}
|
||||
|
||||
void nsHttpConnectionMgr::nsConnectionEntry::DontReuseHttp3Conn() {
|
||||
MOZ_ASSERT(mConnInfo->IsHttp3());
|
||||
|
||||
// If we have any spdy connections, we want to go ahead and close them when
|
||||
// they're done so we can free up some connections.
|
||||
for (uint32_t i = 0; i < mActiveConns.Length(); ++i) {
|
||||
mActiveConns[i]->DontReuse();
|
||||
}
|
||||
|
||||
// Can't coalesce if we're not using http3
|
||||
mCoalescingKeys.Clear();
|
||||
}
|
||||
|
||||
void nsHttpConnectionMgr::nsConnectionEntry::RecordIPFamilyPreference(
|
||||
uint16_t family) {
|
||||
LOG(("nsConnectionEntry::RecordIPFamilyPreference %p, af=%u", this, family));
|
||||
|
|
|
@ -235,8 +235,9 @@ class nsHttpConnectionMgr final : public HttpConnectionMgrShell,
|
|||
|
||||
bool mDoNotDestroy : 1;
|
||||
|
||||
bool AllowSpdy() const { return mCanUseSpdy; }
|
||||
void DisallowSpdy();
|
||||
bool AllowHttp2() const { return mCanUseSpdy; }
|
||||
void DisallowHttp2();
|
||||
void DontReuseHttp3Conn();
|
||||
|
||||
// Set the IP family preference flags according the connected family
|
||||
void RecordIPFamilyPreference(uint16_t family);
|
||||
|
|
|
@ -316,7 +316,7 @@ nsHttpHandler::nsHttpHandler()
|
|||
mNextChannelId(1),
|
||||
mLastActiveTabLoadOptimizationLock(
|
||||
"nsHttpConnectionMgr::LastActiveTabLoadOptimization"),
|
||||
mSpdyBlacklistLock("nsHttpHandler::SpdyBlacklist"),
|
||||
mHttpExclusionLock("nsHttpHandler::HttpExclusion"),
|
||||
mThroughCaptivePortal(false) {
|
||||
LOG(("Creating nsHttpHandler [this=%p].\n", this));
|
||||
|
||||
|
@ -2796,19 +2796,34 @@ bool nsHttpHandler::IsBeforeLastActiveTabLoadOptimization(
|
|||
when <= mLastActiveTabLoadOptimizationHit;
|
||||
}
|
||||
|
||||
void nsHttpHandler::BlacklistSpdy(const nsHttpConnectionInfo* ci) {
|
||||
void nsHttpHandler::ExcludeHttp2(const nsHttpConnectionInfo* ci) {
|
||||
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
|
||||
|
||||
mConnMgr->BlacklistSpdy(ci);
|
||||
if (!mBlacklistedSpdyOrigins.Contains(ci->GetOrigin())) {
|
||||
MutexAutoLock lock(mSpdyBlacklistLock);
|
||||
mBlacklistedSpdyOrigins.PutEntry(ci->GetOrigin());
|
||||
mConnMgr->ExcludeHttp2(ci);
|
||||
if (!mExcludedHttp2Origins.Contains(ci->GetOrigin())) {
|
||||
MutexAutoLock lock(mHttpExclusionLock);
|
||||
mExcludedHttp2Origins.PutEntry(ci->GetOrigin());
|
||||
}
|
||||
}
|
||||
|
||||
bool nsHttpHandler::IsSpdyBlacklisted(const nsHttpConnectionInfo* ci) {
|
||||
MutexAutoLock lock(mSpdyBlacklistLock);
|
||||
return mBlacklistedSpdyOrigins.Contains(ci->GetOrigin());
|
||||
bool nsHttpHandler::IsHttp2Excluded(const nsHttpConnectionInfo* ci) {
|
||||
MutexAutoLock lock(mHttpExclusionLock);
|
||||
return mExcludedHttp2Origins.Contains(ci->GetOrigin());
|
||||
}
|
||||
|
||||
void nsHttpHandler::ExcludeHttp3(const nsHttpConnectionInfo* ci) {
|
||||
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
|
||||
|
||||
mConnMgr->ExcludeHttp3(ci);
|
||||
if (!mExcludedHttp3Origins.Contains(ci->GetOrigin())) {
|
||||
MutexAutoLock lock(mHttpExclusionLock);
|
||||
mExcludedHttp3Origins.PutEntry(ci->GetOrigin());
|
||||
}
|
||||
}
|
||||
|
||||
bool nsHttpHandler::IsHttp3Excluded(const nsHttpConnectionInfo* ci) {
|
||||
MutexAutoLock lock(mHttpExclusionLock);
|
||||
return mExcludedHttp3Origins.Contains(ci->GetOrigin());
|
||||
}
|
||||
|
||||
HttpTrafficAnalyzer* nsHttpHandler::GetHttpTrafficAnalyzer() {
|
||||
|
|
|
@ -359,10 +359,11 @@ class nsHttpHandler final : public nsIHttpProtocolHandler,
|
|||
already_AddRefed<AltSvcMapping> GetAltServiceMapping(
|
||||
const nsACString& scheme, const nsACString& host, int32_t port, bool pb,
|
||||
bool isolated, const nsACString& topWindowOrigin,
|
||||
const OriginAttributes& originAttributes, bool aHttp3Allowed) {
|
||||
const OriginAttributes& originAttributes, bool aHttp2Allowed,
|
||||
bool aHttp3Allowed) {
|
||||
return mAltSvcCache->GetAltServiceMapping(scheme, host, port, pb, isolated,
|
||||
topWindowOrigin, originAttributes,
|
||||
aHttp3Allowed);
|
||||
aHttp2Allowed, aHttp3Allowed);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -833,7 +834,7 @@ class nsHttpHandler final : public nsIHttpProtocolHandler,
|
|||
Mutex mLastActiveTabLoadOptimizationLock;
|
||||
TimeStamp mLastActiveTabLoadOptimizationHit;
|
||||
|
||||
Mutex mSpdyBlacklistLock;
|
||||
Mutex mHttpExclusionLock;
|
||||
|
||||
public:
|
||||
[[nodiscard]] nsresult NewChannelId(uint64_t& channelId);
|
||||
|
@ -841,11 +842,14 @@ class nsHttpHandler final : public nsIHttpProtocolHandler,
|
|||
void RemoveHttpChannel(uint64_t aId);
|
||||
nsWeakPtr GetWeakHttpChannel(uint64_t aId);
|
||||
|
||||
void BlacklistSpdy(const nsHttpConnectionInfo* ci);
|
||||
[[nodiscard]] bool IsSpdyBlacklisted(const nsHttpConnectionInfo* ci);
|
||||
void ExcludeHttp2(const nsHttpConnectionInfo* ci);
|
||||
[[nodiscard]] bool IsHttp2Excluded(const nsHttpConnectionInfo* ci);
|
||||
void ExcludeHttp3(const nsHttpConnectionInfo* ci);
|
||||
[[nodiscard]] bool IsHttp3Excluded(const nsHttpConnectionInfo* ci);
|
||||
|
||||
private:
|
||||
nsTHashtable<nsCStringHashKey> mBlacklistedSpdyOrigins;
|
||||
nsTHashtable<nsCStringHashKey> mExcludedHttp2Origins;
|
||||
nsTHashtable<nsCStringHashKey> mExcludedHttp3Origins;
|
||||
|
||||
bool mThroughCaptivePortal;
|
||||
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
"use strict";
|
||||
|
||||
let httpsOrigin;
|
||||
let h3AltSvc;
|
||||
let h3Port;
|
||||
let h3Route;
|
||||
let prefs;
|
||||
|
||||
let tests = [test_https_alt_svc, testsDone];
|
||||
|
||||
let current_test = 0;
|
||||
|
||||
function run_next_test() {
|
||||
if (current_test < tests.length) {
|
||||
dump("starting test number " + current_test + "\n");
|
||||
tests[current_test]();
|
||||
current_test++;
|
||||
}
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
let env = Cc["@mozilla.org/process/environment;1"].getService(
|
||||
Ci.nsIEnvironment
|
||||
);
|
||||
let h2Port = env.get("MOZHTTP2_PORT");
|
||||
Assert.notEqual(h2Port, null);
|
||||
Assert.notEqual(h2Port, "");
|
||||
let h3Port = env.get("MOZHTTP3_PORT");
|
||||
Assert.notEqual(h3Port, null);
|
||||
Assert.notEqual(h3Port, "");
|
||||
h3AltSvc = ":" + h3Port;
|
||||
|
||||
h3Route = "foo.example.com:" + h3Port;
|
||||
do_get_profile();
|
||||
prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
|
||||
|
||||
prefs.setBoolPref("network.http.http3.enabled", true);
|
||||
prefs.setCharPref("network.dns.localDomains", "foo.example.com");
|
||||
|
||||
// The certificate for the http3server server is for foo.example.com and
|
||||
// is signed by http2-ca.pem so add that cert to the trust list as a
|
||||
// signing cert.
|
||||
let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(
|
||||
Ci.nsIX509CertDB
|
||||
);
|
||||
addCertFromFile(certdb, "http2-ca.pem", "CTu,u,u");
|
||||
httpsOrigin = "https://foo.example.com:" + h2Port + "/";
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function makeChan(uri) {
|
||||
let chan = NetUtil.newChannel({
|
||||
uri,
|
||||
loadUsingSystemPrincipal: true,
|
||||
}).QueryInterface(Ci.nsIHttpChannel);
|
||||
chan.loadFlags = Ci.nsIChannel.LOAD_INITIAL_DOCUMENT_URI;
|
||||
return chan;
|
||||
}
|
||||
|
||||
let WaitForHttp3Listener = function() {};
|
||||
|
||||
WaitForHttp3Listener.prototype = {
|
||||
onDataAvailableFired: false,
|
||||
expectedRoute: "",
|
||||
|
||||
onStartRequest: function testOnStartRequest(request) {
|
||||
Assert.ok(request instanceof Ci.nsIHttpChannel);
|
||||
Assert.equal(request.responseStatus, 200);
|
||||
},
|
||||
|
||||
onDataAvailable: function testOnDataAvailable(request, stream, off, cnt) {
|
||||
this.onDataAvailableFired = true;
|
||||
read_stream(stream, cnt);
|
||||
},
|
||||
|
||||
onStopRequest: function testOnStopRequest(request, status) {
|
||||
let routed = "NA";
|
||||
try {
|
||||
routed = request.getRequestHeader("Alt-Used");
|
||||
} catch (e) {}
|
||||
dump("routed is " + routed + "\n");
|
||||
|
||||
if (routed == this.expectedRoute) {
|
||||
let httpVersion = "";
|
||||
try {
|
||||
httpVersion = request.protocolVersion;
|
||||
} catch (e) {}
|
||||
Assert.equal(httpVersion, "h3");
|
||||
run_next_test();
|
||||
} else {
|
||||
dump("poll later for alt svc mapping\n");
|
||||
do_test_pending();
|
||||
do_timeout(500, () => {
|
||||
doTest(this.uri, this.expectedRoute, this.h3AltSvc);
|
||||
});
|
||||
}
|
||||
|
||||
do_test_finished();
|
||||
},
|
||||
};
|
||||
|
||||
function doTest(uri, expectedRoute, altSvc) {
|
||||
let chan = makeChan(uri);
|
||||
let listener = new WaitForHttp3Listener();
|
||||
listener.uri = uri;
|
||||
listener.expectedRoute = expectedRoute;
|
||||
listener.h3AltSvc = altSvc;
|
||||
chan.setRequestHeader("x-altsvc", altSvc, false);
|
||||
chan.asyncOpen(listener);
|
||||
}
|
||||
|
||||
// Test Alt-Svc for http3.
|
||||
// H2 server returns alt-svc=h2=foo2.example.com:8000,h3-27=:h3port,h3-29=foo2.example.com:8443
|
||||
function test_https_alt_svc() {
|
||||
dump("test_https_alt_svc()\n");
|
||||
do_test_pending();
|
||||
doTest(httpsOrigin + "http3-test2", h3Route, h3AltSvc);
|
||||
}
|
||||
|
||||
function testsDone() {
|
||||
prefs.clearUserPref("network.http.http3.enabled");
|
||||
prefs.clearUserPref("network.dns.localDomains");
|
||||
dump("testDone\n");
|
||||
}
|
|
@ -447,5 +447,7 @@ skip-if = os == "android"
|
|||
[test_blob_channelname.js]
|
||||
[test_altsvc_pref.js]
|
||||
skip-if = asan || tsan || os == 'win' || os =='android'
|
||||
[test_http3_alt_svc.js]
|
||||
skip-if = asan || tsan || os == 'win' || os =='android'
|
||||
[test_use_httpssvc.js]
|
||||
skip-if = os == "android"
|
||||
|
|
|
@ -553,6 +553,16 @@ function handleRequest(req, res) {
|
|||
res.setHeader("Cache-Control", "no-cache");
|
||||
res.setHeader("Alt-Svc", "h3-27=" + req.headers["x-altsvc"]);
|
||||
}
|
||||
// for use with test_http3.js
|
||||
else if (u.pathname === "/http3-test2") {
|
||||
res.setHeader("Cache-Control", "no-cache");
|
||||
res.setHeader(
|
||||
"Alt-Svc",
|
||||
"h2=foo2.example.com:8000,h3-27=" +
|
||||
req.headers["x-altsvc"] +
|
||||
",h3-29=foo2.example.com:8443"
|
||||
);
|
||||
}
|
||||
// for use with test_trr.js
|
||||
else if (u.pathname === "/dns-cname") {
|
||||
// asking for cname.example.com
|
||||
|
|
Загрузка…
Ссылка в новой задаче