bug 955161 - spdy session sometimes shutdown when gecko cancels a sub transaction r=hurley
--- a/netwerk/protocol/http/ASpdySession.h
+++ b/netwerk/protocol/http/ASpdySession.h
@@ -39,16 +39,23 @@ public:
const static uint32_t kSendingChunkSize = 4096;
const static uint32_t kTCPSendBufferSize = 131072;
// until we have an API that can push back on receiving data (right now
// WriteSegments is obligated to accept data and buffer) there is no
// reason to throttle with the rwin other than in server push
// scenarios.
const static uint32_t kInitialRwin = 256 * 1024 * 1024;
+
+ bool SoftStreamError(nsresult code)
+ {
+ return (code == NS_BASE_STREAM_CLOSED || code == NS_BINDING_FAILED ||
+ code == NS_BINDING_ABORTED || code == NS_BINDING_REDIRECTED ||
+ code == NS_BINDING_RETARGETED);
+ }
};
// this is essentially a single instantiation as a member of nsHttpHandler.
// It could be all static except using static ctors of XPCOM objects is a
// bad idea.
class SpdyInformation
{
public:
--- a/netwerk/protocol/http/SpdySession3.cpp
+++ b/netwerk/protocol/http/SpdySession3.cpp
@@ -2011,32 +2011,33 @@ SpdySession3::WriteSegments(nsAHttpSegme
mNeedsCleanup = nullptr; /* just in case */
mSegmentWriter = writer;
rv = mInputFrameDataStream->WriteSegments(this, count, countWritten);
mSegmentWriter = nullptr;
mLastDataReadEpoch = mLastReadEpoch;
- if (rv == NS_BASE_STREAM_CLOSED) {
+ if (SoftStreamError(rv)) {
// This will happen when the transaction figures out it is EOF, generally
- // due to a content-length match being made
+ // due to a content-length match being made. Return OK from this function
+ // otherwise the whole session would be torn down.
SpdyStream3 *stream = mInputFrameDataStream;
// if we were doing PROCESSING_COMPLETE_HEADERS need to pop the state
// back to PROCESSING_DATA_FRAME where we came from
mDownstreamState = PROCESSING_DATA_FRAME;
if (mInputFrameDataRead == mInputFrameDataSize)
ResetDownstreamState();
LOG3(("SpdySession3::WriteSegments session=%p stream=%p 0x%X "
"needscleanup=%p. cleanup stream based on "
- "stream->writeSegments returning BASE_STREAM_CLOSED\n",
+ "stream->writeSegments returning code %X\n",
this, stream, stream ? stream->StreamID() : 0,
- mNeedsCleanup));
+ mNeedsCleanup, rv));
CleanupStream(stream, NS_OK, RST_CANCEL);
MOZ_ASSERT(!mNeedsCleanup, "double cleanup out of data frame");
mNeedsCleanup = nullptr; /* just in case */
return NS_OK;
}
if (mNeedsCleanup) {
LOG3(("SpdySession3::WriteSegments session=%p stream=%p 0x%X "
--- a/netwerk/protocol/http/SpdySession31.cpp
+++ b/netwerk/protocol/http/SpdySession31.cpp
@@ -2080,32 +2080,33 @@ SpdySession31::WriteSegments(nsAHttpSegm
mNeedsCleanup = nullptr; /* just in case */
mSegmentWriter = writer;
rv = mInputFrameDataStream->WriteSegments(this, count, countWritten);
mSegmentWriter = nullptr;
mLastDataReadEpoch = mLastReadEpoch;
- if (rv == NS_BASE_STREAM_CLOSED) {
+ if (SoftStreamError(rv)) {
// This will happen when the transaction figures out it is EOF, generally
- // due to a content-length match being made
+ // due to a content-length match being made. Return OK from this function
+ // otherwise the whole session would be torn down.
SpdyStream31 *stream = mInputFrameDataStream;
// if we were doing PROCESSING_COMPLETE_HEADERS need to pop the state
// back to PROCESSING_DATA_FRAME where we came from
mDownstreamState = PROCESSING_DATA_FRAME;
if (mInputFrameDataRead == mInputFrameDataSize)
ResetDownstreamState();
LOG3(("SpdySession31::WriteSegments session=%p stream=%p 0x%X "
"needscleanup=%p. cleanup stream based on "
- "stream->writeSegments returning BASE_STREAM_CLOSED\n",
+ "stream->writeSegments returning code %X\n",
this, stream, stream ? stream->StreamID() : 0,
- mNeedsCleanup));
+ mNeedsCleanup, rv));
CleanupStream(stream, NS_OK, RST_CANCEL);
MOZ_ASSERT(!mNeedsCleanup, "double cleanup out of data frame");
mNeedsCleanup = nullptr; /* just in case */
return NS_OK;
}
if (mNeedsCleanup) {
LOG3(("SpdySession31::WriteSegments session=%p stream=%p 0x%X "