-
Notifications
You must be signed in to change notification settings - Fork 43
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
Semantics of informational responses. #1108
Comments
Don't get too hung up on the high-level semantic categories of responses. While one could argue that 101 is more appropriately cast as a final response (e.g., 2xx), there are counter-arguments, including that the operation on the target resource never actually completes from a HTTP standpoint when the protocol switches. 101 does specify its semantics with precision. While new status codes are required to conform to the general requirements of the category they're in, there are many exceptions due to history -- see eg a very similar situation with regard to whether a status code can have content. |
I totally see your point -- 101 indicates that the protocol being spoken on the connection has changed, and the request's response will occur in the new protocol. As far as HTTP is concerned, it can be viewed as final, since there's no more HTTP to do; as far as the request is concerned, it's not, since the request is the starting point for the new protocol. (As you alluded to, this is reflected in the now-deprecated Personally, I think our mistake was in removing Upgrade/101 support in HTTP/2+; the CONNECT + Both Upgrade and CONNECT have semantics that don't sit well with the rest of HTTP, and unfortunately one just has to special-case them. I don't think changing the specs in this respect will make them fit any better, just differently. |
I would like to discuss how we may improve the clarity of the specification with respect to informational responses. Thanks in advance for everyone's efforts in discussing this matter.
Firstly, let's clarify, a response is a status code, a set of headers, and an optional body, as shown in https://www.rfc-editor.org/rfc/rfc9110#section-3.9. Furthermore, a response may use the 1xx status code, which is considered "Informational" and "Interim" and "prior to completing a final response".
By this definition, one may expect that responses with a 1xx status code will always be followed by a non-1xx final response. This is important for ensuring secure response handling with persistent connections. For example, a persistent connection is only secure if, after making a request, all responses are consumed relating to that request. As HTTP/1.x provides no additional request/response delineation, I believe it's important that we have a clear definition of "interim" and "final" response codes.
For the sake of the argument, a client may do the following:
If, for whatever reason, the specification of
final?
is not well-defined, it would be entirely possible for the next user of the connection, to read a response from a previous request, causing a potentially serious security issue. Unfortunately HTTP request smuggling is a fairly common form of attack, usually due to ambiguity in request/response processing and interpretation.My goal is to seek clarity regarding the definition of "final" response - as the author of HTTP/1, HTTP/2 and HTTP/3 (in progress) client and server implementations for Ruby, I have significant exposure to these specifications and implementation details. Recently, I was made aware that I was handling this incorrectly and sought out clarifications from the specifications (RFCs), but felt the wording of the informational responses does not reflect the reality of how they must be handled.
Specifically,
101 Switching Protocols
does not appear to be an interim response, at least not in all cases, and certainly not with respect to the framing of the connection as per the above pseudo-code example. It's true that clients must handle 101 explicitly, but at the protocol/stream level, my implementation handles it the same as any other response (as per the above pseudo code, essentially). In that case, the 101 response MUST be returned to the client as a final response, so that it can complete the upgrade.In other words, even thought the specifications state that responses with a 1xx status code will be followed by a "final response", this is not true for
101 Switching Protocols
.I believe that additional clarification should be provided around the
101 Switching Protocols
status code. Perhaps under https://www.rfc-editor.org/rfc/rfc9110#section-15.2.2 we can state that "A response with a status code of 101 switching protocols, in the context of the original connection, is considered a final response, as no subsequent non-1xx response will be sent by the server."To support this change, I present the following thoughts:
CONNECT
and expects a normal final response with status code 200 in order to complete the negotiation. I think this strongly suggests that the use of 101 in HTTP/1.1 for WebSockets, was at best, a stretch (hypothetically speaking, it feels more like201 Switching Protocols
).101 Switching Protocols
and HTTP/2's200 OK
are the same for the sake of what the user actually cares about, and at the level of the client implementation, are considered the same "final response" before wrapping the underlying stream with WebSocket framing.101 Switching Protocols
having a subsequent response at the same protocol level. It was used (but apparently deprecated) for upgrading HTTP/1 to HTTP/2 in the past, however, this "final response" is operating at a totally different semantic level to the original request protocol, so I don't feel that we should consider this example.1xx
responses should be followed by a final response. In other words, such a clarification seeks to resolve ambiguity but does not introduce any new semantics or definitions that aren't already present in the specification.My hope, by clarifying this, is that I can be confident in saying "101 Switching Protocols" is, for all intents and purposes, considered a final response, with respect to the protocol and framing of the original connection. The specification is, in my humble opinion, currently, both at odds and in support of the above statement. I'd like to fix that.
The text was updated successfully, but these errors were encountered: