Bug 1623501 - WebSocket cannot run over http3. r=kershaw

Differential Revision: https://phabricator.services.mozilla.com/D67890

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Dragana Damjanovic 2020-03-24 21:23:28 +00:00
Родитель f5ff895032
Коммит dbac585790
9 изменённых файлов: 57 добавлений и 29 удалений

Просмотреть файл

@ -1113,7 +1113,7 @@ 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) {
const OriginAttributes& originAttributes, bool aHttp3Allowed) {
EnsureStorageInited();
bool isHTTPS;
@ -1139,6 +1139,11 @@ already_AddRefed<AltSvcMapping> AltSvcCache::GetAltServiceMapping(
if (existing && !existing->Validated()) {
existing = nullptr;
}
if (existing && existing->IsHttp3() && !aHttp3Allowed) {
existing = nullptr;
}
return existing.forget();
}

Просмотреть файл

@ -194,7 +194,7 @@ 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);
const OriginAttributes& originAttributes, bool aHttp3Allowed);
void ClearAltServiceMappings();
void ClearHostMapping(const nsACString& host, int32_t port,
const OriginAttributes& originAttributes,

Просмотреть файл

@ -645,7 +645,7 @@ void Http3Session::ResetRecvd(uint64_t aStreamId, uint64_t aError) {
stream->SetRecvdReset();
// We only handle some of Http3 error as epecial, the res are just equivalent
// We only handle some of Http3 error as epecial, the rest are just equivalent
// to cancel.
if (aError == HTTP3_APP_ERROR_VERSION_FALLBACK) {
// We will restart the request and the alt-svc will be removed

Просмотреть файл

@ -349,7 +349,7 @@ nsresult TRRServiceChannel::BeginConnect() {
(scheme.EqualsLiteral("http") || scheme.EqualsLiteral("https")) &&
(mapping = gHttpHandler->GetAltServiceMapping(
scheme, host, port, mPrivateBrowsing, IsIsolated(),
GetTopWindowOrigin(), OriginAttributes()))) {
GetTopWindowOrigin(), OriginAttributes(), false))) {
LOG(("TRRServiceChannel %p Alt Service Mapping Found %s://%s:%d [%s]\n",
this, scheme.get(), mapping->AlternateHost().get(),
mapping->AlternatePort(), mapping->HashKey().get()));

Просмотреть файл

@ -116,6 +116,10 @@ const char kHttp3VersionHEX[] = "ff0000001b"; // this is draft 27.
// The connection could bring the peeked data for sniffing
#define NS_HTTP_CALL_CONTENT_SNIFFER (1 << 21)
// Disallow the use of the HTTP3 protocol. This is meant for the contexts
// such as HTTP upgrade which are not supported by HTTP3.
#define NS_HTTP_DISALLOW_HTTP3 (1 << 22)
#define NS_HTTP_TRR_FLAGS_FROM_MODE(x) ((static_cast<uint32_t>(x) & 3) << 19)
#define NS_HTTP_TRR_MODE_FROM_FLAGS(x) \

Просмотреть файл

@ -667,6 +667,8 @@ nsresult nsHttpChannel::ContinueOnBeforeConnect(bool aShouldUpgrade,
} else {
mCaps |= NS_HTTP_DISALLOW_SPDY;
}
// Upgrades cannot use HTTP/3.
mCaps |= NS_HTTP_DISALLOW_HTTP3;
}
if (mIsTRRServiceChannel) {
@ -995,7 +997,8 @@ void nsHttpChannel::SpeculativeConnect() {
Unused << gHttpHandler->SpeculativeConnect(
mConnectionInfo, callbacks,
mCaps & (NS_HTTP_DISALLOW_SPDY | NS_HTTP_TRR_MODE_MASK |
NS_HTTP_DISABLE_IPV4 | NS_HTTP_DISABLE_IPV6));
NS_HTTP_DISABLE_IPV4 | NS_HTTP_DISABLE_IPV6 |
NS_HTTP_DISALLOW_HTTP3));
}
void nsHttpChannel::DoNotifyListenerCleanup() {
@ -6726,7 +6729,8 @@ nsresult nsHttpChannel::BeginConnect() {
(scheme.EqualsLiteral("http") || scheme.EqualsLiteral("https")) &&
(mapping = gHttpHandler->GetAltServiceMapping(
scheme, host, port, mPrivateBrowsing, IsIsolated(),
GetTopWindowOrigin(), originAttributes))) {
GetTopWindowOrigin(), originAttributes,
!mUpgradeProtocolCallback && !mProxyInfo))) {
LOG(("nsHttpChannel %p Alt Service Mapping Found %s://%s:%d [%s]\n", this,
scheme.get(), mapping->AlternateHost().get(), mapping->AlternatePort(),
mapping->HashKey().get()));

Просмотреть файл

@ -703,7 +703,8 @@ nsresult nsHttpConnectionMgr::RemoveIdleConnection(nsHttpConnection* conn) {
}
HttpConnectionBase* nsHttpConnectionMgr::FindCoalescableConnectionByHashKey(
nsConnectionEntry* ent, const nsCString& key, bool justKidding) {
nsConnectionEntry* ent, const nsCString& key, bool justKidding,
bool aNoHttp3) {
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
MOZ_ASSERT(ent->mConnInfo);
nsHttpConnectionInfo* ci = ent->mConnInfo;
@ -733,6 +734,10 @@ HttpConnectionBase* nsHttpConnectionMgr::FindCoalescableConnectionByHashKey(
continue; // without adjusting iterator
}
if (aNoHttp3 && potentialMatch->UsingHttp3()) {
j++;
continue;
}
bool couldJoin;
if (justKidding) {
couldJoin =
@ -783,7 +788,7 @@ static void BuildOriginFrameHashKey(nsACString& newKey,
}
HttpConnectionBase* nsHttpConnectionMgr::FindCoalescableConnection(
nsConnectionEntry* ent, bool justKidding) {
nsConnectionEntry* ent, bool justKidding, bool aNoHttp3) {
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
MOZ_ASSERT(ent->mConnInfo);
nsHttpConnectionInfo* ci = ent->mConnInfo;
@ -792,7 +797,7 @@ HttpConnectionBase* nsHttpConnectionMgr::FindCoalescableConnection(
nsCString newKey;
BuildOriginFrameHashKey(newKey, ci, ci->GetOrigin(), ci->OriginPort());
HttpConnectionBase* conn =
FindCoalescableConnectionByHashKey(ent, newKey, justKidding);
FindCoalescableConnectionByHashKey(ent, newKey, justKidding, aNoHttp3);
if (conn) {
LOG(("FindCoalescableConnection(%s) match conn %p on frame key %s\n",
ci->HashKey().get(), conn, newKey.get()));
@ -804,7 +809,7 @@ HttpConnectionBase* nsHttpConnectionMgr::FindCoalescableConnection(
uint32_t keyLen = ent->mCoalescingKeys.Length();
for (uint32_t i = 0; i < keyLen; ++i) {
conn = FindCoalescableConnectionByHashKey(ent, ent->mCoalescingKeys[i],
justKidding);
justKidding, aNoHttp3);
if (conn) {
LOG(("FindCoalescableConnection(%s) match conn %p on dns key %s\n",
ci->HashKey().get(), conn, ent->mCoalescingKeys[i].get()));
@ -825,7 +830,7 @@ void nsHttpConnectionMgr::UpdateCoalescingForNewConn(
MOZ_ASSERT(ent);
MOZ_ASSERT(mCT.GetWeak(newConn->ConnectionInfo()->HashKey()) == ent);
HttpConnectionBase* existingConn = FindCoalescableConnection(ent, true);
HttpConnectionBase* existingConn = FindCoalescableConnection(ent, true, false);
if (existingConn) {
LOG(
("UpdateCoalescingForNewConn() found existing active conn that could "
@ -1571,7 +1576,8 @@ nsresult nsHttpConnectionMgr::TryDispatchTransaction(
// essentially pipelining without head of line blocking
if (!(caps & NS_HTTP_DISALLOW_SPDY) && gHttpHandler->IsSpdyEnabled()) {
RefPtr<HttpConnectionBase> conn = GetH2orH3ActiveConn(ent);
RefPtr<HttpConnectionBase> conn = GetH2orH3ActiveConn(ent,
(!gHttpHandler->IsHttp3Enabled() || (caps & NS_HTTP_DISALLOW_HTTP3)));
if (conn) {
if (trans->IsWebsocketUpgrade() && !conn->CanAcceptWebsocket()) {
// This is a websocket transaction and we already have a h2 connection
@ -1961,7 +1967,8 @@ nsresult nsHttpConnectionMgr::ProcessNewTransaction(nsHttpTransaction* trans) {
MOZ_ASSERT(ci);
nsConnectionEntry* ent =
GetOrCreateConnectionEntry(ci, !!trans->TunnelProvider());
GetOrCreateConnectionEntry(ci, !!trans->TunnelProvider(),
trans->Caps() & NS_HTTP_DISALLOW_HTTP3);
MOZ_ASSERT(ent);
ReportProxyTelemetry(ent);
@ -2173,7 +2180,7 @@ void nsHttpConnectionMgr::DispatchSpdyPendingQ(
// active h2 or h3 connection either in that same entry or from the
// coalescing hash table
void nsHttpConnectionMgr::ProcessSpdyPendingQ(nsConnectionEntry* ent) {
HttpConnectionBase* conn = GetH2orH3ActiveConn(ent);
HttpConnectionBase* conn = GetH2orH3ActiveConn(ent, false);
if (!conn || !conn->CanDirectlyActivate()) {
return;
}
@ -2205,7 +2212,7 @@ void nsHttpConnectionMgr::OnMsgProcessAllSpdyPendingQ(int32_t, ARefBase*) {
// Given a connection entry, return an active h2 or h3 connection
// that can be directly activated or null.
HttpConnectionBase* nsHttpConnectionMgr::GetH2orH3ActiveConn(
nsConnectionEntry* ent) {
nsConnectionEntry* ent, bool aNoHttp3) {
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
MOZ_ASSERT(ent);
@ -2267,7 +2274,8 @@ HttpConnectionBase* nsHttpConnectionMgr::GetH2orH3ActiveConn(
// there was no active spdy connection in the connection entry, but
// there might be one in the hash table for coalescing
HttpConnectionBase* existingConn = FindCoalescableConnection(ent, false);
HttpConnectionBase* existingConn = FindCoalescableConnection(ent, false,
aNoHttp3);
if (existingConn) {
LOG(
("GetH2orH3ActiveConn() request for ent %p %s "
@ -2859,7 +2867,7 @@ void nsHttpConnectionMgr::OnMsgReclaimConnection(HttpConnectionBase* conn) {
// this can happen if the connection is made outside of the
// connection manager and is being "reclaimed" for use with
// future transactions. HTTP/2 tunnels work like this.
ent = GetOrCreateConnectionEntry(conn->ConnectionInfo(), true);
ent = GetOrCreateConnectionEntry(conn->ConnectionInfo(), true, false);
LOG(
("nsHttpConnectionMgr::OnMsgReclaimConnection conn %p "
"forced new hash entry %s\n",
@ -3885,7 +3893,7 @@ void nsHttpConnectionMgr::TimeoutTick() {
nsHttpConnectionMgr::nsConnectionEntry*
nsHttpConnectionMgr::GetOrCreateConnectionEntry(
nsHttpConnectionInfo* specificCI, bool prohibitWildCard) {
nsHttpConnectionInfo* specificCI, bool prohibitWildCard, bool aNoHttp3) {
// step 1
nsConnectionEntry* specificEnt = mCT.GetWeak(specificCI->HashKey());
if (specificEnt && specificEnt->AvailableForDispatchNow()) {
@ -3899,7 +3907,7 @@ nsHttpConnectionMgr::GetOrCreateConnectionEntry(
anonInvertedCI->SetAnonymous(!specificCI->GetAnonymous());
nsConnectionEntry* invertedEnt = mCT.GetWeak(anonInvertedCI->HashKey());
if (invertedEnt) {
HttpConnectionBase* h2orh3conn = GetH2orH3ActiveConn(invertedEnt);
HttpConnectionBase* h2orh3conn = GetH2orH3ActiveConn(invertedEnt, aNoHttp3);
if (h2orh3conn && h2orh3conn->IsExperienced() &&
h2orh3conn->NoClientCertAuth()) {
MOZ_ASSERT(h2orh3conn->UsingSpdy() || h2orh3conn->UsingHttp3());
@ -3916,7 +3924,7 @@ nsHttpConnectionMgr::GetOrCreateConnectionEntry(
}
// step 2
if (!prohibitWildCard) {
if (!prohibitWildCard && !aNoHttp3) {
RefPtr<nsHttpConnectionInfo> wildCardProxyCI;
DebugOnly<nsresult> rv =
specificCI->CreateWildCard(getter_AddRefs(wildCardProxyCI));
@ -3963,7 +3971,8 @@ void nsHttpConnectionMgr::OnMsgSpeculativeConnect(int32_t, ARefBase* param) {
args->mTrans->ConnectionInfo()->HashKey().get()));
nsConnectionEntry* ent =
GetOrCreateConnectionEntry(args->mTrans->ConnectionInfo(), false);
GetOrCreateConnectionEntry(args->mTrans->ConnectionInfo(), false,
args->mTrans->Caps() & NS_HTTP_DISALLOW_HTTP3);
uint32_t parallelSpeculativeConnectLimit =
gHttpHandler->ParallelSpeculativeConnectLimit();
@ -5375,7 +5384,8 @@ bool nsHttpConnectionMgr::nsConnectionEntry::AvailableForDispatchNow() {
return true;
}
return gHttpHandler->ConnMgr()->GetH2orH3ActiveConn(this) ? true : false;
return gHttpHandler->ConnMgr()->GetH2orH3ActiveConn(this, false) ? true
: false;
}
bool nsHttpConnectionMgr::GetConnectionData(nsTArray<HttpRetParams>* aArg) {
@ -5665,7 +5675,7 @@ void nsHttpConnectionMgr::MoveToWildCardConnEntry(
return;
}
nsConnectionEntry* wcEnt = GetOrCreateConnectionEntry(wildCardCI, true);
nsConnectionEntry* wcEnt = GetOrCreateConnectionEntry(wildCardCI, true, false);
if (wcEnt == ent) {
// nothing to do!
return;

Просмотреть файл

@ -525,7 +525,8 @@ class nsHttpConnectionMgr final : public HttpConnectionMgrShell,
bool aInsertAsFirstForTheSamePriority = false);
nsConnectionEntry* GetOrCreateConnectionEntry(nsHttpConnectionInfo*,
bool allowWildCard);
bool allowWildCard,
bool aNoHttp3);
MOZ_MUST_USE nsresult MakeNewConnection(
nsConnectionEntry* ent, PendingTransactionInfo* pendingTransInfo);
@ -535,13 +536,16 @@ class nsHttpConnectionMgr final : public HttpConnectionMgrShell,
nsClassHashtable<nsCStringHashKey, nsTArray<nsWeakPtr>> mCoalescingHash;
HttpConnectionBase* FindCoalescableConnection(nsConnectionEntry* ent,
bool justKidding);
bool justKidding,
bool aNoHttp3);
HttpConnectionBase* FindCoalescableConnectionByHashKey(nsConnectionEntry* ent,
const nsCString& key,
bool justKidding);
bool justKidding,
bool aNoHttp3);
void UpdateCoalescingForNewConn(HttpConnectionBase* conn,
nsConnectionEntry* ent);
HttpConnectionBase* GetH2orH3ActiveConn(nsConnectionEntry* ent);
HttpConnectionBase* GetH2orH3ActiveConn(nsConnectionEntry* ent,
bool aNoHttp3);
void ProcessSpdyPendingQ(nsConnectionEntry* ent);
void DispatchSpdyPendingQ(nsTArray<RefPtr<PendingTransactionInfo>>& pendingQ,

Просмотреть файл

@ -350,9 +350,10 @@ 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) {
const OriginAttributes& originAttributes, bool aHttp3Allowed) {
return mAltSvcCache->GetAltServiceMapping(
scheme, host, port, pb, isolated, topWindowOrigin, originAttributes);
scheme, host, port, pb, isolated, topWindowOrigin, originAttributes,
aHttp3Allowed);
}
//