forked from quic-go/quic-go
http3: convert RequestStream from an interface to a struct (#5153)
This commit is contained in:
@@ -127,7 +127,7 @@ func newClientConn(
|
||||
}
|
||||
|
||||
// OpenRequestStream opens a new request stream on the HTTP/3 connection.
|
||||
func (c *ClientConn) OpenRequestStream(ctx context.Context) (RequestStream, error) {
|
||||
func (c *ClientConn) OpenRequestStream(ctx context.Context) (*RequestStream, error) {
|
||||
return c.openRequestStream(ctx, c.requestWriter, nil, c.disableCompression, c.maxResponseHeaderBytes)
|
||||
}
|
||||
|
||||
@@ -300,7 +300,7 @@ func (c *ClientConn) sendRequestBody(str Stream, body io.ReadCloser, contentLeng
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *ClientConn) doRequest(req *http.Request, str *requestStream) (*http.Response, error) {
|
||||
func (c *ClientConn) doRequest(req *http.Request, str *RequestStream) (*http.Response, error) {
|
||||
trace := httptrace.ContextClientTrace(req.Context())
|
||||
if err := str.SendRequestHeader(req); err != nil {
|
||||
traceWroteRequest(trace, err)
|
||||
|
||||
@@ -119,7 +119,7 @@ func (c *connection) openRequestStream(
|
||||
reqDone chan<- struct{},
|
||||
disableCompression bool,
|
||||
maxHeaderBytes uint64,
|
||||
) (*requestStream, error) {
|
||||
) (*RequestStream, error) {
|
||||
if c.perspective == protocol.PerspectiveClient {
|
||||
c.streamMx.Lock()
|
||||
maxStreamID := c.maxStreamID
|
||||
|
||||
@@ -23,23 +23,7 @@ type Stream interface {
|
||||
ReceiveDatagram(context.Context) ([]byte, error)
|
||||
}
|
||||
|
||||
// A RequestStream is an HTTP/3 request stream.
|
||||
// When writing to and reading from the stream, data is framed in HTTP/3 DATA frames.
|
||||
type RequestStream interface {
|
||||
Stream
|
||||
|
||||
// SendRequestHeader sends the HTTP request.
|
||||
// It is invalid to call it more than once.
|
||||
// It is invalid to call it after Write has been called.
|
||||
SendRequestHeader(req *http.Request) error
|
||||
|
||||
// ReadResponse reads the HTTP response from the stream.
|
||||
// It is invalid to call it more than once.
|
||||
// It doesn't set Response.Request and Response.TLS.
|
||||
// It is invalid to call it after Read has been called.
|
||||
ReadResponse() (*http.Response, error)
|
||||
}
|
||||
|
||||
type stream struct {
|
||||
quic.Stream
|
||||
conn *connection
|
||||
@@ -135,9 +119,11 @@ func (s *stream) StreamID() protocol.StreamID {
|
||||
return s.Stream.StreamID()
|
||||
}
|
||||
|
||||
// The stream conforms to the quic.Stream interface, but instead of writing to and reading directly
|
||||
// from the QUIC stream, it writes to and reads from the HTTP stream.
|
||||
type requestStream struct {
|
||||
// A RequestStream is a low-level abstraction representing an HTTP/3 request stream.
|
||||
// It decouples sending of the HTTP request from reading the HTTP response, allowing
|
||||
// the application to optimistically use the stream (and, for example, send datagrams)
|
||||
// before receiving the response.
|
||||
type RequestStream struct {
|
||||
*stream
|
||||
|
||||
responseBody io.ReadCloser // set by ReadResponse
|
||||
@@ -156,8 +142,6 @@ type requestStream struct {
|
||||
firstByte bool
|
||||
}
|
||||
|
||||
var _ RequestStream = &requestStream{}
|
||||
|
||||
func newRequestStream(
|
||||
str *stream,
|
||||
requestWriter *requestWriter,
|
||||
@@ -167,8 +151,8 @@ func newRequestStream(
|
||||
maxHeaderBytes uint64,
|
||||
rsp *http.Response,
|
||||
trace *httptrace.ClientTrace,
|
||||
) *requestStream {
|
||||
return &requestStream{
|
||||
) *RequestStream {
|
||||
return &RequestStream{
|
||||
stream: str,
|
||||
requestWriter: requestWriter,
|
||||
reqDone: reqDone,
|
||||
@@ -180,14 +164,17 @@ func newRequestStream(
|
||||
}
|
||||
}
|
||||
|
||||
func (s *requestStream) Read(b []byte) (int, error) {
|
||||
func (s *RequestStream) Read(b []byte) (int, error) {
|
||||
if s.responseBody == nil {
|
||||
return 0, errors.New("http3: invalid use of RequestStream.Read: need to call ReadResponse first")
|
||||
}
|
||||
return s.responseBody.Read(b)
|
||||
}
|
||||
|
||||
func (s *requestStream) SendRequestHeader(req *http.Request) error {
|
||||
// SendRequestHeader sends the HTTP request.
|
||||
// It is invalid to call it more than once.
|
||||
// It is invalid to call it after Write has been called.
|
||||
func (s *RequestStream) SendRequestHeader(req *http.Request) error {
|
||||
if s.sentRequest {
|
||||
return errors.New("http3: invalid duplicate use of SendRequestHeader")
|
||||
}
|
||||
@@ -200,7 +187,11 @@ func (s *requestStream) SendRequestHeader(req *http.Request) error {
|
||||
return s.requestWriter.WriteRequestHeader(s.Stream, req, s.requestedGzip)
|
||||
}
|
||||
|
||||
func (s *requestStream) ReadResponse() (*http.Response, error) {
|
||||
// ReadResponse reads the HTTP response from the stream.
|
||||
// It is invalid to call it more than once.
|
||||
// It doesn't set Response.Request and Response.TLS.
|
||||
// It is invalid to call it after Read has been called.
|
||||
func (s *RequestStream) ReadResponse() (*http.Response, error) {
|
||||
fp := &frameParser{
|
||||
conn: s.conn,
|
||||
r: &tracingReader{
|
||||
|
||||
@@ -42,10 +42,10 @@ func (m *MockClientConn) EXPECT() *MockClientConnMockRecorder {
|
||||
}
|
||||
|
||||
// OpenRequestStream mocks base method.
|
||||
func (m *MockClientConn) OpenRequestStream(arg0 context.Context) (RequestStream, error) {
|
||||
func (m *MockClientConn) OpenRequestStream(arg0 context.Context) (*RequestStream, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "OpenRequestStream", arg0)
|
||||
ret0, _ := ret[0].(RequestStream)
|
||||
ret0, _ := ret[0].(*RequestStream)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
@@ -63,19 +63,19 @@ type MockClientConnOpenRequestStreamCall struct {
|
||||
}
|
||||
|
||||
// Return rewrite *gomock.Call.Return
|
||||
func (c *MockClientConnOpenRequestStreamCall) Return(arg0 RequestStream, arg1 error) *MockClientConnOpenRequestStreamCall {
|
||||
func (c *MockClientConnOpenRequestStreamCall) Return(arg0 *RequestStream, arg1 error) *MockClientConnOpenRequestStreamCall {
|
||||
c.Call = c.Call.Return(arg0, arg1)
|
||||
return c
|
||||
}
|
||||
|
||||
// Do rewrite *gomock.Call.Do
|
||||
func (c *MockClientConnOpenRequestStreamCall) Do(f func(context.Context) (RequestStream, error)) *MockClientConnOpenRequestStreamCall {
|
||||
func (c *MockClientConnOpenRequestStreamCall) Do(f func(context.Context) (*RequestStream, error)) *MockClientConnOpenRequestStreamCall {
|
||||
c.Call = c.Call.Do(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// DoAndReturn rewrite *gomock.Call.DoAndReturn
|
||||
func (c *MockClientConnOpenRequestStreamCall) DoAndReturn(f func(context.Context) (RequestStream, error)) *MockClientConnOpenRequestStreamCall {
|
||||
func (c *MockClientConnOpenRequestStreamCall) DoAndReturn(f func(context.Context) (*RequestStream, error)) *MockClientConnOpenRequestStreamCall {
|
||||
c.Call = c.Call.DoAndReturn(f)
|
||||
return c
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ type RoundTripOpt struct {
|
||||
}
|
||||
|
||||
type clientConn interface {
|
||||
OpenRequestStream(context.Context) (RequestStream, error)
|
||||
OpenRequestStream(context.Context) (*RequestStream, error)
|
||||
RoundTrip(*http.Request) (*http.Response, error)
|
||||
}
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ func TestHTTPSettings(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func dialAndOpenHTTPDatagramStream(t *testing.T, addr string) http3.RequestStream {
|
||||
func dialAndOpenHTTPDatagramStream(t *testing.T, addr string) *http3.RequestStream {
|
||||
t.Helper()
|
||||
|
||||
u, err := url.Parse(addr)
|
||||
|
||||
Reference in New Issue
Block a user