Skip to content

Commit c88d49f

Browse files
committed
Adds --http3 flag to buf curl
1 parent c11801c commit c88d49f

File tree

4 files changed

+118
-12
lines changed

4 files changed

+118
-12
lines changed

go.mod

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ require (
2727
github.com/klauspost/pgzip v1.2.6
2828
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c
2929
github.com/pkg/profile v1.7.0
30+
github.com/quic-go/quic-go v0.45.1
3031
github.com/rs/cors v1.11.0
3132
github.com/spf13/cobra v1.8.1
3233
github.com/spf13/pflag v1.0.5
@@ -74,6 +75,7 @@ require (
7475
github.com/felixge/httpsnoop v1.0.4 // indirect
7576
github.com/go-logr/logr v1.4.2 // indirect
7677
github.com/go-logr/stdr v1.2.2 // indirect
78+
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
7779
github.com/gogo/protobuf v1.3.2 // indirect
7880
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
7981
github.com/golang/protobuf v1.5.4 // indirect
@@ -91,11 +93,13 @@ require (
9193
github.com/moby/sys/userns v0.1.0 // indirect
9294
github.com/moby/term v0.5.0 // indirect
9395
github.com/morikuni/aec v1.0.0 // indirect
96+
github.com/onsi/ginkgo/v2 v2.9.5 // indirect
9497
github.com/opencontainers/go-digest v1.0.0 // indirect
9598
github.com/opencontainers/image-spec v1.1.0 // indirect
9699
github.com/opencontainers/runtime-spec v1.2.0 // indirect
97100
github.com/pkg/errors v0.9.1 // indirect
98101
github.com/pmezard/go-difflib v1.0.0 // indirect
102+
github.com/quic-go/qpack v0.4.0 // indirect
99103
github.com/rogpeppe/go-internal v1.12.0 // indirect
100104
github.com/russross/blackfriday/v2 v2.1.0 // indirect
101105
github.com/sirupsen/logrus v1.9.3 // indirect
@@ -104,6 +108,7 @@ require (
104108
go.opencensus.io v0.24.0 // indirect
105109
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect
106110
go.opentelemetry.io/otel/metric v1.28.0 // indirect
111+
go.uber.org/mock v0.4.0 // indirect
107112
golang.org/x/sys v0.24.0 // indirect
108113
golang.org/x/text v0.17.0 // indirect
109114
google.golang.org/genproto/googleapis/api v0.0.0-20240812133136-8ffd90a71988 // indirect

go.sum

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
9999
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
100100
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
101101
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
102+
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
103+
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
102104
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
103105
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
104106
github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY=
@@ -188,6 +190,10 @@ github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
188190
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
189191
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
190192
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
193+
github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q=
194+
github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k=
195+
github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
196+
github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
191197
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
192198
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
193199
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
@@ -206,8 +212,12 @@ github.com/pkg/profile v1.7.0/go.mod h1:8Uer0jas47ZQMJ7VD+OHknK4YDY07LPUC6dEvqDj
206212
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
207213
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
208214
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
209-
github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
210-
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
215+
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
216+
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
217+
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
218+
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
219+
github.com/quic-go/quic-go v0.45.1 h1:tPfeYCk+uZHjmDRwHHQmvHRYL2t44ROTujLeFVBmjCA=
220+
github.com/quic-go/quic-go v0.45.1/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI=
211221
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
212222
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
213223
github.com/rs/cors v1.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po=
@@ -225,6 +235,7 @@ github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8w
225235
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
226236
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
227237
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
238+
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
228239
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
229240
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
230241
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
@@ -259,6 +270,8 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
259270
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
260271
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
261272
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
273+
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
274+
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
262275
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
263276
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
264277
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
@@ -315,8 +328,8 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
315328
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
316329
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
317330
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
318-
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44=
319-
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
331+
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
332+
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
320333
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
321334
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
322335
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=

private/buf/bufcurl/tls.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ type TLSSettings struct {
3838
// "h2", and exclude "http/1.1". If the server does not pick a
3939
// protocol, "h2" is assumed as the default.
4040
HTTP2PriorKnowledge bool
41+
42+
HTTP3 bool
4143
}
4244

4345
// MakeVerboseTLSConfig constructs a *tls.Config that logs information to the
@@ -46,6 +48,8 @@ func MakeVerboseTLSConfig(settings *TLSSettings, authority string, printer verbo
4648
var conf tls.Config
4749
if settings.HTTP2PriorKnowledge {
4850
conf.NextProtos = []string{"h2"}
51+
} else if settings.HTTP3 {
52+
conf.NextProtos = []string{"h3"}
4953
} else {
5054
conf.NextProtos = []string{"h2", "http/1.1"}
5155
}
@@ -59,6 +63,8 @@ func MakeVerboseTLSConfig(settings *TLSSettings, authority string, printer verbo
5963
if state.NegotiatedProtocol == "" {
6064
if settings.HTTP2PriorKnowledge {
6165
printer.Printf("* ALPN: server did not agree on a protocol. Using default h2")
66+
} else if settings.HTTP3 {
67+
printer.Printf("* ALPN: server did not agree on a protocol. Still attempting h3")
6268
} else {
6369
printer.Printf("* ALPN: server did not agree on a protocol. Using default http/1.1.")
6470
}

private/buf/cmd/buf/command/curl/curl.go

Lines changed: 90 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ import (
4141
"github.com/bufbuild/buf/private/pkg/netrc"
4242
"github.com/bufbuild/buf/private/pkg/stringutil"
4343
"github.com/bufbuild/buf/private/pkg/verbose"
44+
"github.com/quic-go/quic-go"
45+
"github.com/quic-go/quic-go/http3"
4446
"github.com/spf13/pflag"
4547
"go.uber.org/multierr"
4648
"golang.org/x/net/http2"
@@ -60,6 +62,7 @@ const (
6062
protocolFlagName = "protocol"
6163
unixSocketFlagName = "unix-socket"
6264
http2PriorKnowledgeFlagName = "http2-prior-knowledge"
65+
http3FlagName = "http3"
6366

6467
// TLS flags
6568
keyFlagName = "key"
@@ -207,6 +210,7 @@ type flags struct {
207210
Protocol string
208211
UnixSocket string
209212
HTTP2PriorKnowledge bool
213+
HTTP3 bool
210214

211215
// TLS
212216
Key, Cert, CACert, ServerName string
@@ -324,6 +328,16 @@ choose either HTTP 1.1 or HTTP/2 for URLs with an https scheme. With this flag s
324328
HTTP/2 is always used, even over plain-text.`,
325329
)
326330

331+
flagSet.BoolVar(
332+
&f.HTTP3,
333+
http3FlagName,
334+
false,
335+
`This flag can be used to indicate that HTTP/3 should be used. Without this, HTTP 1.1
336+
will be used with URLs with an http scheme, and protocol negotiation will be used to
337+
choose either HTTP 1.1 or HTTP/2 for URLs with an https scheme. With this flag set,
338+
HTTP/3 is always used.`,
339+
)
340+
327341
flagSet.BoolVar(
328342
&f.NoKeepAlive,
329343
noKeepAliveFlagName,
@@ -544,6 +558,19 @@ func (f *flags) validate(hasURL, isSecure bool) error {
544558
return fmt.Errorf("grpc protocol cannot be used with plain-text URLs (http) unless --%s flag is set", http2PriorKnowledgeFlagName)
545559
}
546560

561+
if !isSecure && f.HTTP3 {
562+
return fmt.Errorf("--%s cannot be used with plain-text URLs (http)", http3FlagName)
563+
}
564+
565+
if f.UnixSocket != "" && f.HTTP3 {
566+
return fmt.Errorf("--%s cannot be used with --%s", unixSocketFlagName, http3FlagName)
567+
}
568+
569+
// NOTE: This can be removed once trailer support lands for quic-go: https://github.com/quic-go/quic-go/issues/2266
570+
if f.Protocol == connect.ProtocolGRPC && f.HTTP3 {
571+
return fmt.Errorf("--%s cannot be used with --%s=%s", http3FlagName, protocolFlagName, connect.ProtocolGRPC)
572+
}
573+
547574
if f.Netrc && f.NetrcFile != "" {
548575
return fmt.Errorf("--%s and --%s flags are mutually exclusive; they may not both be specified", netrcFlagName, netrcFileFlagName)
549576
}
@@ -691,6 +718,18 @@ func (f *flags) determineCredentials(
691718
return basicAuth(username, password), nil
692719
}
693720

721+
func (f *flags) getTLSConfig(authority string, printer verbose.Printer) (*tls.Config, error) {
722+
return bufcurl.MakeVerboseTLSConfig(&bufcurl.TLSSettings{
723+
KeyFile: f.Key,
724+
CertFile: f.Cert,
725+
CACertFile: f.CACert,
726+
ServerName: f.ServerName,
727+
Insecure: f.Insecure,
728+
HTTP2PriorKnowledge: f.HTTP2PriorKnowledge,
729+
HTTP3: f.HTTP3,
730+
}, authority, printer)
731+
}
732+
694733
func promptForPassword(ctx context.Context, container app.Container, prompt string) (string, error) {
695734
// NB: The comments below and the mechanism of handling I/O async was
696735
// copied from the "registry login" command.
@@ -916,6 +955,9 @@ func run(ctx context.Context, container appext.Container, f *flags) (err error)
916955
// This shouldn't be possible since we check in flags.validate, but just in case
917956
return nil, errors.New("URL positional argument is missing")
918957
}
958+
if f.HTTP3 {
959+
return makeHTTP3Client(f, bufcurl.GetAuthority(host, requestHeaders), container.VerbosePrinter())
960+
}
919961
return makeHTTPClient(f, isSecure, bufcurl.GetAuthority(host, requestHeaders), container.VerbosePrinter())
920962
})
921963

@@ -1035,6 +1077,7 @@ func makeHTTPClient(f *flags, isSecure bool, authority string, printer verbose.P
10351077
} else {
10361078
dialer.KeepAlive = secondsToDuration(f.KeepAliveTimeSeconds)
10371079
}
1080+
10381081
var dialFunc func(ctx context.Context, network, address string) (net.Conn, error)
10391082
if f.UnixSocket != "" {
10401083
dialFunc = func(ctx context.Context, network, addr string) (net.Conn, error) {
@@ -1055,14 +1098,7 @@ func makeHTTPClient(f *flags, isSecure bool, authority string, printer verbose.P
10551098

10561099
var dialTLSFunc func(ctx context.Context, network, address string) (net.Conn, error)
10571100
if isSecure {
1058-
tlsConfig, err := bufcurl.MakeVerboseTLSConfig(&bufcurl.TLSSettings{
1059-
KeyFile: f.Key,
1060-
CertFile: f.Cert,
1061-
CACertFile: f.CACert,
1062-
ServerName: f.ServerName,
1063-
Insecure: f.Insecure,
1064-
HTTP2PriorKnowledge: f.HTTP2PriorKnowledge,
1065-
}, authority, printer)
1101+
tlsConfig, err := f.getTLSConfig(authority, printer)
10661102
if err != nil {
10671103
return nil, err
10681104
}
@@ -1107,6 +1143,52 @@ func makeHTTPClient(f *flags, isSecure bool, authority string, printer verbose.P
11071143
return bufcurl.NewVerboseHTTPClient(transport, printer), nil
11081144
}
11091145

1146+
func makeHTTP3Client(f *flags, authority string, printer verbose.Printer) (connect.HTTPClient, error) {
1147+
quicCfg := &quic.Config{
1148+
KeepAlivePeriod: -1,
1149+
}
1150+
if f.ConnectTimeoutSeconds != 0 {
1151+
quicCfg.HandshakeIdleTimeout = secondsToDuration(f.ConnectTimeoutSeconds)
1152+
}
1153+
if !f.NoKeepAlive {
1154+
quicCfg.KeepAlivePeriod = secondsToDuration(f.KeepAliveTimeSeconds)
1155+
}
1156+
1157+
tlsConfig, err := f.getTLSConfig(authority, printer)
1158+
if err != nil {
1159+
return nil, err
1160+
}
1161+
1162+
udpConn, err := net.ListenUDP("udp", nil)
1163+
if err != nil {
1164+
return nil, err
1165+
}
1166+
transport := &quic.Transport{Conn: udpConn}
1167+
roundTripper := &http3.RoundTripper{
1168+
TLSClientConfig: tlsConfig,
1169+
QUICConfig: quicCfg,
1170+
Dial: func(ctx context.Context, addr string, tlsCfg *tls.Config, cfg *quic.Config) (quic.EarlyConnection, error) {
1171+
printer.Printf("* Dialing (udp) %s...", addr)
1172+
udpAddr, err := net.ResolveUDPAddr("udp", addr)
1173+
if err != nil {
1174+
return nil, err
1175+
}
1176+
printer.Printf("* ALPN: offering %s", strings.Join(tlsCfg.NextProtos, ","))
1177+
conn, err := transport.DialEarly(ctx, udpAddr, tlsCfg, cfg)
1178+
if err != nil {
1179+
return nil, err
1180+
}
1181+
printer.Printf("* Connected to %s", conn.RemoteAddr().String())
1182+
return conn, err
1183+
},
1184+
EnableDatagrams: false,
1185+
AdditionalSettings: map[uint64]uint64{},
1186+
MaxResponseHeaderBytes: 0,
1187+
DisableCompression: false,
1188+
}
1189+
return bufcurl.NewVerboseHTTPClient(roundTripper, printer), nil
1190+
}
1191+
11101192
func secondsToDuration(secs float64) time.Duration {
11111193
return time.Duration(float64(time.Second) * secs)
11121194
}

0 commit comments

Comments
 (0)