From 97d11fb71a75405e7f8233a884023434182667e6 Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Sat, 9 Jan 2021 10:46:50 +1300 Subject: [PATCH] HTTP/3: Fix decoding trailing headers (#46734) --- .../System/Net/Http/aspnetcore/Http3/QPack/QPackDecoder.cs | 11 +++++++++-- .../System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs | 3 +++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/QPackDecoder.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/QPackDecoder.cs index a500c9b..fdb0356 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/QPackDecoder.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/QPackDecoder.cs @@ -167,14 +167,21 @@ namespace System.Net.Http.QPack } } + /// + /// Reset the decoder state back to its initial value. Resetting state is required when reusing a decoder with multiple + /// header frames. For example, decoding a response's headers and trailers. + /// + public void Reset() + { + _state = State.RequiredInsertCount; + } + public void Decode(in ReadOnlySequence headerBlock, IHttpHeadersHandler handler) { foreach (ReadOnlyMemory segment in headerBlock) { Decode(segment.Span, handler); } - - _state = State.RequiredInsertCount; } public void Decode(ReadOnlySpan headerBlock, IHttpHeadersHandler handler) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs index eefd608..ad85cbd 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs @@ -808,6 +808,9 @@ namespace System.Net.Http _recvBuffer.Discard(processLength); headersLength -= processLength; } + + // Reset decoder state. Require because one decoder instance is reused to decode headers and trailers. + _headerDecoder.Reset(); } private static ReadOnlySpan StatusHeaderNameBytes => new byte[] { (byte)'s', (byte)'t', (byte)'a', (byte)'t', (byte)'u', (byte)'s' }; -- 2.7.4