@@ -380,7 +380,7 @@ func (c *Client) Post(dst []byte, url string, postArgs *Args) (statusCode int, b
380
380
// and AcquireResponse in performance-critical code.
381
381
func (c * Client ) DoTimeout (req * Request , resp * Response , timeout time.Duration ) error {
382
382
req .timeout = timeout
383
- if req .timeout < 0 {
383
+ if req .timeout <= 0 {
384
384
return ErrTimeout
385
385
}
386
386
return c .Do (req , resp )
@@ -412,7 +412,7 @@ func (c *Client) DoTimeout(req *Request, resp *Response, timeout time.Duration)
412
412
// and AcquireResponse in performance-critical code.
413
413
func (c * Client ) DoDeadline (req * Request , resp * Response , deadline time.Time ) error {
414
414
req .timeout = time .Until (deadline )
415
- if req .timeout < 0 {
415
+ if req .timeout <= 0 {
416
416
return ErrTimeout
417
417
}
418
418
return c .Do (req , resp )
@@ -1158,7 +1158,7 @@ func ReleaseResponse(resp *Response) {
1158
1158
// and AcquireResponse in performance-critical code.
1159
1159
func (c * HostClient ) DoTimeout (req * Request , resp * Response , timeout time.Duration ) error {
1160
1160
req .timeout = timeout
1161
- if req .timeout < 0 {
1161
+ if req .timeout <= 0 {
1162
1162
return ErrTimeout
1163
1163
}
1164
1164
return c .Do (req , resp )
@@ -1185,7 +1185,7 @@ func (c *HostClient) DoTimeout(req *Request, resp *Response, timeout time.Durati
1185
1185
// and AcquireResponse in performance-critical code.
1186
1186
func (c * HostClient ) DoDeadline (req * Request , resp * Response , deadline time.Time ) error {
1187
1187
req .timeout = time .Until (deadline )
1188
- if req .timeout < 0 {
1188
+ if req .timeout <= 0 {
1189
1189
return ErrTimeout
1190
1190
}
1191
1191
return c .Do (req , resp )
@@ -1243,8 +1243,27 @@ func (c *HostClient) Do(req *Request, resp *Response) error {
1243
1243
attempts := 0
1244
1244
hasBodyStream := req .IsBodyStream ()
1245
1245
1246
+ // If a request has a timeout we store the timeout
1247
+ // and calculate a deadline so we can keep updating the
1248
+ // timeout on each retry.
1249
+ deadline := time.Time {}
1250
+ timeout := req .timeout
1251
+ if timeout > 0 {
1252
+ deadline = time .Now ().Add (timeout )
1253
+ }
1254
+
1246
1255
atomic .AddInt32 (& c .pendingRequests , 1 )
1247
1256
for {
1257
+ // If the original timeout was set, we need to update
1258
+ // the one set on the request to reflect the remaining time.
1259
+ if timeout > 0 {
1260
+ req .timeout = time .Until (deadline )
1261
+ if req .timeout <= 0 {
1262
+ err = ErrTimeout
1263
+ break
1264
+ }
1265
+ }
1266
+
1248
1267
retry , err = c .do (req , resp )
1249
1268
if err == nil || ! retry {
1250
1269
break
@@ -1272,6 +1291,9 @@ func (c *HostClient) Do(req *Request, resp *Response) error {
1272
1291
}
1273
1292
atomic .AddInt32 (& c .pendingRequests , - 1 )
1274
1293
1294
+ // Restore the original timeout.
1295
+ req .timeout = timeout
1296
+
1275
1297
if err == io .EOF {
1276
1298
err = ErrConnectionClosed
1277
1299
}
@@ -2288,7 +2310,7 @@ func (c *pipelineConnClient) DoDeadline(req *Request, resp *Response, deadline t
2288
2310
c .init ()
2289
2311
2290
2312
timeout := time .Until (deadline )
2291
- if timeout < 0 {
2313
+ if timeout <= 0 {
2292
2314
return ErrTimeout
2293
2315
}
2294
2316
0 commit comments