Skip to content

Commit

Permalink
Refactor http3 implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
imroc committed Feb 6, 2023
1 parent 8adac86 commit 6d9b23e
Show file tree
Hide file tree
Showing 371 changed files with 84 additions and 62,440 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Full documentation is available on the official website: https://req.cool.

**Install**

You first need [Go](https://go.dev/) installed (version 1.16+ is required), then you can use the below Go command to install req:
You first need [Go](https://go.dev/) installed (version 1.18+ is required), then you can use the below Go command to install req:

``` sh
go get github.com/imroc/req/v3
Expand Down
31 changes: 16 additions & 15 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
module github.com/imroc/req/v3

go 1.16
go 1.18

require (
github.com/cheekybits/genny v1.0.0
github.com/francoispqt/gojay v1.2.13
github.com/golang/mock v1.6.0
github.com/hashicorp/go-multierror v1.1.1
github.com/marten-seemann/qtls-go1-16 v0.1.5
github.com/marten-seemann/qtls-go1-17 v0.1.2
github.com/marten-seemann/qtls-go1-18 v0.1.3
github.com/marten-seemann/qtls-go1-19 v0.1.1
github.com/onsi/ginkgo v1.16.5
github.com/onsi/gomega v1.20.1
github.com/quic-go/qpack v0.4.0
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519
golang.org/x/net v0.0.0-20220722155237-a158d28d115b
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f
golang.org/x/text v0.3.7
github.com/quic-go/quic-go v0.32.0
golang.org/x/net v0.4.0
golang.org/x/text v0.5.0
)

require (
github.com/fsnotify/fsnotify v1.5.4 // indirect
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/onsi/ginkgo/v2 v2.2.0 // indirect
github.com/quic-go/qtls-go1-18 v0.2.0 // indirect
github.com/quic-go/qtls-go1-19 v0.2.0 // indirect
github.com/quic-go/qtls-go1-20 v0.1.0 // indirect
golang.org/x/crypto v0.4.0 // indirect
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect
golang.org/x/mod v0.6.0 // indirect
golang.org/x/sys v0.3.0 // indirect
golang.org/x/tools v0.2.0 // indirect
)
287 changes: 22 additions & 265 deletions go.sum

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion internal/http3/body.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"io"
"net"

"github.com/imroc/req/v3/internal/quic-go"
"github.com/quic-go/quic-go"
)

// The HTTPStreamer allows taking over a HTTP/3 stream. The interface is implemented by:
Expand Down
54 changes: 0 additions & 54 deletions internal/http3/body_test.go

This file was deleted.

45 changes: 28 additions & 17 deletions internal/http3/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@ import (
"errors"
"fmt"
"github.com/imroc/req/v3/internal/dump"
"github.com/imroc/req/v3/internal/quic-go"
"github.com/imroc/req/v3/internal/quic-go/protocol"
"github.com/imroc/req/v3/internal/quic-go/qtls"
"github.com/imroc/req/v3/internal/quic-go/quicvarint"
"github.com/imroc/req/v3/internal/quic-go/utils"
"github.com/imroc/req/v3/internal/transport"
"github.com/quic-go/qpack"
"github.com/quic-go/quic-go"
"io"
"net/http"
"reflect"
"strconv"
"sync"
"time"
Expand All @@ -28,10 +27,16 @@ const (
defaultMaxResponseHeaderBytes = 10 * 1 << 20 // 10 MB
)

const (
VersionDraft29 quic.VersionNumber = 0xff00001d
Version1 quic.VersionNumber = 0x1
Version2 quic.VersionNumber = 0x6b3343cf
)

var defaultQuicConfig = &quic.Config{
MaxIncomingStreams: -1, // don't allow the server to create bidirectional streams
KeepAlivePeriod: 10 * time.Second,
Versions: []quic.VersionNumber{protocol.VersionTLS},
Versions: []quic.VersionNumber{Version1},
}

type dialFunc func(ctx context.Context, addr string, tlsCfg *tls.Config, cfg *quic.Config) (quic.EarlyConnection, error)
Expand Down Expand Up @@ -65,10 +70,10 @@ type client struct {
hostname string
conn quic.EarlyConnection

logger utils.Logger
opt *transport.Options
}

func newClient(hostname string, tlsConf *tls.Config, opts *roundTripperOpts, conf *quic.Config, dialer dialFunc) (*client, error) {
func newClient(hostname string, tlsConf *tls.Config, opts *roundTripperOpts, conf *quic.Config, dialer dialFunc, opt *transport.Options) (*client, error) {
if conf == nil {
conf = defaultQuicConfig.Clone()
} else if len(conf.Versions) == 0 {
Expand All @@ -82,7 +87,10 @@ func newClient(hostname string, tlsConf *tls.Config, opts *roundTripperOpts, con
conf.MaxIncomingStreams = -1 // don't allow any bidirectional streams
}
conf.EnableDatagrams = opts.EnableDatagram
logger := utils.DefaultLogger.WithPrefix("h3 client")
var debugf func(format string, v ...interface{})
if opt != nil && opt.Debugf != nil {
debugf = opt.Debugf
}

if tlsConf == nil {
tlsConf = &tls.Config{}
Expand All @@ -95,12 +103,12 @@ func newClient(hostname string, tlsConf *tls.Config, opts *roundTripperOpts, con
return &client{
hostname: authorityAddr("https", hostname),
tlsConf: tlsConf,
requestWriter: newRequestWriter(logger),
requestWriter: newRequestWriter(debugf),
decoder: qpack.NewDecoder(func(hf qpack.HeaderField) {}),
config: conf,
opts: opts,
dialer: dialer,
logger: logger,
opt: opt,
}, nil
}

Expand All @@ -118,7 +126,7 @@ func (c *client) dial(ctx context.Context) error {
// send the SETTINGs frame, using 0-RTT data, if possible
go func() {
if err := c.setupConn(); err != nil {
c.logger.Debugf("Setting up connection failed: %s", err)
c.opt.Debugf("setting up http3 connection failed: %s", err)
c.conn.CloseWithError(quic.ApplicationErrorCode(errorInternalError), "")
}
}()
Expand Down Expand Up @@ -148,7 +156,7 @@ func (c *client) handleBidirectionalStreams() {
for {
str, err := c.conn.AcceptStream(context.Background())
if err != nil {
c.logger.Debugf("accepting bidirectional stream failed: %s", err)
c.opt.Debugf("accepting bidirectional stream failed: %s", err)
return
}
go func(str quic.Stream) {
Expand All @@ -159,7 +167,7 @@ func (c *client) handleBidirectionalStreams() {
return
}
if err != nil {
c.logger.Debugf("error handling stream: %s", err)
c.opt.Debugf("error handling stream: %s", err)
}
c.conn.CloseWithError(quic.ApplicationErrorCode(errorFrameUnexpected), "received HTTP/3 frame on bidirectional stream")
}(str)
Expand All @@ -170,7 +178,7 @@ func (c *client) handleUnidirectionalStreams() {
for {
str, err := c.conn.AcceptUniStream(context.Background())
if err != nil {
c.logger.Debugf("accepting unidirectional stream failed: %s", err)
c.opt.Debugf("accepting unidirectional stream failed: %s", err)
return
}

Expand All @@ -180,7 +188,7 @@ func (c *client) handleUnidirectionalStreams() {
if c.opts.UniStreamHijacker != nil && c.opts.UniStreamHijacker(StreamType(streamType), c.conn, str, err) {
return
}
c.logger.Debugf("reading stream type on stream %d failed: %s", str.StreamID(), err)
c.opt.Debugf("reading stream type on stream %d failed: %s", str.StreamID(), err)
return
}
// We're only interested in the control stream here.
Expand Down Expand Up @@ -391,7 +399,7 @@ func (c *client) doRequest(req *http.Request, str quic.Stream, opt RoundTripOpt,
}
}
if err := c.sendRequestBody(hstr, req.Body, bodyDumps); err != nil {
c.logger.Errorf("Error writing request: %s", err)
c.opt.Debugf("error writing request: %s", err)
}
if !opt.DontCloseRequestStream {
hstr.Close()
Expand Down Expand Up @@ -436,7 +444,10 @@ func (c *client) doRequest(req *http.Request, str quic.Stream, opt RoundTripOpt,
return nil, newConnError(errorGeneralProtocolError, err)
}

connState := qtls.ToTLSConnectionState(c.conn.ConnectionState().TLS)
connState, ok := reflect.ValueOf(c.conn.ConnectionState().TLS).Field(0).Interface().(tls.ConnectionState)
if !ok {
panic(fmt.Sprintf("bad tls connection state type: %s", reflect.ValueOf(c.conn.ConnectionState().TLS).Field(0).Type().Name()))
}
res := &http.Response{
Proto: "HTTP/3.0",
ProtoMajor: 3,
Expand Down
Loading

0 comments on commit 6d9b23e

Please sign in to comment.