-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Don't assume 1xx (101) should have the (streaming) body stripped by Rack::Response
.
#1987
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
b982e29
to
9f79a1e
Compare
9f79a1e
to
b5b5cac
Compare
@jeremyevans stripping headers and effectively setting an empty body in
In that case, I'd vote for |
RFC 2616 and 7231 (HTTP 1.1) do not allow bodies for any 1xx responses:
RFC 7540 (HTTP 2) seems to imply 101 can have a body (https://datatracker.ietf.org/doc/html/rfc7540#section-8.1.3). So it would probably be best to only keep the body for 101 if HTTP 2 is the protocol in use. |
There is no technical limitation for HTTP/2 to have a response body for any status code. This is different from HTTP/1 where the client will literally break because it affects the protocol parser state. I personally think that the server itself should enforce the semantics of the protocol, but I'm not against the You are correct that HTTP/1 101 status code does not officially have a body in the typical sense of all other HTTP/1 responses. However we treat it as equivalent for the sake of convenience and this distinction is unimportant for HTTP/2 since it does not have an upgrade mechanism. (1) Since servers already have to do this (or risk being totally broken), why is it also important for (2) Your proposal of handling 101 for HTTP/2 doesn't make sense since HTTP/2 doesn't use 101 upgrade mechanism. So do you agree with this PR or want additional changes or a different approach entirely? |
If this doesn't matter for HTTP/2, and the HTTP/1.1 RFCs do not allow for a body for any 1xx response, I would leave the current behavior. Why would we want to break backwards compatibility to allow something that isn't allowed by the RFCs? If you want to allow the new behavior, the new behavior needs to be optional and off by default. If you want to change the default behavior, you need to put the change through a normal deprecation cycle (warning for all responses with bodies where you will change the behavior) before the default behavior is changed in Rack 4. |
Can you explain how one is supposed to send a 101 upgrade with a streaming response body using |
To clarify:
They do not allow for an entity body which I would argue is only a subset of Rack's concept of a response body (i.e. a streaming response body can be used for an upgrade request). In other words, it's perfectly valid to return |
@@ -537,7 +537,11 @@ def context(env, app = @app) | |||
} | |||
|
|||
# Responses with HTTP status codes that should not have an entity body | |||
STATUS_WITH_NO_ENTITY_BODY = Hash[((100..199).to_a << 204 << 304).product([true])] | |||
STATUS_WITH_NO_ENTITY_BODY = { | |||
100 => true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd be happy to add 102 and 103 to this list.
Alternatively, we could just remove this check entirely from Rack::Response
which is probably slightly more correct (servers MUST implement it anyway, otherwise raw [status, headers, body]
response could break the connection). However, this breaks more tests which assume Rack::Response
cleans things up in this regard.
Thank you for explaining the difference.
So for 101 (or all 1xx, 204, 302 statuses), passing a callable body through without changes seems reasonable. However, I think an enumerable body should still be replaced with an empty array. |
This is required to use
Rack::Response
for generating streaming responses. Otherwise, for 101 status codes, it will strip the body.Alternatives include changing
Rack::Response#finish
to not do any stripping, and leave it up to the sever (to fail would probably be the best, generating content for a No Content or Not Changed response seems at best weird and at worst a bug).