-
Notifications
You must be signed in to change notification settings - Fork 62
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
Transfer-Encoding and Content-Length #90
Comments
Sounds like a good course of action to me. What do you think @njsmith? |
Hmm. This is a tricky issue. I think your interpretation of the RFC isn't quite right, and then separately there's a question of what h11 should do, so I'll discuss those separately. What does RFC 7230 actually say?
This is unambiguous about what senders have to do, but technically it doesn't say anything about what receivers should do. And RFC 7230 often makes different rules for the two. For an especially egregious example, consider request targets. They have both an "origin form" ( What requirements does the RFC impose on receivers? There's this bit you quote:
...but I don't think that helps us here. This is from a section that's summarizing changes from RFC 2616, so it's not the actual standard; it's just referring to text elsewhere in the RFC for the details. And I think specifically it's referring to this bit from 3.3.3:
This is one of the few places where RFC 7230 uses that unambiguous "MUST treat it as an unrecoverable error" language. But notice that it specifically goes out of its way to not forbid a The key section here in general is 3.3.3, which is worth reading carefully in its entirety. Basically h11's message framing handling right now is a strict translation of the algorithm given in 3.3.3 into code. And in particular, that section is clear that But it still manages to leave a fair amount of wiggle room, including this very frustrating paragraph:
So it says you "ought" to "handle it as an error", AND ALSO gives instructions on how to handle it as not-an-error. And I have no idea what "ought" or "handled as an error" mean in RFC-ese; they're undefined terms. Fabulous. So... I think that's all we're getting from RFC 7230. What should h11 do?The current behavior is definitely defensible within the RFC. But the RFC isn't totally clear, plus we sometimes intentionally deviate from the RFC when it makes sense, so that doesn't settle things. I can think of three options that are worth considering (am I missing any?):
The trade-off here is that if we're more restrictive, then we're more robust against smuggling/splitting attacks, but we might be less interoperable with other implementations. Phil found an example of haproxy being vulnerable to smuggling attacks here, but that was fixed a while ago. I'm not sure how serious a concern this is currently; if everyone implements the RFC properly, then this isn't an issue, so the question is how well other code implements it, which is something I don't know. That's also the issue with interoperability... before making any changes, it would be good to check how some other major HTTP implementations handle this case, like browsers, curl, go's net/http. (My guess is that they all act like h11 does now, i.e. silently ignore the |
Currently h11 accepts a message with both Content-Length and Transfer-Encoding with the latter taking precedence. However RFC 7230 states
A sender MUST NOT send a Content-Length header field in any message that contains a Transfer-Encoding header field.
. This seems to be an intentional change from RFC 2616 (Bogus Content-Length header fields are now required to be handled as errors by recipients. (Section 3.3.2)
).Would you accept a PR to change the handling from 2616 to 7230 i.e. raise a ProtocolError if both are present?
The text was updated successfully, but these errors were encountered: