mirror of https://github.com/golang/go.git
TimeoutHandler: distinguish between timeouts and client hangups
This commit is contained in:
parent
aded1679ef
commit
0b667ac94e
|
|
@ -3304,6 +3304,7 @@ func TimeoutHandler(h Handler, dt time.Duration, msg string) Handler {
|
|||
// ErrHandlerTimeout is returned on ResponseWriter Write calls
|
||||
// in handlers which have timed out.
|
||||
var ErrHandlerTimeout = errors.New("http: Handler timeout")
|
||||
var ErrClientHangup = errors.New("http: Client hung up")
|
||||
|
||||
type timeoutHandler struct {
|
||||
handler Handler
|
||||
|
|
@ -3364,9 +3365,14 @@ func (h *timeoutHandler) ServeHTTP(w ResponseWriter, r *Request) {
|
|||
case <-ctx.Done():
|
||||
tw.mu.Lock()
|
||||
defer tw.mu.Unlock()
|
||||
w.WriteHeader(StatusServiceUnavailable)
|
||||
io.WriteString(w, h.errorBody())
|
||||
tw.timedOut = true
|
||||
switch err := ctx.Err(); err {
|
||||
case context.DeadlineExceeded:
|
||||
w.WriteHeader(StatusServiceUnavailable)
|
||||
io.WriteString(w, h.errorBody())
|
||||
tw.timedOut = true
|
||||
case context.Canceled:
|
||||
tw.clientHangup = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3376,10 +3382,11 @@ type timeoutWriter struct {
|
|||
wbuf bytes.Buffer
|
||||
req *Request
|
||||
|
||||
mu sync.Mutex
|
||||
timedOut bool
|
||||
wroteHeader bool
|
||||
code int
|
||||
mu sync.Mutex
|
||||
timedOut bool
|
||||
clientHangup bool
|
||||
wroteHeader bool
|
||||
code int
|
||||
}
|
||||
|
||||
var _ Pusher = (*timeoutWriter)(nil)
|
||||
|
|
@ -3400,6 +3407,9 @@ func (tw *timeoutWriter) Write(p []byte) (int, error) {
|
|||
if tw.timedOut {
|
||||
return 0, ErrHandlerTimeout
|
||||
}
|
||||
if tw.clientHangup {
|
||||
return 0, ErrClientHangup
|
||||
}
|
||||
if !tw.wroteHeader {
|
||||
tw.writeHeaderLocked(StatusOK)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue