58 lines
1.8 KiB
Go
58 lines
1.8 KiB
Go
package server
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
"net"
|
|
"net/http"
|
|
|
|
"github.com/containous/traefik/log"
|
|
"github.com/containous/traefik/middlewares"
|
|
)
|
|
|
|
// StatusClientClosedRequest non-standard HTTP status code for client disconnection
|
|
const StatusClientClosedRequest = 499
|
|
|
|
// StatusClientClosedRequestText non-standard HTTP status for client disconnection
|
|
const StatusClientClosedRequestText = "Client Closed Request"
|
|
|
|
// RecordingErrorHandler is an error handler, implementing the vulcand/oxy
|
|
// error handler interface, which is recording network errors by using the netErrorRecorder.
|
|
// In addition it sets a proper HTTP status code and body, depending on the type of error occurred.
|
|
type RecordingErrorHandler struct {
|
|
netErrorRecorder middlewares.NetErrorRecorder
|
|
}
|
|
|
|
// NewRecordingErrorHandler creates and returns a new instance of RecordingErrorHandler.
|
|
func NewRecordingErrorHandler(recorder middlewares.NetErrorRecorder) *RecordingErrorHandler {
|
|
return &RecordingErrorHandler{recorder}
|
|
}
|
|
|
|
func (eh *RecordingErrorHandler) ServeHTTP(w http.ResponseWriter, req *http.Request, err error) {
|
|
statusCode := http.StatusInternalServerError
|
|
|
|
if e, ok := err.(net.Error); ok {
|
|
eh.netErrorRecorder.Record(req.Context())
|
|
if e.Timeout() {
|
|
statusCode = http.StatusGatewayTimeout
|
|
} else {
|
|
statusCode = http.StatusBadGateway
|
|
}
|
|
} else if err == io.EOF {
|
|
eh.netErrorRecorder.Record(req.Context())
|
|
statusCode = http.StatusBadGateway
|
|
} else if err == context.Canceled {
|
|
statusCode = StatusClientClosedRequest
|
|
}
|
|
|
|
w.WriteHeader(statusCode)
|
|
w.Write([]byte(statusText(statusCode)))
|
|
log.Debugf("'%d %s' caused by: %v", statusCode, statusText(statusCode), err)
|
|
}
|
|
|
|
func statusText(statusCode int) string {
|
|
if statusCode == StatusClientClosedRequest {
|
|
return StatusClientClosedRequestText
|
|
}
|
|
return http.StatusText(statusCode)
|
|
}
|