net/http: make Client.Timeout return net.Error errors indicating timeout

Co-hacking with Dave Cheney.

Fixes #9405

Change-Id: I14fc3b6a47dcdb5e514e93d062b804bb24e89f47
Reviewed-on: https://go-review.googlesource.com/1875
Reviewed-by: Dave Cheney <dave@cheney.net>
This commit is contained in:
Brad Fitzpatrick 2014-12-20 15:46:09 +11:00
parent 421c01706f
commit 01b2560068
2 changed files with 75 additions and 5 deletions

View file

@ -899,14 +899,57 @@ func TestClientTimeout(t *testing.T) {
select {
case err := <-errc:
if err == nil {
t.Error("expected error from ReadAll")
t.Fatal("expected error from ReadAll")
}
ne, ok := err.(net.Error)
if !ok {
t.Errorf("error value from ReadAll was %T; expected some net.Error", err)
} else if !ne.Timeout() {
t.Errorf("net.Error.Timeout = false; want true")
}
if got := ne.Error(); !strings.Contains(got, "Client.Timeout exceeded") {
t.Errorf("error string = %q; missing timeout substring", got)
}
// Expected error.
case <-time.After(failTime):
t.Errorf("timeout after %v waiting for timeout of %v", failTime, timeout)
}
}
// Client.Timeout firing before getting to the body
func TestClientTimeout_Headers(t *testing.T) {
if testing.Short() {
t.Skip("skipping in short mode")
}
defer afterTest(t)
donec := make(chan bool)
ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
<-donec
}))
defer ts.Close()
defer close(donec)
c := &Client{Timeout: 500 * time.Millisecond}
_, err := c.Get(ts.URL)
if err == nil {
t.Fatal("got response from Get; expected error")
}
ue, ok := err.(*url.Error)
if !ok {
t.Fatalf("Got error of type %T; want *url.Error", err)
}
ne, ok := ue.Err.(net.Error)
if !ok {
t.Fatalf("Got url.Error.Err of type %T; want some net.Error", err)
}
if !ne.Timeout() {
t.Error("net.Error.Timeout = false; want true")
}
if got := ne.Error(); !strings.Contains(got, "Client.Timeout exceeded") {
t.Errorf("error string = %q; missing timeout substring", got)
}
}
func TestClientRedirectEatsBody(t *testing.T) {
defer afterTest(t)
saw := make(chan string, 2)