mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 19:35:51 +00:00
Bug 1429973 part 1 - plumb through trailers in h2 to support server-timing. r=bagder
MozReview-Commit-ID: JV1Ikb9cYCV --HG-- extra : rebase_source : fa67fef606fc02355579dae42f8e66c4754d60a0
This commit is contained in:
parent
d956bcaac3
commit
be1b7537f2
@ -1433,13 +1433,16 @@ Http2Session::ResponseHeadersComplete()
|
||||
LOG3(("Http2Session::ResponseHeadersComplete %p for 0x%X fin=%d",
|
||||
this, mInputFrameDataStream->StreamID(), mInputFrameFinal));
|
||||
|
||||
// only interpret headers once, afterwards ignore as trailers
|
||||
// Anything prior to AllHeadersReceived() => true is actual headers. After
|
||||
// that, we need to handle them as trailers instead (which are special-cased
|
||||
// so we don't have to use the nasty chunked parser for all h2, just in case).
|
||||
if (mInputFrameDataStream->AllHeadersReceived()) {
|
||||
LOG3(("Http2Session::ResponseHeadersComplete extra headers"));
|
||||
LOG3(("Http2Session::ResponseHeadersComplete processing trailers"));
|
||||
MOZ_ASSERT(mInputFrameFlags & kFlag_END_STREAM);
|
||||
nsresult rv = UncompressAndDiscard(false);
|
||||
nsresult rv = mInputFrameDataStream->ConvertResponseTrailers(&mDecompressor,
|
||||
mDecompressBuffer);
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG3(("Http2Session::ResponseHeadersComplete extra uncompress failed\n"));
|
||||
LOG3(("Http2Session::ResponseHeadersComplete trailer conversion failed\n"));
|
||||
return rv;
|
||||
}
|
||||
mFlatHTTPResponseHeadersOut = 0;
|
||||
|
@ -1023,6 +1023,8 @@ Http2Stream::ConvertResponseHeaders(Http2Decompressor *decompressor,
|
||||
int32_t &httpResponseCode)
|
||||
{
|
||||
aHeadersOut.Truncate();
|
||||
// Add in some space to hopefully not have to reallocate while decompressing
|
||||
// the headers. 512 bytes seems like a good enough number.
|
||||
aHeadersOut.SetCapacity(aHeadersIn.Length() + 512);
|
||||
|
||||
nsresult rv =
|
||||
@ -1106,6 +1108,8 @@ Http2Stream::ConvertPushHeaders(Http2Decompressor *decompressor,
|
||||
nsACString &aHeadersOut)
|
||||
{
|
||||
aHeadersOut.Truncate();
|
||||
// Add in some space to hopefully not have to reallocate while decompressing
|
||||
// the headers. 512 bytes seems like a good enough number.
|
||||
aHeadersOut.SetCapacity(aHeadersIn.Length() + 512);
|
||||
nsresult rv =
|
||||
decompressor->DecodeHeaderBlock(reinterpret_cast<const uint8_t *>(aHeadersIn.BeginReading()),
|
||||
@ -1142,6 +1146,35 @@ Http2Stream::ConvertPushHeaders(Http2Decompressor *decompressor,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Http2Stream::ConvertResponseTrailers(Http2Decompressor *decompressor,
|
||||
nsACString &aTrailersIn)
|
||||
{
|
||||
LOG3(("Http2Stream::ConvertResponseTrailers %p", this));
|
||||
nsAutoCString flatTrailers;
|
||||
// Add in some space to hopefully not have to reallocate while decompressing
|
||||
// the headers. 512 bytes seems like a good enough number.
|
||||
flatTrailers.SetCapacity(aTrailersIn.Length() + 512);
|
||||
|
||||
nsresult rv =
|
||||
decompressor->DecodeHeaderBlock(reinterpret_cast<const uint8_t *>(aTrailersIn.BeginReading()),
|
||||
aTrailersIn.Length(),
|
||||
flatTrailers, false);
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG3(("Http2Stream::ConvertResponseTrailers %p decode Error", this));
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsHttpTransaction *trans = mTransaction->QueryHttpTransaction();
|
||||
if (trans) {
|
||||
trans->SetHttpTrailers(flatTrailers);
|
||||
} else {
|
||||
LOG3(("Http2Stream::ConvertResponseTrailers %p no trans", this));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
Http2Stream::Close(nsresult reason)
|
||||
{
|
||||
|
@ -125,6 +125,8 @@ public:
|
||||
nsACString &, int32_t &);
|
||||
MOZ_MUST_USE nsresult ConvertPushHeaders(Http2Decompressor *, nsACString &,
|
||||
nsACString &);
|
||||
MOZ_MUST_USE nsresult ConvertResponseTrailers(Http2Decompressor *,
|
||||
nsACString &);
|
||||
|
||||
bool AllowFlowControlledWrite();
|
||||
void UpdateServerReceiveWindow(int32_t delta);
|
||||
|
@ -1782,9 +1782,9 @@ nsHttpTransaction::HandleContent(char *buf,
|
||||
if ((mContentRead == mContentLength) ||
|
||||
(mChunkedDecoder && mChunkedDecoder->ReachedEOF())) {
|
||||
MutexAutoLock lock(*nsHttp::GetLock());
|
||||
mForTakeResponseTrailers = mChunkedDecoder
|
||||
? mChunkedDecoder->TakeTrailers()
|
||||
: nullptr;
|
||||
if (mChunkedDecoder) {
|
||||
mForTakeResponseTrailers = mChunkedDecoder->TakeTrailers();
|
||||
}
|
||||
|
||||
// the transaction is done with a complete response.
|
||||
mTransactionDone = true;
|
||||
@ -2438,5 +2438,42 @@ nsHttpTransaction::Refused0RTT()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHttpTransaction::SetHttpTrailers(nsCString &aTrailers)
|
||||
{
|
||||
LOG(("nsHttpTransaction::SetHttpTrailers %p", this));
|
||||
LOG(("[\n %s\n]", aTrailers.BeginReading()));
|
||||
if (!mForTakeResponseTrailers) {
|
||||
mForTakeResponseTrailers = new nsHttpHeaderArray();
|
||||
}
|
||||
|
||||
int32_t cur = 0;
|
||||
int32_t len = aTrailers.Length();
|
||||
while (cur < len) {
|
||||
int32_t newline = aTrailers.FindCharInSet("\n", cur);
|
||||
if (newline == -1) {
|
||||
newline = len;
|
||||
}
|
||||
|
||||
int32_t end = aTrailers[newline - 1] == '\r' ? newline - 1 : newline;
|
||||
nsDependentCSubstring line(aTrailers, cur, end);
|
||||
nsHttpAtom hdr = {nullptr};
|
||||
nsAutoCString hdrNameOriginal;
|
||||
nsAutoCString val;
|
||||
if (NS_SUCCEEDED(mForTakeResponseTrailers->ParseHeaderLine(line, &hdr, &hdrNameOriginal, &val))) {
|
||||
if (hdr == nsHttp::Server_Timing) {
|
||||
Unused << mForTakeResponseTrailers->SetHeaderFromNet(hdr, hdrNameOriginal, val, true);
|
||||
}
|
||||
}
|
||||
|
||||
cur = newline + 1;
|
||||
}
|
||||
|
||||
if (mForTakeResponseTrailers->Count() == 0) {
|
||||
// Didn't find a Server-Timing header, so get rid of this.
|
||||
mForTakeResponseTrailers = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
@ -191,6 +191,8 @@ public:
|
||||
}
|
||||
|
||||
void SetFastOpenStatus(uint8_t aStatus) override;
|
||||
|
||||
void SetHttpTrailers(nsCString &aTrailers);
|
||||
private:
|
||||
friend class DeleteHttpTransaction;
|
||||
virtual ~nsHttpTransaction();
|
||||
|
Loading…
Reference in New Issue
Block a user