summaryrefslogtreecommitdiffstats
path: root/netwerk/protocol/http
diff options
context:
space:
mode:
Diffstat (limited to 'netwerk/protocol/http')
-rw-r--r--netwerk/protocol/http/TunnelUtils.cpp67
-rw-r--r--netwerk/protocol/http/TunnelUtils.h11
-rw-r--r--netwerk/protocol/http/nsHttpConnection.cpp21
-rw-r--r--netwerk/protocol/http/nsHttpConnection.h3
4 files changed, 71 insertions, 31 deletions
diff --git a/netwerk/protocol/http/TunnelUtils.cpp b/netwerk/protocol/http/TunnelUtils.cpp
index 4cc24a07f..6880e0187 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 {
@@ -42,6 +43,7 @@ TLSFilterTransaction::TLSFilterTransaction(nsAHttpTransaction *aWrapped,
, mSegmentReader(aReader)
, mSegmentWriter(aWriter)
, mForce(false)
+ , mReadSegmentReturnValue(NS_OK)
, mNudgeCounter(0)
{
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
@@ -130,6 +132,19 @@ TLSFilterTransaction::Close(nsresult aReason)
}
mTransaction->Close(aReason);
mTransaction = nullptr;
+
+ RefPtr<NullHttpTransaction> baseTrans(do_QueryReferent(mWeakTrans));
+ SpdyConnectTransaction *trans = baseTrans
+ ? baseTrans->QuerySpdyConnectTransaction()
+ : nullptr;
+
+ LOG(("TLSFilterTransaction::Close %p aReason=%" PRIx32 " trans=%p\n",
+ this, static_cast<uint32_t>(aReason), trans));
+
+ if (trans) {
+ trans->Close(aReason);
+ trans = nullptr;
+ }
}
nsresult
@@ -140,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;
@@ -188,10 +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
- mReadSegmentBlocked = (PR_GetError() == PR_WOULD_BLOCK_ERROR);
- return mReadSegmentBlocked ? NS_BASE_STREAM_WOULD_BLOCK : NS_ERROR_FAILURE;
+ PRErrorCode code = PR_GetError();
+ mReadSegmentReturnValue = ErrorAccordingToNSPR(code);
+
+ return mReadSegmentReturnValue;
}
aCount -= written;
aData += written;
@@ -273,10 +290,18 @@ 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;
+ // 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<uint32_t>(mFilterReadCode)));
+ }
+ return mFilterReadCode;
}
*outCountRead = bytesRead;
@@ -303,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;
}
}
@@ -325,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<uint32_t>(rv)));
Connection()->ForceSend();
}
- return rv;
+ return NS_SUCCEEDED(rv) ? mReadSegmentReturnValue : rv;
}
nsresult
@@ -442,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;
}
@@ -456,7 +483,7 @@ TLSFilterTransaction::StartTimerCallback()
// This class can be called re-entrantly, so cleanup m* before ->on()
RefPtr<NudgeTunnelCallback> cb(mNudgeCallback);
mNudgeCallback = nullptr;
- cb->OnTunnelNudged(this);
+ return cb->OnTunnelNudged(this);
}
return NS_OK;
}
@@ -675,10 +702,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<nsIInterfaceRequestor> callbacks;
@@ -688,6 +717,8 @@ TLSFilterTransaction::SetProxiedTransaction(nsAHttpTransaction *aTrans)
secCtrl->SetNotificationCallbacks(callbacks);
}
+ mWeakTrans = do_GetWeakReference(aSpdyConnectTransaction);
+
return NS_OK;
}
@@ -1075,7 +1106,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..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
@@ -121,7 +122,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 +155,7 @@ private:
private:
RefPtr<nsAHttpTransaction> mTransaction;
+ nsWeakPtr mWeakTrans; // SpdyConnectTransaction *
nsCOMPtr<nsISupports> mSecInfo;
nsCOMPtr<nsITimer> mTimer;
RefPtr<NudgeTunnelCallback> mNudgeCallback;
@@ -168,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 8ccba76e2..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
@@ -639,7 +639,9 @@ nsHttpConnection::Activate(nsAHttpTransaction *trans, uint32_t caps, int32_t pri
}
if (mTLSFilter) {
- mTLSFilter->SetProxiedTransaction(trans);
+ RefPtr<NullHttpTransaction> 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<nsAHttpTransaction> mTransaction;
RefPtr<TLSFilterTransaction> mTLSFilter;
+ nsWeakPtr mWeakTrans; // SpdyConnectTransaction *
RefPtr<nsHttpHandler> mHttpHandler; // keep gHttpHandler alive