-
Notifications
You must be signed in to change notification settings - Fork 45
Description
tldr: We're currently always accepting Expect: 100-continue
headers, where we should be enabling header validation before we send back an intermediate 100
status code.
Expected behavior
The 100 continue
header exists in order to signal to a client that the request has been understood, and all the headers are correct. This enables validating things like encoding, offsets, and authentication before proceeding to transfer a significant amount of data.
The validation of these headers should be defined by end-users, as they are the ones that will know which combination of headers is acceptable.
Current behavior
async-h1
is currently hardcoded to always reply with 100
to the Expect: 100-continue
header. This means end-users don't have a chance to validate headers before proceeding.
Lines 132 to 144 in 3a368bd
const EXPECT_HEADER_VALUE: &str = "100-continue"; | |
const EXPECT_RESPONSE: &[u8] = b"HTTP/1.1 100 Continue\r\n\r\n"; | |
async fn handle_100_continue<IO>(req: &Request, io: &mut IO) -> http_types::Result<()> | |
where | |
IO: Write + Unpin, | |
{ | |
if let Some(EXPECT_HEADER_VALUE) = req.header(EXPECT).map(|h| h.as_str()) { | |
io.write_all(EXPECT_RESPONSE).await?; | |
} | |
Ok(()) | |
} |
Implementation
We should provide some way for end-users to validate headers before sending back the 100 continue response. I'm not quite sure how to do this, but one option would be to handle only send over 100-continue
when the first chunk of the request body is requested. That would indicate that the framework has successfully parsed the headers, and is now ready to receive the body.
If a Response
is returned before the Request
body has finished, that would likely carry a non-100
status code, and the client would know not to send the request body. So semantically I think that would be the right way to go?
If at all possible I think we should evade exposing the Expect: 100-continue
semantics to end-users, since the back and forth dance is quite complex, needs to work out of the box, and doesn't fit well with the req/res
model we use in http-rs.