diff options
Diffstat (limited to 'netwerk/protocol/http')
-rw-r--r-- | netwerk/protocol/http/AlternateServices.cpp | 5 | ||||
-rw-r--r-- | netwerk/protocol/http/Http2Push.cpp | 81 | ||||
-rw-r--r-- | netwerk/protocol/http/Http2Push.h | 18 | ||||
-rw-r--r-- | netwerk/protocol/http/Http2Session.cpp | 24 | ||||
-rw-r--r-- | netwerk/protocol/http/Http2Stream.cpp | 4 | ||||
-rw-r--r-- | netwerk/protocol/http/Http2Stream.h | 2 | ||||
-rw-r--r-- | netwerk/protocol/http/nsCORSListenerProxy.cpp | 3 | ||||
-rw-r--r-- | netwerk/protocol/http/nsHttpChannel.cpp | 4 | ||||
-rw-r--r-- | netwerk/protocol/http/nsHttpChannel.h | 9 | ||||
-rw-r--r-- | netwerk/protocol/http/nsHttpChannelAuthProvider.cpp | 25 | ||||
-rw-r--r-- | netwerk/protocol/http/nsHttpChannelAuthProvider.h | 3 | ||||
-rw-r--r-- | netwerk/protocol/http/nsHttpConnectionMgr.cpp | 33 | ||||
-rw-r--r-- | netwerk/protocol/http/nsHttpHandler.h | 3 | ||||
-rw-r--r-- | netwerk/protocol/http/nsHttpTransaction.h | 16 |
14 files changed, 187 insertions, 43 deletions
diff --git a/netwerk/protocol/http/AlternateServices.cpp b/netwerk/protocol/http/AlternateServices.cpp index ee2fa9331..10bd61928 100644 --- a/netwerk/protocol/http/AlternateServices.cpp +++ b/netwerk/protocol/http/AlternateServices.cpp @@ -121,6 +121,11 @@ AltSvcMapping::ProcessHeader(const nsCString &buf, const nsCString &originScheme continue; } + if (NS_FAILED(NS_CheckPortSafety(portno, originScheme.get()))) { + LOG(("Alt Svc does not allow port %d, ignoring request", portno)); + continue; + } + // unescape modifies a c string in place, so afterwards // update nsCString length nsUnescape(npnToken.BeginWriting()); diff --git a/netwerk/protocol/http/Http2Push.cpp b/netwerk/protocol/http/Http2Push.cpp index b6fc485e2..34fc425d2 100644 --- a/netwerk/protocol/http/Http2Push.cpp +++ b/netwerk/protocol/http/Http2Push.cpp @@ -30,8 +30,8 @@ class CallChannelOnPush final : public Runnable { Http2PushedStream *pushStream) : mAssociatedChannel(associatedChannel) , mPushedURI(pushedURI) - , mPushedStream(pushStream) { + mPushedStreamWrapper = new Http2PushedStreamWrapper(pushStream); } NS_IMETHOD Run() override @@ -40,21 +40,94 @@ class CallChannelOnPush final : public Runnable { RefPtr<nsHttpChannel> channel; CallQueryInterface(mAssociatedChannel, channel.StartAssignment()); MOZ_ASSERT(channel); - if (channel && NS_SUCCEEDED(channel->OnPush(mPushedURI, mPushedStream))) { + if (channel && NS_SUCCEEDED(channel->OnPush(mPushedURI, mPushedStreamWrapper))) { return NS_OK; } LOG3(("Http2PushedStream Orphan %p failed OnPush\n", this)); - mPushedStream->OnPushFailed(); + mPushedStreamWrapper->OnPushFailed(); return NS_OK; } private: nsCOMPtr<nsIHttpChannelInternal> mAssociatedChannel; const nsCString mPushedURI; - Http2PushedStream *mPushedStream; + RefPtr<Http2PushedStreamWrapper> mPushedStreamWrapper; }; +// Because WeakPtr isn't thread-safe we must ensure that the object is destroyed +// on the socket thread, so any Release() called on a different thread is +// dispatched to the socket thread. +bool Http2PushedStreamWrapper::DispatchRelease() { + if (PR_GetCurrentThread() == gSocketThread) { + return false; + } + + gSocketTransportService->Dispatch( + NewNonOwningRunnableMethod(this, &Http2PushedStreamWrapper::Release), + NS_DISPATCH_NORMAL); + + return true; +} + +NS_IMPL_ADDREF(Http2PushedStreamWrapper) +NS_IMETHODIMP_(MozExternalRefCountType) +Http2PushedStreamWrapper::Release() { + nsrefcnt count = mRefCnt - 1; + if (DispatchRelease()) { + // Redispatched to the socket thread. + return count; + } + + MOZ_ASSERT(0 != mRefCnt, "dup release"); + count = --mRefCnt; + NS_LOG_RELEASE(this, count, "Http2PushedStreamWrapper"); + + if (0 == count) { + mRefCnt = 1; + delete (this); + return 0; + } + + return count; +} + +NS_INTERFACE_MAP_BEGIN(Http2PushedStreamWrapper) +NS_INTERFACE_MAP_END + +Http2PushedStreamWrapper::Http2PushedStreamWrapper( + Http2PushedStream* aPushStream) { + MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread, "not on socket thread"); + mStream = aPushStream; + mRequestString = aPushStream->GetRequestString(); +} + +Http2PushedStreamWrapper::~Http2PushedStreamWrapper() { + MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread, "not on socket thread"); +} + +Http2PushedStream* Http2PushedStreamWrapper::GetStream() { + MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread, "not on socket thread"); + if (mStream) { + Http2Stream* stream = mStream; + return static_cast<Http2PushedStream*>(stream); + } + return nullptr; +} + +void Http2PushedStreamWrapper::OnPushFailed() { + if (PR_GetCurrentThread() == gSocketThread) { + if (mStream) { + Http2Stream* stream = mStream; + static_cast<Http2PushedStream*>(stream)->OnPushFailed(); + } + } else { + gSocketTransportService->Dispatch( + NewRunnableMethod(this, &Http2PushedStreamWrapper::OnPushFailed), + NS_DISPATCH_NORMAL); + } +} + ////////////////////////////////////////// // Http2PushedStream ////////////////////////////////////////// diff --git a/netwerk/protocol/http/Http2Push.h b/netwerk/protocol/http/Http2Push.h index fd39eb2c7..d4b71c1ef 100644 --- a/netwerk/protocol/http/Http2Push.h +++ b/netwerk/protocol/http/Http2Push.h @@ -123,6 +123,24 @@ private: uint32_t mBufferedHTTP1Consumed; }; +class Http2PushedStreamWrapper : public nsISupports { +public: + NS_DECL_THREADSAFE_ISUPPORTS + bool DispatchRelease(); + + explicit Http2PushedStreamWrapper(Http2PushedStream* aPushStream); + + nsCString& GetRequestString() { return mRequestString; } + Http2PushedStream* GetStream(); + void OnPushFailed(); + +private: + virtual ~Http2PushedStreamWrapper(); + + nsCString mRequestString; + WeakPtr<Http2Stream> mStream; +}; + } // namespace net } // namespace mozilla diff --git a/netwerk/protocol/http/Http2Session.cpp b/netwerk/protocol/http/Http2Session.cpp index 4a178f091..86e8c74f6 100644 --- a/netwerk/protocol/http/Http2Session.cpp +++ b/netwerk/protocol/http/Http2Session.cpp @@ -380,12 +380,24 @@ Http2Session::AddStream(nsAHttpTransaction *aHttpTransaction, if (mClosed || mShouldGoAway) { nsHttpTransaction *trans = aHttpTransaction->QueryHttpTransaction(); - if (trans && !trans->GetPushedStream()) { - LOG3(("Http2Session::AddStream %p atrans=%p trans=%p session unusable - resched.\n", - this, aHttpTransaction, trans)); - aHttpTransaction->SetConnection(nullptr); - gHttpHandler->InitiateTransaction(trans, trans->Priority()); - return true; + if (trans) { + RefPtr<Http2PushedStreamWrapper> pushedStreamWrapper; + pushedStreamWrapper = trans->GetPushedStream(); + if (!pushedStreamWrapper || !pushedStreamWrapper->GetStream()) { + LOG3( + ("Http2Session::AddStream %p atrans=%p trans=%p session unusable - " + "resched.\n", this, aHttpTransaction, trans)); + aHttpTransaction->SetConnection(nullptr); + nsresult rv = + gHttpHandler->InitiateTransaction(trans, trans->Priority()); + if (NS_FAILED(rv)) { + LOG3( + ("Http2Session::AddStream %p atrans=%p trans=%p failed to " + "initiate transaction (%08x).\n", + this, aHttpTransaction, trans, static_cast<uint32_t>(rv))); + } + return true; + } } } diff --git a/netwerk/protocol/http/Http2Stream.cpp b/netwerk/protocol/http/Http2Stream.cpp index 581ebe016..22d8142c9 100644 --- a/netwerk/protocol/http/Http2Stream.cpp +++ b/netwerk/protocol/http/Http2Stream.cpp @@ -442,12 +442,14 @@ Http2Stream::ParseHttpRequestHeaders(const char *buf, requestContext->GetSpdyPushCache(&cache); } + RefPtr<Http2PushedStreamWrapper> pushedStreamWrapper; Http2PushedStream *pushedStream = nullptr; // If a push stream is attached to the transaction via onPush, match only with that // one. This occurs when a push was made with in conjunction with a nsIHttpPushListener nsHttpTransaction *trans = mTransaction->QueryHttpTransaction(); - if (trans && (pushedStream = trans->TakePushedStream())) { + if (trans && (pushedStreamWrapper = trans->TakePushedStream()) && + (pushedStream = pushedStreamWrapper->GetStream())) { if (pushedStream->mSession == mSession) { LOG3(("Pushed Stream match based on OnPush correlation %p", pushedStream)); } else { diff --git a/netwerk/protocol/http/Http2Stream.h b/netwerk/protocol/http/Http2Stream.h index 8783eefed..484457650 100644 --- a/netwerk/protocol/http/Http2Stream.h +++ b/netwerk/protocol/http/Http2Stream.h @@ -28,8 +28,10 @@ class Http2Decompressor; class Http2Stream : public nsAHttpSegmentReader , public nsAHttpSegmentWriter + , public SupportsWeakPtr<Http2Stream> { public: + MOZ_DECLARE_WEAKREFERENCE_TYPENAME(Http2Stream) NS_DECL_NSAHTTPSEGMENTREADER NS_DECL_NSAHTTPSEGMENTWRITER diff --git a/netwerk/protocol/http/nsCORSListenerProxy.cpp b/netwerk/protocol/http/nsCORSListenerProxy.cpp index b9355c82b..70035be28 100644 --- a/netwerk/protocol/http/nsCORSListenerProxy.cpp +++ b/netwerk/protocol/http/nsCORSListenerProxy.cpp @@ -907,6 +907,9 @@ nsCORSListenerProxy::UpdateChannel(nsIChannel* aChannel, NS_ENSURE_SUCCESS(rv, rv); } + // TODO: Bug 1353683 + // consider calling SetBlockedRequest in nsCORSListenerProxy::UpdateChannel + // // Check that the uri is ok to load rv = nsContentUtils::GetSecurityManager()-> CheckLoadURIWithPrincipal(mRequestingPrincipal, uri, diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index 481df5ff0..05383916f 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -7828,7 +7828,7 @@ nsHttpChannel::AwaitingCacheCallbacks() } void -nsHttpChannel::SetPushedStream(Http2PushedStream *stream) +nsHttpChannel::SetPushedStream(Http2PushedStreamWrapper *stream) { MOZ_ASSERT(stream); MOZ_ASSERT(!mPushedStream); @@ -7836,7 +7836,7 @@ nsHttpChannel::SetPushedStream(Http2PushedStream *stream) } nsresult -nsHttpChannel::OnPush(const nsACString &url, Http2PushedStream *pushedStream) +nsHttpChannel::OnPush(const nsACString &url, Http2PushedStreamWrapper *pushedStream) { MOZ_ASSERT(NS_IsMainThread()); LOG(("nsHttpChannel::OnPush [this=%p]\n", this)); diff --git a/netwerk/protocol/http/nsHttpChannel.h b/netwerk/protocol/http/nsHttpChannel.h index 0038e1f71..defd710c3 100644 --- a/netwerk/protocol/http/nsHttpChannel.h +++ b/netwerk/protocol/http/nsHttpChannel.h @@ -126,7 +126,7 @@ public: const nsID& aChannelId, nsContentPolicyType aContentPolicyType) override; - nsresult OnPush(const nsACString &uri, Http2PushedStream *pushedStream); + nsresult OnPush(const nsACString &uri, Http2PushedStreamWrapper *pushedStream); static bool IsRedirectStatus(uint32_t status); @@ -448,7 +448,7 @@ private: nsresult OpenCacheInputStream(nsICacheEntry* cacheEntry, bool startBuffering, bool checkingAppCacheEntry); - void SetPushedStream(Http2PushedStream *stream); + void SetPushedStream(Http2PushedStreamWrapper *stream); void SetDoNotTrack(); @@ -578,9 +578,10 @@ private: nsTArray<nsContinueRedirectionFunc> mRedirectFuncStack; // Needed for accurate DNS timing - RefPtr<nsDNSPrefetch> mDNSPrefetch; + RefPtr<nsDNSPrefetch> mDNSPrefetch; - Http2PushedStream *mPushedStream; + RefPtr<Http2PushedStreamWrapper> mPushedStream; + // True if the channel's principal was found on a phishing, malware, or // tracking (if tracking protection is enabled) blocklist bool mLocalBlocklist; diff --git a/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp b/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp index 0e7eb55c3..a6681cfc6 100644 --- a/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp +++ b/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp @@ -95,6 +95,8 @@ nsHttpChannelAuthProvider::~nsHttpChannelAuthProvider() uint32_t nsHttpChannelAuthProvider::sAuthAllowPref = SUBRESOURCE_AUTH_DIALOG_ALLOW_ALL; +bool nsHttpChannelAuthProvider::sImgCrossOriginAuthAllowPref = false; + void nsHttpChannelAuthProvider::InitializePrefs() { @@ -102,6 +104,9 @@ nsHttpChannelAuthProvider::InitializePrefs() mozilla::Preferences::AddUintVarCache(&sAuthAllowPref, "network.auth.subresource-http-auth-allow", SUBRESOURCE_AUTH_DIALOG_ALLOW_ALL); + mozilla::Preferences::AddBoolVarCache(&sImgCrossOriginAuthAllowPref, + "network.auth.subresource-http-img-XO-auth", + false); } NS_IMETHODIMP @@ -867,15 +872,15 @@ nsHttpChannelAuthProvider::GetCredentialsForChallenge(const char *challenge, else if (authFlags & nsIHttpAuthenticator::IDENTITY_ENCRYPTED) level = nsIAuthPrompt2::LEVEL_PW_ENCRYPTED; - // Depending on the pref setting, the authentication dialog may be + // Depending on the pref settings, the authentication dialog may be // blocked for all sub-resources, blocked for cross-origin // sub-resources, or always allowed for sub-resources. - // For more details look at the bug 647010. - // BlockPrompt will set mCrossOrigin parameter as well. + // If always allowed, image prompts may still be blocked by pref. + // BlockPrompt() will set the mCrossOrigin parameter as well. if (BlockPrompt()) { LOG(("nsHttpChannelAuthProvider::GetCredentialsForChallenge: " - "Prompt is blocked [this=%p pref=%d]\n", - this, sAuthAllowPref)); + "Prompt is blocked [this=%p pref=%d img-pref=%d]\n", + this, sAuthAllowPref, sImgCrossOriginAuthAllowPref)); return NS_ERROR_ABORT; } @@ -983,7 +988,15 @@ nsHttpChannelAuthProvider::BlockPrompt() // the sub-resources only if they are not cross-origin. return !topDoc && !xhr && mCrossOrigin; case SUBRESOURCE_AUTH_DIALOG_ALLOW_ALL: - // Allow the http-authentication dialog. + // Allow the http-authentication dialog for subresources. + // If the pref network.auth.subresource-http-img-XO-auth is set to false, + // the http authentication dialog for image subresources is still blocked. + if (!sImgCrossOriginAuthAllowPref && + loadInfo && + ((loadInfo->GetExternalContentPolicyType() == nsIContentPolicy::TYPE_IMAGE) || + (loadInfo->GetExternalContentPolicyType() == nsIContentPolicy::TYPE_IMAGESET))) { + return true; + } return false; default: // This is an invalid value. diff --git a/netwerk/protocol/http/nsHttpChannelAuthProvider.h b/netwerk/protocol/http/nsHttpChannelAuthProvider.h index 44d79b22b..0d6045875 100644 --- a/netwerk/protocol/http/nsHttpChannelAuthProvider.h +++ b/netwerk/protocol/http/nsHttpChannelAuthProvider.h @@ -179,10 +179,11 @@ private: RefPtr<nsHttpHandler> mHttpHandler; // keep gHttpHandler alive - // A variable holding the preference settings to whether to open HTTP + // Variables holding the preference settings for whether to open HTTP // authentication credentials dialogs for sub-resources and cross-origin // sub-resources. static uint32_t sAuthAllowPref; + static bool sImgCrossOriginAuthAllowPref; nsCOMPtr<nsICancelable> mGenerateCredentialsCancelable; }; diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp index 907f33436..d402b4104 100644 --- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp +++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp @@ -373,8 +373,12 @@ nsHttpConnectionMgr::VerifyTraffic() nsresult nsHttpConnectionMgr::DoShiftReloadConnectionCleanup(nsHttpConnectionInfo *aCI) { + RefPtr<nsHttpConnectionInfo> ci; + if (aCI) { + ci = aCI->Clone(); + } return PostEvent(&nsHttpConnectionMgr::OnMsgDoShiftReloadConnectionCleanup, - 0, aCI); + 0, ci); } class SpeculativeConnectArgs : public ARefBase @@ -504,9 +508,13 @@ nsHttpConnectionMgr::UpdateParam(nsParamName name, uint16_t value) } nsresult -nsHttpConnectionMgr::ProcessPendingQ(nsHttpConnectionInfo *ci) +nsHttpConnectionMgr::ProcessPendingQ(nsHttpConnectionInfo* aCI) { - LOG(("nsHttpConnectionMgr::ProcessPendingQ [ci=%s]\n", ci->HashKey().get())); + LOG(("nsHttpConnectionMgr::ProcessPendingQ [ci=%s]\n", aCI->HashKey().get())); + RefPtr<nsHttpConnectionInfo> ci; + if (aCI) { + ci = aCI->Clone(); + } return PostEvent(&nsHttpConnectionMgr::OnMsgProcessPendingQ, 0, ci); } @@ -1819,13 +1827,18 @@ nsHttpConnectionMgr::ProcessNewTransaction(nsHttpTransaction *trans) trans->SetPendingTime(); - Http2PushedStream *pushedStream = trans->GetPushedStream(); - if (pushedStream) { - LOG((" ProcessNewTransaction %p tied to h2 session push %p\n", - trans, pushedStream->Session())); - return pushedStream->Session()-> - AddStream(trans, trans->Priority(), false, nullptr) ? - NS_OK : NS_ERROR_UNEXPECTED; + RefPtr<Http2PushedStreamWrapper> pushedStreamWrapper = + trans->GetPushedStream(); + if (pushedStreamWrapper) { + Http2PushedStream* pushedStream = pushedStreamWrapper->GetStream(); + if (pushedStream) { + LOG((" ProcessNewTransaction %p tied to h2 session push %p\n", trans, + pushedStream->Session())); + return pushedStream->Session()->AddStream(trans, trans->Priority(), false, + nullptr) + ? NS_OK + : NS_ERROR_UNEXPECTED; + } } nsresult rv = NS_OK; diff --git a/netwerk/protocol/http/nsHttpHandler.h b/netwerk/protocol/http/nsHttpHandler.h index 67b9ebe0e..402147577 100644 --- a/netwerk/protocol/http/nsHttpHandler.h +++ b/netwerk/protocol/http/nsHttpHandler.h @@ -246,7 +246,8 @@ public: uint32_t caps = 0) { TickleWifi(callbacks); - return mConnMgr->SpeculativeConnect(ci, callbacks, caps); + RefPtr<nsHttpConnectionInfo> clone = ci->Clone(); + return mConnMgr->SpeculativeConnect(clone, callbacks, caps); } // Alternate Services Maps are main thread only diff --git a/netwerk/protocol/http/nsHttpTransaction.h b/netwerk/protocol/http/nsHttpTransaction.h index 262796d71..1197bd98e 100644 --- a/netwerk/protocol/http/nsHttpTransaction.h +++ b/netwerk/protocol/http/nsHttpTransaction.h @@ -131,14 +131,14 @@ public: nsHttpTransaction *QueryHttpTransaction() override { return this; } - Http2PushedStream *GetPushedStream() { return mPushedStream; } - Http2PushedStream *TakePushedStream() - { - Http2PushedStream *r = mPushedStream; - mPushedStream = nullptr; - return r; + already_AddRefed<Http2PushedStreamWrapper> GetPushedStream() { + return do_AddRef(mPushedStream); } - void SetPushedStream(Http2PushedStream *push) { mPushedStream = push; } + already_AddRefed<Http2PushedStreamWrapper> TakePushedStream() {
+ return mPushedStream.forget();
+ }
+
+ void SetPushedStream(Http2PushedStreamWrapper* push) { mPushedStream = push; } uint32_t InitialRwin() const { return mInitialRwin; }; bool ChannelPipeFull() { return mWaitingOnPipeOut; } @@ -264,7 +264,7 @@ private: // so far been skipped. uint32_t mInvalidResponseBytesRead; - Http2PushedStream *mPushedStream; + RefPtr<Http2PushedStreamWrapper> mPushedStream; uint32_t mInitialRwin; nsHttpChunkedDecoder *mChunkedDecoder; |