@@ -116,13 +116,13 @@ type Transport struct {
116
116
117
117
// PingTimeout is the timeout after which the connection will be closed
118
118
// if a response to Ping is not received.
119
- // 0 means no periodic pings. Defaults to 0.
119
+ // Defaults to PingPeriod/2
120
120
PingTimeout time.Duration
121
121
122
122
// ReadIdleTimeout is the timeout after which the periodic ping for
123
123
// connection health check will begin if no frame is received on the
124
124
// connection.
125
- // The health check will stop once there is frame received on the
125
+ // The health check will stop once there is a frame received on the
126
126
// connection.
127
127
// Defaults to 60s.
128
128
ReadIdleTimeout time.Duration
@@ -158,6 +158,14 @@ func (t *Transport) readIdleTimeout() time.Duration {
158
158
return to
159
159
}
160
160
161
+ func (t * Transport ) pingTimeout () time.Duration {
162
+ if t .PingTimeout == 0 {
163
+ return t .PingPeriod / 2
164
+ }
165
+ return t .PingTimeout
166
+
167
+ }
168
+
161
169
// ConfigureTransport configures a net/http HTTP/1 Transport to use HTTP/2.
162
170
// It returns an error if t1 has already been HTTP/2-enabled.
163
171
func ConfigureTransport (t1 * http.Transport ) error {
@@ -267,7 +275,8 @@ type ClientConn struct {
267
275
wmu sync.Mutex // held while writing; acquire AFTER mu if holding both
268
276
werr error // first write error that has occurred
269
277
270
- healthCheckStopCh chan struct {}
278
+ hmu sync.Mutex // guard the healthCheckStopCh
279
+ healthCheckStopCh chan struct {} // A close-only channel to stop the health check.
271
280
}
272
281
273
282
// clientStream is the state for a single HTTP/2 stream. One of these
@@ -705,7 +714,7 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro
705
714
706
715
func (cc * ClientConn ) healthCheck (stop chan struct {}) {
707
716
pingPeriod := cc .t .PingPeriod
708
- pingTimeout := cc .t .PingTimeout
717
+ pingTimeout := cc .t .pingTimeout ()
709
718
if pingPeriod == 0 || pingTimeout == 0 {
710
719
return
711
720
}
@@ -729,6 +738,8 @@ func (cc *ClientConn) healthCheck(stop chan struct{}) {
729
738
}
730
739
731
740
func (cc * ClientConn ) startHealthCheck () {
741
+ cc .hmu .Lock ()
742
+ defer cc .hmu .Unlock ()
732
743
if cc .healthCheckStopCh != nil {
733
744
// a health check is already running
734
745
return
@@ -738,6 +749,8 @@ func (cc *ClientConn) startHealthCheck() {
738
749
}
739
750
740
751
func (cc * ClientConn ) stopHealthCheck () {
752
+ cc .hmu .Lock ()
753
+ defer cc .hmu .Unlock ()
741
754
if cc .healthCheckStopCh == nil {
742
755
// no health check running
743
756
return
@@ -934,7 +947,7 @@ func (cc *ClientConn) Close() error {
934
947
935
948
// closes the client connection immediately. In-flight requests are interrupted.
936
949
func (cc * ClientConn ) closeForLostPing () error {
937
- err := errors .New ("http2: client connection force closed because ping frame is not responded " )
950
+ err := errors .New ("http2: client connection force closed because ping frame was not answered " )
938
951
return cc .closeForError (err )
939
952
}
940
953
0 commit comments