mirror of
https://github.com/labstack/echo.git
synced 2025-07-17 01:43:02 +02:00
Fixed recover and gzip middleware
Signed-off-by: Vishal Rana <vr@labstack.com>
This commit is contained in:
@ -26,7 +26,6 @@ type (
|
|||||||
Context interface {
|
Context interface {
|
||||||
netContext.Context
|
netContext.Context
|
||||||
Request() engine.Request
|
Request() engine.Request
|
||||||
SetResponse(engine.Response)
|
|
||||||
Response() engine.Response
|
Response() engine.Response
|
||||||
Path() string
|
Path() string
|
||||||
P(int) string
|
P(int) string
|
||||||
@ -111,11 +110,6 @@ func (c *context) Request() engine.Request {
|
|||||||
return c.request
|
return c.request
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetResponse sets `engine.Response`.
|
|
||||||
func (c *context) SetResponse(r engine.Response) {
|
|
||||||
c.response = r
|
|
||||||
}
|
|
||||||
|
|
||||||
// Response returns `engine.Response`.
|
// Response returns `engine.Response`.
|
||||||
func (c *context) Response() engine.Response {
|
func (c *context) Response() engine.Response {
|
||||||
return c.response
|
return c.response
|
||||||
|
4
echo.go
4
echo.go
@ -197,7 +197,7 @@ func New() (e *Echo) {
|
|||||||
|
|
||||||
// Logger
|
// Logger
|
||||||
e.logger = log.New("echo")
|
e.logger = log.New("echo")
|
||||||
e.logger.SetLevel(log.FATAL)
|
e.logger.SetLevel(log.ERROR)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -249,7 +249,7 @@ func (e *Echo) DefaultHTTPErrorHandler(err error, c Context) {
|
|||||||
if !c.Response().Committed() {
|
if !c.Response().Committed() {
|
||||||
c.String(code, msg)
|
c.String(code, msg)
|
||||||
}
|
}
|
||||||
e.logger.Debug(err)
|
e.logger.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetHTTPErrorHandler registers a custom Echo.HTTPErrorHandler.
|
// SetHTTPErrorHandler registers a custom Echo.HTTPErrorHandler.
|
||||||
|
@ -40,8 +40,8 @@ type (
|
|||||||
Status() int
|
Status() int
|
||||||
Size() int64
|
Size() int64
|
||||||
Committed() bool
|
Committed() bool
|
||||||
// SetWriter(io.Writer)
|
SetWriter(io.Writer)
|
||||||
// Writer() io.Writer
|
Writer() io.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
// Header defines an interface for HTTP header.
|
// Header defines an interface for HTTP header.
|
||||||
|
@ -62,13 +62,13 @@ func (r *Response) Committed() bool {
|
|||||||
return r.committed
|
return r.committed
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (r *Response) SetWriter(w io.Writer) {
|
func (r *Response) SetWriter(w io.Writer) {
|
||||||
// r.writer = w
|
r.writer = w
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// func (r *Response) Writer() io.Writer {
|
func (r *Response) Writer() io.Writer {
|
||||||
// return r.writer
|
return r.writer
|
||||||
// }
|
}
|
||||||
|
|
||||||
func (r *Response) reset(c *fasthttp.RequestCtx, h engine.Header) {
|
func (r *Response) reset(c *fasthttp.RequestCtx, h engine.Header) {
|
||||||
r.RequestCtx = c
|
r.RequestCtx = c
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package standard
|
package standard
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/labstack/echo/engine"
|
"github.com/labstack/echo/engine"
|
||||||
@ -14,8 +15,8 @@ type (
|
|||||||
status int
|
status int
|
||||||
size int64
|
size int64
|
||||||
committed bool
|
committed bool
|
||||||
// writer io.Writer
|
writer io.Writer
|
||||||
logger *log.Logger
|
logger *log.Logger
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -23,8 +24,8 @@ func NewResponse(w http.ResponseWriter, l *log.Logger) *Response {
|
|||||||
return &Response{
|
return &Response{
|
||||||
ResponseWriter: w,
|
ResponseWriter: w,
|
||||||
header: &Header{w.Header()},
|
header: &Header{w.Header()},
|
||||||
// writer: w,
|
writer: w,
|
||||||
logger: l,
|
logger: l,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +44,7 @@ func (r *Response) WriteHeader(code int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *Response) Write(b []byte) (n int, err error) {
|
func (r *Response) Write(b []byte) (n int, err error) {
|
||||||
n, err = r.ResponseWriter.Write(b)
|
n, err = r.writer.Write(b)
|
||||||
r.size += int64(n)
|
r.size += int64(n)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -60,13 +61,13 @@ func (r *Response) Committed() bool {
|
|||||||
return r.committed
|
return r.committed
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (r *Response) SetWriter(w io.Writer) {
|
func (r *Response) SetWriter(w io.Writer) {
|
||||||
// r.writer = w
|
r.writer = w
|
||||||
// }
|
}
|
||||||
|
|
||||||
// func (r *Response) Writer() io.Writer {
|
func (r *Response) Writer() io.Writer {
|
||||||
// return r.writer
|
return r.writer
|
||||||
// }
|
}
|
||||||
|
|
||||||
func (r *Response) reset(w http.ResponseWriter, h engine.Header) {
|
func (r *Response) reset(w http.ResponseWriter, h engine.Header) {
|
||||||
r.ResponseWriter = w
|
r.ResponseWriter = w
|
||||||
@ -74,5 +75,5 @@ func (r *Response) reset(w http.ResponseWriter, h engine.Header) {
|
|||||||
r.status = http.StatusOK
|
r.status = http.StatusOK
|
||||||
r.size = 0
|
r.size = 0
|
||||||
r.committed = false
|
r.committed = false
|
||||||
// r.writer = w
|
r.writer = w
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import (
|
|||||||
|
|
||||||
type (
|
type (
|
||||||
Server struct {
|
Server struct {
|
||||||
server *http.Server
|
*http.Server
|
||||||
config *engine.Config
|
config *engine.Config
|
||||||
handler engine.Handler
|
handler engine.Handler
|
||||||
logger *log.Logger
|
logger *log.Logger
|
||||||
@ -42,7 +42,7 @@ func NewFromTLS(addr, certfile, keyfile string) *Server {
|
|||||||
|
|
||||||
func NewFromConfig(c *engine.Config) (s *Server) {
|
func NewFromConfig(c *engine.Config) (s *Server) {
|
||||||
s = &Server{
|
s = &Server{
|
||||||
server: new(http.Server),
|
Server: new(http.Server),
|
||||||
config: c,
|
config: c,
|
||||||
pool: &Pool{
|
pool: &Pool{
|
||||||
request: sync.Pool{
|
request: sync.Pool{
|
||||||
@ -71,8 +71,8 @@ func NewFromConfig(c *engine.Config) (s *Server) {
|
|||||||
}),
|
}),
|
||||||
logger: log.New("echo"),
|
logger: log.New("echo"),
|
||||||
}
|
}
|
||||||
s.server.Addr = c.Address
|
s.Addr = c.Address
|
||||||
s.server.Handler = s
|
s.Handler = s
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,9 +88,9 @@ func (s *Server) Start() {
|
|||||||
certfile := s.config.TLSCertfile
|
certfile := s.config.TLSCertfile
|
||||||
keyfile := s.config.TLSKeyfile
|
keyfile := s.config.TLSKeyfile
|
||||||
if certfile != "" && keyfile != "" {
|
if certfile != "" && keyfile != "" {
|
||||||
s.logger.Fatal(s.server.ListenAndServeTLS(certfile, keyfile))
|
s.logger.Fatal(s.ListenAndServeTLS(certfile, keyfile))
|
||||||
} else {
|
} else {
|
||||||
s.logger.Fatal(s.server.ListenAndServe())
|
s.logger.Fatal(s.ListenAndServe())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,10 +118,6 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
s.pool.header.Put(resHdr)
|
s.pool.header.Put(resHdr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) Server() *http.Server {
|
|
||||||
return s.server
|
|
||||||
}
|
|
||||||
|
|
||||||
// WrapHandler wraps `http.Handler` into `echo.HandlerFunc`.
|
// WrapHandler wraps `http.Handler` into `echo.HandlerFunc`.
|
||||||
func WrapHandler(h http.Handler) echo.HandlerFunc {
|
func WrapHandler(h http.Handler) echo.HandlerFunc {
|
||||||
return func(c echo.Context) error {
|
return func(c echo.Context) error {
|
||||||
|
@ -32,14 +32,14 @@ func Gzip(options ...*GzipOptions) echo.MiddlewareFunc {
|
|||||||
c.Response().Header().Add(echo.Vary, echo.AcceptEncoding)
|
c.Response().Header().Add(echo.Vary, echo.AcceptEncoding)
|
||||||
if strings.Contains(c.Request().Header().Get(echo.AcceptEncoding), scheme) {
|
if strings.Contains(c.Request().Header().Get(echo.AcceptEncoding), scheme) {
|
||||||
w := pool.Get().(*gzip.Writer)
|
w := pool.Get().(*gzip.Writer)
|
||||||
w.Reset(c.Response())
|
w.Reset(c.Response().Writer())
|
||||||
defer func() {
|
defer func() {
|
||||||
w.Close()
|
w.Close()
|
||||||
pool.Put(w)
|
pool.Put(w)
|
||||||
}()
|
}()
|
||||||
gw := gzipResponseWriter{Response: c.Response(), Writer: w}
|
g := gzipResponseWriter{Response: c.Response(), Writer: w}
|
||||||
c.Response().Header().Set(echo.ContentEncoding, scheme)
|
c.Response().Header().Set(echo.ContentEncoding, scheme)
|
||||||
c.SetResponse(gw)
|
c.Response().SetWriter(g)
|
||||||
}
|
}
|
||||||
if err := next.Handle(c); err != nil {
|
if err := next.Handle(c); err != nil {
|
||||||
c.Error(err)
|
c.Error(err)
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"errors"
|
||||||
|
|
||||||
"runtime"
|
|
||||||
|
|
||||||
"github.com/labstack/echo"
|
"github.com/labstack/echo"
|
||||||
)
|
)
|
||||||
@ -17,14 +15,22 @@ type (
|
|||||||
// and handles the control to the centralized HTTPErrorHandler.
|
// and handles the control to the centralized HTTPErrorHandler.
|
||||||
func Recover(options ...*RecoverOptions) echo.MiddlewareFunc {
|
func Recover(options ...*RecoverOptions) echo.MiddlewareFunc {
|
||||||
return func(next echo.Handler) echo.Handler {
|
return func(next echo.Handler) echo.Handler {
|
||||||
// TODO: Provide better stack trace `https://github.com/go-errors/errors` `https://github.com/docker/libcontainer/tree/master/stacktrace`
|
// TODO: Provide better stack trace
|
||||||
|
// - `https://github.com/go-errors/errors`
|
||||||
|
// - `https://github.com/docker/libcontainer/tree/master/stacktrace`
|
||||||
return echo.HandlerFunc(func(c echo.Context) error {
|
return echo.HandlerFunc(func(c echo.Context) error {
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := recover(); err != nil {
|
if r := recover(); r != nil {
|
||||||
trace := make([]byte, 1<<16)
|
e := ""
|
||||||
n := runtime.Stack(trace, true)
|
switch r := r.(type) {
|
||||||
c.Error(fmt.Errorf("panic recover\n %v\n stack trace %d bytes\n %s",
|
case string:
|
||||||
err, n, trace[:n]))
|
e = r
|
||||||
|
case error:
|
||||||
|
e = r.Error()
|
||||||
|
default:
|
||||||
|
e = "unknown error"
|
||||||
|
}
|
||||||
|
c.Error(errors.New("panic recover|" + e))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
return next.Handle(c)
|
return next.Handle(c)
|
||||||
|
@ -41,7 +41,7 @@ SetLogOutput sets the output destination for the logger. Default value is `os.St
|
|||||||
|
|
||||||
`echo#SetLogLevel(l log.Level)`
|
`echo#SetLogLevel(l log.Level)`
|
||||||
|
|
||||||
SetLogLevel sets the log level for the logger. Default value is `log.FATAL`.
|
SetLogLevel sets the log level for the logger. Default value is `log.ERROR`.
|
||||||
|
|
||||||
### Auto index
|
### Auto index
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user