Skip to content

Commit f095481

Browse files
Request.SetTimeout (#1415)
* Request.SetTimeout This functionally works the same as e.g. Client.DoTimeout(), but we can also use it for Client.DoRedirect(). There is no way as far as I can tell to set a timeout on a DoRedirect call, so this makes it possible. * tests * docs
1 parent c88dd5d commit f095481

File tree

2 files changed

+101
-0
lines changed

2 files changed

+101
-0
lines changed

Diff for: client_test.go

+93
Original file line numberDiff line numberDiff line change
@@ -1566,6 +1566,56 @@ func TestClientFollowRedirects(t *testing.T) {
15661566
ReleaseResponse(resp)
15671567
}
15681568

1569+
for i := 0; i < 10; i++ {
1570+
req := AcquireRequest()
1571+
resp := AcquireResponse()
1572+
1573+
req.SetRequestURI("http://xxx/foo")
1574+
1575+
req.SetTimeout(time.Second)
1576+
err := c.DoRedirects(req, resp, 16)
1577+
if err != nil {
1578+
t.Fatalf("unexpected error: %v", err)
1579+
}
1580+
1581+
if statusCode := resp.StatusCode(); statusCode != StatusOK {
1582+
t.Fatalf("unexpected status code: %d", statusCode)
1583+
}
1584+
1585+
if body := string(resp.Body()); body != "/bar" {
1586+
t.Fatalf("unexpected response %q. Expecting %q", body, "/bar")
1587+
}
1588+
1589+
ReleaseRequest(req)
1590+
ReleaseResponse(resp)
1591+
}
1592+
1593+
for i := 0; i < 10; i++ {
1594+
req := AcquireRequest()
1595+
resp := AcquireResponse()
1596+
1597+
req.SetRequestURI("http://xxx/foo")
1598+
1599+
testConn, _ := net.Dial("tcp", ln.Addr().String())
1600+
timeoutConn := &Client{
1601+
Dial: func(addr string) (net.Conn, error) {
1602+
return &readTimeoutConn{Conn: testConn, t: time.Second}, nil
1603+
},
1604+
}
1605+
1606+
req.SetTimeout(time.Millisecond)
1607+
err := timeoutConn.DoRedirects(req, resp, 16)
1608+
if err == nil {
1609+
t.Errorf("expecting error")
1610+
}
1611+
if err != ErrTimeout {
1612+
t.Errorf("unexpected error: %v. Expecting %v", err, ErrTimeout)
1613+
}
1614+
1615+
ReleaseRequest(req)
1616+
ReleaseResponse(resp)
1617+
}
1618+
15691619
req := AcquireRequest()
15701620
resp := AcquireResponse()
15711621

@@ -1613,6 +1663,7 @@ func TestClientDoTimeoutSuccess(t *testing.T) {
16131663
defer s.Stop()
16141664

16151665
testClientDoTimeoutSuccess(t, &defaultClient, "http://"+s.Addr(), 100)
1666+
testClientRequestSetTimeoutSuccess(t, &defaultClient, "http://"+s.Addr(), 100)
16161667
}
16171668

16181669
func TestClientDoTimeoutSuccessConcurrent(t *testing.T) {
@@ -1627,6 +1678,7 @@ func TestClientDoTimeoutSuccessConcurrent(t *testing.T) {
16271678
go func() {
16281679
defer wg.Done()
16291680
testClientDoTimeoutSuccess(t, &defaultClient, "http://"+s.Addr(), 100)
1681+
testClientRequestSetTimeoutSuccess(t, &defaultClient, "http://"+s.Addr(), 100)
16301682
}()
16311683
}
16321684
wg.Wait()
@@ -1687,6 +1739,7 @@ func TestClientDoTimeoutError(t *testing.T) {
16871739
}
16881740

16891741
testClientDoTimeoutError(t, c, 100)
1742+
testClientRequestSetTimeoutError(t, c, 100)
16901743
}
16911744

16921745
func TestClientDoTimeoutErrorConcurrent(t *testing.T) {
@@ -1748,6 +1801,22 @@ func testClientGetTimeoutError(t *testing.T, c *Client, n int) {
17481801
}
17491802
}
17501803

1804+
func testClientRequestSetTimeoutError(t *testing.T, c *Client, n int) {
1805+
var req Request
1806+
var resp Response
1807+
req.SetRequestURI("http://foobar.com/baz")
1808+
for i := 0; i < n; i++ {
1809+
req.SetTimeout(time.Millisecond)
1810+
err := c.Do(&req, &resp)
1811+
if err == nil {
1812+
t.Errorf("expecting error")
1813+
}
1814+
if err != ErrTimeout {
1815+
t.Errorf("unexpected error: %v. Expecting %v", err, ErrTimeout)
1816+
}
1817+
}
1818+
}
1819+
17511820
type readTimeoutConn struct {
17521821
net.Conn
17531822
t time.Duration
@@ -2398,6 +2467,30 @@ func testClientDoTimeoutSuccess(t *testing.T, c *Client, addr string, n int) {
23982467
}
23992468
}
24002469

2470+
func testClientRequestSetTimeoutSuccess(t *testing.T, c *Client, addr string, n int) {
2471+
var req Request
2472+
var resp Response
2473+
2474+
for i := 0; i < n; i++ {
2475+
uri := fmt.Sprintf("%s/foo/%d?bar=baz", addr, i)
2476+
req.SetRequestURI(uri)
2477+
req.SetTimeout(time.Second)
2478+
if err := c.Do(&req, &resp); err != nil {
2479+
t.Errorf("unexpected error: %v", err)
2480+
}
2481+
if resp.StatusCode() != StatusOK {
2482+
t.Errorf("unexpected status code: %d. Expecting %d", resp.StatusCode(), StatusOK)
2483+
}
2484+
resultURI := string(resp.Body())
2485+
if strings.HasPrefix(uri, "https") {
2486+
resultURI = uri[:5] + resultURI[4:]
2487+
}
2488+
if resultURI != uri {
2489+
t.Errorf("unexpected uri %q. Expecting %q", resultURI, uri)
2490+
}
2491+
}
2492+
}
2493+
24012494
func testClientGetTimeoutSuccess(t *testing.T, c *Client, addr string, n int) {
24022495
var buf []byte
24032496
for i := 0; i < n; i++ {

Diff for: http.go

+8
Original file line numberDiff line numberDiff line change
@@ -2290,3 +2290,11 @@ func round2(n int) int {
22902290

22912291
return int(x + 1)
22922292
}
2293+
2294+
// SetTimeout sets timeout for the request.
2295+
//
2296+
// req.SetTimeout(t); c.Do(&req, &resp) is equivalent to
2297+
// c.DoTimeout(&req, &resp, t)
2298+
func (req *Request) SetTimeout(t time.Duration) {
2299+
req.timeout = t
2300+
}

0 commit comments

Comments
 (0)