aboutsummaryrefslogtreecommitdiff
path: root/vendor/golang.org/x/net/http2/transport.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/net/http2/transport.go')
-rw-r--r--vendor/golang.org/x/net/http2/transport.go66
1 files changed, 61 insertions, 5 deletions
diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go
index 54acc1e..76a92e0 100644
--- a/vendor/golang.org/x/net/http2/transport.go
+++ b/vendor/golang.org/x/net/http2/transport.go
@@ -108,6 +108,19 @@ type Transport struct {
108 // waiting for their turn. 108 // waiting for their turn.
109 StrictMaxConcurrentStreams bool 109 StrictMaxConcurrentStreams bool
110 110
111 // ReadIdleTimeout is the timeout after which a health check using ping
112 // frame will be carried out if no frame is received on the connection.
113 // Note that a ping response will is considered a received frame, so if
114 // there is no other traffic on the connection, the health check will
115 // be performed every ReadIdleTimeout interval.
116 // If zero, no health check is performed.
117 ReadIdleTimeout time.Duration
118
119 // PingTimeout is the timeout after which the connection will be closed
120 // if a response to Ping is not received.
121 // Defaults to 15s.
122 PingTimeout time.Duration
123
111 // t1, if non-nil, is the standard library Transport using 124 // t1, if non-nil, is the standard library Transport using
112 // this transport. Its settings are used (but not its 125 // this transport. Its settings are used (but not its
113 // RoundTrip method, etc). 126 // RoundTrip method, etc).
@@ -131,6 +144,14 @@ func (t *Transport) disableCompression() bool {
131 return t.DisableCompression || (t.t1 != nil && t.t1.DisableCompression) 144 return t.DisableCompression || (t.t1 != nil && t.t1.DisableCompression)
132} 145}
133 146
147func (t *Transport) pingTimeout() time.Duration {
148 if t.PingTimeout == 0 {
149 return 15 * time.Second
150 }
151 return t.PingTimeout
152
153}
154
134// ConfigureTransport configures a net/http HTTP/1 Transport to use HTTP/2. 155// ConfigureTransport configures a net/http HTTP/1 Transport to use HTTP/2.
135// It returns an error if t1 has already been HTTP/2-enabled. 156// It returns an error if t1 has already been HTTP/2-enabled.
136func ConfigureTransport(t1 *http.Transport) error { 157func ConfigureTransport(t1 *http.Transport) error {
@@ -675,6 +696,20 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro
675 return cc, nil 696 return cc, nil
676} 697}
677 698
699func (cc *ClientConn) healthCheck() {
700 pingTimeout := cc.t.pingTimeout()
701 // We don't need to periodically ping in the health check, because the readLoop of ClientConn will
702 // trigger the healthCheck again if there is no frame received.
703 ctx, cancel := context.WithTimeout(context.Background(), pingTimeout)
704 defer cancel()
705 err := cc.Ping(ctx)
706 if err != nil {
707 cc.closeForLostPing()
708 cc.t.connPool().MarkDead(cc)
709 return
710 }
711}
712
678func (cc *ClientConn) setGoAway(f *GoAwayFrame) { 713func (cc *ClientConn) setGoAway(f *GoAwayFrame) {
679 cc.mu.Lock() 714 cc.mu.Lock()
680 defer cc.mu.Unlock() 715 defer cc.mu.Unlock()
@@ -846,14 +881,12 @@ func (cc *ClientConn) sendGoAway() error {
846 return nil 881 return nil
847} 882}
848 883
849// Close closes the client connection immediately. 884// closes the client connection immediately. In-flight requests are interrupted.
850// 885// err is sent to streams.
851// In-flight requests are interrupted. For a graceful shutdown, use Shutdown instead. 886func (cc *ClientConn) closeForError(err error) error {
852func (cc *ClientConn) Close() error {
853 cc.mu.Lock() 887 cc.mu.Lock()
854 defer cc.cond.Broadcast() 888 defer cc.cond.Broadcast()
855 defer cc.mu.Unlock() 889 defer cc.mu.Unlock()
856 err := errors.New("http2: client connection force closed via ClientConn.Close")
857 for id, cs := range cc.streams { 890 for id, cs := range cc.streams {
858 select { 891 select {
859 case cs.resc <- resAndError{err: err}: 892 case cs.resc <- resAndError{err: err}:
@@ -866,6 +899,20 @@ func (cc *ClientConn) Close() error {
866 return cc.tconn.Close() 899 return cc.tconn.Close()
867} 900}
868 901
902// Close closes the client connection immediately.
903//
904// In-flight requests are interrupted. For a graceful shutdown, use Shutdown instead.
905func (cc *ClientConn) Close() error {
906 err := errors.New("http2: client connection force closed via ClientConn.Close")
907 return cc.closeForError(err)
908}
909
910// closes the client connection immediately. In-flight requests are interrupted.
911func (cc *ClientConn) closeForLostPing() error {
912 err := errors.New("http2: client connection lost")
913 return cc.closeForError(err)
914}
915
869const maxAllocFrameSize = 512 << 10 916const maxAllocFrameSize = 512 << 10
870 917
871// frameBuffer returns a scratch buffer suitable for writing DATA frames. 918// frameBuffer returns a scratch buffer suitable for writing DATA frames.
@@ -1737,8 +1784,17 @@ func (rl *clientConnReadLoop) run() error {
1737 rl.closeWhenIdle = cc.t.disableKeepAlives() || cc.singleUse 1784 rl.closeWhenIdle = cc.t.disableKeepAlives() || cc.singleUse
1738 gotReply := false // ever saw a HEADERS reply 1785 gotReply := false // ever saw a HEADERS reply
1739 gotSettings := false 1786 gotSettings := false
1787 readIdleTimeout := cc.t.ReadIdleTimeout
1788 var t *time.Timer
1789 if readIdleTimeout != 0 {
1790 t = time.AfterFunc(readIdleTimeout, cc.healthCheck)
1791 defer t.Stop()
1792 }
1740 for { 1793 for {
1741 f, err := cc.fr.ReadFrame() 1794 f, err := cc.fr.ReadFrame()
1795 if t != nil {
1796 t.Reset(readIdleTimeout)
1797 }
1742 if err != nil { 1798 if err != nil {
1743 cc.vlogf("http2: Transport readFrame error on conn %p: (%T) %v", cc, err, err) 1799 cc.vlogf("http2: Transport readFrame error on conn %p: (%T) %v", cc, err, err)
1744 } 1800 }