From d38ddd92e159113aae22c4dc8f03dc2285e01b14 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Thu, 7 Mar 2019 12:45:54 +0100 Subject: Part 1: network component changes. --- netwerk/protocol/http/AlternateServices.cpp | 7 ++- netwerk/protocol/http/HttpBaseChannel.cpp | 5 ++- netwerk/protocol/http/HttpBaseChannel.h | 3 +- netwerk/protocol/http/nsHttpChannel.cpp | 14 ++++-- netwerk/protocol/http/nsHttpChannel.h | 3 +- netwerk/protocol/http/nsHttpHandler.cpp | 67 ++++++++++++++++++++++++++--- netwerk/protocol/http/nsHttpHandler.h | 20 +++++++-- 7 files changed, 100 insertions(+), 19 deletions(-) (limited to 'netwerk/protocol/http') diff --git a/netwerk/protocol/http/AlternateServices.cpp b/netwerk/protocol/http/AlternateServices.cpp index b3e6babe3..ee2fa9331 100644 --- a/netwerk/protocol/http/AlternateServices.cpp +++ b/netwerk/protocol/http/AlternateServices.cpp @@ -654,8 +654,13 @@ private: { nsID channelId; nsLoadFlags flags; + + nsContentPolicyType contentPolicyType = + loadInfo ? loadInfo->GetExternalContentPolicyType() + : nsIContentPolicy::TYPE_OTHER; + if (NS_FAILED(gHttpHandler->NewChannelId(&channelId)) || - NS_FAILED(chan->Init(uri, caps, nullptr, 0, nullptr, channelId)) || + NS_FAILED(chan->Init(uri, caps, nullptr, 0, nullptr, channelId, contentPolicyType)) || NS_FAILED(chan->SetAllowAltSvc(false)) || NS_FAILED(chan->SetRedirectMode(nsIHttpChannelInternal::REDIRECT_MODE_ERROR)) || NS_FAILED(chan->SetLoadInfo(loadInfo)) || diff --git a/netwerk/protocol/http/HttpBaseChannel.cpp b/netwerk/protocol/http/HttpBaseChannel.cpp index 9e43d89e0..86e177e71 100644 --- a/netwerk/protocol/http/HttpBaseChannel.cpp +++ b/netwerk/protocol/http/HttpBaseChannel.cpp @@ -151,7 +151,8 @@ HttpBaseChannel::Init(nsIURI *aURI, nsProxyInfo *aProxyInfo, uint32_t aProxyResolveFlags, nsIURI *aProxyURI, - const nsID& aChannelId) + const nsID& aChannelId, + nsContentPolicyType aContentPolicyType) { LOG(("HttpBaseChannel::Init [this=%p]\n", this)); @@ -200,7 +201,7 @@ HttpBaseChannel::Init(nsIURI *aURI, rv = mRequestHead.SetHeader(nsHttp::Host, hostLine); if (NS_FAILED(rv)) return rv; - rv = gHttpHandler->AddStandardRequestHeaders(&mRequestHead, isHTTPS); + rv = gHttpHandler->AddStandardRequestHeaders(&mRequestHead, isHTTPS, aContentPolicyType); if (NS_FAILED(rv)) return rv; nsAutoCString type; diff --git a/netwerk/protocol/http/HttpBaseChannel.h b/netwerk/protocol/http/HttpBaseChannel.h index 9aa696a70..8def0f23c 100644 --- a/netwerk/protocol/http/HttpBaseChannel.h +++ b/netwerk/protocol/http/HttpBaseChannel.h @@ -99,7 +99,8 @@ public: virtual nsresult Init(nsIURI *aURI, uint32_t aCaps, nsProxyInfo *aProxyInfo, uint32_t aProxyResolveFlags, nsIURI *aProxyURI, - const nsID& aChannelId); + const nsID& aChannelId, + nsContentPolicyType aContentPolicyType); // nsIRequest NS_IMETHOD GetName(nsACString& aName) override; diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index a890c51b3..481df5ff0 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -324,10 +324,16 @@ nsHttpChannel::Init(nsIURI *uri, nsProxyInfo *proxyInfo, uint32_t proxyResolveFlags, nsIURI *proxyURI, - const nsID& channelId) -{ - nsresult rv = HttpBaseChannel::Init(uri, caps, proxyInfo, - proxyResolveFlags, proxyURI, channelId); + const nsID& channelId, + nsContentPolicyType aContentPolicyType) +{ + nsresult rv = HttpBaseChannel::Init(uri, + caps, + proxyInfo, + proxyResolveFlags, + proxyURI, + channelId, + aContentPolicyType); if (NS_FAILED(rv)) return rv; diff --git a/netwerk/protocol/http/nsHttpChannel.h b/netwerk/protocol/http/nsHttpChannel.h index 554875b1c..0038e1f71 100644 --- a/netwerk/protocol/http/nsHttpChannel.h +++ b/netwerk/protocol/http/nsHttpChannel.h @@ -123,7 +123,8 @@ public: virtual nsresult Init(nsIURI *aURI, uint32_t aCaps, nsProxyInfo *aProxyInfo, uint32_t aProxyResolveFlags, nsIURI *aProxyURI, - const nsID& aChannelId) override; + const nsID& aChannelId, + nsContentPolicyType aContentPolicyType) override; nsresult OnPush(const nsACString &uri, Http2PushedStream *pushedStream); diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp index 477961454..0f4c94202 100644 --- a/netwerk/protocol/http/nsHttpHandler.cpp +++ b/netwerk/protocol/http/nsHttpHandler.cpp @@ -468,7 +468,9 @@ nsHttpHandler::InitConnectionMgr() } nsresult -nsHttpHandler::AddStandardRequestHeaders(nsHttpRequestHead *request, bool isSecure) +nsHttpHandler::AddStandardRequestHeaders(nsHttpRequestHead *request, + bool isSecure, + nsContentPolicyType aContentPolicyType) { nsresult rv; @@ -481,7 +483,20 @@ nsHttpHandler::AddStandardRequestHeaders(nsHttpRequestHead *request, bool isSecu // Add the "Accept" header. Note, this is set as an override because the // service worker expects to see it. The other "default" headers are // hidden from service worker interception. - rv = request->SetHeader(nsHttp::Accept, mAccept, + nsAutoCString accept; + if (aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT || + aContentPolicyType == nsIContentPolicy::TYPE_SUBDOCUMENT) { + accept.Assign(mAcceptNavigation); + } else if (aContentPolicyType == nsIContentPolicy::TYPE_IMAGE || + aContentPolicyType == nsIContentPolicy::TYPE_IMAGESET) { + accept.Assign(mAcceptImage); + } else if (aContentPolicyType == nsIContentPolicy::TYPE_STYLESHEET) { + accept.Assign(mAcceptStyle); + } else { + accept.Assign(mAcceptDefault); + } + + rv = request->SetHeader(nsHttp::Accept, accept, false, nsHttpHeaderArray::eVarietyRequestOverride); if (NS_FAILED(rv)) return rv; @@ -1268,12 +1283,36 @@ nsHttpHandler::PrefsChanged(nsIPrefBranch *prefs, const char *pref) mQoSBits = (uint8_t) clamped(val, 0, 0xff); } + if (PREF_CHANGED(HTTP_PREF("accept.navigation"))) { + nsXPIDLCString accept; + rv = prefs->GetCharPref(HTTP_PREF("accept.navigation"), + getter_Copies(accept)); + if (NS_SUCCEEDED(rv)) + SetAccept(accept, ACCEPT_NAVIGATION); + } + + if (PREF_CHANGED(HTTP_PREF("accept.image"))) { + nsXPIDLCString accept; + rv = prefs->GetCharPref(HTTP_PREF("accept.image"), + getter_Copies(accept)); + if (NS_SUCCEEDED(rv)) + SetAccept(accept, ACCEPT_IMAGE); + } + + if (PREF_CHANGED(HTTP_PREF("accept.style"))) { + nsXPIDLCString accept; + rv = prefs->GetCharPref(HTTP_PREF("accept.style"), + getter_Copies(accept)); + if (NS_SUCCEEDED(rv)) + SetAccept(accept, ACCEPT_STYLE); + } + if (PREF_CHANGED(HTTP_PREF("accept.default"))) { nsXPIDLCString accept; rv = prefs->GetCharPref(HTTP_PREF("accept.default"), getter_Copies(accept)); if (NS_SUCCEEDED(rv)) - SetAccept(accept); + SetAccept(accept, ACCEPT_DEFAULT); } if (PREF_CHANGED(HTTP_PREF("accept-encoding"))) { @@ -1897,9 +1936,21 @@ nsHttpHandler::SetAcceptLanguages() } nsresult -nsHttpHandler::SetAccept(const char *aAccept) +nsHttpHandler::SetAccept(const char *aAccept, AcceptType aType) { - mAccept = aAccept; + switch (aType) { + case ACCEPT_NAVIGATION: + mAcceptNavigation = aAccept; + break; + case ACCEPT_IMAGE: + mAcceptImage = aAccept; + break; + case ACCEPT_STYLE: + mAcceptStyle = aAccept; + break; + case ACCEPT_DEFAULT: + mAcceptDefault = aAccept; + } return NS_OK; } @@ -2057,7 +2108,11 @@ nsHttpHandler::NewProxiedChannel2(nsIURI *uri, rv = NewChannelId(&channelId); NS_ENSURE_SUCCESS(rv, rv); - rv = httpChannel->Init(uri, caps, proxyInfo, proxyResolveFlags, proxyURI, channelId); + nsContentPolicyType contentPolicyType = + aLoadInfo ? aLoadInfo->GetExternalContentPolicyType() + : nsIContentPolicy::TYPE_OTHER; + + rv = httpChannel->Init(uri, caps, proxyInfo, proxyResolveFlags, proxyURI, channelId, contentPolicyType); if (NS_FAILED(rv)) return rv; diff --git a/netwerk/protocol/http/nsHttpHandler.h b/netwerk/protocol/http/nsHttpHandler.h index f1ec0f947..67b9ebe0e 100644 --- a/netwerk/protocol/http/nsHttpHandler.h +++ b/netwerk/protocol/http/nsHttpHandler.h @@ -15,6 +15,7 @@ #include "nsCOMPtr.h" #include "nsWeakReference.h" +#include "nsIContentPolicy.h" #include "nsIHttpProtocolHandler.h" #include "nsIObserver.h" #include "nsISpeculativeConnect.h" @@ -50,6 +51,14 @@ enum FrameCheckLevel { FRAMECHECK_STRICT }; +// Fetch spec different http Accept types +enum AcceptType { + ACCEPT_NAVIGATION, + ACCEPT_IMAGE, + ACCEPT_STYLE, + ACCEPT_DEFAULT, +}; + //----------------------------------------------------------------------------- // nsHttpHandler - protocol handler for HTTP and HTTPS //----------------------------------------------------------------------------- @@ -70,7 +79,7 @@ public: nsHttpHandler(); nsresult Init(); - nsresult AddStandardRequestHeaders(nsHttpRequestHead *, bool isSecure); + nsresult AddStandardRequestHeaders(nsHttpRequestHead *, bool isSecure, nsContentPolicyType aContentPolicyType); nsresult AddConnectionHeader(nsHttpRequestHead *, uint32_t capabilities); bool IsAcceptableEncoding(const char *encoding, bool isSecure); @@ -385,7 +394,7 @@ private: void InitUserAgentComponents(); void PrefsChanged(nsIPrefBranch *prefs, const char *pref); - nsresult SetAccept(const char *); + nsresult SetAccept(const char *, AcceptType aType); nsresult SetAcceptLanguages(); nsresult SetAcceptEncodings(const char *, bool mIsSecure); @@ -394,8 +403,8 @@ private: void NotifyObservers(nsIHttpChannel *chan, const char *event); static void TimerCallback(nsITimer * aTimer, void * aClosure); + private: - // cached services nsMainThreadPtrHandle mIOService; nsMainThreadPtrHandle mStreamConvSvc; @@ -460,7 +469,10 @@ private: bool mPipeliningOverSSL; bool mEnforceAssocReq; - nsCString mAccept; + nsCString mAcceptNavigation; + nsCString mAcceptImage; + nsCString mAcceptStyle; + nsCString mAcceptDefault; nsCString mAcceptLanguages; nsCString mHttpAcceptEncodings; nsCString mHttpsAcceptEncodings; -- cgit v1.2.3 From 3403d5f049bf476a495c30026d5002db0e742887 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Fri, 22 Mar 2019 18:41:22 +0100 Subject: Close the transaction if PR_Read/PR_Write failed. When PR_Read/PR_White returns -1, we have to use ErrorAccordingToNSPR to get the error code. We need to close the transaction if a real error happens. --- netwerk/protocol/http/TunnelUtils.cpp | 44 ++++++++++++++++++++++++------ netwerk/protocol/http/TunnelUtils.h | 4 ++- netwerk/protocol/http/nsHttpConnection.cpp | 15 ++++++---- netwerk/protocol/http/nsHttpConnection.h | 3 +- 4 files changed, 51 insertions(+), 15 deletions(-) (limited to 'netwerk/protocol/http') diff --git a/netwerk/protocol/http/TunnelUtils.cpp b/netwerk/protocol/http/TunnelUtils.cpp index 4cc24a07f..71adef9d7 100644 --- a/netwerk/protocol/http/TunnelUtils.cpp +++ b/netwerk/protocol/http/TunnelUtils.cpp @@ -23,6 +23,7 @@ #include "nsNetCID.h" #include "nsServiceManagerUtils.h" #include "nsComponentManagerUtils.h" +#include "nsSocketTransport2.h" namespace mozilla { namespace net { @@ -130,6 +131,19 @@ TLSFilterTransaction::Close(nsresult aReason) } mTransaction->Close(aReason); mTransaction = nullptr; + + RefPtr baseTrans(do_QueryReferent(mWeakTrans)); + SpdyConnectTransaction *trans = baseTrans + ? baseTrans->QuerySpdyConnectTransaction() + : nullptr; + + LOG(("TLSFilterTransaction::Close %p aReason=%" PRIx32 " trans=%p\n", + this, static_cast(aReason), trans)); + + if (trans) { + trans->Close(aReason); + trans = nullptr; + } } nsresult @@ -190,8 +204,15 @@ TLSFilterTransaction::OnReadSegment(const char *aData, // mTransaction ReadSegments actually obscures this code, so // keep it in a member var for this::ReadSegments to insepct. Similar // to nsHttpConnection::mSocketOutCondition - mReadSegmentBlocked = (PR_GetError() == PR_WOULD_BLOCK_ERROR); - return mReadSegmentBlocked ? NS_BASE_STREAM_WOULD_BLOCK : NS_ERROR_FAILURE; + PRErrorCode code = PR_GetError(); + mReadSegmentBlocked = (code == PR_WOULD_BLOCK_ERROR); + if (mReadSegmentBlocked) { + return NS_BASE_STREAM_WOULD_BLOCK; + } + + nsresult rv = ErrorAccordingToNSPR(code); + Close(rv); + return rv; } aCount -= written; aData += written; @@ -273,10 +294,13 @@ TLSFilterTransaction::OnWriteSegment(char *aData, mFilterReadCode = NS_OK; int32_t bytesRead = PR_Read(mFD, aData, aCount); if (bytesRead == -1) { - if (PR_GetError() == PR_WOULD_BLOCK_ERROR) { + PRErrorCode code = PR_GetError(); + if (code == PR_WOULD_BLOCK_ERROR) { return NS_BASE_STREAM_WOULD_BLOCK; } - return NS_ERROR_FAILURE; + nsresult rv = ErrorAccordingToNSPR(code); + Close(rv); + return rv; } *outCountRead = bytesRead; @@ -675,10 +699,12 @@ TLSFilterTransaction::TakeSubTransactions( } nsresult -TLSFilterTransaction::SetProxiedTransaction(nsAHttpTransaction *aTrans) +TLSFilterTransaction::SetProxiedTransaction(nsAHttpTransaction *aTrans, + nsAHttpTransaction *aSpdyConnectTransaction) { - LOG(("TLSFilterTransaction::SetProxiedTransaction [this=%p] aTrans=%p\n", - this, aTrans)); + LOG(("TLSFilterTransaction::SetProxiedTransaction [this=%p] aTrans=%p, " + "aSpdyConnectTransaction=%p\n", + this, aTrans, aSpdyConnectTransaction)); mTransaction = aTrans; nsCOMPtr callbacks; @@ -688,6 +714,8 @@ TLSFilterTransaction::SetProxiedTransaction(nsAHttpTransaction *aTrans) secCtrl->SetNotificationCallbacks(callbacks); } + mWeakTrans = do_GetWeakReference(aSpdyConnectTransaction); + return NS_OK; } @@ -1075,7 +1103,7 @@ SpdyConnectTransaction::MapStreamToHttpConnection(nsISocketTransport *aTransport if (mForcePlainText) { mTunneledConn->ForcePlainText(); } else { - mTunneledConn->SetupSecondaryTLS(); + mTunneledConn->SetupSecondaryTLS(this); mTunneledConn->SetInSpdyTunnel(true); } diff --git a/netwerk/protocol/http/TunnelUtils.h b/netwerk/protocol/http/TunnelUtils.h index 20cfaf7ee..7e491a0d7 100644 --- a/netwerk/protocol/http/TunnelUtils.h +++ b/netwerk/protocol/http/TunnelUtils.h @@ -121,7 +121,8 @@ public: nsresult CommitToSegmentSize(uint32_t size, bool forceCommitment) override; nsresult GetTransactionSecurityInfo(nsISupports **) override; nsresult NudgeTunnel(NudgeTunnelCallback *callback); - nsresult SetProxiedTransaction(nsAHttpTransaction *aTrans); + MOZ_MUST_USE nsresult SetProxiedTransaction(nsAHttpTransaction *aTrans, + nsAHttpTransaction *aSpdyConnectTransaction = nullptr); void newIODriver(nsIAsyncInputStream *aSocketIn, nsIAsyncOutputStream *aSocketOut, nsIAsyncInputStream **outSocketIn, @@ -153,6 +154,7 @@ private: private: RefPtr mTransaction; + nsWeakPtr mWeakTrans; // SpdyConnectTransaction * nsCOMPtr mSecInfo; nsCOMPtr mTimer; RefPtr mNudgeCallback; diff --git a/netwerk/protocol/http/nsHttpConnection.cpp b/netwerk/protocol/http/nsHttpConnection.cpp index 8ccba76e2..71a08e177 100644 --- a/netwerk/protocol/http/nsHttpConnection.cpp +++ b/netwerk/protocol/http/nsHttpConnection.cpp @@ -639,7 +639,9 @@ nsHttpConnection::Activate(nsAHttpTransaction *trans, uint32_t caps, int32_t pri } if (mTLSFilter) { - mTLSFilter->SetProxiedTransaction(trans); + RefPtr baseTrans(do_QueryReferent(mWeakTrans)); + rv = mTLSFilter->SetProxiedTransaction(trans, baseTrans); + NS_ENSURE_SUCCESS(rv, rv); mTransaction = mTLSFilter; } @@ -1979,7 +1981,7 @@ nsHttpConnection::OnSocketReadable() // negotiation are known (which is determined from the write path). // If the server speaks SPDY it is likely the readable data here is // a spdy settings frame and without NPN it would be misinterpreted - // as HTTP/* + // as HTTP LOG(("nsHttpConnection::OnSocketReadable %p return due to inactive " "tunnel setup but incomplete NPN state\n", this)); @@ -2019,12 +2021,14 @@ nsHttpConnection::OnSocketReadable() } void -nsHttpConnection::SetupSecondaryTLS() +nsHttpConnection::SetupSecondaryTLS(nsAHttpTransaction *aSpdyConnectTransaction) { MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); MOZ_ASSERT(!mTLSFilter); - LOG(("nsHttpConnection %p SetupSecondaryTLS %s %d\n", - this, mConnInfo->Origin(), mConnInfo->OriginPort())); + LOG(("nsHttpConnection %p SetupSecondaryTLS %s %d " + "aSpdyConnectTransaction=%p\n", + this, mConnInfo->Origin(), mConnInfo->OriginPort(), + aSpdyConnectTransaction)); nsHttpConnectionInfo *ci = nullptr; if (mTransaction) { @@ -2041,6 +2045,7 @@ nsHttpConnection::SetupSecondaryTLS() if (mTransaction) { mTransaction = mTLSFilter; } + mWeakTrans = do_GetWeakReference(aSpdyConnectTransaction); } void diff --git a/netwerk/protocol/http/nsHttpConnection.h b/netwerk/protocol/http/nsHttpConnection.h index 08eea1de2..ce7523eb5 100644 --- a/netwerk/protocol/http/nsHttpConnection.h +++ b/netwerk/protocol/http/nsHttpConnection.h @@ -202,7 +202,7 @@ public: static nsresult MakeConnectString(nsAHttpTransaction *trans, nsHttpRequestHead *request, nsACString &result); - void SetupSecondaryTLS(); + void SetupSecondaryTLS(nsAHttpTransaction *aSpdyConnectTransaction = nullptr); void SetInSpdyTunnel(bool arg); // Check active connections for traffic (or not). SPDY connections send a @@ -281,6 +281,7 @@ private: // transaction is open, otherwise it is null. RefPtr mTransaction; RefPtr mTLSFilter; + nsWeakPtr mWeakTrans; // SpdyConnectTransaction * RefPtr mHttpHandler; // keep gHttpHandler alive -- cgit v1.2.3 From a4013251854b88cacf4eeb221c36e696f468ed64 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Fri, 22 Mar 2019 20:11:09 +0100 Subject: Return proper error if the nss layer encounters an error on the http tunnel. --- netwerk/protocol/http/TunnelUtils.cpp | 43 ++++++++++++++++-------------- netwerk/protocol/http/TunnelUtils.h | 7 ++--- netwerk/protocol/http/nsHttpConnection.cpp | 6 ++--- 3 files changed, 30 insertions(+), 26 deletions(-) (limited to 'netwerk/protocol/http') diff --git a/netwerk/protocol/http/TunnelUtils.cpp b/netwerk/protocol/http/TunnelUtils.cpp index 71adef9d7..6880e0187 100644 --- a/netwerk/protocol/http/TunnelUtils.cpp +++ b/netwerk/protocol/http/TunnelUtils.cpp @@ -43,6 +43,7 @@ TLSFilterTransaction::TLSFilterTransaction(nsAHttpTransaction *aWrapped, , mSegmentReader(aReader) , mSegmentWriter(aWriter) , mForce(false) + , mReadSegmentReturnValue(NS_OK) , mNudgeCounter(0) { MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); @@ -154,7 +155,7 @@ TLSFilterTransaction::OnReadSegment(const char *aData, LOG(("TLSFilterTransaction %p OnReadSegment %d (buffered %d)\n", this, aCount, mEncryptedTextUsed)); - mReadSegmentBlocked = false; + mReadSegmentReturnValue = NS_OK; MOZ_ASSERT(mSegmentReader); if (!mSecInfo) { return NS_ERROR_FAILURE; @@ -202,17 +203,12 @@ TLSFilterTransaction::OnReadSegment(const char *aData, return NS_OK; } // mTransaction ReadSegments actually obscures this code, so - // keep it in a member var for this::ReadSegments to insepct. Similar + // keep it in a member var for this::ReadSegments to inspect. Similar // to nsHttpConnection::mSocketOutCondition PRErrorCode code = PR_GetError(); - mReadSegmentBlocked = (code == PR_WOULD_BLOCK_ERROR); - if (mReadSegmentBlocked) { - return NS_BASE_STREAM_WOULD_BLOCK; - } + mReadSegmentReturnValue = ErrorAccordingToNSPR(code); - nsresult rv = ErrorAccordingToNSPR(code); - Close(rv); - return rv; + return mReadSegmentReturnValue; } aCount -= written; aData += written; @@ -298,9 +294,14 @@ TLSFilterTransaction::OnWriteSegment(char *aData, if (code == PR_WOULD_BLOCK_ERROR) { return NS_BASE_STREAM_WOULD_BLOCK; } - nsresult rv = ErrorAccordingToNSPR(code); - Close(rv); - return rv; + // If reading from the socket succeeded (NS_SUCCEEDED(mFilterReadCode)), + // but the nss layer encountered an error remember the error. + if (NS_SUCCEEDED(mFilterReadCode)) { + mFilterReadCode = ErrorAccordingToNSPR(code); + LOG(("TLSFilterTransaction::OnWriteSegment %p nss error %" PRIx32 ".\n", + this, static_cast(mFilterReadCode))); + } + return mFilterReadCode; } *outCountRead = bytesRead; @@ -327,7 +328,7 @@ TLSFilterTransaction::FilterInput(char *aBuf, int32_t aAmount) if (NS_SUCCEEDED(mFilterReadCode) && outCountRead) { LOG(("TLSFilterTransaction::FilterInput rv=%x read=%d input from net " "1 layer stripped, 1 still on\n", mFilterReadCode, outCountRead)); - if (mReadSegmentBlocked) { + if (mReadSegmentReturnValue == NS_BASE_STREAM_WOULD_BLOCK) { mNudgeCounter = 0; } } @@ -349,19 +350,18 @@ TLSFilterTransaction::ReadSegments(nsAHttpSegmentReader *aReader, return NS_ERROR_UNEXPECTED; } - mReadSegmentBlocked = false; + mReadSegmentReturnValue = NS_OK; mSegmentReader = aReader; nsresult rv = mTransaction->ReadSegments(this, aCount, outCountRead); LOG(("TLSFilterTransaction %p called trans->ReadSegments rv=%x %d\n", this, rv, *outCountRead)); - if (NS_SUCCEEDED(rv) && mReadSegmentBlocked) { - rv = NS_BASE_STREAM_WOULD_BLOCK; + if (NS_SUCCEEDED(rv) && (mReadSegmentReturnValue == NS_BASE_STREAM_WOULD_BLOCK)) { LOG(("TLSFilterTransaction %p read segment blocked found rv=%x\n", - this, rv)); + this, static_cast(rv))); Connection()->ForceSend(); } - return rv; + return NS_SUCCEEDED(rv) ? mReadSegmentReturnValue : rv; } nsresult @@ -466,7 +466,10 @@ TLSFilterTransaction::Notify(nsITimer *timer) if (timer != mTimer) { return NS_ERROR_UNEXPECTED; } - StartTimerCallback(); + nsresult rv = StartTimerCallback(); + if (NS_FAILED(rv)) { + Close(rv); + } return NS_OK; } @@ -480,7 +483,7 @@ TLSFilterTransaction::StartTimerCallback() // This class can be called re-entrantly, so cleanup m* before ->on() RefPtr cb(mNudgeCallback); mNudgeCallback = nullptr; - cb->OnTunnelNudged(this); + return cb->OnTunnelNudged(this); } return NS_OK; } diff --git a/netwerk/protocol/http/TunnelUtils.h b/netwerk/protocol/http/TunnelUtils.h index 7e491a0d7..4a003082e 100644 --- a/netwerk/protocol/http/TunnelUtils.h +++ b/netwerk/protocol/http/TunnelUtils.h @@ -93,10 +93,11 @@ class TLSFilterTransaction; class NudgeTunnelCallback : public nsISupports { public: - virtual void OnTunnelNudged(TLSFilterTransaction *) = 0; + virtual nsresult OnTunnelNudged(TLSFilterTransaction *) = 0; }; -#define NS_DECL_NUDGETUNNELCALLBACK void OnTunnelNudged(TLSFilterTransaction *) override; +#define NS_DECL_NUDGETUNNELCALLBACK \ + nsresult OnTunnelNudged(TLSFilterTransaction *) override; class TLSFilterTransaction final : public nsAHttpTransaction @@ -170,7 +171,7 @@ private: nsresult mFilterReadCode; bool mForce; - bool mReadSegmentBlocked; + nsresult mReadSegmentReturnValue; uint32_t mNudgeCounter; }; diff --git a/netwerk/protocol/http/nsHttpConnection.cpp b/netwerk/protocol/http/nsHttpConnection.cpp index 71a08e177..505d849c0 100644 --- a/netwerk/protocol/http/nsHttpConnection.cpp +++ b/netwerk/protocol/http/nsHttpConnection.cpp @@ -535,16 +535,16 @@ npnComplete: return true; } -void +nsresult nsHttpConnection::OnTunnelNudged(TLSFilterTransaction *trans) { MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); LOG(("nsHttpConnection::OnTunnelNudged %p\n", this)); if (trans != mTLSFilter) { - return; + return NS_OK; } LOG(("nsHttpConnection::OnTunnelNudged %p Calling OnSocketWritable\n", this)); - OnSocketWritable(); + return OnSocketWritable(); } // called on the socket thread -- cgit v1.2.3