author | Phil Ringnalda <philringnalda@gmail.com> |
Sat, 04 Oct 2014 20:10:19 -0700 | |
changeset 208833 | 916f2837201cfa240febe707f2ba73f0c6e33cd1 |
parent 208832 | 9f6ad16ffec652fc1ec5dc2cb403b6026c3ce90b |
child 208834 | 41ce29f771b23dc619c2589ef1c30648e16599bb |
push id | 1 |
push user | root |
push date | Mon, 20 Oct 2014 17:29:22 +0000 |
bugs | 1003448 |
milestone | 35.0a1 |
backs out | 61f98b1d29f99d995c6482347cff94fe5f7e59af 8e947d1636f10aa16abfe578f96405325dda730c |
--- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -1242,26 +1242,16 @@ pref("network.http.spdy.timeout", 180); pref("network.http.spdy.coalesce-hostnames", true); pref("network.http.spdy.persistent-settings", false); pref("network.http.spdy.ping-threshold", 58); pref("network.http.spdy.ping-timeout", 8); pref("network.http.spdy.send-buffer-size", 131072); pref("network.http.spdy.allow-push", true); pref("network.http.spdy.push-allowance", 131072); -// alt-svc allows separation of transport routing from -// the origin host without using a proxy. -#ifdef RELEASE_BUILD -pref("network.http.altsvc.enabled", false); -pref("network.http.altsvc.oe", false); -#else -pref("network.http.altsvc.enabled", true); -pref("network.http.altsvc.oe", true); -#endif - pref("network.http.diagnostics", false); pref("network.http.pacing.requests.enabled", true); pref("network.http.pacing.requests.min-parallelism", 6); pref("network.http.pacing.requests.hz", 100); pref("network.http.pacing.requests.burst", 32); // TCP Keepalive config for HTTP connections.
--- a/netwerk/base/public/nsISpeculativeConnect.idl +++ b/netwerk/base/public/nsISpeculativeConnect.idl @@ -30,17 +30,17 @@ interface nsISpeculativeConnect : nsISup }; /** * This is used to override the default values for various values (documented * inline) to determine whether or not to actually make a speculative * connection. */ -[builtinclass, uuid(f6a0d1e5-369f-4abc-81ae-d370d36e4006)] +[builtinclass, uuid(a9cdd875-2ef8-4d53-95d6-e4e18f65e0db)] interface nsISpeculativeConnectionOverrider : nsISupports { /** * Used to determine the maximum number of unused speculative connections * we will have open for a host at any one time */ [infallible] readonly attribute unsigned long parallelSpeculativeConnectLimit; @@ -58,14 +58,9 @@ interface nsISpeculativeConnectionOverri */ [infallible] readonly attribute boolean ignoreIdle; /* * Used by the Predictor to gather telemetry data on speculative connection * usage. */ [infallible] readonly attribute boolean isFromPredictor; - - /** - * by default speculative connections are not made to RFC 1918 addresses - */ - [infallible] readonly attribute boolean allow1918; };
--- a/netwerk/base/src/Predictor.cpp +++ b/netwerk/base/src/Predictor.cpp @@ -390,23 +390,16 @@ Predictor::GetParallelSpeculativeConnect NS_IMETHODIMP Predictor::GetIsFromPredictor(bool *isFromPredictor) { *isFromPredictor = true; return NS_OK; } -NS_IMETHODIMP -Predictor::GetAllow1918(bool *allow1918) -{ - *allow1918 = false; - return NS_OK; -} - // Predictor::nsIInterfaceRequestor NS_IMETHODIMP Predictor::GetInterface(const nsIID &iid, void **result) { return QueryInterface(iid, result); }
deleted file mode 100644 --- a/netwerk/protocol/http/AlternateServices.cpp +++ /dev/null @@ -1,452 +0,0 @@ -/* -*- 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/. */ - -#include "HttpLog.h" - -#include "AlternateServices.h" -#include "nsHttpConnectionInfo.h" -#include "nsHttpHandler.h" -#include "nsThreadUtils.h" -#include "NullHttpTransaction.h" -#include "nsISSLStatusProvider.h" -#include "nsISSLStatus.h" -#include "nsISSLSocketControl.h" - -namespace mozilla { -namespace net { - -AltSvcMapping::AltSvcMapping(const nsACString &originScheme, - const nsACString &originHost, - int32_t originPort, - const nsACString &username, - bool privateBrowsing, - uint32_t expiresAt, - const nsACString &alternateHost, - int32_t alternatePort, - const nsACString &npnToken) - : mAlternateHost(alternateHost) - , mAlternatePort(alternatePort) - , mOriginHost(originHost) - , mOriginPort(originPort) - , mUsername(username) - , mPrivate(privateBrowsing) - , mExpiresAt(expiresAt) - , mValidated(false) - , mRunning(false) - , mNPNToken(npnToken) -{ - mHttps = originScheme.Equals("https"); - - if (mAlternatePort == -1) { - mAlternatePort = mHttps ? NS_HTTPS_DEFAULT_PORT : NS_HTTP_DEFAULT_PORT; - } - if (mOriginPort == -1) { - mOriginPort = mHttps ? NS_HTTPS_DEFAULT_PORT : NS_HTTP_DEFAULT_PORT; - } - - LOG(("AltSvcMapping ctor %p %s://%s:%d to %s:%d\n", this, - nsCString(originScheme).get(), mOriginHost.get(), mOriginPort, - mAlternateHost.get(), mAlternatePort)); - - if (mAlternateHost.IsEmpty()) { - mAlternateHost = mOriginHost; - } - MakeHashKey(mHashKey, originScheme, mOriginHost, mOriginPort, mPrivate); -} - -void -AltSvcMapping::MakeHashKey(nsCString &outKey, - const nsACString &originScheme, - const nsACString &originHost, - int32_t originPort, - bool privateBrowsing) -{ - if (originPort == -1) { - bool isHttps = originScheme.Equals("https"); - originPort = isHttps ? NS_HTTPS_DEFAULT_PORT : NS_HTTP_DEFAULT_PORT; - } - - outKey.Append(originScheme); - outKey.Append(':'); - outKey.Append(originHost); - outKey.Append(':'); - outKey.AppendInt(originPort); - outKey.Append(':'); - outKey.Append(privateBrowsing ? 'P' : '.'); -} - -int32_t -AltSvcMapping::TTL() -{ - return mExpiresAt - NowInSeconds(); -} - -void -AltSvcMapping::SetExpired() -{ - mExpiresAt = NowInSeconds() - 1; -} - -bool -AltSvcMapping::RouteEquals(AltSvcMapping *map) -{ - MOZ_ASSERT(map->mHashKey.Equals(mHashKey)); - return mAlternateHost.Equals(map->mAlternateHost) && - (mAlternatePort == map->mAlternatePort) && - mNPNToken.Equals(map->mNPNToken); - - return false; -} - -void -AltSvcMapping::GetConnectionInfo(nsHttpConnectionInfo **outCI, - nsProxyInfo *pi) -{ - nsRefPtr<nsHttpConnectionInfo> ci = - new nsHttpConnectionInfo(mAlternateHost, mAlternatePort, mNPNToken, - mUsername, pi, mOriginHost, mOriginPort); - if (!mHttps) { - ci->SetRelaxed(true); - } - ci->SetPrivate(mPrivate); - ci.forget(outCI); -} - -// This is the asynchronous null transaction used to validate -// an alt-svc advertisement -class AltSvcTransaction MOZ_FINAL : public NullHttpTransaction -{ -public: - AltSvcTransaction(AltSvcMapping *map, - nsHttpConnectionInfo *ci, - nsIInterfaceRequestor *callbacks, - uint32_t caps) - : NullHttpTransaction(ci, callbacks, caps) - , mMapping(map) - , mRunning(false) - , mTriedToValidate(false) - , mTriedToWrite(false) - { - MOZ_ASSERT(mMapping); - LOG(("AltSvcTransaction ctor %p map %p [%s -> %s]", - this, map, map->OriginHost().get(), map->AlternateHost().get())); - } - - ~AltSvcTransaction() - { - LOG(("AltSvcTransaction dtor %p map %p running %d", - this, mMapping.get(), mRunning)); - - if (mRunning) { - MOZ_ASSERT(mMapping->IsRunning()); - MaybeValidate(NS_OK); - } - if (!mMapping->Validated()) { - // try again later - mMapping->SetExpiresAt(NowInSeconds() + 2); - } - LOG(("AltSvcTransaction dtor %p map %p validated %d [%s]", - this, mMapping.get(), mMapping->Validated(), - mMapping->HashKey().get())); - mMapping->SetRunning(false); - } - - void StartTransaction() - { - LOG(("AltSvcTransaction::StartTransaction() %p", this)); - - MOZ_ASSERT(!mRunning); - MOZ_ASSERT(!mMapping->IsRunning()); - mCaps &= ~NS_HTTP_ALLOW_KEEPALIVE; - mRunning = true; - mMapping->SetRunning(true); - } - - void MaybeValidate(nsresult reason) - { - if (mTriedToValidate) { - return; - } - mTriedToValidate = true; - - LOG(("AltSvcTransaction::MaybeValidate() %p reason=%x running=%d conn=%p write=%d", - this, reason, mRunning, mConnection.get(), mTriedToWrite)); - - if (mTriedToWrite && reason == NS_BASE_STREAM_CLOSED) { - // The normal course of events is to cause the transaction to fail with CLOSED - // on a write - so that's a success that means the HTTP/2 session is setup. - reason = NS_OK; - } - - if (NS_FAILED(reason) || !mRunning || !mConnection) { - LOG(("AltSvcTransaction::MaybeValidate %p Failed due to precondition", this)); - return; - } - - // insist on spdy/3* or >= http/2 - uint32_t version = mConnection->Version(); - LOG(("AltSvcTransaction::MaybeValidate() %p version %d\n", this, version)); - if ((version < HTTP_VERSION_2) && - (version != SPDY_VERSION_31) && (version != SPDY_VERSION_3)) { - LOG(("AltSvcTransaction::MaybeValidate %p Failed due to protocol version", this)); - return; - } - - nsCOMPtr<nsISupports> secInfo; - mConnection->GetSecurityInfo(getter_AddRefs(secInfo)); - nsCOMPtr<nsISSLSocketControl> socketControl = do_QueryInterface(secInfo); - bool bypassAuth = false; - - if (!socketControl || - NS_FAILED(socketControl->GetBypassAuthentication(&bypassAuth))) { - bypassAuth = false; - } - - LOG(("AltSvcTransaction::MaybeValidate() %p socketControl=%p bypass=%d", - this, socketControl.get(), bypassAuth)); - - if (bypassAuth) { - LOG(("AltSvcTransaction::MaybeValidate() %p " - "validating alternate service because relaxed", this)); - mMapping->SetValidated(true); - return; - } - - if (socketControl->GetFailedVerification()) { - LOG(("AltSvcTransaction::MaybeValidate() %p " - "not validated due to auth error", this)); - return; - } - - LOG(("AltSvcTransaction::MaybeValidate() %p " - "validating alternate service with auth check", this)); - mMapping->SetValidated(true); - } - - void Close(nsresult reason) MOZ_OVERRIDE - { - LOG(("AltSvcTransaction::Close() %p reason=%x running %d", - this, reason, mRunning)); - - MaybeValidate(reason); - if (!mMapping->Validated() && mConnection) { - mConnection->DontReuse(); - } - NullHttpTransaction::Close(reason); - } - - nsresult ReadSegments(nsAHttpSegmentReader *reader, - uint32_t count, uint32_t *countRead) MOZ_OVERRIDE - { - LOG(("AltSvcTransaction::ReadSegements() %p\n")); - mTriedToWrite = true; - return NullHttpTransaction::ReadSegments(reader, count, countRead); - } - -private: - nsRefPtr<AltSvcMapping> mMapping; - uint32_t mRunning : 1; - uint32_t mTriedToValidate : 1; - uint32_t mTriedToWrite : 1; -}; - -void -AltSvcCache::UpdateAltServiceMapping(AltSvcMapping *map, nsProxyInfo *pi, - nsIInterfaceRequestor *aCallbacks, - uint32_t caps) -{ - MOZ_ASSERT(NS_IsMainThread()); - AltSvcMapping *existing = mHash.GetWeak(map->mHashKey); - LOG(("AltSvcCache::UpdateAltServiceMapping %p map %p existing %p %s", - this, map, existing, map->AlternateHost().get())); - - if (existing && (existing->TTL() <= 0)) { - LOG(("AltSvcCache::UpdateAltServiceMapping %p map %p is expired", - this, map)); - existing = nullptr; - mHash.Remove(map->mHashKey); - } - - if (existing && existing->mValidated) { - if (existing->RouteEquals(map)) { - // update expires - LOG(("AltSvcCache::UpdateAltServiceMapping %p map %p updates ttl of %p\n", - this, map, existing)); - existing->SetExpiresAt(map->GetExpiresAt()); - return; - } - - LOG(("AltSvcCache::UpdateAltServiceMapping %p map %p overwrites %p\n", - this, map, existing)); - existing = nullptr; - mHash.Remove(map->mHashKey); - } - - if (existing) { - LOG(("AltSvcCache::UpdateAltServiceMapping %p map %p ignored because %p " - "still in progress\n", this, map, existing)); - return; - } - - mHash.Put(map->mHashKey, map); - - nsRefPtr<nsHttpConnectionInfo> ci; - map->GetConnectionInfo(getter_AddRefs(ci), pi); - caps |= ci->GetAnonymous() ? NS_HTTP_LOAD_ANONYMOUS : 0; - - nsCOMPtr<nsIInterfaceRequestor> callbacks = new AltSvcOverride(aCallbacks); - - nsRefPtr<AltSvcTransaction> nullTransaction = - new AltSvcTransaction(map, ci, aCallbacks, caps); - nullTransaction->StartTransaction(); - gHttpHandler->ConnMgr()->SpeculativeConnect(ci, callbacks, caps, nullTransaction); -} - -AltSvcMapping * -AltSvcCache::GetAltServiceMapping(const nsACString &scheme, const nsACString &host, - int32_t port, bool privateBrowsing) -{ - MOZ_ASSERT(NS_IsMainThread()); - if (!gHttpHandler->AllowAltSvc()) { - return nullptr; - } - if (!gHttpHandler->AllowAltSvcOE() && scheme.Equals(NS_LITERAL_CSTRING("http"))) { - return nullptr; - } - - nsAutoCString key; - AltSvcMapping::MakeHashKey(key, scheme, host, port, privateBrowsing); - AltSvcMapping *existing = mHash.GetWeak(key); - LOG(("AltSvcCache::GetAltServiceMapping %p key=%s " - "existing=%p validated=%d running=%d ttl=%d", - this, key.get(), existing, existing ? existing->mValidated : 0, - existing ? existing->mRunning : 0, - existing ? existing->TTL() : 0)); - if (existing && (existing->TTL() <= 0)) { - LOG(("AltSvcCache::GetAltServiceMapping %p map %p is expired", this, existing)); - mHash.Remove(existing->mHashKey); - existing = nullptr; - } - if (existing && existing->mValidated) - return existing; - return nullptr; -} - -class ProxyClearHostMapping : public nsRunnable { -public: - explicit ProxyClearHostMapping(const nsACString &host, int32_t port) - : mHost(host) - , mPort(port) - {} - - NS_IMETHOD Run() - { - MOZ_ASSERT(NS_IsMainThread()); - gHttpHandler->ConnMgr()->ClearHostMapping(mHost, mPort); - return NS_OK; - } -private: - nsCString mHost; - int32_t mPort; -}; - -void -AltSvcCache::ClearHostMapping(const nsACString &host, int32_t port) -{ - if (!NS_IsMainThread()) { - nsCOMPtr<nsIRunnable> event = new ProxyClearHostMapping(host, port); - if (event) { - NS_DispatchToMainThread(event); - } - return; - } - - nsAutoCString key; - - AltSvcMapping::MakeHashKey(key, NS_LITERAL_CSTRING("http"), host, port, true); - AltSvcMapping *existing = mHash.GetWeak(key); - if (existing) { - existing->SetExpired(); - } - - AltSvcMapping::MakeHashKey(key, NS_LITERAL_CSTRING("https"), host, port, true); - existing = mHash.GetWeak(key); - if (existing) { - existing->SetExpired(); - } - - AltSvcMapping::MakeHashKey(key, NS_LITERAL_CSTRING("http"), host, port, false); - existing = mHash.GetWeak(key); - if (existing) { - existing->SetExpired(); - } - - AltSvcMapping::MakeHashKey(key, NS_LITERAL_CSTRING("https"), host, port, false); - existing = mHash.GetWeak(key); - if (existing) { - existing->SetExpired(); - } -} - -void -AltSvcCache::ClearAltServiceMappings() -{ - MOZ_ASSERT(NS_IsMainThread()); - mHash.Clear(); -} - -NS_IMETHODIMP -AltSvcOverride::GetInterface(const nsIID &iid, void **result) -{ - if (NS_SUCCEEDED(QueryInterface(iid, result)) && *result) { - return NS_OK; - } - return mCallbacks->GetInterface(iid, result); -} - -NS_IMETHODIMP -AltSvcOverride::GetIgnoreIdle(bool *ignoreIdle) -{ - *ignoreIdle = true; - return NS_OK; -} - -NS_IMETHODIMP -AltSvcOverride::GetIgnorePossibleSpdyConnections(bool *ignorePossibleSpdyConnections) -{ - *ignorePossibleSpdyConnections = true; - return NS_OK; -} - -NS_IMETHODIMP -AltSvcOverride::GetParallelSpeculativeConnectLimit( - uint32_t *parallelSpeculativeConnectLimit) -{ - *parallelSpeculativeConnectLimit = 32; - return NS_OK; -} - -NS_IMETHODIMP -AltSvcOverride::GetIsFromPredictor(bool *isFromPredictor) -{ - *isFromPredictor = false; - return NS_OK; -} - -NS_IMETHODIMP -AltSvcOverride::GetAllow1918(bool *allow) -{ - // normally we don't do speculative connects to 1918.. and we use - // speculative connects for the mapping validation, so override - // that default here for alt-svc - *allow = true; - return NS_OK; -} - -NS_IMPL_ISUPPORTS(AltSvcOverride, nsIInterfaceRequestor, nsISpeculativeConnectionOverrider) - -} // namespace mozilla::net -} // namespace mozilla
deleted file mode 100644 --- a/netwerk/protocol/http/AlternateServices.h +++ /dev/null @@ -1,128 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; 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/. */ - -/* -Alt-Svc allows separation of transport routing from the origin host without -using a proxy. See https://httpwg.github.io/http-extensions/alt-svc.html - - Nice To Have Future Enhancements:: - * flush on network change event when we have an indicator - * use established https channel for http instead separate of conninfo hash - * pin via http-tls header - * clear based on origin when a random fail happens not just 421 - * upon establishment of channel, cancel and retry trans that have not yet written anything - * persistent storage (including private browsing filter) - * memory reporter for cache, but this is rather tiny -*/ - -#ifndef mozilla_net_AlternateServices_h -#define mozilla_net_AlternateServices_h - -#include "nsRefPtrHashtable.h" -#include "nsString.h" -#include "nsIInterfaceRequestor.h" -#include "nsISpeculativeConnect.h" - -class nsProxyInfo; - -namespace mozilla { namespace net { - -class nsHttpConnectionInfo; - -class AltSvcMapping -{ - NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AltSvcMapping) - friend class AltSvcCache; - -public: - AltSvcMapping(const nsACString &originScheme, - const nsACString &originHost, - int32_t originPort, - const nsACString &username, - bool privateBrowsing, - uint32_t expiresAt, - const nsACString &alternateHost, - int32_t alternatePort, - const nsACString &npnToken); - - const nsCString &AlternateHost() const { return mAlternateHost; } - const nsCString &OriginHost() const { return mOriginHost; } - const nsCString &HashKey() const { return mHashKey; } - uint32_t AlternatePort() const { return mAlternatePort; } - bool Validated() { return mValidated; } - void SetValidated(bool val) { mValidated = val; } - bool IsRunning() { return mRunning; } - void SetRunning(bool val) { mRunning = val; } - int32_t GetExpiresAt() { return mExpiresAt; } - void SetExpiresAt(int32_t val) { mExpiresAt = val; } - void SetExpired(); - bool RouteEquals(AltSvcMapping *map); - - void GetConnectionInfo(nsHttpConnectionInfo **outCI, nsProxyInfo *pi); - int32_t TTL(); - -private: - virtual ~AltSvcMapping() {}; - static void MakeHashKey(nsCString &outKey, - const nsACString &originScheme, - const nsACString &originHost, - int32_t originPort, - bool privateBrowsing); - - nsCString mHashKey; - - nsCString mAlternateHost; - int32_t mAlternatePort; - - nsCString mOriginHost; - int32_t mOriginPort; - - nsCString mUsername; - bool mPrivate; - - uint32_t mExpiresAt; - - bool mValidated; - bool mRunning; - bool mHttps; - - nsCString mNPNToken; -}; - -class AltSvcOverride : public nsIInterfaceRequestor - , public nsISpeculativeConnectionOverrider -{ -public: - NS_DECL_THREADSAFE_ISUPPORTS - NS_DECL_NSISPECULATIVECONNECTIONOVERRIDER - NS_DECL_NSIINTERFACEREQUESTOR - - AltSvcOverride(nsIInterfaceRequestor *aRequestor) - : mCallbacks(aRequestor) {} - -private: - virtual ~AltSvcOverride() {} - nsCOMPtr<nsIInterfaceRequestor> mCallbacks; -}; - -class AltSvcCache -{ -public: - void UpdateAltServiceMapping(AltSvcMapping *map, nsProxyInfo *pi, - nsIInterfaceRequestor *, uint32_t caps); // main thread - AltSvcMapping *GetAltServiceMapping(const nsACString &scheme, - const nsACString &host, - int32_t port, bool pb); - void ClearAltServiceMappings(); - void ClearHostMapping(const nsACString &host, int32_t port); - -private: - nsRefPtrHashtable<nsCStringHashKey, AltSvcMapping> mHash; -}; - -}} // namespace mozilla::net - -#endif // include guard
--- a/netwerk/protocol/http/Http2Session.cpp +++ b/netwerk/protocol/http/Http2Session.cpp @@ -253,18 +253,17 @@ static Http2ControlFx sControlFunctions[ Http2Session::RecvHeaders, Http2Session::RecvPriority, Http2Session::RecvRstStream, Http2Session::RecvSettings, Http2Session::RecvPushPromise, Http2Session::RecvPing, Http2Session::RecvGoAway, Http2Session::RecvWindowUpdate, - Http2Session::RecvContinuation, - Http2Session::RecvAltSvc // extension for type 0x0A + Http2Session::RecvContinuation }; bool Http2Session::RoomForMoreConcurrent() { MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); return (mConcurrent < mMaxConcurrent); } @@ -438,18 +437,17 @@ Http2Session::AddStream(nsAHttpTransacti LOG3(("Http2Session::AddStream %p stream %p activated immediately.", this, stream)); ActivateStream(stream); } else { LOG3(("Http2Session::AddStream %p stream %p queued.", this, stream)); mQueuedStreams.Push(stream); } - if (!(aHttpTransaction->Caps() & NS_HTTP_ALLOW_KEEPALIVE) && - !aHttpTransaction->IsNullTransaction()) { + if (!(aHttpTransaction->Caps() & NS_HTTP_ALLOW_KEEPALIVE)) { LOG3(("Http2Session::AddStream %p transaction %p forces keep-alive off.\n", this, aHttpTransaction)); DontReuse(); } return true; } @@ -1855,218 +1853,16 @@ Http2Session::RecvContinuation(Http2Sess // continued push promise if (self->mInputFrameFlags & kFlag_END_HEADERS) { self->mInputFrameFlags &= ~kFlag_END_HEADERS; self->mInputFrameFlags |= kFlag_END_PUSH_PROMISE; } return RecvPushPromise(self); } -class UpdateAltSvcEvent : public nsRunnable -{ -public: - UpdateAltSvcEvent(const nsCString &host, const uint16_t port, - const nsCString &npnToken, const uint32_t expires, - const nsCString &aOrigin, - nsHttpConnectionInfo *aCI, - nsIInterfaceRequestor *callbacks) - : mHost(host) - , mPort(port) - , mNPNToken(npnToken) - , mExpires(expires) - , mOrigin(aOrigin) - , mCI(aCI) - , mCallbacks(callbacks) - { - } - - NS_IMETHOD Run() MOZ_OVERRIDE - { - MOZ_ASSERT(NS_IsMainThread()); - - nsCString originScheme; - nsCString originHost; - int32_t originPort = -1; - - nsCOMPtr<nsIURI> uri; - if (NS_FAILED(NS_NewURI(getter_AddRefs(uri), mOrigin))) { - LOG(("UpdateAltSvcEvent origin does not parse %s\n", - mOrigin.get())); - return NS_OK; - } - uri->GetScheme(originScheme); - uri->GetHost(originHost); - uri->GetPort(&originPort); - - const char *username = mCI->Username(); - const bool privateBrowsing = mCI->GetPrivate(); - - LOG(("UpdateAltSvcEvent location=%s:%u protocol=%s expires=%u " - "origin=%s://%s:%u user=%s private=%d", mHost.get(), mPort, - mNPNToken.get(), mExpires, originScheme.get(), originHost.get(), - originPort, username, privateBrowsing)); - nsRefPtr<AltSvcMapping> mapping = new AltSvcMapping( - nsDependentCString(originScheme.get()), - nsDependentCString(originHost.get()), - originPort, nsDependentCString(username), privateBrowsing, mExpires, - mHost, mPort, mNPNToken); - - nsProxyInfo *proxyInfo = mCI->ProxyInfo(); - gHttpHandler->UpdateAltServiceMapping(mapping, proxyInfo, mCallbacks, 0); - return NS_OK; - } - -private: - nsCString mHost; - uint16_t mPort; - nsCString mNPNToken; - uint32_t mExpires; - nsCString mOrigin; - nsRefPtr<nsHttpConnectionInfo> mCI; - nsCOMPtr<nsIInterfaceRequestor> mCallbacks; -}; - -// defined as an http2 extension - alt-svc -// defines receipt of frame type 0x0A.. See AlternateSevices.h -nsresult -Http2Session::RecvAltSvc(Http2Session *self) -{ - MOZ_ASSERT(self->mInputFrameType == FRAME_TYPE_ALTSVC); - LOG3(("Http2Session::RecvAltSvc %p Flags 0x%X id 0x%X\n", self, - self->mInputFrameFlags, self->mInputFrameID)); - - if (self->mInputFrameDataSize < 8) { - LOG3(("Http2Session::RecvAltSvc %p frame too small", self)); - RETURN_SESSION_ERROR(self, FRAME_SIZE_ERROR); - } - - uint32_t maxAge = - PR_ntohl(*reinterpret_cast<uint32_t *>(self->mInputFrameBuffer.get() + kFrameHeaderBytes)); - uint16_t portRoute = - PR_ntohs(*reinterpret_cast<uint16_t *>(self->mInputFrameBuffer.get() + kFrameHeaderBytes + 4)); - uint8_t protoLen = self->mInputFrameBuffer.get()[kFrameHeaderBytes + 6]; - LOG3(("Http2Session::RecvAltSvc %p maxAge=%d port=%d protoLen=%d", self, - maxAge, portRoute, protoLen)); - - if (self->mInputFrameDataSize < (8U + protoLen)) { - LOG3(("Http2Session::RecvAltSvc %p frame too small for protocol", self)); - RETURN_SESSION_ERROR(self, FRAME_SIZE_ERROR); - } - nsAutoCString protocol; - protocol.Assign(self->mInputFrameBuffer.get() + kFrameHeaderBytes + 7, protoLen); - - uint32_t spdyIndex; - SpdyInformation *spdyInfo = gHttpHandler->SpdyInfo(); - if (!(NS_SUCCEEDED(spdyInfo->GetNPNIndex(protocol, &spdyIndex)) && - spdyInfo->ProtocolEnabled(spdyIndex))) { - LOG3(("Http2Session::RecvAltSvc %p unknown protocol %s, ignoring", self, - protocol.BeginReading())); - self->ResetDownstreamState(); - return NS_OK; - } - - uint8_t hostLen = self->mInputFrameBuffer.get()[kFrameHeaderBytes + 7 + protoLen]; - if (self->mInputFrameDataSize < (8U + protoLen + hostLen)) { - LOG3(("Http2Session::RecvAltSvc %p frame too small for host", self)); - RETURN_SESSION_ERROR(self, FRAME_SIZE_ERROR); - } - - nsRefPtr<nsHttpConnectionInfo> ci(self->ConnectionInfo()); - if (!self->mConnection || !ci) { - LOG3(("Http2Session::RecvAltSvc %p no connection or conninfo for %d", self, - self->mInputFrameID)); - self->ResetDownstreamState(); - return NS_OK; - } - - nsAutoCString hostRoute; - hostRoute.Assign(self->mInputFrameBuffer.get() + kFrameHeaderBytes + 8 + protoLen, hostLen); - - uint32_t originLen = self->mInputFrameDataSize - 8 - protoLen - hostLen; - nsAutoCString specifiedOrigin; - if (originLen) { - if (self->mInputFrameID) { - LOG3(("Http2Session::RecvAltSvc %p got frame w/origin on non zero stream", self)); - self->ResetDownstreamState(); - return NS_OK; - } - specifiedOrigin.Assign( - self->mInputFrameBuffer.get() + kFrameHeaderBytes + 8 + protoLen + hostLen, - originLen); - - bool okToReroute = true; - nsCOMPtr<nsISupports> securityInfo; - self->mConnection->GetSecurityInfo(getter_AddRefs(securityInfo)); - nsCOMPtr<nsISSLSocketControl> ssl = do_QueryInterface(securityInfo); - if (!ssl) { - okToReroute = false; - } - - // a little off main thread origin parser. This is a non critical function because - // any alternate route created has to be verified anyhow - nsAutoCString specifiedOriginHost; - if (specifiedOrigin.EqualsIgnoreCase("https://", 8)) { - specifiedOriginHost.Assign(specifiedOrigin.get() + 8, - specifiedOrigin.Length() - 8); - if (ci->GetRelaxed()) { - // technically this is ok because it will still be confirmed before being used - // but let's not support it. - okToReroute = false; - } - } else if (specifiedOrigin.EqualsIgnoreCase("http://", 7)) { - specifiedOriginHost.Assign(specifiedOrigin.get() + 7, - specifiedOrigin.Length() - 7); - } - - int32_t colonOffset = specifiedOriginHost.FindCharInSet(":", 0); - if (colonOffset != kNotFound) { - specifiedOriginHost.Truncate(colonOffset); - } - - if (okToReroute) { - ssl->IsAcceptableForHost(specifiedOriginHost, &okToReroute); - } - if (!okToReroute) { - LOG3(("Http2Session::RecvAltSvc %p can't reroute non-authoritative origin %s", - self, specifiedOrigin.BeginReading())); - self->ResetDownstreamState(); - return NS_OK; - } - } else { - // no origin specified in frame. We need to have an active pull stream to match - // this up to as if it were a response header. - if (!(self->mInputFrameID & 0x1) || - NS_FAILED(self->SetInputFrameDataStream(self->mInputFrameID)) || - !self->mInputFrameDataStream->Transaction() || - !self->mInputFrameDataStream->Transaction()->RequestHead()) { - LOG3(("Http2Session::RecvAltSvc %p got frame w/o origin on invalid stream", self)); - self->ResetDownstreamState(); - return NS_OK; - } - - specifiedOrigin.Assign( - self->mInputFrameDataStream->Transaction()->RequestHead()->Origin()); - } - - nsCOMPtr<nsISupports> callbacks; - self->mConnection->GetSecurityInfo(getter_AddRefs(callbacks)); - nsCOMPtr<nsIInterfaceRequestor> irCallbacks = do_QueryInterface(callbacks); - - nsRefPtr<UpdateAltSvcEvent> event = new UpdateAltSvcEvent( - hostRoute, portRoute, protocol, NowInSeconds() + maxAge, - specifiedOrigin, ci, irCallbacks); - NS_DispatchToMainThread(event); - - LOG3(("Http2Session::RecvAltSvc %p processed location=%s:%u protocol=%s " - "maxAge=%u origin=%s", self, hostRoute.get(), portRoute, - protocol.get(), maxAge, specifiedOrigin.get())); - self->ResetDownstreamState(); - return NS_OK; -} - //----------------------------------------------------------------------------- // nsAHttpTransaction. It is expected that nsHttpConnection is the caller // of these methods //----------------------------------------------------------------------------- void Http2Session::OnTransportStatus(nsITransport* aTransport, nsresult aStatus, uint64_t aProgress) @@ -2182,27 +1978,20 @@ Http2Session::ReadSegments(nsAHttpSegmen } else { rv = NS_BASE_STREAM_WOULD_BLOCK; } SetWriteCallbacks(); return rv; } if (NS_FAILED(rv)) { - LOG3(("Http2Session::ReadSegments %p may return FAIL code %X", + LOG3(("Http2Session::ReadSegments %p returning FAIL code %X", this, rv)); - if (rv == NS_BASE_STREAM_WOULD_BLOCK) { - return rv; - } - - CleanupStream(stream, rv, CANCEL_ERROR); - if (SoftStreamError(rv)) { - LOG3(("Http2Session::ReadSegments %p soft error override\n", this)); - rv = NS_OK; - } + if (rv != NS_BASE_STREAM_WOULD_BLOCK) + CleanupStream(stream, rv, CANCEL_ERROR); return rv; } if (*countRead > 0) { LOG3(("Http2Session::ReadSegments %p stream=%p countread=%d", this, stream, *countRead)); mReadyForWrite.Push(stream); SetWriteCallbacks();
--- a/netwerk/protocol/http/Http2Session.h +++ b/netwerk/protocol/http/Http2Session.h @@ -70,28 +70,27 @@ public: +-+-------------+---------------+-------------------------------+ |R| Stream Identifier (31) | +-+-------------------------------------------------------------+ | Frame Data (0...) ... +---------------------------------------------------------------+ */ enum frameType { - FRAME_TYPE_DATA = 0x0, - FRAME_TYPE_HEADERS = 0x1, - FRAME_TYPE_PRIORITY = 0x2, - FRAME_TYPE_RST_STREAM = 0x3, - FRAME_TYPE_SETTINGS = 0x4, - FRAME_TYPE_PUSH_PROMISE = 0x5, - FRAME_TYPE_PING = 0x6, - FRAME_TYPE_GOAWAY = 0x7, - FRAME_TYPE_WINDOW_UPDATE = 0x8, - FRAME_TYPE_CONTINUATION = 0x9, - FRAME_TYPE_ALTSVC = 0xA, - FRAME_TYPE_LAST = 0xB + FRAME_TYPE_DATA = 0, + FRAME_TYPE_HEADERS = 1, + FRAME_TYPE_PRIORITY = 2, + FRAME_TYPE_RST_STREAM = 3, + FRAME_TYPE_SETTINGS = 4, + FRAME_TYPE_PUSH_PROMISE = 5, + FRAME_TYPE_PING = 6, + FRAME_TYPE_GOAWAY = 7, + FRAME_TYPE_WINDOW_UPDATE = 8, + FRAME_TYPE_CONTINUATION = 9, + FRAME_TYPE_LAST = 10 }; // NO_ERROR is a macro defined on windows, so we'll name the HTTP2 goaway // code NO_ERROR to be NO_HTTP_ERROR enum errorType { NO_HTTP_ERROR = 0, PROTOCOL_ERROR = 1, INTERNAL_ERROR = 2, @@ -164,17 +163,16 @@ public: static nsresult RecvPriority(Http2Session *); static nsresult RecvRstStream(Http2Session *); static nsresult RecvSettings(Http2Session *); static nsresult RecvPushPromise(Http2Session *); static nsresult RecvPing(Http2Session *); static nsresult RecvGoAway(Http2Session *); static nsresult RecvWindowUpdate(Http2Session *); static nsresult RecvContinuation(Http2Session *); - static nsresult RecvAltSvc(Http2Session *); char *EnsureOutputBuffer(uint32_t needed); template<typename charType> void CreateFrameHeader(charType dest, uint16_t frameLength, uint8_t frameType, uint8_t frameFlags, uint32_t streamID);
--- a/netwerk/protocol/http/NullHttpTransaction.cpp +++ b/netwerk/protocol/http/NullHttpTransaction.cpp @@ -18,20 +18,20 @@ namespace net { NS_IMPL_ISUPPORTS(NullHttpTransaction, NullHttpTransaction, nsISupportsWeakReference) NullHttpTransaction::NullHttpTransaction(nsHttpConnectionInfo *ci, nsIInterfaceRequestor *callbacks, uint32_t caps) : mStatus(NS_OK) , mCaps(caps | NS_HTTP_ALLOW_KEEPALIVE) , mCapsToClear(0) + , mCallbacks(callbacks) + , mConnectionInfo(ci) , mRequestHead(nullptr) , mIsDone(false) - , mCallbacks(callbacks) - , mConnectionInfo(ci) { } NullHttpTransaction::~NullHttpTransaction() { mCallbacks = nullptr; delete mRequestHead; }
--- a/netwerk/protocol/http/NullHttpTransaction.h +++ b/netwerk/protocol/http/NullHttpTransaction.h @@ -44,31 +44,27 @@ public: return PR_SecondsToInterval(15); } protected: virtual ~NullHttpTransaction(); private: nsresult mStatus; -protected: uint32_t mCaps; -private: // mCapsToClear holds flags that should be cleared in mCaps, e.g. unset // NS_HTTP_REFRESH_DNS when DNS refresh request has completed to avoid // redundant requests on the network. To deal with raciness, only unsetting // bitfields should be allowed: 'lost races' will thus err on the // conservative side, e.g. by going ahead with a 2nd DNS refresh. uint32_t mCapsToClear; - nsHttpRequestHead *mRequestHead; - bool mIsDone; - -protected: nsRefPtr<nsAHttpConnection> mConnection; nsCOMPtr<nsIInterfaceRequestor> mCallbacks; nsRefPtr<nsHttpConnectionInfo> mConnectionInfo; + nsHttpRequestHead *mRequestHead; + bool mIsDone; }; NS_DEFINE_STATIC_IID_ACCESSOR(NullHttpTransaction, NS_NULLHTTPTRANSACTION_IID) }} // namespace mozilla::net #endif // mozilla_net_NullHttpTransaction_h
--- a/netwerk/protocol/http/SpdySession3.cpp +++ b/netwerk/protocol/http/SpdySession3.cpp @@ -381,40 +381,37 @@ SpdySession3::AddStream(nsAHttpTransacti this, stream)); ActivateStream(stream); } else { LOG3(("SpdySession3::AddStream %p stream %p queued.", this, stream)); mQueuedStreams.Push(stream); } - if (!(aHttpTransaction->Caps() & NS_HTTP_ALLOW_KEEPALIVE) && - !aHttpTransaction->IsNullTransaction()) { + if (!(aHttpTransaction->Caps() & NS_HTTP_ALLOW_KEEPALIVE)) { LOG3(("SpdySession3::AddStream %p transaction %p forces keep-alive off.\n", this, aHttpTransaction)); DontReuse(); } return true; } void SpdySession3::ActivateStream(SpdyStream3 *stream) { MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); MOZ_ASSERT(!stream->StreamID() || (stream->StreamID() & 1), "Do not activate pushed streams"); - if (!(stream->Transaction() && stream->Transaction()->IsNullTransaction())) { - ++mConcurrent; - if (mConcurrent > mConcurrentHighWater) - mConcurrentHighWater = mConcurrent; - LOG3(("SpdySession3::AddStream %p activating stream %p Currently %d " - "streams in session, high water mark is %d", - this, stream, mConcurrent, mConcurrentHighWater)); - } + ++mConcurrent; + if (mConcurrent > mConcurrentHighWater) + mConcurrentHighWater = mConcurrent; + LOG3(("SpdySession3::AddStream %p activating stream %p Currently %d " + "streams in session, high water mark is %d", + this, stream, mConcurrent, mConcurrentHighWater)); mReadyForWrite.Push(stream); SetWriteCallbacks(); // Kick off the SYN transmit without waiting for the poll loop // This won't work for stream id=1 because there is no segment reader // yet. if (mSegmentReader) { @@ -1759,27 +1756,20 @@ SpdySession3::ReadSegments(nsAHttpSegmen rv = NS_OK; else rv = NS_BASE_STREAM_WOULD_BLOCK; SetWriteCallbacks(); return rv; } if (NS_FAILED(rv)) { - LOG3(("SpdySession3::ReadSegments %p may return FAIL code %X", + LOG3(("SpdySession3::ReadSegments %p returning FAIL code %X", this, rv)); - if (rv == NS_BASE_STREAM_WOULD_BLOCK) { - return rv; - } - - CleanupStream(stream, rv, RST_CANCEL); - if (SoftStreamError(rv)) { - LOG3(("SpdySession3::ReadSegments %p soft error override\n", this)); - rv = NS_OK; - } + if (rv != NS_BASE_STREAM_WOULD_BLOCK) + CleanupStream(stream, rv, RST_CANCEL); return rv; } if (*countRead > 0) { LOG3(("SpdySession3::ReadSegments %p stream=%p countread=%d", this, stream, *countRead)); mReadyForWrite.Push(stream); SetWriteCallbacks();
--- a/netwerk/protocol/http/SpdySession31.cpp +++ b/netwerk/protocol/http/SpdySession31.cpp @@ -384,42 +384,38 @@ SpdySession31::AddStream(nsAHttpTransact this, stream)); ActivateStream(stream); } else { LOG3(("SpdySession31::AddStream %p stream %p queued.", this, stream)); mQueuedStreams.Push(stream); } - if (!(aHttpTransaction->Caps() & NS_HTTP_ALLOW_KEEPALIVE) && - !aHttpTransaction->IsNullTransaction()) { + if (!(aHttpTransaction->Caps() & NS_HTTP_ALLOW_KEEPALIVE)) { LOG3(("SpdySession31::AddStream %p transaction %p forces keep-alive off.\n", this, aHttpTransaction)); DontReuse(); } return true; } void SpdySession31::ActivateStream(SpdyStream31 *stream) { MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); MOZ_ASSERT(!stream->StreamID() || (stream->StreamID() & 1), "Do not activate pushed streams"); - if (!(stream->Transaction() && stream->Transaction()->IsNullTransaction())) { - ++mConcurrent; - if (mConcurrent > mConcurrentHighWater) { - mConcurrentHighWater = mConcurrent; - } - LOG3(("SpdySession31::AddStream %p activating stream %p Currently %d " - "streams in session, high water mark is %d", - this, stream, mConcurrent, mConcurrentHighWater)); - } + ++mConcurrent; + if (mConcurrent > mConcurrentHighWater) + mConcurrentHighWater = mConcurrent; + LOG3(("SpdySession31::AddStream %p activating stream %p Currently %d " + "streams in session, high water mark is %d", + this, stream, mConcurrent, mConcurrentHighWater)); mReadyForWrite.Push(stream); SetWriteCallbacks(); // Kick off the SYN transmit without waiting for the poll loop // This won't work for stream id=1 because there is no segment reader // yet. if (mSegmentReader) { @@ -1826,27 +1822,20 @@ SpdySession31::ReadSegments(nsAHttpSegme rv = NS_OK; else rv = NS_BASE_STREAM_WOULD_BLOCK; SetWriteCallbacks(); return rv; } if (NS_FAILED(rv)) { - LOG3(("SpdySession31::ReadSegments %p may return FAIL code %X", + LOG3(("SpdySession31::ReadSegments %p returning FAIL code %X", this, rv)); - if (rv == NS_BASE_STREAM_WOULD_BLOCK) { - return rv; - } - - CleanupStream(stream, rv, RST_CANCEL); - if (SoftStreamError(rv)) { - LOG3(("SpdySession31::ReadSegments %p soft error override\n", this)); - rv = NS_OK; - } + if (rv != NS_BASE_STREAM_WOULD_BLOCK) + CleanupStream(stream, rv, RST_CANCEL); return rv; } if (*countRead > 0) { LOG3(("SpdySession31::ReadSegments %p stream=%p countread=%d", this, stream, *countRead)); mReadyForWrite.Push(stream); SetWriteCallbacks();
--- a/netwerk/protocol/http/moz.build +++ b/netwerk/protocol/http/moz.build @@ -36,17 +36,16 @@ EXPORTS.mozilla.net += [ 'PSpdyPush.h', ] # ASpdySession.cpp and nsHttpAuthCache cannot be built in unified mode because # they use plarena.h. # The rest of these files cannot be built in unified mode because they want to # force NSPR logging. SOURCES += [ - 'AlternateServices.cpp', 'ASpdySession.cpp', 'ConnectionDiagnostics.cpp', 'Http2Compression.cpp', 'Http2Push.cpp', 'Http2Session.cpp', 'Http2Stream.cpp', 'HttpBaseChannel.cpp', 'HttpChannelChild.cpp',
--- a/netwerk/protocol/http/nsAHttpConnection.h +++ b/netwerk/protocol/http/nsAHttpConnection.h @@ -135,19 +135,16 @@ public: // The number of transaction bytes written out on this HTTP Connection, does // not count CONNECT tunnel setup virtual int64_t BytesWritten() = 0; // Update the callbacks used to provide security info. May be called on // any thread. virtual void SetSecurityCallbacks(nsIInterfaceRequestor* aCallbacks) = 0; - - // nsHttp.h version - virtual uint32_t Version() = 0; }; NS_DEFINE_STATIC_IID_ACCESSOR(nsAHttpConnection, NS_AHTTPCONNECTION_IID) #define NS_DECL_NSAHTTPCONNECTION(fwdObject) \ nsresult OnHeadersAvailable(nsAHttpTransaction *, nsHttpRequestHead *, nsHttpResponseHead *, bool *reset); \ void CloseTransaction(nsAHttpTransaction *, nsresult); \ nsresult TakeTransport(nsISocketTransport **, \ @@ -205,22 +202,16 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsAHttpCon return (fwdObject)->ForceRecv(); \ } \ nsISocketTransport *Transport() \ { \ if (!(fwdObject)) \ return nullptr; \ return (fwdObject)->Transport(); \ } \ - uint32_t Version() \ - { \ - return (fwdObject) ? \ - (fwdObject)->Version() : \ - NS_HTTP_VERSION_UNKNOWN; \ - } \ bool IsProxyConnectInProgress() \ { \ return (fwdObject)->IsProxyConnectInProgress(); \ } \ bool LastTransactionExpectedNoContent() \ { \ return (fwdObject)->LastTransactionExpectedNoContent(); \ } \
--- a/netwerk/protocol/http/nsAHttpTransaction.h +++ b/netwerk/protocol/http/nsAHttpTransaction.h @@ -198,17 +198,17 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsAHttpTra nsresult status, uint64_t progress); \ bool IsDone(); \ nsresult Status(); \ uint32_t Caps(); \ void SetDNSWasRefreshed(); \ uint64_t Available(); \ virtual nsresult ReadSegments(nsAHttpSegmentReader *, uint32_t, uint32_t *); \ virtual nsresult WriteSegments(nsAHttpSegmentWriter *, uint32_t, uint32_t *); \ - virtual void Close(nsresult reason); \ + void Close(nsresult reason); \ nsHttpConnectionInfo *ConnectionInfo(); \ void SetProxyConnectFailed(); \ virtual nsHttpRequestHead *RequestHead(); \ uint32_t Http1xTransactionCount(); \ nsresult TakeSubTransactions(nsTArray<nsRefPtr<nsAHttpTransaction> > &outTransactions); \ nsresult AddTransaction(nsAHttpTransaction *); \ uint32_t PipelineDepth(); \ nsresult SetPipelinePosition(int32_t); \
--- a/netwerk/protocol/http/nsHttp.cpp +++ b/netwerk/protocol/http/nsHttp.cpp @@ -341,133 +341,11 @@ void EnsureBuffer(nsAutoArrayPtr<char> & localEnsureBuffer<char> (buf, newSize, preserve, objSize); } void EnsureBuffer(nsAutoArrayPtr<uint8_t> &buf, uint32_t newSize, uint32_t preserve, uint32_t &objSize) { localEnsureBuffer<uint8_t> (buf, newSize, preserve, objSize); } -/// - -void -ParsedHeaderValueList::Tokenize(char *input, uint32_t inputLen, char **token, - uint32_t *tokenLen, bool *foundEquals, char **next) -{ - if (foundEquals) { - *foundEquals = false; - } - if (next) { - *next = nullptr; - } - if (inputLen < 1 || !input || !token) { - return; - } - - bool foundFirst = false; - bool inQuote = false; - bool foundToken = false; - *token = input; - *tokenLen = inputLen; - - for (uint32_t index = 0; !foundToken && index < inputLen; ++index) { - // strip leading cruft - if (!foundFirst && - (input[index] == ' ' || input[index] == '"' || input[index] == '\t')) { - (*token)++; - } else { - foundFirst = true; - } - - if (input[index] == '"') { - inQuote = !inQuote; - continue; - } - - if (inQuote) { - continue; - } - - if (input[index] == '=' || input[index] == ';') { - *tokenLen = (input + index) - *token; - if (next && ((index + 1) < inputLen)) { - *next = input + index + 1; - } - foundToken = true; - if (foundEquals && input[index] == '=') { - *foundEquals = true; - } - break; - } - } - - if (!foundToken) { - *tokenLen = (input + inputLen) - *token; - } - - // strip trailing cruft - for (char *index = *token + *tokenLen - 1; index >= *token; --index) { - if (*index != ' ' && *index != '\t' && *index != '"') { - break; - } - --(*tokenLen); - if (*index == '"') { - break; - } - } -} - -ParsedHeaderValueList::ParsedHeaderValueList(char *t, uint32_t len) -{ - char *name = nullptr; - uint32_t nameLen = 0; - char *value = nullptr; - uint32_t valueLen = 0; - char *next = nullptr; - bool foundEquals; - - while (t) { - Tokenize(t, len, &name, &nameLen, &foundEquals, &next); - if (next) { - len -= next - t; - } - t = next; - if (foundEquals && t) { - Tokenize(t, len, &value, &valueLen, nullptr, &next); - if (next) { - len -= next - t; - } - t = next; - } - mValues.AppendElement(ParsedHeaderPair(name, nameLen, value, valueLen)); - value = name = nullptr; - valueLen = nameLen = 0; - next = nullptr; - } -} - -ParsedHeaderValueListList::ParsedHeaderValueListList(const nsCString &fullHeader) - : mFull(fullHeader) -{ - char *t = mFull.BeginWriting(); - uint32_t len = mFull.Length(); - char *last = t; - bool inQuote = false; - for (uint32_t index = 0; index < len; ++index) { - if (t[index] == '"') { - inQuote = !inQuote; - continue; - } - if (inQuote) { - continue; - } - if (t[index] == ',') { - mValues.AppendElement(ParsedHeaderValueList(last, (t + index) - last)); - last = t + index + 1; - } - } - if (!inQuote) { - mValues.AppendElement(ParsedHeaderValueList(last, (t + len) - last)); - } -} } // namespace mozilla::net } // namespace mozilla
--- a/netwerk/protocol/http/nsHttp.h +++ b/netwerk/protocol/http/nsHttp.h @@ -7,17 +7,16 @@ #ifndef nsHttp_h__ #define nsHttp_h__ #include <stdint.h> #include "prtime.h" #include "nsAutoPtr.h" #include "nsString.h" #include "nsError.h" -#include "nsTArray.h" // http version codes #define NS_HTTP_VERSION_UNKNOWN 0 #define NS_HTTP_VERSION_0_9 9 #define NS_HTTP_VERSION_1_0 10 #define NS_HTTP_VERSION_1_1 11 #define NS_HTTP_VERSION_2_0 20 @@ -199,62 +198,12 @@ PRTimeToSeconds(PRTime t_usec) #define HTTP_LWS " \t" #define HTTP_HEADER_VALUE_SEPS HTTP_LWS "," void EnsureBuffer(nsAutoArrayPtr<char> &buf, uint32_t newSize, uint32_t preserve, uint32_t &objSize); void EnsureBuffer(nsAutoArrayPtr<uint8_t> &buf, uint32_t newSize, uint32_t preserve, uint32_t &objSize); -// h2=":443"; ma=60; single -// results in 3 mValues = {{h2, :443}, {ma, 60}, {single}} - -class ParsedHeaderPair -{ -public: - ParsedHeaderPair(const char *name, int32_t nameLen, - const char *val, int32_t valLen) - { - if (nameLen > 0) { - mName.Rebind(name, name + nameLen); - } - if (valLen > 0) { - mValue.Rebind(val, val + valLen); - } - } - - ParsedHeaderPair(ParsedHeaderPair const ©) - : mName(copy.mName) - , mValue(copy.mValue) - { - } - - nsDependentCSubstring mName; - nsDependentCSubstring mValue; -}; - -class ParsedHeaderValueList -{ -public: - ParsedHeaderValueList(char *t, uint32_t len); - nsTArray<ParsedHeaderPair> mValues; - -private: - void ParsePair(char *t, uint32_t len); - void Tokenize(char *input, uint32_t inputLen, char **token, - uint32_t *tokenLen, bool *foundEquals, char **next); -}; - -class ParsedHeaderValueListList -{ -public: - explicit ParsedHeaderValueListList(const nsCString &txt); - nsTArray<ParsedHeaderValueList> mValues; - -private: - nsCString mFull; -}; - - } // namespace mozilla::net } // namespace mozilla #endif // nsHttp_h__
--- a/netwerk/protocol/http/nsHttpAtomList.h +++ b/netwerk/protocol/http/nsHttpAtomList.h @@ -18,18 +18,16 @@ ******/ HTTP_ATOM(Accept, "Accept") HTTP_ATOM(Accept_Encoding, "Accept-Encoding") HTTP_ATOM(Accept_Language, "Accept-Language") HTTP_ATOM(Accept_Ranges, "Accept-Ranges") HTTP_ATOM(Age, "Age") HTTP_ATOM(Allow, "Allow") -HTTP_ATOM(Alternate_Service, "Alt-Svc") -HTTP_ATOM(Alternate_Service_Used, "Alt-Svc-Used") HTTP_ATOM(Assoc_Req, "Assoc-Req") HTTP_ATOM(Authentication, "Authentication") HTTP_ATOM(Authorization, "Authorization") HTTP_ATOM(Cache_Control, "Cache-Control") HTTP_ATOM(Connection, "Connection") HTTP_ATOM(Content_Disposition, "Content-Disposition") HTTP_ATOM(Content_Encoding, "Content-Encoding") HTTP_ATOM(Content_Language, "Content-Language")
--- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -60,17 +60,16 @@ #include "nsISocketTransport.h" #include "nsIStreamConverterService.h" #include "nsISiteSecurityService.h" #include "nsCRT.h" #include "nsPIDOMWindow.h" #include "nsPerformance.h" #include "CacheObserver.h" #include "mozilla/Telemetry.h" -#include "AlternateServices.h" namespace mozilla { namespace net { namespace { // True if the local cache should be bypassed when processing a request. #define BYPASS_LOCAL_CACHE(loadFlags) \ (loadFlags & (nsIRequest::LOAD_BYPASS_CACHE | \ @@ -274,21 +273,21 @@ nsHttpChannel::Connect() nsresult rv; LOG(("nsHttpChannel::Connect [this=%p]\n", this)); // Even if we're in private browsing mode, we still enforce existing STS // data (it is read-only). // if the connection is not using SSL and either the exact host matches or // a superdomain wants to force HTTPS, do it. - bool isHttps = false; - rv = mURI->SchemeIs("https", &isHttps); + bool usingSSL = false; + rv = mURI->SchemeIs("https", &usingSSL); NS_ENSURE_SUCCESS(rv,rv); - if (mAllowSTS && !isHttps) { + if (mAllowSTS && !usingSSL) { // enforce Strict-Transport-Security nsISiteSecurityService* sss = gHttpHandler->GetSSService(); NS_ENSURE_TRUE(sss, NS_ERROR_OUT_OF_MEMORY); bool isStsHost = false; uint32_t flags = mPrivateBrowsing ? nsISocketProvider::NO_PERMANENT_STORAGE : 0; rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, mURI, flags, &isStsHost); @@ -322,17 +321,17 @@ nsHttpChannel::Connect() return NS_ERROR_DOCUMENT_NOT_CACHED; } if (!gHttpHandler->UseCache()) { return ContinueConnect(); } // open a cache entry for this channel... - rv = OpenCacheEntry(isHttps); + rv = OpenCacheEntry(usingSSL); // do not continue if asyncOpenCacheEntry is in progress if (mCacheEntriesToWaitFor) { MOZ_ASSERT(NS_SUCCEEDED(rv), "Unexpected state"); return NS_OK; } if (NS_FAILED(rv)) { @@ -1226,137 +1225,16 @@ nsHttpChannel::ProcessSSLInformation() expireTime); LOG(("nsHttpChannel::ProcessSSLInformation [this=%p] " "falsestart-rsa permission granted for this host\n", this)); } else { permMgr->RemoveFromPrincipal(principal, "falsestart-rsa"); } } -void -nsHttpChannel::ProcessAltService() -{ - // e.g. Alt-Svc: h2=":443"; ma=60 - // e.g. Alt-Svc: h2="otherhost:443" - // Alt-Svc = 1#( alternative *( OWS ";" OWS parameter ) ) - // alternative = protocol-id "=" alt-authority - // protocol-id = token ; percent-encoded ALPN protocol identifier - // alt-authority = quoted-string ; containing [ uri-host ] ":" port - - if (!gHttpHandler->AllowAltSvc()) { - return; - } - - nsAutoCString scheme; - mURI->GetScheme(scheme); - bool isHttp = scheme.Equals(NS_LITERAL_CSTRING("http")); - if (!isHttp && !scheme.Equals(NS_LITERAL_CSTRING("https"))) { - return; - } - - if (isHttp && !gHttpHandler->AllowAltSvcOE()) { - return; - } - - const char *altSvc; - if (!(altSvc = mResponseHead->PeekHeader(nsHttp::Alternate_Service))) { - return; - } - - LOG(("nsHttpChannel %p Alt-Svc Response Header %s\n", this, altSvc)); - - nsCString buf(altSvc); - if (!nsHttp::IsReasonableHeaderValue(buf)) { - LOG(("Alt-Svc Response Header seems unreasonable - skipping\n")); - return; - } - - ParsedHeaderValueListList parsedAltSvc(buf); - nsRefPtr<AltSvcMapping> mapping; - - nsAutoCString originHost; - int32_t originPort = 80; - mURI->GetPort(&originPort); - if (NS_FAILED(mURI->GetHost(originHost))) { - return; - } - uint32_t now = NowInSeconds(), currentAge = 0; - mResponseHead->ComputeCurrentAge(now, mRequestTime, ¤tAge); - - for (uint32_t index = 0; index < parsedAltSvc.mValues.Length(); ++index) { - uint32_t maxage = 86400; // default - nsAutoCString hostname; // Always empty in the header form - nsAutoCString npnToken; - int32_t portno = originPort; - - for (uint32_t pairIndex = 0; - pairIndex < parsedAltSvc.mValues[index].mValues.Length(); - ++pairIndex) { - nsDependentCSubstring ¤tName = - parsedAltSvc.mValues[index].mValues[pairIndex].mName; - nsDependentCSubstring ¤tValue = - parsedAltSvc.mValues[index].mValues[pairIndex].mValue; - - if (!pairIndex) { - // h2=:443 - npnToken = currentName; - int32_t colonIndex = currentValue.FindChar(':'); - if (colonIndex >= 0) { - portno = - atoi(PromiseFlatCString(currentValue).get() + colonIndex + 1); - } else { - colonIndex = 0; - } - hostname.Assign(currentValue.BeginReading(), colonIndex); - } else if (currentName.Equals(NS_LITERAL_CSTRING("ma"))) { - maxage = atoi(PromiseFlatCString(currentValue).get()); - break; - } - } - - // unescape modifies a c string in place, so afterwards - // update nsCString length - nsUnescape(npnToken.BeginWriting()); - npnToken.SetLength(strlen(npnToken.BeginReading())); - - uint32_t spdyIndex; - SpdyInformation *spdyInfo = gHttpHandler->SpdyInfo(); - if (!(NS_SUCCEEDED(spdyInfo->GetNPNIndex(npnToken, &spdyIndex)) && - spdyInfo->ProtocolEnabled(spdyIndex))) { - LOG(("Alt Svc %p unknown protocol %s, ignoring", this, npnToken.get())); - continue; - } - - mapping = new AltSvcMapping(scheme, - originHost, originPort, - mUsername, mPrivateBrowsing, - NowInSeconds() + maxage, - hostname, portno, npnToken); - if (!mapping) { - continue; - } - - nsCOMPtr<nsIInterfaceRequestor> callbacks; - NS_NewNotificationCallbacksAggregation(mCallbacks, mLoadGroup, - getter_AddRefs(callbacks)); - if (!callbacks) { - return; - } - - nsCOMPtr<nsProxyInfo> proxyInfo; - if (mProxyInfo) { - proxyInfo = do_QueryInterface(mProxyInfo); - } - - gHttpHandler-> - UpdateAltServiceMapping(mapping, proxyInfo, callbacks, - mCaps & (NS_HTTP_ALLOW_RSA_FALSESTART | NS_HTTP_DISALLOW_SPDY)); - } -} - nsresult nsHttpChannel::ProcessResponse() { nsresult rv; uint32_t httpStatus = mResponseHead->Status(); // Gather data on whether the transaction and page (if this is // the initial page load) is being loaded with SSL. @@ -1401,20 +1279,16 @@ nsHttpChannel::ProcessResponse() // reset the authentication's current continuation state because our // last authentication attempt has been completed successfully mAuthProvider->Disconnect(NS_ERROR_ABORT); mAuthProvider = nullptr; LOG((" continuation state has been reset")); } - if (httpStatus < 500) { - ProcessAltService(); - } - bool successfulReval = false; // handle different server response categories. Note that we handle // caching or not caching of error pages in // nsHttpResponseHead::MustValidate; if you change this switch, update that // one switch (httpStatus) { case 200: @@ -2634,17 +2508,17 @@ IsSubRangeRequest(nsHttpRequestHead &aRe if (!aRequestHead.PeekHeader(nsHttp::Range)) return false; nsAutoCString byteRange; aRequestHead.GetHeader(nsHttp::Range, byteRange); return !byteRange.EqualsLiteral("bytes=0-"); } nsresult -nsHttpChannel::OpenCacheEntry(bool isHttps) +nsHttpChannel::OpenCacheEntry(bool usingSSL) { MOZ_EVENT_TRACER_EXEC(this, "net::http::OpenCacheEntry"); // Handle correctly mCacheEntriesToWaitFor AutoCacheWaitFlags waitFlags(this); // Drop this flag here mConcurentCacheAccess = 0; @@ -2961,18 +2835,18 @@ nsHttpChannel::OnCacheEntryCheck(nsICach // also set. MOZ_ASSERT(mLoadFlags & LOAD_ONLY_IF_MODIFIED); } else { return rv; } } } - bool isHttps = false; - rv = mURI->SchemeIs("https", &isHttps); + bool usingSSL = false; + rv = mURI->SchemeIs("https", &usingSSL); NS_ENSURE_SUCCESS(rv,rv); bool doValidation = false; bool canAddImsHeader = true; bool isForcedValid = false; entry->GetIsForcedValid(&isForcedValid); @@ -3001,17 +2875,17 @@ nsHttpChannel::OnCacheEntryCheck(nsICach } // Even if the VALIDATE_NEVER flag is set, there are still some cases in // which we must validate the cached response with the server. else if (mLoadFlags & nsIRequest::VALIDATE_NEVER) { LOG(("VALIDATE_NEVER set\n")); // if no-store or if no-cache and ssl, validate cached response (see // bug 112564 for an explanation of this logic) if (mCachedResponseHead->NoStore() || - (mCachedResponseHead->NoCache() && isHttps)) { + (mCachedResponseHead->NoCache() && usingSSL)) { LOG(("Validating based on (no-store || (no-cache && ssl)) logic\n")); doValidation = true; } else { LOG(("NOT validating based on VALIDATE_NEVER load flag\n")); doValidation = false; } } @@ -3556,21 +3430,21 @@ nsHttpChannel::ShouldUpdateOfflineCacheE } nsresult nsHttpChannel::OpenCacheInputStream(nsICacheEntry* cacheEntry, bool startBuffering, bool checkingAppCacheEntry) { nsresult rv; - bool isHttps = false; - rv = mURI->SchemeIs("https", &isHttps); + bool usingSSL = false; + rv = mURI->SchemeIs("https", &usingSSL); NS_ENSURE_SUCCESS(rv,rv); - if (isHttps) { + if (usingSSL) { rv = cacheEntry->GetSecurityInfo( getter_AddRefs(mCachedSecurityInfo)); if (NS_FAILED(rv)) { LOG(("failed to parse security-info [channel=%p, entry=%p]", this, cacheEntry)); NS_WARNING("failed to parse security-info"); return rv; } @@ -3914,21 +3788,19 @@ void nsHttpChannel::UpdateInhibitPersistentCachingFlag() { // The no-store directive within the 'Cache-Control:' header indicates // that we must not store the response in a persistent cache. if (mResponseHead->NoStore()) mLoadFlags |= INHIBIT_PERSISTENT_CACHING; // Only cache SSL content on disk if the pref is set - bool isHttps; if (!gHttpHandler->IsPersistentHttpsCachingEnabled() && - NS_SUCCEEDED(mURI->SchemeIs("https", &isHttps)) && isHttps) { + mConnectionInfo->EndToEndSSL()) mLoadFlags |= INHIBIT_PERSISTENT_CACHING; - } } nsresult nsHttpChannel::InitOfflineCacheEntry() { // This function can be called even when we fail to connect (bug 551990) if (!mOfflineCacheEntry) { @@ -4689,85 +4561,44 @@ nsHttpChannel::AsyncOpen(nsIStreamListen nsresult nsHttpChannel::BeginConnect() { LOG(("nsHttpChannel::BeginConnect [this=%p]\n", this)); nsresult rv; // Construct connection info object nsAutoCString host; - nsAutoCString scheme; int32_t port = -1; - bool isHttps = false; - - rv = mURI->GetScheme(scheme); - if (NS_SUCCEEDED(rv)) - rv = mURI->SchemeIs("https", &isHttps); + nsAutoCString username; + bool usingSSL = false; + + rv = mURI->SchemeIs("https", &usingSSL); if (NS_SUCCEEDED(rv)) rv = mURI->GetAsciiHost(host); if (NS_SUCCEEDED(rv)) rv = mURI->GetPort(&port); if (NS_SUCCEEDED(rv)) - mURI->GetUsername(mUsername); + mURI->GetUsername(username); if (NS_SUCCEEDED(rv)) rv = mURI->GetAsciiSpec(mSpec); if (NS_FAILED(rv)) return rv; // Reject the URL if it doesn't specify a host if (host.IsEmpty()) return NS_ERROR_MALFORMED_URI; LOG(("host=%s port=%d\n", host.get(), port)); LOG(("uri=%s\n", mSpec.get())); nsCOMPtr<nsProxyInfo> proxyInfo; if (mProxyInfo) proxyInfo = do_QueryInterface(mProxyInfo); - mRequestHead.SetHTTPS(isHttps); - mRequestHead.SetOrigin(scheme, host, port); - - nsRefPtr<AltSvcMapping> mapping; - if ((scheme.Equals(NS_LITERAL_CSTRING("http")) || - scheme.Equals(NS_LITERAL_CSTRING("https"))) && - (mapping = gHttpHandler->GetAltServiceMapping(scheme, - host, port, - mPrivateBrowsing))) { - LOG(("nsHttpChannel %p Alt Service Mapping Found %s://%s:%d\n", this, - scheme.get(), mapping->AlternateHost().get(), - mapping->AlternatePort())); - mRequestHead.SetHeader(nsHttp::Alternate_Service_Used, NS_LITERAL_CSTRING("1")); - - nsCOMPtr<nsIConsoleService> consoleService = - do_GetService(NS_CONSOLESERVICE_CONTRACTID); - if (consoleService) { - nsAutoString message(NS_LITERAL_STRING("Alternate Service Mapping found: ")); - AppendASCIItoUTF16(scheme.get(), message); - message.Append(NS_LITERAL_STRING("://")); - AppendASCIItoUTF16(host.get(), message); - message.Append(NS_LITERAL_STRING(":")); - message.AppendInt(port); - message.Append(NS_LITERAL_STRING(" to ")); - AppendASCIItoUTF16(scheme.get(), message); - message.Append(NS_LITERAL_STRING("://")); - AppendASCIItoUTF16(mapping->AlternateHost().get(), message); - message.Append(NS_LITERAL_STRING(":")); - message.AppendInt(mapping->AlternatePort()); - consoleService->LogStringMessage(message.get()); - } - - LOG(("nsHttpChannel %p Using connection info from altsvc mapping", this)); - mapping->GetConnectionInfo(getter_AddRefs(mConnectionInfo), proxyInfo); - Telemetry::Accumulate(Telemetry::HTTP_TRANSACTION_USE_ALTSVC, true); - Telemetry::Accumulate(Telemetry::HTTP_TRANSACTION_USE_ALTSVC_OE, !isHttps); - } else { - LOG(("nsHttpChannel %p Using default connection info", this)); - mConnectionInfo = new nsHttpConnectionInfo(host, port, EmptyCString(), mUsername, proxyInfo, isHttps); - Telemetry::Accumulate(Telemetry::HTTP_TRANSACTION_USE_ALTSVC, false); - } + mConnectionInfo = new nsHttpConnectionInfo(host, port, username, proxyInfo, usingSSL); + mRequestHead.SetHTTPS(usingSSL); mAuthProvider = do_CreateInstance("@mozilla.org/network/http-channel-auth-provider;1", &rv); if (NS_SUCCEEDED(rv)) rv = mAuthProvider->Init(this); if (NS_FAILED(rv)) return rv; @@ -5032,20 +4863,18 @@ nsHttpChannel::GetResponseEnd(TimeStamp* //----------------------------------------------------------------------------- // nsHttpChannel::nsIHttpAuthenticableChannel //----------------------------------------------------------------------------- NS_IMETHODIMP nsHttpChannel::GetIsSSL(bool *aIsSSL) { - // this attribute is really misnamed - it wants to know if - // https:// is being used. SSL might be used to cover http:// - // in some circumstances (proxies, http/2, etc..) - return mURI->SchemeIs("https", aIsSSL); + *aIsSSL = mConnectionInfo->EndToEndSSL(); + return NS_OK; } NS_IMETHODIMP nsHttpChannel::GetProxyMethodIsConnect(bool *aProxyMethodIsConnect) { *aProxyMethodIsConnect = mConnectionInfo->UsingConnect(); return NS_OK; }
--- a/netwerk/protocol/http/nsHttpChannel.h +++ b/netwerk/protocol/http/nsHttpChannel.h @@ -200,17 +200,16 @@ private: void SpeculativeConnect(); nsresult SetupTransaction(); void SetupTransactionLoadGroupInfo(); nsresult CallOnStartRequest(); nsresult ProcessResponse(); nsresult ContinueProcessResponse(nsresult); nsresult ProcessNormal(); nsresult ContinueProcessNormal(nsresult); - void ProcessAltService(); nsresult ProcessNotModified(); nsresult AsyncProcessRedirection(uint32_t httpStatus); nsresult ContinueProcessRedirection(nsresult); nsresult ContinueProcessRedirectionAfterFallback(nsresult); nsresult ProcessFailedProxyConnect(uint32_t httpStatus); nsresult ProcessFallback(bool *waitingForRedirectCallback); nsresult ContinueProcessFallback(nsresult); void HandleAsyncAbort(); @@ -423,18 +422,16 @@ private: // Needed for accurate DNS timing nsRefPtr<nsDNSPrefetch> mDNSPrefetch; nsresult WaitForRedirectCallback(); void PushRedirectAsyncFunc(nsContinueRedirectionFunc func); void PopRedirectAsyncFunc(nsContinueRedirectionFunc func); - nsCString mUsername; - protected: virtual void DoNotifyListenerCleanup(); nsPerformance* GetPerformance(); private: // cache telemetry bool mDidReval; };
--- a/netwerk/protocol/http/nsHttpConnection.cpp +++ b/netwerk/protocol/http/nsHttpConnection.cpp @@ -478,58 +478,35 @@ nsHttpConnection::SetupSSL() // offer list for both NPN and ALPN. ALPN validation callbacks are made // now before the handshake is complete, and NPN validation callbacks // are made during the handshake. nsresult nsHttpConnection::SetupNPNList(nsISSLSocketControl *ssl, uint32_t caps) { nsTArray<nsCString> protocolArray; - nsCString npnToken = mConnInfo->GetNPNToken(); - if (npnToken.IsEmpty()) { - // The first protocol is used as the fallback if none of the - // protocols supported overlap with the server's list. - // When using ALPN the advertised preferences are protocolArray indicies - // {1, .., N, 0} in decreasing order. - // For NPN, In the case of overlap, matching priority is driven by - // the order of the server's advertisement - with index 0 used when - // there is no match. - protocolArray.AppendElement(NS_LITERAL_CSTRING("http/1.1")); + // The first protocol is used as the fallback if none of the + // protocols supported overlap with the server's list. + // When using ALPN the advertised preferences are protocolArray indicies + // {1, .., N, 0} in decreasing order. + // For NPN, In the case of overlap, matching priority is driven by + // the order of the server's advertisement - with index 0 used when + // there is no match. + protocolArray.AppendElement(NS_LITERAL_CSTRING("http/1.1")); - if (gHttpHandler->IsSpdyEnabled() && - !(caps & NS_HTTP_DISALLOW_SPDY)) { - LOG(("nsHttpConnection::SetupSSL Allow SPDY NPN selection")); - const SpdyInformation *info = gHttpHandler->SpdyInfo(); - for (uint32_t index = SpdyInformation::kCount; index > 0; --index) { - if (info->ProtocolEnabled(index - 1) && - info->ALPNCallbacks[index - 1](ssl)) { - protocolArray.AppendElement(info->VersionString[index - 1]); - } + if (gHttpHandler->IsSpdyEnabled() && + !(caps & NS_HTTP_DISALLOW_SPDY)) { + LOG(("nsHttpConnection::SetupSSL Allow SPDY NPN selection")); + const SpdyInformation *info = gHttpHandler->SpdyInfo(); + for (uint32_t index = SpdyInformation::kCount; index > 0; --index) { + if (info->ProtocolEnabled(index - 1) && + info->ALPNCallbacks[index - 1](ssl)) { + protocolArray.AppendElement(info->VersionString[index - 1]); } } - } else { - LOG(("nsHttpConnection::SetupSSL limiting NPN selection to %s", - npnToken.get())); - protocolArray.AppendElement(npnToken); - } - - nsCString authHost = mConnInfo->GetAuthenticationHost(); - int32_t authPort = mConnInfo->GetAuthenticationPort(); - - if (!authHost.IsEmpty()) { - ssl->SetAuthenticationName(authHost); - ssl->SetAuthenticationPort(authPort); - } - - if (mConnInfo->GetRelaxed()) { // http:// over tls - if (authHost.IsEmpty() || authHost.Equals(mConnInfo->GetHost())) { - LOG(("nsHttpConnection::SetupSSL %p TLS-Relaxed " - "with Same Host Auth Bypass", this)); - ssl->SetBypassAuthentication(true); - } } nsresult rv = ssl->SetNPNList(protocolArray); LOG(("nsHttpConnection::SetupNPNList %p %x\n",this, rv)); return rv; } nsresult @@ -549,24 +526,16 @@ nsHttpConnection::AddTransaction(nsAHttp bool needTunnel = transCI->UsingHttpsProxy(); needTunnel = needTunnel && !mTLSFilter; needTunnel = needTunnel && transCI->UsingConnect(); needTunnel = needTunnel && httpTransaction->QueryHttpTransaction(); LOG(("nsHttpConnection::AddTransaction for SPDY%s", needTunnel ? " over tunnel" : "")); - // do a runtime check here just for defense in depth - if (transCI->GetRelaxed() && - httpTransaction->RequestHead() && httpTransaction->RequestHead()->IsHTTPS()) { - LOG(("This Cannot happen - https on relaxed tls stream\n")); - MOZ_ASSERT(false, "https:// on tls relaxed"); - return NS_ERROR_FAILURE; - } - if (!mSpdySession->AddStream(httpTransaction, priority, needTunnel, mCallbacks)) { MOZ_ASSERT(false); // this cannot happen! httpTransaction->Close(NS_ERROR_ABORT); return NS_ERROR_FAILURE; } ResumeSend(); @@ -1433,22 +1402,16 @@ nsHttpConnection::EndIdleMonitoring() if (mIdleMonitoring) { LOG(("Leaving Idle Monitoring Mode [this=%p]", this)); mIdleMonitoring = false; if (mSocketIn) mSocketIn->AsyncWait(nullptr, 0, 0, nullptr); } } -uint32_t -nsHttpConnection::Version() -{ - return mUsingSpdyVersion ? mUsingSpdyVersion : mLastHttpResponseVersion; -} - //----------------------------------------------------------------------------- // nsHttpConnection <private> //----------------------------------------------------------------------------- void nsHttpConnection::CloseTransaction(nsAHttpTransaction *trans, nsresult reason) { LOG(("nsHttpConnection::CloseTransaction[this=%p trans=%p reason=%x]\n",
--- a/netwerk/protocol/http/nsHttpConnection.h +++ b/netwerk/protocol/http/nsHttpConnection.h @@ -206,18 +206,16 @@ public: void CheckForTraffic(bool check); // NoTraffic() returns true if there's been no traffic on the (non-spdy) // connection since CheckForTraffic() was called. bool NoTraffic() { return mTrafficStamp && (mTrafficCount == (mTotalBytesWritten + mTotalBytesRead)); } - // override of nsAHttpConnection - virtual uint32_t Version(); private: // Value (set in mTCPKeepaliveConfig) indicates which set of prefs to use. enum TCPKeepaliveConfig { kTCPKeepaliveDisabled = 0, kTCPKeepaliveShortLivedConfig, kTCPKeepaliveLongLivedConfig };
--- a/netwerk/protocol/http/nsHttpConnectionInfo.cpp +++ b/netwerk/protocol/http/nsHttpConnectionInfo.cpp @@ -15,59 +15,26 @@ #include "nsHttpConnectionInfo.h" #include "mozilla/net/DNS.h" #include "prnetdb.h" namespace mozilla { namespace net { -nsHttpConnectionInfo::nsHttpConnectionInfo(const nsACString &physicalHost, - int32_t physicalPort, - const nsACString &npnToken, +nsHttpConnectionInfo::nsHttpConnectionInfo(const nsACString &host, int32_t port, const nsACString &username, - nsProxyInfo *proxyInfo, + nsProxyInfo* proxyInfo, bool endToEndSSL) - : mAuthenticationPort(443) -{ - Init(physicalHost, physicalPort, npnToken, username, proxyInfo, endToEndSSL); -} - -nsHttpConnectionInfo::nsHttpConnectionInfo(const nsACString &physicalHost, - int32_t physicalPort, - const nsACString &npnToken, - const nsACString &username, - nsProxyInfo *proxyInfo, - const nsACString &logicalHost, - int32_t logicalPort) - + : mUsername(username) + , mProxyInfo(proxyInfo) + , mEndToEndSSL(endToEndSSL) + , mUsingConnect(false) { - mEndToEndSSL = true; // so DefaultPort() works - mAuthenticationPort = logicalPort == -1 ? DefaultPort() : logicalPort; - - if (!physicalHost.Equals(logicalHost) || (physicalPort != logicalPort)) { - mAuthenticationHost = logicalHost; - } - Init(physicalHost, physicalPort, npnToken, username, proxyInfo, true); -} - -void -nsHttpConnectionInfo::Init(const nsACString &host, int32_t port, - const nsACString &npnToken, - const nsACString &username, - nsProxyInfo* proxyInfo, - bool e2eSSL) -{ - LOG(("Init nsHttpConnectionInfo @%p\n", this)); - - mUsername = username; - mProxyInfo = proxyInfo; - mEndToEndSSL = e2eSSL; - mUsingConnect = false; - mNPNToken = npnToken; + LOG(("Creating nsHttpConnectionInfo @%x\n", this)); 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)) && @@ -106,19 +73,18 @@ nsHttpConnectionInfo::SetOriginServer(co keyPort = Port(); } // The hashkey has 4 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 R/. R is for 'relaxed' unauthed TLS for http:// uris + mHashKey.AssignLiteral("...."); - mHashKey.AssignLiteral("....."); mHashKey.Append(keyHost); mHashKey.Append(':'); mHashKey.AppendInt(keyPort); if (!mUsername.IsEmpty()) { mHashKey.Append('['); mHashKey.Append(mUsername); mHashKey.Append(']'); } @@ -147,86 +113,44 @@ nsHttpConnectionInfo::SetOriginServer(co mHashKey.AppendLiteral(" ("); mHashKey.Append(ProxyType()); mHashKey.Append(':'); mHashKey.Append(ProxyHost()); mHashKey.Append(':'); mHashKey.AppendInt(ProxyPort()); mHashKey.Append(')'); } - - if(!mAuthenticationHost.IsEmpty()) { - mHashKey.AppendLiteral(" <TLS-LOGIC "); - mHashKey.Append(mAuthenticationHost); - mHashKey.Append(':'); - mHashKey.AppendInt(mAuthenticationPort); - mHashKey.Append('>'); - } - - if (!mNPNToken.IsEmpty()) { - mHashKey.AppendLiteral(" {NPN-TOKEN "); - mHashKey.Append(mNPNToken); - mHashKey.AppendLiteral("}"); - } } nsHttpConnectionInfo* nsHttpConnectionInfo::Clone() const { - nsHttpConnectionInfo *clone; - if (mAuthenticationHost.IsEmpty()) { - clone = new nsHttpConnectionInfo(mHost, mPort, mNPNToken, mUsername, mProxyInfo, mEndToEndSSL); - } else { - MOZ_ASSERT(mEndToEndSSL); - clone = new nsHttpConnectionInfo(mHost, mPort, mNPNToken, mUsername, mProxyInfo, - mAuthenticationHost, - mAuthenticationPort); - } + nsHttpConnectionInfo* clone = new nsHttpConnectionInfo(mHost, mPort, mUsername, mProxyInfo, mEndToEndSSL); - // Make sure the anonymous, relaxed, and private flags are transferred + // Make sure the anonymous and private flags are transferred! clone->SetAnonymous(GetAnonymous()); clone->SetPrivate(GetPrivate()); - clone->SetRelaxed(GetRelaxed()); MOZ_ASSERT(clone->Equals(this)); - return clone; } -void -nsHttpConnectionInfo::CloneAsDirectRoute(nsHttpConnectionInfo **outCI) -{ - if (mAuthenticationHost.IsEmpty()) { - *outCI = Clone(); - return; - } - - nsRefPtr<nsHttpConnectionInfo> clone = - new nsHttpConnectionInfo(mAuthenticationHost, mAuthenticationPort, - EmptyCString(), mUsername, mProxyInfo, mEndToEndSSL); - // Make sure the anonymous, relaxed, and private flags are transferred - clone->SetAnonymous(GetAnonymous()); - clone->SetPrivate(GetPrivate()); - clone->SetRelaxed(GetRelaxed()); - 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; } nsRefPtr<nsHttpConnectionInfo> clone; clone = new nsHttpConnectionInfo(NS_LITERAL_CSTRING("*"), 0, - mNPNToken, mUsername, mProxyInfo, true); + mUsername, mProxyInfo, true); // Make sure the anonymous and private flags are transferred! clone->SetAnonymous(GetAnonymous()); clone->SetPrivate(GetPrivate()); clone.forget(outParam); return NS_OK; } bool
--- a/netwerk/protocol/http/nsHttpConnectionInfo.h +++ b/netwerk/protocol/http/nsHttpConnectionInfo.h @@ -27,48 +27,39 @@ extern PRLogModuleInfo *gHttpLog; // and multiplex non tunneled transactions at the same time, so they have a // special wildcard CI that accepts all origins through that proxy. namespace mozilla { namespace net { class nsHttpConnectionInfo { public: - nsHttpConnectionInfo(const nsACString &physicalHost, - int32_t physicalPort, - const nsACString &npnToken, + nsHttpConnectionInfo(const nsACString &host, int32_t port, const nsACString &username, - nsProxyInfo *proxyInfo, + nsProxyInfo* proxyInfo, bool endToEndSSL = false); - // this version must use TLS and you may supply the domain - // information to be validated - nsHttpConnectionInfo(const nsACString &physicalHost, - int32_t physicalPort, - const nsACString &npnToken, - const nsACString &username, - nsProxyInfo *proxyInfo, - const nsACString &logicalHost, - int32_t logicalPort); - private: virtual ~nsHttpConnectionInfo() { PR_LOG(gHttpLog, 4, ("Destroying nsHttpConnectionInfo @%x\n", this)); } public: const nsAFlatCString &HashKey() const { return mHashKey; } - const nsCString &GetAuthenticationHost() const { return mAuthenticationHost; } - int32_t GetAuthenticationPort() const { return mAuthenticationPort; } + void SetOriginServer(const nsACString &host, int32_t port); + + void SetOriginServer(const char *host, int32_t port) + { + SetOriginServer(nsDependentCString(host), port); + } // OK to treat these as an infalible allocation nsHttpConnectionInfo* Clone() const; - void CloneAsDirectRoute(nsHttpConnectionInfo **outParam); nsresult CreateWildCard(nsHttpConnectionInfo **outParam); const char *ProxyHost() const { return mProxyInfo ? mProxyInfo->Host().get() : nullptr; } int32_t ProxyPort() const { return mProxyInfo ? mProxyInfo->Port() : -1; } const char *ProxyType() const { return mProxyInfo ? mProxyInfo->Type() : nullptr; } // Compare this connection info to another... // Two connections are 'equal' if they end up talking the same @@ -87,22 +78,18 @@ public: const char *Username() const { return mUsername.get(); } nsProxyInfo *ProxyInfo() { return mProxyInfo; } int32_t DefaultPort() const { return mEndToEndSSL ? NS_HTTPS_DEFAULT_PORT : NS_HTTP_DEFAULT_PORT; } void SetAnonymous(bool anon) { mHashKey.SetCharAt(anon ? 'A' : '.', 2); } bool GetAnonymous() const { return mHashKey.CharAt(2) == 'A'; } void SetPrivate(bool priv) { mHashKey.SetCharAt(priv ? 'P' : '.', 3); } bool GetPrivate() const { return mHashKey.CharAt(3) == 'P'; } - void SetRelaxed(bool relaxed) - { mHashKey.SetCharAt(relaxed ? 'R' : '.', 4); } - bool GetRelaxed() const { return mHashKey.CharAt(4) == 'R'; } const nsCString &GetHost() { return mHost; } - const nsCString &GetNPNToken() { return mNPNToken; } // Returns true for any kind of proxy (http, socks, https, etc..) bool UsingProxy(); // Returns true when proxying over HTTP or HTTPS bool UsingHttpProxy() const { return mUsingHttpProxy || mUsingHttpsProxy; } // Returns true when proxying over HTTPS @@ -116,36 +103,25 @@ public: // Returns true when CONNECT is used to tunnel through the proxy (e.g. https:// or ws://) bool UsingConnect() const { return mUsingConnect; } // Returns true when mHost is an RFC1918 literal. bool HostIsLocalIPLiteral() const; private: - void Init(const nsACString &host, - int32_t port, - const nsACString &npnToken, - const nsACString &username, - nsProxyInfo* proxyInfo, - bool EndToEndSSL); - void SetOriginServer(const nsACString &host, int32_t port); - nsCString mHashKey; nsCString mHost; int32_t mPort; nsCString mUsername; - nsCString mAuthenticationHost; - int32_t mAuthenticationPort; nsCOMPtr<nsProxyInfo> mProxyInfo; bool mUsingHttpProxy; bool mUsingHttpsProxy; bool mEndToEndSSL; bool mUsingConnect; // if will use CONNECT with http proxy - nsCString mNPNToken; // for nsRefPtr NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsHttpConnectionInfo) }; }} // namespace mozilla::net #endif // nsHttpConnectionInfo_h__
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp +++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp @@ -377,75 +377,65 @@ public: public: // intentional! nsRefPtr<NullHttpTransaction> mTrans; bool mOverridesOK; uint32_t mParallelSpeculativeConnectLimit; bool mIgnoreIdle; bool mIgnorePossibleSpdyConnections; bool mIsFromPredictor; - bool mAllow1918; // As above, added manually so we can use nsRefPtr without inheriting from // nsISupports protected: ThreadSafeAutoRefCnt mRefCnt; NS_DECL_OWNINGTHREAD }; NS_IMPL_ADDREF(SpeculativeConnectArgs) NS_IMPL_RELEASE(SpeculativeConnectArgs) nsresult nsHttpConnectionMgr::SpeculativeConnect(nsHttpConnectionInfo *ci, nsIInterfaceRequestor *callbacks, - uint32_t caps, - NullHttpTransaction *nullTransaction) + uint32_t caps) { MOZ_ASSERT(NS_IsMainThread(), "nsHttpConnectionMgr::SpeculativeConnect called off main thread!"); LOG(("nsHttpConnectionMgr::SpeculativeConnect [ci=%s]\n", ci->HashKey().get())); - nsCOMPtr<nsISpeculativeConnectionOverrider> overrider = - do_GetInterface(callbacks); - - bool allow1918 = false; - if (overrider) { - overrider->GetAllow1918(&allow1918); - } - // Hosts that are Local IP Literals should not be speculatively // connected - Bug 853423. - if ((!allow1918) && ci && ci->HostIsLocalIPLiteral()) { + if (ci && ci->HostIsLocalIPLiteral()) { LOG(("nsHttpConnectionMgr::SpeculativeConnect skipping RFC1918 " "address [%s]", ci->Host())); return NS_OK; } nsRefPtr<SpeculativeConnectArgs> args = new SpeculativeConnectArgs(); // Wrap up the callbacks and the target to ensure they're released on the target // thread properly. nsCOMPtr<nsIInterfaceRequestor> wrappedCallbacks; NS_NewInterfaceRequestorAggregation(callbacks, nullptr, getter_AddRefs(wrappedCallbacks)); caps |= ci->GetAnonymous() ? NS_HTTP_LOAD_ANONYMOUS : 0; - args->mTrans = - nullTransaction ? nullTransaction : new NullHttpTransaction(ci, wrappedCallbacks, caps); - + args->mTrans = new NullHttpTransaction(ci, wrappedCallbacks, caps); + + nsCOMPtr<nsISpeculativeConnectionOverrider> overrider = + do_GetInterface(callbacks); if (overrider) { args->mOverridesOK = true; overrider->GetParallelSpeculativeConnectLimit( &args->mParallelSpeculativeConnectLimit); overrider->GetIgnoreIdle(&args->mIgnoreIdle); overrider->GetIgnorePossibleSpdyConnections( &args->mIgnorePossibleSpdyConnections); overrider->GetIsFromPredictor(&args->mIsFromPredictor); - overrider->GetAllow1918(&args->mAllow1918); } nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgSpeculativeConnect, 0, args); if (NS_SUCCEEDED(rv)) unused << args.forget(); return rv; } @@ -1302,17 +1292,17 @@ nsHttpConnectionMgr::ReportFailedToProce if (NS_SUCCEEDED(rv)) uri->GetUsername(username); if (NS_FAILED(rv) || !isHttp || host.IsEmpty()) return; // report the event for all the permutations of anonymous and // private versions of this host nsRefPtr<nsHttpConnectionInfo> ci = - new nsHttpConnectionInfo(host, port, EmptyCString(), username, nullptr, usingSSL); + new nsHttpConnectionInfo(host, port, username, nullptr, usingSSL); ci->SetAnonymous(false); ci->SetPrivate(false); PipelineFeedbackInfo(ci, RedCorruptedContent, nullptr, 0); ci = ci->Clone(); ci->SetAnonymous(false); ci->SetPrivate(true); PipelineFeedbackInfo(ci, RedCorruptedContent, nullptr, 0); @@ -1515,17 +1505,17 @@ nsHttpConnectionMgr::MakeNewConnection(n if ((mNumIdleConns + mNumActiveConns + 1 >= mMaxConns) && mNumActiveConns && gHttpHandler->IsSpdyEnabled()) mCT.Enumerate(PurgeExcessSpdyConnectionsCB, this); if (AtActiveConnectionLimit(ent, trans->Caps())) return NS_ERROR_NOT_AVAILABLE; - nsresult rv = CreateTransport(ent, trans, trans->Caps(), false, false, true); + nsresult rv = CreateTransport(ent, trans, trans->Caps(), false); if (NS_FAILED(rv)) { /* hard failure */ LOG(("nsHttpConnectionMgr::MakeNewConnection [ci = %s trans = %p] " "CreateTransport() hard failure.\n", ent->mConnInfo->HashKey().get(), trans)); trans->Close(rv); if (rv == NS_ERROR_NOT_AVAILABLE) rv = NS_ERROR_FAILURE; @@ -2142,25 +2132,23 @@ nsHttpConnectionMgr::RecvdConnect() ConditionallyStopTimeoutTick(); } nsresult nsHttpConnectionMgr::CreateTransport(nsConnectionEntry *ent, nsAHttpTransaction *trans, uint32_t caps, bool speculative, - bool isFromPredictor, - bool allow1918) + bool isFromPredictor) { MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); nsRefPtr<nsHalfOpenSocket> sock = new nsHalfOpenSocket(ent, trans, caps); if (speculative) { sock->SetSpeculative(true); - sock->SetAllow1918(allow1918); Telemetry::AutoCounter<Telemetry::HTTPCONNMGR_TOTAL_SPECULATIVE_CONN> totalSpeculativeConn; ++totalSpeculativeConn; if (isFromPredictor) { sock->SetIsFromPredictor(true); Telemetry::AutoCounter<Telemetry::PREDICTOR_TOTAL_PRECONNECTS_CREATED> totalPreconnectsCreated; ++totalPreconnectsCreated; } @@ -2935,33 +2923,30 @@ nsHttpConnectionMgr::OnMsgSpeculativeCon if (preferredEntry) ent = preferredEntry; uint32_t parallelSpeculativeConnectLimit = gHttpHandler->ParallelSpeculativeConnectLimit(); bool ignorePossibleSpdyConnections = false; bool ignoreIdle = false; bool isFromPredictor = false; - bool allow1918 = false; if (args->mOverridesOK) { parallelSpeculativeConnectLimit = args->mParallelSpeculativeConnectLimit; ignorePossibleSpdyConnections = args->mIgnorePossibleSpdyConnections; ignoreIdle = args->mIgnoreIdle; isFromPredictor = args->mIsFromPredictor; - allow1918 = args->mAllow1918; } - bool keepAlive = args->mTrans->Caps() & NS_HTTP_ALLOW_KEEPALIVE; if (mNumHalfOpenConns < parallelSpeculativeConnectLimit && ((ignoreIdle && (ent->mIdleConns.Length() < parallelSpeculativeConnectLimit)) || !ent->mIdleConns.Length()) && - !(keepAlive && RestrictConnections(ent, ignorePossibleSpdyConnections)) && + !RestrictConnections(ent, ignorePossibleSpdyConnections) && !AtActiveConnectionLimit(ent, args->mTrans->Caps())) { - CreateTransport(ent, args->mTrans, args->mTrans->Caps(), true, isFromPredictor, allow1918); + CreateTransport(ent, args->mTrans, args->mTrans->Caps(), true, isFromPredictor); } else { LOG((" Transport not created due to existing connection count\n")); } } bool nsHttpConnectionMgr::nsConnectionHandle::IsPersistent() @@ -2985,32 +2970,32 @@ nsresult nsHttpConnectionMgr::nsConnectionHandle::PushBack(const char *buf, uint32_t bufLen) { return mConn->PushBack(buf, bufLen); } //////////////////////// nsHalfOpenSocket + NS_IMPL_ISUPPORTS(nsHttpConnectionMgr::nsHalfOpenSocket, nsIOutputStreamCallback, nsITransportEventSink, nsIInterfaceRequestor, nsITimerCallback) nsHttpConnectionMgr:: nsHalfOpenSocket::nsHalfOpenSocket(nsConnectionEntry *ent, nsAHttpTransaction *trans, uint32_t caps) : mEnt(ent) , mTransaction(trans) , mCaps(caps) , mSpeculative(false) , mIsFromPredictor(false) - , mAllow1918(true) , mHasConnected(false) , mPrimaryConnectedOK(false) , mBackupConnectedOK(false) { MOZ_ASSERT(ent && trans, "constructor with null arguments"); LOG(("Creating nsHalfOpenSocket [this=%p trans=%p ent=%s key=%s]\n", this, trans, ent->mConnInfo->Host(), ent->mConnInfo->HashKey().get())); } @@ -3076,17 +3061,17 @@ nsHalfOpenSocket::SetupStreams(nsISocket if (mEnt->mPreferIPv6) { tmpFlags |= nsISocketTransport::DISABLE_IPV4; } else if (mEnt->mPreferIPv4 || (isBackup && gHttpHandler->FastFallbackToIPv4())) { tmpFlags |= nsISocketTransport::DISABLE_IPV6; } - if (!Allow1918()) { + if (IsSpeculative()) { tmpFlags |= nsISocketTransport::DISABLE_RFC1918; } socketTransport->SetConnectionFlags(tmpFlags); socketTransport->SetQoSBits(gHttpHandler->GetQoSBits()); rv = socketTransport->SetEventSink(this, nullptr); @@ -3140,18 +3125,16 @@ nsHttpConnectionMgr::nsHalfOpenSocket::S mSocketTransport = nullptr; } return rv; } nsresult nsHttpConnectionMgr::nsHalfOpenSocket::SetupBackupStreams() { - MOZ_ASSERT(mTransaction && !mTransaction->IsNullTransaction()); - mBackupSynStarted = TimeStamp::Now(); nsresult rv = SetupStreams(getter_AddRefs(mBackupTransport), getter_AddRefs(mBackupStreamIn), getter_AddRefs(mBackupStreamOut), true); LOG(("nsHalfOpenSocket::SetupBackupStream [this=%p ent=%s rv=%x]", this, mEnt->mConnInfo->Host(), rv)); if (NS_FAILED(rv)) { @@ -3164,18 +3147,18 @@ nsHttpConnectionMgr::nsHalfOpenSocket::S return rv; } void nsHttpConnectionMgr::nsHalfOpenSocket::SetupBackupTimer() { uint16_t timeout = gHttpHandler->GetIdleSynTimeout(); MOZ_ASSERT(!mSynTimer, "timer already initd"); - if (timeout && !mTransaction->IsDone() && - !mTransaction->IsNullTransaction()) { + + if (timeout && !mTransaction->IsDone()) { // Setup the timer that will establish a backup socket // if we do not get a writable event on the main one. // We do this because a lost SYN takes a very long time // to repair at the TCP level. // // Failure to setup the timer is something we can live with, // so don't return an error in that case. nsresult rv; @@ -3351,17 +3334,18 @@ nsHalfOpenSocket::OnOutputStreamReady(ns index = mEnt->mPendingQ.IndexOf(mTransaction); if (index != -1) { MOZ_ASSERT(!mSpeculative, "Speculative Half Open found mTransaction"); nsRefPtr<nsHttpTransaction> temp = dont_AddRef(mEnt->mPendingQ[index]); mEnt->mPendingQ.RemoveElementAt(index); gHttpHandler->ConnMgr()->AddActiveConn(conn, mEnt); rv = gHttpHandler->ConnMgr()->DispatchTransaction(mEnt, temp, conn); - } else { + } + else { // this transaction was dispatched off the pending q before all the // sockets established themselves. // After about 1 second allow for the possibility of restarting a // transaction due to server close. Keep at sub 1 second as that is the // minimum granularity we can expect a server to be timing out with. conn->SetIsReusedAfter(950); @@ -3369,32 +3353,27 @@ nsHalfOpenSocket::OnOutputStreamReady(ns // then form a null transaction to drive the SSL handshake to // completion. Afterwards the connection will be 100% ready for the next // transaction to use it. Make an exception for SSL tunneled HTTP proxy as the // NullHttpTransaction does not know how to drive Connect if (mEnt->mConnInfo->FirstHopSSL() && !mEnt->mPendingQ.Length() && !mEnt->mConnInfo->UsingConnect()) { LOG(("nsHalfOpenSocket::OnOutputStreamReady null transaction will " "be used to finish SSL handshake on conn %p\n", conn.get())); - nsRefPtr<nsAHttpTransaction> trans; - if (mTransaction->IsNullTransaction()) { - // null transactions cannot be put in the entry queue, so that - // explains why it is not present. - trans = mTransaction; - } else { - trans = new NullHttpTransaction(mEnt->mConnInfo, - callbacks, - mCaps & ~NS_HTTP_ALLOW_PIPELINING); - } + nsRefPtr<NullHttpTransaction> trans = + new NullHttpTransaction(mEnt->mConnInfo, + callbacks, + mCaps & ~NS_HTTP_ALLOW_PIPELINING); gHttpHandler->ConnMgr()->AddActiveConn(conn, mEnt); conn->Classify(nsAHttpTransaction::CLASS_SOLO); rv = gHttpHandler->ConnMgr()-> DispatchAbstractTransaction(mEnt, trans, mCaps, conn, 0); - } else { + } + else { // otherwise just put this in the persistent connection pool LOG(("nsHalfOpenSocket::OnOutputStreamReady no transaction match " "returning conn %p to pool\n", conn.get())); nsRefPtr<nsHttpConnection> copy(conn); // forget() to effectively addref because onmsg*() will drop a ref gHttpHandler->ConnMgr()->OnMsgReclaimConnection( 0, conn.forget().take()); }
--- a/netwerk/protocol/http/nsHttpConnectionMgr.h +++ b/netwerk/protocol/http/nsHttpConnectionMgr.h @@ -11,33 +11,30 @@ #include "nsTArray.h" #include "nsThreadUtils.h" #include "nsClassHashtable.h" #include "nsDataHashtable.h" #include "nsAutoPtr.h" #include "mozilla/ReentrantMonitor.h" #include "mozilla/TimeStamp.h" #include "mozilla/Attributes.h" -#include "AlternateServices.h" #include "nsIObserver.h" #include "nsITimer.h" class nsIHttpUpgradeListener; namespace mozilla { namespace net { class EventTokenBucket; -class NullHttpTransaction; struct HttpRetParams; //----------------------------------------------------------------------------- class nsHttpConnectionMgr : public nsIObserver - , public AltSvcCache { public: NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSIOBSERVER // parameter names enum nsParamName { MAX_CONNECTIONS, @@ -113,18 +110,17 @@ public: // called to indicate a transaction for the connectionInfo is likely coming // soon. The connection manager may use this information to start a TCP // and/or SSL level handshake for that resource immediately so that it is // ready when the transaction is submitted. No obligation is taken on by the // connection manager, nor is the submitter obligated to actually submit a // real transaction for this connectionInfo. nsresult SpeculativeConnect(nsHttpConnectionInfo *, nsIInterfaceRequestor *, - uint32_t caps = 0, - NullHttpTransaction * = nullptr); + uint32_t caps = 0); // called when a connection is done processing a transaction. if the // connection can be reused then it will be added to the idle list, else // it will be closed. nsresult ReclaimConnection(nsHttpConnection *conn); // called by the main thread to execute the taketransport() logic on the // socket thread after a 101 response has been received and the socket @@ -464,19 +460,16 @@ private: nsAHttpTransaction *Transaction() { return mTransaction; } bool IsSpeculative() { return mSpeculative; } void SetSpeculative(bool val) { mSpeculative = val; } bool IsFromPredictor() { return mIsFromPredictor; } void SetIsFromPredictor(bool val) { mIsFromPredictor = val; } - bool Allow1918() { return mAllow1918; } - void SetAllow1918(bool val) { mAllow1918 = val; } - bool HasConnected() { return mHasConnected; } void PrintDiagnostics(nsCString &log); private: nsConnectionEntry *mEnt; nsRefPtr<nsAHttpTransaction> mTransaction; nsCOMPtr<nsISocketTransport> mSocketTransport; nsCOMPtr<nsIAsyncOutputStream> mStreamOut; @@ -492,18 +485,16 @@ private: // more connections that are needed.) bool mSpeculative; // mIsFromPredictor is set if the socket originated from the network // Predictor. It is used to gather telemetry data on used speculative // connections from the predictor. bool mIsFromPredictor; - bool mAllow1918; - TimeStamp mPrimarySynStarted; TimeStamp mBackupSynStarted; // for syn retry nsCOMPtr<nsITimer> mSynTimer; nsCOMPtr<nsISocketTransport> mBackupTransport; nsCOMPtr<nsIAsyncOutputStream> mBackupStreamOut; nsCOMPtr<nsIAsyncInputStream> mBackupStreamIn; @@ -566,17 +557,17 @@ private: nsAHttpTransaction *, nsHttpPipeline **); bool RestrictConnections(nsConnectionEntry *, bool = false); nsresult ProcessNewTransaction(nsHttpTransaction *); nsresult EnsureSocketThreadTarget(); void ClosePersistentConnections(nsConnectionEntry *ent); void ReportProxyTelemetry(nsConnectionEntry *ent); nsresult CreateTransport(nsConnectionEntry *, nsAHttpTransaction *, - uint32_t, bool, bool, bool); + uint32_t, bool, bool = false); void AddActiveConn(nsHttpConnection *, nsConnectionEntry *); void DecrementActiveConnCount(nsHttpConnection *); void StartedConnect(); void RecvdConnect(); nsConnectionEntry *GetOrCreateConnectionEntry(nsHttpConnectionInfo *, bool allowWildCard);
--- a/netwerk/protocol/http/nsHttpHandler.cpp +++ b/netwerk/protocol/http/nsHttpHandler.cpp @@ -185,18 +185,16 @@ nsHttpHandler::nsHttpHandler() , mSpdyV3(true) , mSpdyV31(true) , mHttp2DraftEnabled(true) , mHttp2Enabled(true) , mEnforceHttp2TlsProfile(true) , mCoalesceSpdy(true) , mSpdyPersistentSettings(false) , mAllowPush(true) - , mEnableAltSvc(true) - , mEnableAltSvcOE(true) , mSpdySendingChunkSize(ASpdySession::kSendingChunkSize) , mSpdySendBufferSize(ASpdySession::kTCPSendBufferSize) , mSpdyPushAllowance(32768) , mSpdyPingThreshold(PR_SecondsToInterval(58)) , mSpdyPingTimeout(PR_SecondsToInterval(8)) , mConnectTimeout(90000) , mParallelSpeculativeConnectLimit(6) , mRequestTokenBucketEnabled(true) @@ -1227,31 +1225,16 @@ nsHttpHandler::PrefsChanged(nsIPrefBranc if (PREF_CHANGED(HTTP_PREF("spdy.allow-push"))) { rv = prefs->GetBoolPref(HTTP_PREF("spdy.allow-push"), &cVar); if (NS_SUCCEEDED(rv)) mAllowPush = cVar; } - if (PREF_CHANGED(HTTP_PREF("altsvc.enabled"))) { - rv = prefs->GetBoolPref(HTTP_PREF("atsvc.enabled"), - &cVar); - if (NS_SUCCEEDED(rv)) - mEnableAltSvc = cVar; - } - - - if (PREF_CHANGED(HTTP_PREF("altsvc.oe"))) { - rv = prefs->GetBoolPref(HTTP_PREF("atsvc.oe"), - &cVar); - if (NS_SUCCEEDED(rv)) - mEnableAltSvcOE = cVar; - } - if (PREF_CHANGED(HTTP_PREF("spdy.push-allowance"))) { rv = prefs->GetIntPref(HTTP_PREF("spdy.push-allowance"), &val); if (NS_SUCCEEDED(rv)) { mSpdyPushAllowance = static_cast<uint32_t> (clamped(val, 1024, static_cast<int32_t>(ASpdySession::kInitialRwin))); } } @@ -1846,28 +1829,21 @@ nsHttpHandler::Observe(nsISupports *subj } } else if (!strcmp(topic, "net:failed-to-process-uri-content")) { nsCOMPtr<nsIURI> uri = do_QueryInterface(subject); if (uri && mConnMgr) { mConnMgr->ReportFailedToProcess(uri); } } else if (!strcmp(topic, "last-pb-context-exited")) { mPrivateAuthCache.ClearAll(); - if (mConnMgr) { - mConnMgr->ClearAltServiceMappings(); - } } else if (!strcmp(topic, "browser:purge-session-history")) { - if (mConnMgr) { - if (gSocketTransportService) { - nsCOMPtr<nsIRunnable> event = - NS_NewRunnableMethod(mConnMgr, - &nsHttpConnectionMgr::ClearConnectionHistory); - gSocketTransportService->Dispatch(event, NS_DISPATCH_NORMAL); - } - mConnMgr->ClearAltServiceMappings(); + if (mConnMgr && gSocketTransportService) { + nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(mConnMgr, + &nsHttpConnectionMgr::ClearConnectionHistory); + gSocketTransportService->Dispatch(event, NS_DISPATCH_NORMAL); } } else if (!strcmp(topic, NS_NETWORK_LINK_TOPIC)) { nsAutoCString converted = NS_ConvertUTF16toUTF8(data); if (!strcmp(converted.get(), NS_NETWORK_LINK_DATA_CHANGED)) { if (mConnMgr) { mConnMgr->PruneDeadConnections(); mConnMgr->VerifyTraffic(); } @@ -1936,17 +1912,17 @@ nsHttpHandler::SpeculativeConnect(nsIURI rv = aURI->GetPort(&port); if (NS_FAILED(rv)) return rv; nsAutoCString username; aURI->GetUsername(username); nsHttpConnectionInfo *ci = - new nsHttpConnectionInfo(host, port, EmptyCString(), username, nullptr, usingSSL); + new nsHttpConnectionInfo(host, port, username, nullptr, usingSSL); return SpeculativeConnect(ci, aCallbacks); } void nsHttpHandler::TickleWifi(nsIInterfaceRequestor *cb) { if (!cb || !mWifiTickler)
--- a/netwerk/protocol/http/nsHttpHandler.h +++ b/netwerk/protocol/http/nsHttpHandler.h @@ -32,17 +32,16 @@ class nsITimer; namespace mozilla { namespace net { class ATokenBucketEvent; class EventTokenBucket; class Tickler; class nsHttpConnection; class nsHttpConnectionInfo; class nsHttpTransaction; -class AltSvcMapping; //----------------------------------------------------------------------------- // nsHttpHandler - protocol handler for HTTP and HTTPS //----------------------------------------------------------------------------- class nsHttpHandler MOZ_FINAL : public nsIHttpProtocolHandler , public nsIObserver , public nsSupportsWeakReference @@ -104,18 +103,16 @@ public: bool CoalesceSpdy() { return mCoalesceSpdy; } bool UseSpdyPersistentSettings() { return mSpdyPersistentSettings; } uint32_t SpdySendingChunkSize() { return mSpdySendingChunkSize; } uint32_t SpdySendBufferSize() { return mSpdySendBufferSize; } uint32_t SpdyPushAllowance() { return mSpdyPushAllowance; } PRIntervalTime SpdyPingThreshold() { return mSpdyPingThreshold; } PRIntervalTime SpdyPingTimeout() { return mSpdyPingTimeout; } bool AllowPush() { return mAllowPush; } - bool AllowAltSvc() { return mEnableAltSvc; } - bool AllowAltSvcOE() { return mEnableAltSvcOE; } uint32_t ConnectTimeout() { return mConnectTimeout; } uint32_t ParallelSpeculativeConnectLimit() { return mParallelSpeculativeConnectLimit; } bool CriticalRequestPrioritization() { return mCriticalRequestPrioritization; } uint32_t MaxConnectionsPerOrigin() { return mMaxPersistentConnectionsPerServer; } bool UseRequestTokenBucket() { return mRequestTokenBucketEnabled; } uint16_t RequestTokenBucketMinParallelism() { return mRequestTokenBucketMinParallelism; } uint32_t RequestTokenBucketHz() { return mRequestTokenBucketHz; } @@ -217,32 +214,16 @@ public: nsresult SpeculativeConnect(nsHttpConnectionInfo *ci, nsIInterfaceRequestor *callbacks, uint32_t caps = 0) { TickleWifi(callbacks); return mConnMgr->SpeculativeConnect(ci, callbacks, caps); } - // Alternate Services Maps are main thread only - void UpdateAltServiceMapping(AltSvcMapping *map, - nsProxyInfo *proxyInfo, - nsIInterfaceRequestor *callbacks, - uint32_t caps) - { - mConnMgr->UpdateAltServiceMapping(map, proxyInfo, callbacks, caps); - } - - AltSvcMapping *GetAltServiceMapping(const nsACString &scheme, - const nsACString &host, - int32_t port, bool pb) - { - return mConnMgr->GetAltServiceMapping(scheme, host, port, pb); - } - // // The HTTP handler caches pointers to specific XPCOM services, and // provides the following helper routines for accessing those services: // nsresult GetStreamConverterService(nsIStreamConverterService **); nsresult GetIOService(nsIIOService** service); nsICookieService * GetCookieService(); // not addrefed nsISiteSecurityService * GetSSService(); @@ -468,18 +449,16 @@ private: uint32_t mSpdyV3 : 1; uint32_t mSpdyV31 : 1; uint32_t mHttp2DraftEnabled : 1; uint32_t mHttp2Enabled : 1; uint32_t mEnforceHttp2TlsProfile : 1; uint32_t mCoalesceSpdy : 1; uint32_t mSpdyPersistentSettings : 1; uint32_t mAllowPush : 1; - uint32_t mEnableAltSvc : 1; - uint32_t mEnableAltSvcOE : 1; // Try to use SPDY features instead of HTTP/1.1 over SSL SpdyInformation mSpdyInfo; uint32_t mSpdySendingChunkSize; uint32_t mSpdySendBufferSize; uint32_t mSpdyPushAllowance; PRIntervalTime mSpdyPingThreshold;
--- a/netwerk/protocol/http/nsHttpRequestHead.cpp +++ b/netwerk/protocol/http/nsHttpRequestHead.cpp @@ -46,28 +46,16 @@ nsHttpRequestHead::SetMethod(const nsACS mParsedMethod = kMethod_Head; } else if (!strcmp(mMethod.get(), "PUT")) { mParsedMethod = kMethod_Put; } else if (!strcmp(mMethod.get(), "TRACE")) { mParsedMethod = kMethod_Trace; } } -void -nsHttpRequestHead::SetOrigin(const nsACString &scheme, const nsACString &host, int32_t port) -{ - mOrigin.Assign(scheme); - mOrigin.Append(NS_LITERAL_CSTRING("://")); - mOrigin.Append(host); - if (port >= 0) { - mOrigin.Append(NS_LITERAL_CSTRING(":")); - mOrigin.AppendInt(port); - } -} - bool nsHttpRequestHead::IsSafeMethod() const { // This code will need to be extended for new safe methods, otherwise // they'll default to "not safe". if (IsGet() || IsHead() || IsOptions() || IsTrace()) { return true; }
--- a/netwerk/protocol/http/nsHttpRequestHead.h +++ b/netwerk/protocol/http/nsHttpRequestHead.h @@ -31,19 +31,16 @@ public: nsHttpHeaderArray & Headers() { return mHeaders; } const nsCString &Method() const { return mMethod; } nsHttpVersion Version() const { return mVersion; } const nsCSubstring &RequestURI() const { return mRequestURI; } void SetHTTPS(bool val) { mHTTPS = val; } bool IsHTTPS() const { return mHTTPS; } - void SetOrigin(const nsACString &scheme, const nsACString &host, int32_t port); - const nsCString &Origin() const { return mOrigin; } - const char *PeekHeader(nsHttpAtom h) const { return mHeaders.PeekHeader(h); } nsresult SetHeader(nsHttpAtom h, const nsACString &v, bool m=false) { return mHeaders.SetHeader(h, v, m); } nsresult GetHeader(nsHttpAtom h, nsACString &v) const { return mHeaders.GetHeader(h, v); @@ -95,16 +92,15 @@ public: bool IsTrace() const { return EqualsMethod(kMethod_Trace); } private: // All members must be copy-constructable and assignable nsHttpHeaderArray mHeaders; nsCString mMethod; nsHttpVersion mVersion; nsCString mRequestURI; - nsCString mOrigin; ParsedMethodType mParsedMethod; bool mHTTPS; }; }} // namespace mozilla::net #endif // nsHttpRequestHead_h__
--- a/netwerk/protocol/http/nsHttpTransaction.cpp +++ b/netwerk/protocol/http/nsHttpTransaction.cpp @@ -86,16 +86,17 @@ LogHeaders(const char *lineStart) //----------------------------------------------------------------------------- // nsHttpTransaction <public> //----------------------------------------------------------------------------- nsHttpTransaction::nsHttpTransaction() : mLock("transaction lock") , mRequestSize(0) , mConnection(nullptr) + , mConnInfo(nullptr) , mRequestHead(nullptr) , mResponseHead(nullptr) , mContentLength(-1) , mContentRead(0) , mInvalidResponseBytesRead(0) , mChunkedDecoder(nullptr) , mStatus(NS_OK) , mPriority(0) @@ -118,17 +119,16 @@ nsHttpTransaction::nsHttpTransaction() , mStatusEventPending(false) , mHasRequestBody(false) , mProxyConnectFailed(false) , mHttpResponseMatched(false) , mPreserveStream(false) , mDispatchedAsBlocking(false) , mResponseTimeoutEnabled(true) , mDontRouteViaWildCard(false) - , mForceRestart(false) , mReportedStart(false) , mReportedResponseHeader(false) , mForTakeResponseHead(nullptr) , mResponseHeadTaken(false) , mSubmittedRatePacing(false) , mPassedRatePacing(false) , mSynchronousRatePaceRequest(false) , mCountRecv(0) @@ -843,21 +843,16 @@ nsHttpTransaction::Close(nsresult reason // // NOTE: because of the way SSL proxy CONNECT is implemented, it is // possible that the transaction may have received data without having // sent any data. for this reason, mSendData == FALSE does not imply // mReceivedData == FALSE. (see bug 203057 for more info.) // if (reason == NS_ERROR_NET_RESET || reason == NS_OK) { - if (mForceRestart && NS_SUCCEEDED(Restart())) { - LOG(("transaction force restarted\n")); - return; - } - // reallySentData is meant to separate the instances where data has // been sent by this transaction but buffered at a higher level while // a TLS session (perhaps via a tunnel) is setup. bool reallySentData = mSentData && (!mConnection || mConnection->BytesWritten()); if (!mReceivedData && (!reallySentData || connReused || mPipelinePosition)) { @@ -1110,27 +1105,16 @@ nsHttpTransaction::Restart() } // disable pipelining for the next attempt in case pipelining caused the // reset. this is being overly cautious since we don't know if pipelining // was the problem here. mCaps &= ~NS_HTTP_ALLOW_PIPELINING; SetPipelinePosition(0); - if (!mConnInfo->GetAuthenticationHost().IsEmpty()) { - MutexAutoLock lock(*nsHttp::GetLock()); - nsRefPtr<nsHttpConnectionInfo> ci; - mConnInfo->CloneAsDirectRoute(getter_AddRefs(ci)); - mConnInfo = ci; - if (mRequestHead) { - mRequestHead->SetHeader(nsHttp::Alternate_Service_Used, NS_LITERAL_CSTRING("0")); - } - } - mForceRestart = false; - return gHttpHandler->InitiateTransaction(this, mPriority); } char * nsHttpTransaction::LocateHttpStart(char *buf, uint32_t len, bool aAllowPartialMatch) { MOZ_ASSERT(!aAllowPartialMatch || mLineBuf.IsEmpty()); @@ -1392,21 +1376,21 @@ nsHttpTransaction::ParseHead(char *buf, return NS_OK; rv = ParseLineSegment(buf, len); if (NS_FAILED(rv)) return rv; } return NS_OK; } +// called on the socket thread nsresult nsHttpTransaction::HandleContentStart() { LOG(("nsHttpTransaction::HandleContentStart [this=%p]\n", this)); - MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); if (mResponseHead) { #if defined(PR_LOGGING) if (LOG3_ENABLED()) { LOG3(("http response [\n")); nsAutoCString headers; mResponseHead->Flatten(headers, false); LogHeaders(headers.get()); @@ -1440,24 +1424,16 @@ nsHttpTransaction::HandleContentStart() case 101: mPreserveStream = true; // fall through to other no content case 204: case 205: case 304: mNoContent = true; LOG(("this response should not contain a body.\n")); break; - case 421: - if (!mConnInfo->GetAuthenticationHost().IsEmpty()) { - LOG(("Not Authoritative.\n")); - gHttpHandler->ConnMgr()-> - ClearHostMapping(mConnInfo->GetHost(), mConnInfo->Port()); - mForceRestart = true; - } - break; } if (mResponseHead->Status() == 200 && mConnection->IsProxyConnectInProgress()) { // successful CONNECTs do not have response bodies mNoContent = true; } mConnection->SetLastTransactionExpectedNoContent(mNoContent);
--- a/netwerk/protocol/http/nsHttpTransaction.h +++ b/netwerk/protocol/http/nsHttpTransaction.h @@ -259,17 +259,16 @@ private: bool mStatusEventPending; bool mHasRequestBody; bool mProxyConnectFailed; bool mHttpResponseMatched; bool mPreserveStream; bool mDispatchedAsBlocking; bool mResponseTimeoutEnabled; bool mDontRouteViaWildCard; - bool mForceRestart; // mClosed := transaction has been explicitly closed // mTransactionDone := transaction ran to completion or was interrupted // mResponseComplete := transaction ran to completion // For Restart-In-Progress Functionality bool mReportedStart; bool mReportedResponseHeader;
--- a/netwerk/socket/nsISSLSocketControl.idl +++ b/netwerk/socket/nsISSLSocketControl.idl @@ -10,17 +10,17 @@ interface nsIInterfaceRequestor; interface nsIX509Cert; %{C++ template<class T> class nsTArray; class nsCString; %} [ref] native nsCStringTArrayRef(nsTArray<nsCString>); -[scriptable, builtinclass, uuid(f160ec31-01f3-47f2-b542-0e12a647b07f)] +[scriptable, builtinclass, uuid(89b819dc-31b0-4d09-915a-66f8a3703483)] interface nsISSLSocketControl : nsISupports { attribute nsIInterfaceRequestor notificationCallbacks; void proxyStartSSL(); void StartTLS(); /* NPN (Next Protocol Negotiation) is a mechanism for negotiating the protocol to be spoken inside the SSL @@ -48,21 +48,16 @@ interface nsISSLSocketControl : nsISuppo * a desired NPN negotiated protocol of npnProtocol can use the socket * associated with this object instead of making a new one. */ boolean joinConnection( in ACString npnProtocol, /* e.g. "spdy/2" */ in ACString hostname, in long port); - /* Determine if existing connection should be trusted to convey information about - * a hostname. - */ - boolean isAcceptableForHost(in ACString hostname); - /* The Key Exchange Algorithm is used when determining whether or not to do false start and whether or not HTTP/2 can be used. After a handshake is complete it can be read from KEAUsed, before a handshake is started it may be set through KEAExpected. The values correspond to the SSLKEAType enum in NSS or the KEY_EXCHANGE_UNKNOWN constant defined below. @@ -103,31 +98,10 @@ interface nsISSLSocketControl : nsISuppo [infallible] readonly attribute short MACAlgorithmUsed; /** * If set before the server requests a client cert (assuming it does so at * all), then this cert will be presented to the server, instead of asking * the user or searching the set of rememebered user cert decisions. */ attribute nsIX509Cert clientCert; - - /** - * If you wish to verify the host certificate using a different name than - * was used for the tcp connection, but without using proxy semantics, you - * can set authenticationName and authenticationPort - */ - attribute ACString authenticationName; - [infallible] attribute long authenticationPort; - - /** - * set bypassAuthentication to true if the server certificate checks should - * not be enforced. This is to enable non-secure transport over TLS. - */ - [infallible] attribute boolean bypassAuthentication; - - /* - * failedVerification is true if any enforced certificate checks have failed. - * Connections that have not yet tried to verify, have verifications bypassed, - * or are using acceptable exceptions will all return false. - */ - [infallible] readonly attribute boolean failedVerification; };
--- a/netwerk/test/unit/test_http2.js +++ b/netwerk/test/unit/test_http2.js @@ -330,75 +330,27 @@ function test_http2_post() { // Make sure we can do a POST that covers more than 2 frames function test_http2_post_big() { var chan = makeChan("https://localhost:6944/post"); var listener = new Http2PostListener(md5s[1]); do_post(posts[1], chan, listener); } -Cu.import("resource://testing-common/httpd.js"); -var httpserv = null; -var ios = Components.classes["@mozilla.org/network/io-service;1"] - .getService(Components.interfaces.nsIIOService); - -var altsvcClientListener = { - onStartRequest: function test_onStartR(request, ctx) { - do_check_eq(request.status, Components.results.NS_OK); - }, - - onDataAvailable: function test_ODA(request, cx, stream, offset, cnt) { - read_stream(stream, cnt); - }, - - onStopRequest: function test_onStopR(request, ctx, status) { - var isHttp2Connection = checkIsHttp2(request); - if (!isHttp2Connection) { - // not over tls yet - retry. It's all async and transparent to client - var chan = ios.newChannel("http://localhost:" + httpserv.identity.primaryPort + "/altsvc1", - null, null).QueryInterface(Components.interfaces.nsIHttpChannel); - chan.asyncOpen(altsvcClientListener, null); - } else { - do_check_true(isHttp2Connection); - httpserv.stop(do_test_finished); - run_next_test(); - } - } -}; - -function altsvcHttp1Server(metadata, response) { - response.setStatusLine(metadata.httpVersion, 200, "OK"); - response.setHeader("Content-Type", "text/plain", false); - response.setHeader("Alt-Svc", 'h2=":6944"; ma=3200, h2-14=":6944"', false); - var body = "this is where a cool kid would write something neat.\n"; - response.bodyOutputStream.write(body, body.length); -} - -function test_http2_altsvc() { - httpserv = new HttpServer(); - httpserv.registerPathHandler("/altsvc1", altsvcHttp1Server); - httpserv.start(-1); - - var chan = ios.newChannel("http://localhost:" + httpserv.identity.primaryPort + "/altsvc1", - null, null).QueryInterface(Components.interfaces.nsIHttpChannel); - chan.asyncOpen(altsvcClientListener, null); -} - // hack - the header test resets the multiplex object on the server, // so make sure header is always run before the multiplex test. // // make sure post_big runs first to test race condition in restarting // a stalled stream when a SETTINGS frame arrives var tests = [ test_http2_post_big , test_http2_basic , test_http2_push1 , test_http2_push2 , test_http2_push3 , test_http2_push4 - , test_http2_altsvc , test_http2_doubleheader , test_http2_xhr , test_http2_header , test_http2_cookie_crumbling , test_http2_multiplex , test_http2_big , test_http2_post ]; @@ -475,18 +427,16 @@ var tlspref; var loadGroup; function resetPrefs() { prefs.setBoolPref("network.http.spdy.enabled", spdypref); prefs.setBoolPref("network.http.spdy.enabled.v3", spdy3pref); prefs.setBoolPref("network.http.spdy.allow-push", spdypush); prefs.setBoolPref("network.http.spdy.enabled.http2draft", http2pref); prefs.setBoolPref("network.http.spdy.enforce-tls-profile", tlspref); - prefs.setBoolPref("network.http.altsvc.enabled", altsvcpref1); - prefs.setBoolPref("network.http.altsvc.oe", altsvcpref2); } function run_test() { // Set to allow the cert presented by our SPDY server do_get_profile(); var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch); var oldPref = prefs.getIntPref("network.http.speculative-parallel-limit"); prefs.setIntPref("network.http.speculative-parallel-limit", 0); @@ -499,24 +449,19 @@ function run_test() { prefs.setIntPref("network.http.speculative-parallel-limit", oldPref); // Enable all versions of spdy to see that we auto negotiate http/2 spdypref = prefs.getBoolPref("network.http.spdy.enabled"); spdy3pref = prefs.getBoolPref("network.http.spdy.enabled.v3"); spdypush = prefs.getBoolPref("network.http.spdy.allow-push"); http2pref = prefs.getBoolPref("network.http.spdy.enabled.http2draft"); tlspref = prefs.getBoolPref("network.http.spdy.enforce-tls-profile"); - altsvcpref1 = prefs.getBoolPref("network.http.altsvc.enabled"); - altsvcpref2 = prefs.getBoolPref("network.http.altsvc.oe", true); - prefs.setBoolPref("network.http.spdy.enabled", true); prefs.setBoolPref("network.http.spdy.enabled.v3", true); prefs.setBoolPref("network.http.spdy.allow-push", true); prefs.setBoolPref("network.http.spdy.enabled.http2draft", true); prefs.setBoolPref("network.http.spdy.enforce-tls-profile", false); - prefs.setBoolPref("network.http.altsvc.enabled", true); - prefs.setBoolPref("network.http.altsvc.oe", true); loadGroup = Cc["@mozilla.org/network/load-group;1"].createInstance(Ci.nsILoadGroup); // And make go! run_next_test(); }
--- a/security/manager/ssl/src/SSLServerCertVerification.cpp +++ b/security/manager/ssl/src/SSLServerCertVerification.cpp @@ -395,26 +395,16 @@ CertErrorRunnable::CheckCertOverrides() unused << mFdForLogging; if (!NS_IsMainThread()) { NS_ERROR("CertErrorRunnable::CheckCertOverrides called off main thread"); return new SSLServerCertVerificationResult(mInfoObject, mDefaultErrorCodeToReport); } - nsCOMPtr<nsISSLSocketControl> sslSocketControl = do_QueryInterface( - NS_ISUPPORTS_CAST(nsITransportSecurityInfo*, mInfoObject)); - if (sslSocketControl && - sslSocketControl->GetBypassAuthentication()) { - PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, - ("[%p][%p] Bypass Auth in CheckCertOverrides\n", - mFdForLogging, this)); - return new SSLServerCertVerificationResult(mInfoObject, 0); - } - int32_t port; mInfoObject->GetPort(&port); nsCString hostWithPortString; hostWithPortString.AppendASCII(mInfoObject->GetHostNameRaw()); hostWithPortString.Append(':'); hostWithPortString.AppendInt(port); @@ -495,16 +485,18 @@ CertErrorRunnable::CheckCertOverrides() PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("[%p][%p] Certificate error was not overridden\n", mFdForLogging, this)); // Ok, this is a full stop. // First, deliver the technical details of the broken SSL status. // Try to get a nsIBadCertListener2 implementation from the socket consumer. + nsCOMPtr<nsISSLSocketControl> sslSocketControl = do_QueryInterface( + NS_ISUPPORTS_CAST(nsITransportSecurityInfo*, mInfoObject)); if (sslSocketControl) { nsCOMPtr<nsIInterfaceRequestor> cb; sslSocketControl->GetNotificationCallbacks(getter_AddRefs(cb)); if (cb) { nsCOMPtr<nsIBadCertListener2> bcl = do_GetInterface(cb); if (bcl) { nsIInterfaceRequestor* csi = static_cast<nsIInterfaceRequestor*>(mInfoObject);
--- a/security/manager/ssl/src/nsNSSIOLayer.cpp +++ b/security/manager/ssl/src/nsNSSIOLayer.cpp @@ -127,23 +127,21 @@ nsNSSSocketInfo::nsNSSSocketInfo(SharedS mNPNCompleted(false), mFalseStartCallbackCalled(false), mFalseStarted(false), mIsFullHandshake(false), mHandshakeCompleted(false), mJoined(false), mSentClientCert(false), mNotedTimeUntilReady(false), - mFailedVerification(false), mKEAUsed(nsISSLSocketControl::KEY_EXCHANGE_UNKNOWN), mKEAExpected(nsISSLSocketControl::KEY_EXCHANGE_UNKNOWN), mKEAKeyBits(0), mSSLVersionUsed(nsISSLSocketControl::SSL_VERSION_UNKNOWN), mMACAlgorithmUsed(nsISSLSocketControl::SSL_MAC_UNKNOWN), - mBypassAuthentication(false), mProviderFlags(providerFlags), mSocketCreationTimestamp(TimeStamp::Now()), mPlaintextBytesRead(0), mClientCert(nullptr) { mTLSVersionRange.min = 0; mTLSVersionRange.max = 0; } @@ -224,62 +222,16 @@ nsNSSSocketInfo::GetClientCert(nsIX509Ce NS_IMETHODIMP nsNSSSocketInfo::SetClientCert(nsIX509Cert* aClientCert) { mClientCert = aClientCert; return NS_OK; } NS_IMETHODIMP -nsNSSSocketInfo::GetBypassAuthentication(bool* arg) -{ - *arg = mBypassAuthentication; - return NS_OK; -} - -NS_IMETHODIMP -nsNSSSocketInfo::SetBypassAuthentication(bool arg) -{ - mBypassAuthentication = arg; - return NS_OK; -} - -NS_IMETHODIMP -nsNSSSocketInfo::GetFailedVerification(bool* arg) -{ - *arg = mFailedVerification; - return NS_OK; -} - -NS_IMETHODIMP -nsNSSSocketInfo::GetAuthenticationName(nsACString& aAuthenticationName) -{ - aAuthenticationName = GetHostName(); - return NS_OK; -} - -NS_IMETHODIMP -nsNSSSocketInfo::SetAuthenticationName(const nsACString& aAuthenticationName) -{ - return SetHostName(PromiseFlatCString(aAuthenticationName).get()); -} - -NS_IMETHODIMP -nsNSSSocketInfo::GetAuthenticationPort(int32_t* aAuthenticationPort) -{ - return GetPort(aAuthenticationPort); -} - -NS_IMETHODIMP -nsNSSSocketInfo::SetAuthenticationPort(int32_t aAuthenticationPort) -{ - return SetPort(aAuthenticationPort); -} - -NS_IMETHODIMP nsNSSSocketInfo::GetRememberClientAuthCertificate(bool* aRemember) { NS_ENSURE_ARG_POINTER(aRemember); *aRemember = mRememberClientAuthCertificate; return NS_OK; } NS_IMETHODIMP @@ -421,18 +373,31 @@ nsNSSSocketInfo::GetNegotiatedNPN(nsACSt if (!mNPNCompleted) return NS_ERROR_NOT_CONNECTED; aNegotiatedNPN = mNegotiatedNPN; return NS_OK; } NS_IMETHODIMP -nsNSSSocketInfo::IsAcceptableForHost(const nsACString& hostname, bool* _retval) +nsNSSSocketInfo::JoinConnection(const nsACString& npnProtocol, + const nsACString& hostname, + int32_t port, + bool* _retval) { + *_retval = false; + + // Different ports may not be joined together + if (port != GetPort()) + return NS_OK; + + // Make sure NPN has been completed and matches requested npnProtocol + if (!mNPNCompleted || !mNegotiatedNPN.Equals(npnProtocol)) + return NS_OK; + // If this is the same hostname then the certicate status does not // need to be considered. They are joinable. if (hostname.Equals(GetHostName())) { *_retval = true; return NS_OK; } // Before checking the server certificate we need to make sure the @@ -492,46 +457,22 @@ nsNSSSocketInfo::IsAcceptableForHost(con mozilla::pkix::Now(), nullptr, hostnameFlat.get(), false, flags, nullptr, nullptr); if (rv != SECSuccess) { return NS_OK; } - // All tests pass + // All tests pass - this is joinable + mJoined = true; *_retval = true; return NS_OK; } -NS_IMETHODIMP -nsNSSSocketInfo::JoinConnection(const nsACString& npnProtocol, - const nsACString& hostname, - int32_t port, - bool* _retval) -{ - *_retval = false; - - // Different ports may not be joined together - if (port != GetPort()) - return NS_OK; - - // Make sure NPN has been completed and matches requested npnProtocol - if (!mNPNCompleted || !mNegotiatedNPN.Equals(npnProtocol)) - return NS_OK; - - IsAcceptableForHost(hostname, _retval); - - if (*_retval) { - // All tests pass - this is joinable - mJoined = true; - } - return NS_OK; -} - bool nsNSSSocketInfo::GetForSTARTTLS() { return mForSTARTTLS; } void nsNSSSocketInfo::SetForSTARTTLS(bool aForSTARTTLS) @@ -686,17 +627,16 @@ nsNSSSocketInfo::SetCertVerificationResu if (errorCode == 0) { NS_ERROR("SSL_AuthCertificateComplete didn't set error code"); errorCode = PR_INVALID_STATE_ERROR; } } } if (errorCode) { - mFailedVerification = true; SetCanceled(errorCode, errorMessageType); } if (mPlaintextBytesRead && !errorCode) { Telemetry::Accumulate(Telemetry::SSL_BYTES_BEFORE_CERT_CALLBACK, AssertedCast<uint32_t>(mPlaintextBytesRead)); }
--- a/security/manager/ssl/src/nsNSSIOLayer.h +++ b/security/manager/ssl/src/nsNSSIOLayer.h @@ -108,32 +108,16 @@ public: void SetSSLVersionUsed(int16_t version) { mSSLVersionUsed = version; } void SetMACAlgorithmUsed(int16_t mac) { mMACAlgorithmUsed = mac; } - inline bool GetBypassAuthentication() - { - bool result = false; - mozilla::DebugOnly<nsresult> rv = GetBypassAuthentication(&result); - MOZ_ASSERT(NS_SUCCEEDED(rv)); - return result; - } - - inline int32_t GetAuthenticationPort() - { - int32_t result = -1; - mozilla::DebugOnly<nsresult> rv = GetAuthenticationPort(&result); - MOZ_ASSERT(NS_SUCCEEDED(rv)); - return result; - } - protected: virtual ~nsNSSSocketInfo(); private: PRFileDesc* mFd; CertVerificationState mCertVerificationState; @@ -150,26 +134,24 @@ private: bool mNPNCompleted; bool mFalseStartCallbackCalled; bool mFalseStarted; bool mIsFullHandshake; bool mHandshakeCompleted; bool mJoined; bool mSentClientCert; bool mNotedTimeUntilReady; - bool mFailedVerification; // mKEA* are used in false start and http/2 detetermination // Values are from nsISSLSocketControl int16_t mKEAUsed; int16_t mKEAExpected; uint32_t mKEAKeyBits; int16_t mSSLVersionUsed; int16_t mMACAlgorithmUsed; - bool mBypassAuthentication; uint32_t mProviderFlags; mozilla::TimeStamp mSocketCreationTimestamp; uint64_t mPlaintextBytesRead; nsCOMPtr<nsIX509Cert> mClientCert; };
--- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -1188,26 +1188,16 @@ "kind": "boolean", "description": "Whether a HTTP transaction was over SSL or not." }, "HTTP_PAGELOAD_IS_SSL": { "expires_in_version": "never", "kind": "boolean", "description": "Whether a HTTP base page load was over SSL or not." }, - "HTTP_TRANSACTION_USE_ALTSVC": { - "expires_in_version": "never", - "kind": "boolean", - "description": "Whether a HTTP transaction was routed via Alt-Svc or not." - }, - "HTTP_TRANSACTION_USE_ALTSVC_OE": { - "expires_in_version": "never", - "kind": "boolean", - "description": "Whether a HTTP transaction routed via Alt-Svc was scheme=http" - }, "SSL_HANDSHAKE_VERSION": { "expires_in_version": "never", "kind": "enumerated", "n_values": 16, "description": "SSL Version (0=ssl3, 1=tls1, 2=tls1.1, 3=tls1.2)" }, "SSL_TIME_UNTIL_READY": { "expires_in_version": "never",