diff --git a/echo.go b/echo.go index 74c301a8..128ae1c3 100644 --- a/echo.go +++ b/echo.go @@ -253,7 +253,7 @@ func (e *Echo) DefaultHTTPErrorHandler(err error, c Context) { if !c.Response().Committed() { c.String(code, msg) } - e.logger.Debug(err) + e.logger.Error(err) } // SetHTTPErrorHandler registers a custom Echo.HTTPErrorHandler. diff --git a/engine/standard/response.go b/engine/standard/response.go index 319355a2..ad0810f3 100644 --- a/engine/standard/response.go +++ b/engine/standard/response.go @@ -1,7 +1,9 @@ package standard import ( + "bufio" "io" + "net" "net/http" "github.com/labstack/echo/engine" @@ -74,6 +76,29 @@ func (r *Response) SetWriter(w io.Writer) { r.writer = w } +// Flush implements the http.Flusher interface to allow an HTTP handler to flush +// buffered data to the client. +// See [http.Flusher](https://golang.org/pkg/net/http/#Flusher) +func (r *Response) Flush() { + r.ResponseWriter.(http.Flusher).Flush() +} + +// Hijack implements the http.Hijacker interface to allow an HTTP handler to +// take over the connection. +// See [http.Hijacker](https://golang.org/pkg/net/http/#Hijacker) +func (r *Response) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return r.ResponseWriter.(http.Hijacker).Hijack() +} + +// CloseNotify implements the http.CloseNotifier interface to allow detecting +// when the underlying connection has gone away. +// This mechanism can be used to cancel long operations on the server if the +// client has disconnected before the response is ready. +// See [http.CloseNotifier](https://golang.org/pkg/net/http/#CloseNotifier) +func (r *Response) CloseNotify() <-chan bool { + return r.ResponseWriter.(http.CloseNotifier).CloseNotify() +} + func (r *Response) reset(w http.ResponseWriter, h engine.Header) { r.ResponseWriter = w r.header = h @@ -86,3 +111,15 @@ func (r *Response) reset(w http.ResponseWriter, h engine.Header) { func (r *responseAdapter) Write(b []byte) (n int, err error) { return r.writer.Write(b) } + +func (r *responseAdapter) Flush() { + r.ResponseWriter.(http.Flusher).Flush() +} + +func (r *responseAdapter) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return r.ResponseWriter.(http.Hijacker).Hijack() +} + +func (r *responseAdapter) CloseNotify() <-chan bool { + return r.ResponseWriter.(http.CloseNotifier).CloseNotify() +} diff --git a/middleware/recover.go b/middleware/recover.go index d765834a..3885fe5b 100644 --- a/middleware/recover.go +++ b/middleware/recover.go @@ -25,12 +25,12 @@ var ( ) func Recover() echo.MiddlewareFunc { - return RecoverWithConfig(DefaultRecoverConfig) + return RecoverFromConfig(DefaultRecoverConfig) } // Recover returns a middleware which recovers from panics anywhere in the chain // and handles the control to the centralized HTTPErrorHandler. -func RecoverWithConfig(config RecoverConfig) echo.MiddlewareFunc { +func RecoverFromConfig(config RecoverConfig) echo.MiddlewareFunc { return func(next echo.Handler) echo.Handler { return echo.HandlerFunc(func(c echo.Context) error { defer func() { @@ -45,7 +45,7 @@ func RecoverWithConfig(config RecoverConfig) echo.MiddlewareFunc { stack := make([]byte, config.StackSize) length := runtime.Stack(stack, config.StackAll) if config.PrintStack { - c.Logger().Printf("%s|%s", color.Red("PANIC RECOVER"), stack[:length]) + c.Logger().Printf("[%s] %s %s", color.Red("PANIC RECOVER"), err, stack[:length]) } c.Error(err) }