-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
http3: implement HTTP Datagrams and Capsules (RFC 9297) #3522
Comments
Writing and parsing of CAPSULEs was implement by #3607. |
The API will be a bit tricky. Here's a proposal. On the client side
HTTP Datagrams are always associated with an HTTP Request (section 2 of the RFC):
It seems like the type RoundTripperWithDatagrams interface {
RoundTripWithDatagrams(*http.Request) (Datagrammer, <-chan *http.Response, error)
} Calling type Datagrammer interface {
// SendMessage sends an HTTP Datagram associated with an HTTP request.
// It must only be called while the send side of the stream is still open, i.e.
// * on the client side: before calling Close on the request body
// * on the server side: before calling Close on the response body
SendMessage([]byte) error
// SendMessage receives an HTTP Datagram associated with an HTTP request:
// * on the server side: datagrams can be received while the request handler hasn't returned, AND
// the client hasn't close the request stream yet
// * on the client side: datagrams can be received with the server hasn't close the response stream
ReceiveMessage(context.Context) ([]byte, error)
} Note that while this interface looks like the functions exposed the On the server side
On the server side, we need to be able to associate datagrams with an HTTP handler. This is easier to implement, since |
Would like to take a stab. |
Go for it! Happy to review a PR. Let me know if you have any questions! |
I'll be working on this issue in the coming weeks. Thank you @tanghaowillow for your PR, there are a lot of helpful things in there. API-wise, the client side is the tricky part: The client is allowed to send HTTP datagrams as soon as it has opened the stream (or better, to reduce reordering, after the request headers have been sent out). However, #4141 suggests the following API: // RoundTripResult is the result of a HTTP RoundTrip execution
type RoundTripResult struct {
Resp *http.Response
Err error
}
datagrammer, respChan, err := client.Transport.(*http3.RoundTripper).RoundTripWithDatagrams(req) This function would return immediately, or probably better, after the server's SETTINGS were received and the check for HTTP DATAGRAM support was performed. Note that there are now two errors to check: the one returned from I'm currently leaning towards a slightly different API that doesn't change the // RoundTripOpt are options for the Transport.RoundTripOpt method.
type RoundTripOpt struct {
// DatagrammerReady is called as soon as the server's SETTINGS frame is received,
// and HTTP DATAGRAM support is enabled.
// If HTTP DATAGRAMs are not supported, the request won't be sent to the server
// and a ErrNoDatagrams error is returned.
DatagrammerReady func(Datagrammer)
} I don't particularly like this API either, but we're kind of limited with what we can do if we don't want to stray away too far from the standard library's net/http API pattern. |
Hi @marten-seemann sorry for missing this issue. And let move our discussion here. In my previous proposal #4372 I suggest this following APIs. For the client side req, err := http.NewRequest(http.MethodConnect, addr, nil)
req.Proto = "connect-ip"
rsp, err := client.Do(req)
s := rsp.Body.(http3.HTTPStreamer).HTTPStream()
defer s.Close()
d, ok := s.Datagrammer()
data, _ := d.ReceiveMessage(context.Background())
d.SendMessage(data) For the server side server.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.(http.Flusher).Flush()
s := r.Body.(http3.HTTPStreamer).HTTPStream()
defer s.Close()
d, ok := s.Datagrammer()
data, _ := d.ReceiveMessage(context.Background())
d.SendMessage(data)
}) You does not agree this proposal:
Please allow me to explain my design. According to RFC9297:
In theory, the datagram can be transmitted with known stream. However, in reality, it may not. Because if the server The server's SETTINGS frame is received does not necessarily means that the client should send the datagam now. But allowing datagram sending as early as possible is also of performance benefit. But this will complicate the API design Just FYI. |
@marten-seemann Anyway, wish this issue being fixed as soon as possible! |
@marten-seemann Sorry I should have updated my status on #4141 earlier. The implementation was more complex than I thought and yes the API did make me more hesitate to go on. Must say that the newly proposed API is much cleaner since it can get rid of checking peer's setting in every call of |
Hello @marten-seemann , would you like to disclose any progress or schedule for you work on this issue? Thanks~
|
It's part of the milestone for the next release. |
HTTP Datagram support was just merged in #4452! Took us a while, but we're finally there :) Thanks for your patience everyone! |
https://www.rfc-editor.org/rfc/rfc9297.html
The text was updated successfully, but these errors were encountered: