@@ -113,10 +113,12 @@ type Transport struct {
113
113
// if response is not received within PingTimeout.
114
114
// 0 means no periodic pings. Defaults to 0.
115
115
PingPeriod time.Duration
116
+
116
117
// PingTimeout is the timeout after which the connection will be closed
117
118
// if a response to Ping is not received.
118
119
// 0 means no periodic pings. Defaults to 0.
119
120
PingTimeout time.Duration
121
+
120
122
// ReadIdleTimeout is the timeout after which the periodic ping for
121
123
// connection health check will begin if no frame is received on the
122
124
// connection.
@@ -148,6 +150,14 @@ func (t *Transport) disableCompression() bool {
148
150
return t .DisableCompression || (t .t1 != nil && t .t1 .DisableCompression )
149
151
}
150
152
153
+ func (t * Transport ) readIdleTimeout () time.Duration {
154
+ to := t .ReadIdleTimeout
155
+ if to == 0 {
156
+ to = 60 * time .Second
157
+ }
158
+ return to
159
+ }
160
+
151
161
// ConfigureTransport configures a net/http HTTP/1 Transport to use HTTP/2.
152
162
// It returns an error if t1 has already been HTTP/2-enabled.
153
163
func ConfigureTransport (t1 * http.Transport ) error {
@@ -1775,42 +1785,17 @@ func (rl *clientConnReadLoop) cleanup() {
1775
1785
cc .mu .Unlock ()
1776
1786
}
1777
1787
1778
- type frameAndError struct {
1779
- f Frame
1780
- err error
1781
- }
1782
-
1783
- func nonBlockingReadFrame (fr * Framer ) chan frameAndError {
1784
- feCh := make (chan frameAndError )
1785
- go func () {
1786
- f , err := fr .ReadFrame ()
1787
- feCh <- frameAndError {f : f , err : err }
1788
- }()
1789
- return feCh
1790
- }
1791
-
1792
1788
func (rl * clientConnReadLoop ) run () error {
1793
1789
cc := rl .cc
1794
1790
rl .closeWhenIdle = cc .t .disableKeepAlives () || cc .singleUse
1795
1791
gotReply := false // ever saw a HEADERS reply
1796
1792
gotSettings := false
1793
+ to := cc .t .readIdleTimeout ()
1794
+ t := time .AfterFunc (to , cc .startHealthCheck )
1797
1795
for {
1798
- var fe frameAndError
1799
- feCh := nonBlockingReadFrame (cc .fr )
1800
- to := cc .t .ReadIdleTimeout
1801
- if to == 0 {
1802
- to = 60 * time .Second
1803
- }
1804
- readIdleTimer := time .NewTimer (to )
1805
- select {
1806
- case fe = <- feCh :
1807
- cc .stopHealthCheck ()
1808
- readIdleTimer .Stop ()
1809
- case <- readIdleTimer .C :
1810
- cc .startHealthCheck ()
1811
- fe = <- feCh
1812
- }
1813
- f , err := fe .f , fe .err
1796
+ f , err := cc .fr .ReadFrame ()
1797
+ t .Reset (to )
1798
+ cc .stopHealthCheck ()
1814
1799
if err != nil {
1815
1800
cc .vlogf ("http2: Transport readFrame error on conn %p: (%T) %v" , cc , err , err )
1816
1801
}
0 commit comments