Skip to content

Commit 6619d1f

Browse files
author
Chao Xu
committed
http2: add configuration options when constructing http2 transport
This allows the caller to change some configurations of the http2 transport when constructing it from an http1 transport.
1 parent 627f964 commit 6619d1f

File tree

2 files changed

+67
-2
lines changed

2 files changed

+67
-2
lines changed

http2/transport.go

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,19 +152,47 @@ func (t *Transport) pingTimeout() time.Duration {
152152

153153
}
154154

155+
// TransportOptions contains options to configure HTTP/2 transport.
156+
type TransportOptions struct {
157+
// ReadIdleTimeout is the timeout after which a health check using ping
158+
// frame will be carried out if no frame is received on the connection.
159+
// Note that a ping response will is considered a received frame, so if
160+
// there is no other traffic on the connection, the health check will
161+
// be performed every ReadIdleTimeout interval.
162+
// If zero, no health check is performed.
163+
ReadIdleTimeout time.Duration
164+
165+
// PingTimeout is the timeout after which the connection will be closed
166+
// if a response to Ping is not received.
167+
// Defaults to 15s.
168+
PingTimeout time.Duration
169+
}
170+
171+
// ConfigureTransport configures a net/http HTTP/1 Transport to use HTTP/2.
172+
// The options can be used to configure the HTTP/2 Transport.
173+
// It returns an error if t1 has already been HTTP/2-enabled.
174+
func ConfigureTransportWithOptions(t1 *http.Transport, o *TransportOptions) error {
175+
_, err := configureTransport(t1, o)
176+
return err
177+
}
178+
155179
// ConfigureTransport configures a net/http HTTP/1 Transport to use HTTP/2.
156180
// It returns an error if t1 has already been HTTP/2-enabled.
157181
func ConfigureTransport(t1 *http.Transport) error {
158-
_, err := configureTransport(t1)
182+
_, err := configureTransport(t1, nil)
159183
return err
160184
}
161185

162-
func configureTransport(t1 *http.Transport) (*Transport, error) {
186+
func configureTransport(t1 *http.Transport, o *TransportOptions) (*Transport, error) {
163187
connPool := new(clientConnPool)
164188
t2 := &Transport{
165189
ConnPool: noDialClientConnPool{connPool},
166190
t1: t1,
167191
}
192+
if o != nil {
193+
t2.ReadIdleTimeout = o.ReadIdleTimeout
194+
t2.PingTimeout = o.PingTimeout
195+
}
168196
connPool.t = t2
169197
if err := registerHTTPSProtocol(t1, noDialH2RoundTripper{t2}); err != nil {
170198
return nil, err

http2/transport_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
"sync/atomic"
3333
"testing"
3434
"time"
35+
"unsafe"
3536

3637
"golang.org/x/net/http2/hpack"
3738
)
@@ -594,6 +595,42 @@ func TestTransportDialTLS(t *testing.T) {
594595
}
595596
}
596597

598+
func TestConfigureTransportWithOptions(t *testing.T) {
599+
t1 := &http.Transport{}
600+
o := &TransportOptions{ReadIdleTimeout: 10, PingTimeout: 10}
601+
err := ConfigureTransportWithOptions(t1, o)
602+
if err != nil {
603+
t.Fatal(err)
604+
}
605+
rf := reflect.ValueOf(t1).Elem().FieldByName("altProto")
606+
rf = reflect.NewAt(rf.Type(), unsafe.Pointer(rf.UnsafeAddr())).Elem()
607+
v := rf.Interface().(atomic.Value)
608+
altProto := v.Load().(map[string]http.RoundTripper)
609+
rt := (altProto["https"]).(noDialH2RoundTripper)
610+
t2 := rt.Transport
611+
if e, a := o.ReadIdleTimeout, t2.ReadIdleTimeout; e != a {
612+
t.Errorf("expected ReadIdleTimeout to be %d, got %d", e, a)
613+
}
614+
if e, a := o.PingTimeout, t2.PingTimeout; e != a {
615+
t.Errorf("expected PingTimeout to be %d, got %d", e, a)
616+
}
617+
}
618+
619+
func TestInternalConfigureTransport(t *testing.T) {
620+
t1 := &http.Transport{}
621+
o := &TransportOptions{ReadIdleTimeout: 10, PingTimeout: 10}
622+
t2, err := configureTransport(t1, o)
623+
if err != nil {
624+
t.Fatal(err)
625+
}
626+
if e, a := o.ReadIdleTimeout, t2.ReadIdleTimeout; e != a {
627+
t.Errorf("expected ReadIdleTimeout to be %d, got %d", e, a)
628+
}
629+
if e, a := o.PingTimeout, t2.PingTimeout; e != a {
630+
t.Errorf("expected PingTimeout to be %d, got %d", e, a)
631+
}
632+
}
633+
597634
func TestConfigureTransport(t *testing.T) {
598635
t1 := &http.Transport{}
599636
err := ConfigureTransport(t1)

0 commit comments

Comments
 (0)