Skip to content

net/http: Transport.CancelRequest no longer cancels in-flight request #40453

@neild

Description

@neild

(*net/http.Transport).CancelRequest's documentation states:

CancelRequest should only be called after RoundTrip has returned.

Despite this warning, CancelRequest does usually cancel an in-flight request currently blocked in RoundTrip. CL 234894 has inadvertently broken this for requests with a body.

Crude reproduction case follows.

package main

import (
        "bytes"
        "fmt"
        "net/http"
        "testing"
        "time"
)

func init() {
        http.HandleFunc("/ok", func(w http.ResponseWriter, r *http.Request) {
                fmt.Fprintln(w, "ok")
        })
        http.HandleFunc("/hang", func(w http.ResponseWriter, r *http.Request) {
                <-r.Context().Done()
        })
        go http.ListenAndServe("localhost:8080", nil)
}

func TestHTTP(t *testing.T) {
        for {
                _, err := http.Get("http://localhost:8080/ok")
                if err == nil {
                        break
                }
        }

        buf := bytes.NewBuffer([]byte{1, 2, 3})

        req, err := http.NewRequest("GET", "http://localhost:8080/hang", buf)
        if err != nil {
                t.Fatal(err)
        }
        donec := make(chan int)
        go func() {
                defer close(donec)
                http.DefaultTransport.RoundTrip(req)
        }()

        time.Sleep(100 * time.Millisecond)
        http.DefaultTransport.(*http.Transport).CancelRequest(req)
        <-donec
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions