Closed
Description
On HTTP redirect, the HTTP client creates a new request and don't copy over the Cancel
channel. This prevents any redirected request from being cancelled.
Here is a way to reproduce the issue:
package main
import (
"fmt"
"net/http"
"time"
)
func main() {
t := time.Now()
_, err := requestTimeout("http://httpbin.org/delay/10", 2 * time.Second)
fmt.Printf("Err: %v\n", err)
fmt.Printf("Elapsed: %v\n", time.Now().Sub(t))
t = time.Now()
_, err = requestTimeout("http://httpbin.org/redirect-to?url=http://httpbin.org/delay/10", 2 * time.Second)
fmt.Printf("Err: %v\n", err)
fmt.Printf("Elapsed: %v\n", time.Now().Sub(t))
}
func requestTimeout(url string, timeout time.Duration) (res *http.Response, err error) {
req, _ := http.NewRequest("GET", url, nil)
cancel := make(chan struct{})
done := make(chan struct{})
req.Cancel = cancel
go func() {
res, err = http.DefaultClient.Do(req)
close(done)
}()
time.Sleep(timeout)
close(cancel)
<-done
return
}
Output:
Err: Get http://httpbin.org/delay/10: net/http: request canceled
Elapsed: 2.004138928s
Err: <nil>
Elapsed: 10.319406866s