HTTP/2 and HTTP/3 server response should not send an empty trailers frame - #6319
Closed
jnbdz wants to merge 1 commit into
Closed
HTTP/2 and HTTP/3 server response should not send an empty trailers frame#6319jnbdz wants to merge 1 commit into
jnbdz wants to merge 1 commit into
Conversation
…rame Motivation: HttpServerResponse#trailers() lazily creates the trailers map, and the response end logic only checks whether the map exists. A handler that accesses the trailers without adding any makes the response send the last data frame without the end of stream flag, followed by an empty HEADERS frame that carries it. An empty trailers frame is valid, but it is an extra frame that serves no purpose and some clients do not handle it well. Fixes eclipse-vertx#3985. Changes: Treat an empty trailers map like no trailers when ending the response, so that the last data frame ends the stream. Add Http2ServerTest#testEmptyTrailers asserting that a single HEADERS frame is sent and that the last DATA frame ends the stream when the trailers are accessed but left empty.
Member
|
I think it is valid for HTTP/2 to end a stream with an empty headers frame and we should not prevent that, so I'm not if favor of this change. I think instead we should clearly document the side effect of calling the trailers() methods |
Contributor
Author
|
Fair enough, thanks for the review. I'll send a small follow-up documenting on |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
HttpServerResponse#trailers()lazily creates the trailers map, andHttpServerResponseImplonly checks whether the map exists when the response ends:A handler that accesses
trailers()without adding anything therefore sends the last DATA frame withoutEND_STREAM, followed by an empty HEADERS frame carrying it. An empty trailers frame is valid HTTP/2, but it is an extra frame that serves no purpose, and as reported in #3985 some clients do not handle it well.Fixes #3985 (the code discussed there has since been replaced by
HttpServerResponseImpl, shared by HTTP/2 and HTTP/3; the behaviour is the same).Changes
HttpServerResponseImpl#write: an empty trailers map is treated like no trailers, soEND_STREAMrides on the last DATA frame. Non-empty trailers are sent as before.Http2ServerTest#testEmptyTrailers: with the raw test client, asserts that exactly one HEADERS frame is received and that the last DATA frame ends the stream when the trailers are accessed but left empty. Without the change it fails withUnexpected trailers frame expected:<0> but was:<1>/Expected the last data frame to end the stream.HTTP/1.1 is unaffected:
Http1ServerResponsehas its own path where an empty trailer map already produces the same bytes as no trailers.Http2ServerTest,Http2Test,Http2MultiplexTest,Http3Test,Http3ServerTestand the existingtestResponseTrailers*/testResponseNoTrailerstests on HTTP/1.1, HTTP/2 and HTTP/3 pass locally.Independent from #6278 (request trailers), which does not touch the response path.