|
59 | 59 | // anything in the net/http package. Callers should not
|
60 | 60 | // compare errors against this variable.
|
61 | 61 | ErrWriteAfterFlush = errors.New("unused")
|
| 62 | + |
| 63 | + // ErrConnectionClosed is used as a context Cause for contexts |
| 64 | + // cancelled because the client closed their connection while |
| 65 | + // a request was being handled. |
| 66 | + ErrConnectionClosed = errors.New("connection closed") |
| 67 | + |
| 68 | + // ErrConnectionHandled is used as a context Cause for contexts |
| 69 | + // cancelled because the request handler returned. |
| 70 | + ErrConnectionHandled = errors.New("connection handled") |
62 | 71 | )
|
63 | 72 |
|
64 | 73 | // A Handler responds to an HTTP request.
|
@@ -257,7 +266,7 @@ type conn struct {
|
257 | 266 | server *Server
|
258 | 267 |
|
259 | 268 | // cancelCtx cancels the connection-level context.
|
260 |
| - cancelCtx context.CancelFunc |
| 269 | + cancelCtx context.CancelCauseFunc |
261 | 270 |
|
262 | 271 | // rwc is the underlying network connection.
|
263 | 272 | // This is never wrapped by other types and is the value given out
|
@@ -754,8 +763,11 @@ func (cr *connReader) hitReadLimit() bool { return cr.remain <= 0 }
|
754 | 763 | // down its context.
|
755 | 764 | //
|
756 | 765 | // It may be called from multiple goroutines.
|
757 |
| -func (cr *connReader) handleReadError(_ error) { |
758 |
| - cr.conn.cancelCtx() |
| 766 | +func (cr *connReader) handleReadError(err error) { |
| 767 | + if errors.Is(err, io.EOF) { |
| 768 | + err = ErrConnectionClosed |
| 769 | + } |
| 770 | + cr.conn.cancelCtx(err) |
759 | 771 | cr.closeNotify()
|
760 | 772 | }
|
761 | 773 |
|
@@ -2005,9 +2017,9 @@ func (c *conn) serve(ctx context.Context) {
|
2005 | 2017 |
|
2006 | 2018 | // HTTP/1.x from here on.
|
2007 | 2019 |
|
2008 |
| - ctx, cancelCtx := context.WithCancel(ctx) |
| 2020 | + ctx, cancelCtx := context.WithCancelCause(ctx) |
2009 | 2021 | c.cancelCtx = cancelCtx
|
2010 |
| - defer cancelCtx() |
| 2022 | + defer cancelCtx(ErrConnectionHandled) |
2011 | 2023 |
|
2012 | 2024 | c.r = &connReader{conn: c}
|
2013 | 2025 | c.bufr = newBufioReader(c.r)
|
@@ -4021,7 +4033,7 @@ func (w checkConnErrorWriter) Write(p []byte) (n int, err error) {
|
4021 | 4033 | n, err = w.c.rwc.Write(p)
|
4022 | 4034 | if err != nil && w.c.werr == nil {
|
4023 | 4035 | w.c.werr = err
|
4024 |
| - w.c.cancelCtx() |
| 4036 | + w.c.cancelCtx(err) |
4025 | 4037 | }
|
4026 | 4038 | return
|
4027 | 4039 | }
|
|
0 commit comments