refactor HTTP/3 stream handling to use a dedicated stream

Reading from and writing onto this stream applies HTTP/3 DATA framing.
This commit is contained in:
Marten Seemann
2022-05-29 19:22:05 +02:00
parent ccf897e519
commit 04d46526c7
10 changed files with 344 additions and 360 deletions

View File

@@ -38,60 +38,14 @@ func newRequestWriter(logger utils.Logger) *requestWriter {
}
}
func (w *requestWriter) WriteRequest(str quic.Stream, req *http.Request, dontCloseStr, gzip bool) error {
func (w *requestWriter) WriteRequestHeader(str quic.Stream, req *http.Request, gzip bool) error {
// TODO: figure out how to add support for trailers
buf := &bytes.Buffer{}
if err := w.writeHeaders(buf, req, gzip); err != nil {
return err
}
if _, err := str.Write(buf.Bytes()); err != nil {
return err
}
// TODO: add support for trailers
if req.Body == nil {
if !dontCloseStr {
str.Close()
}
return nil
}
// send the request body asynchronously
go func() {
defer req.Body.Close()
b := make([]byte, bodyCopyBufferSize)
for {
n, rerr := req.Body.Read(b)
if n == 0 {
if rerr == nil {
continue
} else if rerr == io.EOF {
break
}
}
buf := &bytes.Buffer{}
(&dataFrame{Length: uint64(n)}).Write(buf)
if _, err := str.Write(buf.Bytes()); err != nil {
w.logger.Errorf("Error writing request: %s", err)
return
}
if _, err := str.Write(b[:n]); err != nil {
w.logger.Errorf("Error writing request: %s", err)
return
}
if rerr != nil {
if rerr == io.EOF {
break
}
str.CancelWrite(quic.StreamErrorCode(errorRequestCanceled))
w.logger.Errorf("Error writing request: %s", rerr)
return
}
}
if !dontCloseStr {
str.Close()
}
}()
return nil
_, err := str.Write(buf.Bytes())
return err
}
func (w *requestWriter) writeHeaders(wr io.Writer, req *http.Request, gzip bool) error {