forked from quic-go/quic-go
http3: add client trace support (#4749)
Since the QUIC connection establishment process includes TLS handshake logic, Connect and TLS handshake are called in the following order: ConnectStart -> TLSHandshakeStart -> TLSHandshakeDone -> ConnectDone. Notice: Wait100Continue not implemented as quic-go doesn't support handling Expect: 100-continue.
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptrace"
|
||||
|
||||
"github.com/quic-go/quic-go"
|
||||
"github.com/quic-go/quic-go/internal/protocol"
|
||||
@@ -147,10 +148,12 @@ type requestStream struct {
|
||||
reqDone chan<- struct{}
|
||||
disableCompression bool
|
||||
response *http.Response
|
||||
trace *httptrace.ClientTrace
|
||||
|
||||
sentRequest bool
|
||||
requestedGzip bool
|
||||
isConnect bool
|
||||
firstByte bool
|
||||
}
|
||||
|
||||
var _ RequestStream = &requestStream{}
|
||||
@@ -163,6 +166,7 @@ func newRequestStream(
|
||||
disableCompression bool,
|
||||
maxHeaderBytes uint64,
|
||||
rsp *http.Response,
|
||||
trace *httptrace.ClientTrace,
|
||||
) *requestStream {
|
||||
return &requestStream{
|
||||
stream: str,
|
||||
@@ -172,6 +176,7 @@ func newRequestStream(
|
||||
disableCompression: disableCompression,
|
||||
maxHeaderBytes: maxHeaderBytes,
|
||||
response: rsp,
|
||||
trace: trace,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,8 +202,12 @@ func (s *requestStream) SendRequestHeader(req *http.Request) error {
|
||||
|
||||
func (s *requestStream) ReadResponse() (*http.Response, error) {
|
||||
fp := &frameParser{
|
||||
r: s.Stream,
|
||||
conn: s.conn,
|
||||
r: &tracingReader{
|
||||
Reader: s.Stream,
|
||||
first: &s.firstByte,
|
||||
trace: s.trace,
|
||||
},
|
||||
}
|
||||
frame, err := fp.ParseNext()
|
||||
if err != nil {
|
||||
@@ -268,3 +277,18 @@ func (s *stream) ReceiveDatagram(ctx context.Context) ([]byte, error) {
|
||||
// TODO: reject if datagrams are not negotiated (yet)
|
||||
return s.datagrams.Receive(ctx)
|
||||
}
|
||||
|
||||
type tracingReader struct {
|
||||
io.Reader
|
||||
first *bool
|
||||
trace *httptrace.ClientTrace
|
||||
}
|
||||
|
||||
func (r *tracingReader) Read(b []byte) (int, error) {
|
||||
n, err := r.Reader.Read(b)
|
||||
if n > 0 && r.first != nil && !*r.first {
|
||||
traceGotFirstResponseByte(r.trace)
|
||||
*r.first = true
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user