http3: add support for HTTP Datagrams (RFC 9297) (#4452)

* http3: add support for HTTP Datagrams (RFC 9297)

* README: reference HTTP Datagrams (RFC 9297)
This commit is contained in:
Marten Seemann
2024-04-26 20:21:04 +02:00
committed by GitHub
parent 11b11594b2
commit 2a37c53143
16 changed files with 790 additions and 121 deletions

View File

@@ -422,8 +422,6 @@ func (s *Server) removeListener(l *QUICEarlyListener) {
}
func (s *Server) handleConn(conn quic.Connection) error {
decoder := qpack.NewDecoder(nil)
// send a SETTINGS frame
str, err := conn.OpenUniStream()
if err != nil {
@@ -441,16 +439,14 @@ func (s *Server) handleConn(conn quic.Connection) error {
hconn := newConnection(
conn,
s.EnableDatagrams,
s.UniStreamHijacker,
protocol.PerspectiveServer,
s.Logger,
)
go hconn.HandleUnidirectionalStreams()
go hconn.HandleUnidirectionalStreams(s.UniStreamHijacker)
// Process all requests immediately.
// It's the client's responsibility to decide which requests are eligible for 0-RTT.
for {
str, err := conn.AcceptStream(context.Background())
str, datagrams, err := hconn.acceptStream(context.Background())
if err != nil {
var appErr *quic.ApplicationError
if errors.As(err, &appErr) && appErr.ErrorCode == quic.ApplicationErrorCode(ErrCodeNoError) {
@@ -458,7 +454,7 @@ func (s *Server) handleConn(conn quic.Connection) error {
}
return fmt.Errorf("accepting stream failed: %w", err)
}
go s.handleRequest(hconn, str, decoder)
go s.handleRequest(hconn, str, datagrams, hconn.decoder)
}
}
@@ -469,7 +465,7 @@ func (s *Server) maxHeaderBytes() uint64 {
return uint64(s.MaxHeaderBytes)
}
func (s *Server) handleRequest(conn *connection, str quic.Stream, decoder *qpack.Decoder) {
func (s *Server) handleRequest(conn *connection, str quic.Stream, datagrams *datagrammer, decoder *qpack.Decoder) {
var ufh unknownFrameHandlerFunc
if s.StreamHijacker != nil {
ufh = func(ft FrameType, e error) (processed bool, err error) {
@@ -528,7 +524,7 @@ func (s *Server) handleRequest(conn *connection, str quic.Stream, decoder *qpack
if _, ok := req.Header["Content-Length"]; ok && req.ContentLength >= 0 {
contentLength = req.ContentLength
}
hstr := newStream(str, conn)
hstr := newStream(str, conn, datagrams)
body := newRequestBody(hstr, contentLength, conn.Context(), conn.ReceivedSettings(), conn.Settings)
req.Body = body
@@ -553,6 +549,7 @@ func (s *Server) handleRequest(conn *connection, str quic.Stream, decoder *qpack
handler = http.DefaultServeMux
}
// It's the client's responsibility to decide which requests are eligible for 0-RTT.
var panicked bool
func() {
defer func() {