Bug 1409570 - Ensure a pushed stream knows we've reached EOS. r=mcmanus

Previously, if a pushed stream was ended with a padding-only DATA frame
with the FIN bit set, and that stream didn't have a Content-Length,
there would be no way of knowing that the stream was finished. Now we
force-mark the push as complete if we hit a padding-only DATA frame with
the FIN bit set.

MozReview-Commit-ID: 7tk8x2FNgSj

--HG--
extra : rebase_source : b95f635b4bb0b4743cf81e888a455365ef561c22
This commit is contained in:
Nicholas Hurley 2017-10-18 12:34:42 -07:00
Родитель 692bf7d21f
Коммит 29bf3169ae
3 изменённых файлов: 13 добавлений и 2 удалений

Просмотреть файл

@ -68,6 +68,7 @@ public:
// overload of Http2Stream
virtual bool HasSink() override { return !!mConsumerStream; }
virtual void SetPushComplete() override { mPushCompleted = true; }
nsCString &GetRequestString() { return mRequestString; }

Просмотреть файл

@ -3284,8 +3284,9 @@ Http2Session::WriteSegmentsAgain(nsAHttpSegmentWriter *writer,
char trash[4096];
uint32_t discardCount = std::min(mInputFrameDataSize - mInputFrameDataRead,
4096U);
LOG3(("Http2Session::WriteSegments %p trying to discard %d bytes of data",
this, discardCount));
LOG3(("Http2Session::WriteSegments %p trying to discard %d bytes of %s",
this, discardCount,
mDownstreamState == DISCARDING_DATA_FRAME ? "data" : "padding"));
if (!discardCount && mDownstreamState == DISCARDING_DATA_FRAME) {
// Only do this short-cirtuit if we're not discarding a pure padding
@ -3317,9 +3318,15 @@ Http2Session::WriteSegmentsAgain(nsAHttpSegmentWriter *writer,
streamToCleanup = mInputFrameDataStream;
}
bool discardedPadding = (mDownstreamState == DISCARDING_DATA_FRAME_PADDING);
ResetDownstreamState();
if (streamToCleanup) {
if (discardedPadding && !(streamToCleanup->StreamID() & 1)) {
// Pushed streams are special on padding-only final data frames.
// See bug 1409570 comments 6-8 for details.
streamToCleanup->SetPushComplete();
}
CleanupStream(streamToCleanup, NS_OK, CANCEL_ERROR);
}
}

Просмотреть файл

@ -153,6 +153,9 @@ public:
// once it is matched to a pull stream.
virtual bool HasSink() { return true; }
// This is a no-op on pull streams. Pushed streams override this.
virtual void SetPushComplete() { };
virtual ~Http2Stream();
Http2Session *Session() { return mSession; }