Figure out what to do about informational status codes
An HTTP/2.0 stream can begin with an arbitrary number of header frames with a 1xx status code.
The current API does not support this. My best guess would be doing something like this:
client
ResponseFuture is modified to be a future of (naming TBD):
enum Head {
Informational(ResponseFuture),
Response(Response<RecvBody>),
}
server
Respond gets a new fn: send_informational(response: Response<()>).
So first off, here's the informational status codes, just so we know what we're dealing with:
- 100 Continue: Should be sent if the client sends
Expect: 100-continuebefore sending a big body. - 101 Switching Protocols: Used for HTTP Upgrade requests, no longer supported in HTTP2.
- 102 Processing: From WebDAV extensions, should be used to let a client know the server is still working, don't time out. (Does this actually see any use?)
- 103 Early Hints: A brand new (Dec 2017) code to allow the sending of
Linkheaders quickly, allowing preloading of needed resources. (This seems like trying to backport push promises to HTTP/1.1, but maybe I'm missing something.)
Of these, I think:
- 100 can be handled automatically by both client and server.
- 101 isn't needed in h2.
- 102, uh, really?
- 103 seems like push promises. Perhaps they can be part of the same thing?
I don't think the h2 library should implicitly handle 100, leaving it up to a higher level library (hyper) to handle that. Also, custom 1xx is permitted and handling 1xx is also explicitly called out in the http 2.0 spec.
In that case, for the client, I'd probably put the informational status codes on a separate pollable method, since they are only informational, and unless I specifically want to handle them, I'd just ignore them.
For the server, a send_informational(res) seems fine.
Adding a server method can be done forwards compatibly, and if we put them in a separate function for the client, it can also.
they are only informational, and unless I specifically want to handle them, I'd just ignore them
This sounds right, do you know if the spec explicitly calls out that it is safe to ignore 1xx responses?
According to HTTP/1.1:
A user agent MAY ignore unexpected 1xx responses.
HTTP2 doesn't define any additional semantic value to 1xx status codes.
Ok, in that case I like adding poll_informational to client::ResponseFuture better. It is also a change that we can make post 0.1, so I will remove this issue from the milestone.
At first 103 might look very similar to server push (promise) It turns out though it is quite useful and different in some scenarios.
- CDNs: Server can't push what it doesn't have; Trigger preloading from different domains.
- Deduplication: where for server push you either know server side what assets the client has cached or risk duplication by relying on the client canceling the push - with early hints (103) the client can determine itself if it needs to load a specific resource which saves complexity and computation time in your application. (You waste some bytes for the potentially unneeded header of course)
These are just the biggest benefits I see in using 103. HAProxy seems to be on of the first to implement it https://www.haproxy.com/blog/haproxy-1-9-has-arrived/
@seanmonstar jfyi https://early-hints.fastlylabs.com/
Currently hyper just breaks with 103. We would like to fix that. Any pointers?
@inikulin I'd say the first step would be to update h2 to accept headers frames with a 1xx status code and at least ignore them, for now. That would make fix any places using them, and ignoring them isn't absurd, they are stricly informational. Since this issue is probably trying to capture "how do we expose those to the user", we could make a separate issue to first ignore them. Want to do that?
As a next step, and without breaking changes, can't we introduce a new method ResponseFuture::informational_responses(&mut self) that returns a stream of, well, informational responses?
The 103 Early Hints is a replacement for Server Push, which get removed from chrome and nginx.
Is there any plan to implement this?
https://github.com/hyperium/h2/pull/601 100-Continue may need to be reworked.