Files
quic-go/http3/body.go
Marten Seemann 4f6d0e651a implement HTTP/3
2019-04-11 09:06:10 +09:00

69 lines
1.2 KiB
Go

package http3
import (
"errors"
"io"
)
// The body of a http.Request or http.Response.
type body struct {
str io.ReadCloser
isRequest bool
bytesRemainingInFrame uint64
}
var _ io.ReadCloser = &body{}
func newRequestBody(str io.ReadCloser) *body {
return &body{
str: str,
isRequest: true,
}
}
func newResponseBody(str io.ReadCloser) *body {
return &body{str: str}
}
func (r *body) Read(b []byte) (int, error) {
if r.bytesRemainingInFrame == 0 {
parseLoop:
for {
frame, err := parseNextFrame(r.str)
if err != nil {
return 0, err
}
switch f := frame.(type) {
case *headersFrame:
// skip HEADERS frames
continue
case *dataFrame:
r.bytesRemainingInFrame = f.Length
break parseLoop
default:
return 0, errors.New("unexpected frame")
}
}
}
var n int
var err error
if r.bytesRemainingInFrame < uint64(len(b)) {
n, err = r.str.Read(b[:r.bytesRemainingInFrame])
} else {
n, err = r.str.Read(b)
}
r.bytesRemainingInFrame -= uint64(n)
return n, err
}
func (r *body) Close() error {
// quic.Stream.Close() closes the write side, not the read side
if r.isRequest {
return nil
}
return r.str.Close()
}