add a http3.RoundTripper.EnableDatagram option

This commit is contained in:
Marten Seemann
2020-12-21 11:28:01 +07:00
parent 0b0cb7c06f
commit 3cb07d8f00
3 changed files with 22 additions and 2 deletions

View File

@@ -37,6 +37,7 @@ var dialAddr = quic.DialAddrEarly
type roundTripperOpts struct { type roundTripperOpts struct {
DisableCompression bool DisableCompression bool
EnableDatagram bool
MaxHeaderBytes int64 MaxHeaderBytes int64
} }
@@ -68,7 +69,7 @@ func newClient(
dialer func(network, addr string, tlsCfg *tls.Config, cfg *quic.Config) (quic.EarlySession, error), dialer func(network, addr string, tlsCfg *tls.Config, cfg *quic.Config) (quic.EarlySession, error),
) (*client, error) { ) (*client, error) {
if quicConfig == nil { if quicConfig == nil {
quicConfig = defaultQuicConfig quicConfig = defaultQuicConfig.Clone()
} else if len(quicConfig.Versions) == 0 { } else if len(quicConfig.Versions) == 0 {
quicConfig = quicConfig.Clone() quicConfig = quicConfig.Clone()
quicConfig.Versions = []quic.VersionNumber{defaultQuicConfig.Versions[0]} quicConfig.Versions = []quic.VersionNumber{defaultQuicConfig.Versions[0]}
@@ -77,6 +78,7 @@ func newClient(
return nil, errors.New("can only use a single QUIC version for dialing a HTTP/3 connection") return nil, errors.New("can only use a single QUIC version for dialing a HTTP/3 connection")
} }
quicConfig.MaxIncomingStreams = -1 // don't allow any bidirectional streams quicConfig.MaxIncomingStreams = -1 // don't allow any bidirectional streams
quicConfig.EnableDatagrams = opts.EnableDatagram
logger := utils.DefaultLogger.WithPrefix("h3 client") logger := utils.DefaultLogger.WithPrefix("h3 client")
if tlsConf == nil { if tlsConf == nil {
@@ -131,7 +133,7 @@ func (c *client) setupSession() error {
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
utils.WriteVarInt(buf, streamTypeControlStream) utils.WriteVarInt(buf, streamTypeControlStream)
// send the SETTINGS frame // send the SETTINGS frame
(&settingsFrame{}).Write(buf) (&settingsFrame{Datagram: c.opts.EnableDatagram}).Write(buf)
_, err = str.Write(buf.Bytes()) _, err = str.Write(buf.Bytes())
return err return err
} }

View File

@@ -136,6 +136,18 @@ var _ = Describe("Client", func() {
Expect(dialerCalled).To(BeTrue()) Expect(dialerCalled).To(BeTrue())
}) })
It("enables HTTP/3 Datagrams", func() {
testErr := errors.New("handshake error")
client, err := newClient("localhost:1337", nil, &roundTripperOpts{EnableDatagram: true}, nil, nil)
Expect(err).ToNot(HaveOccurred())
dialAddr = func(hostname string, _ *tls.Config, quicConf *quic.Config) (quic.EarlySession, error) {
Expect(quicConf.EnableDatagrams).To(BeTrue())
return nil, testErr
}
_, err = client.RoundTrip(req)
Expect(err).To(MatchError(testErr))
})
It("errors when dialing fails", func() { It("errors when dialing fails", func() {
testErr := errors.New("handshake error") testErr := errors.New("handshake error")
client, err := newClient("localhost:1337", nil, &roundTripperOpts{}, nil, nil) client, err := newClient("localhost:1337", nil, &roundTripperOpts{}, nil, nil)

View File

@@ -41,6 +41,11 @@ type RoundTripper struct {
// If nil, reasonable default values will be used. // If nil, reasonable default values will be used.
QuicConfig *quic.Config QuicConfig *quic.Config
// Enable support for HTTP/3 datagrams.
// If set to true, QuicConfig.EnableDatagram will be set.
// See https://www.ietf.org/archive/id/draft-schinazi-masque-h3-datagram-02.html.
EnableDatagrams bool
// Dial specifies an optional dial function for creating QUIC // Dial specifies an optional dial function for creating QUIC
// connections for requests. // connections for requests.
// If Dial is nil, quic.DialAddr will be used. // If Dial is nil, quic.DialAddr will be used.
@@ -135,6 +140,7 @@ func (r *RoundTripper) getClient(hostname string, onlyCached bool) (http.RoundTr
hostname, hostname,
r.TLSClientConfig, r.TLSClientConfig,
&roundTripperOpts{ &roundTripperOpts{
EnableDatagram: r.EnableDatagrams,
DisableCompression: r.DisableCompression, DisableCompression: r.DisableCompression,
MaxHeaderBytes: r.MaxResponseHeaderBytes, MaxHeaderBytes: r.MaxResponseHeaderBytes,
}, },