Skip to content

net/http: Cancel channel is not passed upon redirects #14053

Closed
@rs

Description

@rs

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions