Skip to content

Commit

Permalink
http3: return the context cancellation error from RoundTrip
Browse files Browse the repository at this point in the history
  • Loading branch information
marten-seemann committed Dec 13, 2023
1 parent ff6d575 commit 5716998
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 1 deletion.
9 changes: 9 additions & 0 deletions http3/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,15 @@ func (c *client) maxHeaderBytes() uint64 {

// RoundTripOpt executes a request and returns a response
func (c *client) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error) {
rsp, err := c.roundTripOpt(req, opt)
if err != nil && req.Context().Err() != nil {
// if the context was canceled, return the context cancellation error
err = req.Context().Err()
}
return rsp, err
}

func (c *client) roundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error) {
if authorityAddr("https", hostnameFromRequest(req)) != c.hostname {
return nil, fmt.Errorf("http3 client BUG: RoundTripOpt called for the wrong client (expected %s, got %s)", c.hostname, req.Host)
}
Expand Down
2 changes: 1 addition & 1 deletion http3/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -922,7 +922,7 @@ var _ = Describe("Client", func() {
return 0, errors.New("test done")
})
_, err := cl.RoundTripOpt(req, roundTripOpt)
Expect(err).To(MatchError("test done"))
Expect(err).To(MatchError(context.Canceled))
Eventually(done).Should(BeClosed())
})
})
Expand Down
15 changes: 15 additions & 0 deletions integrationtests/self/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,21 @@ var _ = Describe("HTTP tests", func() {
Expect(string(body)).To(Equal("Hello, World!\n"))
})

It("handles context cancellations", func() {
mux.HandleFunc("/cancel", func(w http.ResponseWriter, r *http.Request) {
<-r.Context().Done()
})

ctx, cancel := context.WithCancel(context.Background())
req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("https://localhost:%d/cancel", port), nil)
Expect(err).ToNot(HaveOccurred())
time.AfterFunc(50*time.Millisecond, cancel)

_, err = client.Do(req)
Expect(err).To(HaveOccurred())
Expect(err).To(MatchError(context.Canceled))
})

It("cancels requests", func() {
handlerCalled := make(chan struct{})
mux.HandleFunc("/cancel", func(w http.ResponseWriter, r *http.Request) {
Expand Down

0 comments on commit 5716998

Please sign in to comment.