Skip to content

x/net/http2: decide what to do about Transport.CancelRequest #13540

@bradfitz

Description

@bradfitz

The net/http.Transport.CancelRequest method is an old feature & wart.

There is no interface which defines it, but it's sniffed for by many RoundTrippers and users of RoundTrippers (including net/http.Client for its Client.Timeout feature), and it's a thorn in the side of people trying to write composable RoundTripper implementations.

The modern replacement is the net/http.Request.Cancel receive-only channel to do cancelations. (closed by caller on cancel)

Unfortunately, net/http.Client doesn't use the Cancel channel. Perhaps it could. But that would require mutating the caller's *Request, at least for Do. But for net/http.Client methods like Get, Head, Post, and PostForm, we create the *http.Request, so we could set the Cancel channel appropriately.

That leaves net/http.Client.Do, which takes a raw *Request. Is it allowed to set the Cancel channel if it's nil? Probably not? Or maybe there is precedent in mutating the Request: we read from the Request.Body, so it's not safe to use concurrently already. So maybe we can just save/restore the Request.Cancel field.

Related to that debate is whether x/net/http2.Transport should have an old-style CancelRequest method. It would really be nice to stop letting that mistake infect things, though, spreading the idea that everybody needs to implement CancelRequest.

But unfortunately as-is, Client Timeouts are failing with http2: https://go-review.googlesource.com/#/c/17528/1 From the second comment:

$ go test -cover
--- FAIL: TestClientTimeout_h2 (2.01s)
    client_test.go:983: timeout after 1s waiting for timeout of 500ms

Thoughts welcome.

/cc @rsc @dsymonds @okdave @mcgreevy @bmizerany

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions