From b1ee77a7cf699c8eedc1e0bf9b46a02b48cad306 Mon Sep 17 00:00:00 2001 From: Patrick McManus Date: Mon, 9 Apr 2012 10:21:17 -0400 Subject: [PATCH] bug 742935: fix landing problem with 603512 r=honzab --- netwerk/protocol/http/nsAHttpConnection.h | 2 +- netwerk/protocol/http/nsHttpChunkedDecoder.h | 2 ++ netwerk/protocol/http/nsHttpConnection.cpp | 1 + netwerk/protocol/http/nsHttpConnection.h | 1 - netwerk/protocol/http/nsHttpConnectionMgr.h | 2 +- netwerk/protocol/http/nsHttpHandler.h | 4 ++-- netwerk/protocol/http/nsHttpPipeline.cpp | 7 +++++-- netwerk/protocol/http/nsHttpTransaction.cpp | 8 +++++--- 8 files changed, 17 insertions(+), 10 deletions(-) diff --git a/netwerk/protocol/http/nsAHttpConnection.h b/netwerk/protocol/http/nsAHttpConnection.h index 2bbb39aeb58e..aeabb751a5c2 100644 --- a/netwerk/protocol/http/nsAHttpConnection.h +++ b/netwerk/protocol/http/nsAHttpConnection.h @@ -122,7 +122,7 @@ public: // called to determine or set if a connection has been reused. virtual bool IsReused() = 0; - virtual void DontReuse() = 0; + virtual void DontReuse() = 0; // called by a transaction when the transaction reads more from the socket // than it should have (eg. containing part of the next pipelined response). diff --git a/netwerk/protocol/http/nsHttpChunkedDecoder.h b/netwerk/protocol/http/nsHttpChunkedDecoder.h index 14620f87f0c2..f0c07e098278 100644 --- a/netwerk/protocol/http/nsHttpChunkedDecoder.h +++ b/netwerk/protocol/http/nsHttpChunkedDecoder.h @@ -67,6 +67,8 @@ public: mTrailers = nsnull; return h; } + PRUint32 GetChunkRemaining() { return mChunkRemaining; } + private: nsresult ParseChunkRemaining(char *buf, PRUint32 count, diff --git a/netwerk/protocol/http/nsHttpConnection.cpp b/netwerk/protocol/http/nsHttpConnection.cpp index 9be69a032242..d63fb8846813 100644 --- a/netwerk/protocol/http/nsHttpConnection.cpp +++ b/netwerk/protocol/http/nsHttpConnection.cpp @@ -56,6 +56,7 @@ #include "SpdySession.h" #include "mozilla/Telemetry.h" #include "nsISupportsPriority.h" +#include "nsHttpPipeline.h" #ifdef DEBUG // defined by the socket transport service while active diff --git a/netwerk/protocol/http/nsHttpConnection.h b/netwerk/protocol/http/nsHttpConnection.h index 959691323bdb..4fcd2ddfce5a 100644 --- a/netwerk/protocol/http/nsHttpConnection.h +++ b/netwerk/protocol/http/nsHttpConnection.h @@ -42,7 +42,6 @@ #include "nsHttp.h" #include "nsHttpConnectionInfo.h" #include "nsAHttpTransaction.h" -#include "nsHttpPipeline.h" #include "nsXPIDLString.h" #include "nsCOMPtr.h" #include "nsAutoPtr.h" diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.h b/netwerk/protocol/http/nsHttpConnectionMgr.h index 19bb33594340..d760957e27d2 100644 --- a/netwerk/protocol/http/nsHttpConnectionMgr.h +++ b/netwerk/protocol/http/nsHttpConnectionMgr.h @@ -55,7 +55,7 @@ #include "nsITimer.h" #include "nsIX509Cert3.h" -#include "nsHttpPipeline.h" +class nsHttpPipeline; //----------------------------------------------------------------------------- diff --git a/netwerk/protocol/http/nsHttpHandler.h b/netwerk/protocol/http/nsHttpHandler.h index 210c1bfdeaf3..1489fb69dde6 100644 --- a/netwerk/protocol/http/nsHttpHandler.h +++ b/netwerk/protocol/http/nsHttpHandler.h @@ -233,9 +233,9 @@ public: nsCString& hostLine); bool GetPipelineAggressive() { return mPipelineAggressive; } - void GetMaxPipelineObjectSize(PRInt64 &outVal) + void GetMaxPipelineObjectSize(PRInt64 *outVal) { - outVal = mMaxPipelineObjectSize; + *outVal = mMaxPipelineObjectSize; } PRIntervalTime GetPipelineTimeout() { return mPipelineReadTimeout; } diff --git a/netwerk/protocol/http/nsHttpPipeline.cpp b/netwerk/protocol/http/nsHttpPipeline.cpp index ab5094fb7f05..edba9e2e70ce 100644 --- a/netwerk/protocol/http/nsHttpPipeline.cpp +++ b/netwerk/protocol/http/nsHttpPipeline.cpp @@ -294,9 +294,10 @@ nsHttpPipeline::CloseTransaction(nsAHttpTransaction *trans, nsresult reason) trans->Close(reason); NS_RELEASE(trans); - if (killPipeline) + if (killPipeline) { // reschedule anything from this pipeline onto a different connection CancelPipeline(reason); + } } void @@ -843,7 +844,9 @@ nsHttpPipeline::CancelPipeline(nsresult originalReason) mRequestQ.Clear(); // any pending responses can be restarted except for the first one, - // that we might want to finish on this pipeline or cancel individually + // that we might want to finish on this pipeline or cancel individually. + // Higher levels of callers ensure that we don't process non-idempotent + // tranasction with the NS_HTTP_ALLOW_PIPELINING bit set for (i = 1; i < respLen; ++i) { trans = Response(i); trans->Close(NS_ERROR_NET_RESET); diff --git a/netwerk/protocol/http/nsHttpTransaction.cpp b/netwerk/protocol/http/nsHttpTransaction.cpp index ee7e73f34656..8699c8feff5e 100644 --- a/netwerk/protocol/http/nsHttpTransaction.cpp +++ b/netwerk/protocol/http/nsHttpTransaction.cpp @@ -144,7 +144,7 @@ nsHttpTransaction::nsHttpTransaction() , mResponseHeadTaken(false) { LOG(("Creating nsHttpTransaction @%x\n", this)); - gHttpHandler->GetMaxPipelineObjectSize(mMaxPipelineObjectSize); + gHttpHandler->GetMaxPipelineObjectSize(&mMaxPipelineObjectSize); } nsHttpTransaction::~nsHttpTransaction() @@ -1366,8 +1366,10 @@ nsHttpTransaction::HandleContent(char *buf, // for this response reschedule the pipeline if ((mClassification != CLASS_SOLO) && mChunkedDecoder && - (mContentRead > mMaxPipelineObjectSize)) + ((mContentRead + mChunkedDecoder->GetChunkRemaining()) > + mMaxPipelineObjectSize)) { CancelPipeline(nsHttpConnectionMgr::BadUnexpectedLarge); + } // check for end-of-file if ((mContentRead == mContentLength) || @@ -1479,7 +1481,7 @@ nsHttpTransaction::CancelPipeline(PRUint32 reason) static_cast(reason), nsnull, mClassification); - mConnection->CancelPipeline(NS_ERROR_CORRUPTED_CONTENT); + mConnection->CancelPipeline(NS_ERROR_ABORT); // Avoid pipelining this transaction on restart by classifying it as solo. // This also prevents BadUnexpectedLarge from being reported more