diff --git a/context.go b/context.go index a4167579..ff7e1a98 100644 --- a/context.go +++ b/context.go @@ -47,7 +47,7 @@ type ( Redirect(int, string) error Error(err error) Logger() *log.Logger - X() *context + Context() *context } context struct { @@ -307,8 +307,8 @@ func (c *context) Logger() *log.Logger { return c.echo.logger } -// X returns the `context` instance. -func (c *context) X() *context { +// Context returns the `context` instance. +func (c *context) Context() *context { return c } diff --git a/context_test.go b/context_test.go index 3a5aa80c..fd127864 100644 --- a/context_test.go +++ b/context_test.go @@ -51,8 +51,8 @@ func TestContext(t *testing.T) { assert.Nil(t, c.Socket()) // Param by id - c.X().pnames = []string{"id"} - c.X().pvalues = []string{"1"} + c.Context().pnames = []string{"id"} + c.Context().pvalues = []string{"1"} assert.Equal(t, "1", c.P(0)) // Param by name @@ -68,13 +68,13 @@ func TestContext(t *testing.T) { // JSON testBindOk(t, c, ApplicationJSON) - c.X().request = test.NewRequest(POST, "/", strings.NewReader(incorrectContent)) + c.Context().request = test.NewRequest(POST, "/", strings.NewReader(incorrectContent)) testBindError(t, c, ApplicationJSON) // XML - c.X().request = test.NewRequest(POST, "/", strings.NewReader(userXML)) + c.Context().request = test.NewRequest(POST, "/", strings.NewReader(userXML)) testBindOk(t, c, ApplicationXML) - c.X().request = test.NewRequest(POST, "/", strings.NewReader(incorrectContent)) + c.Context().request = test.NewRequest(POST, "/", strings.NewReader(incorrectContent)) testBindError(t, c, ApplicationXML) // Unsupported @@ -87,14 +87,14 @@ func TestContext(t *testing.T) { tpl := &Template{ templates: template.Must(template.New("hello").Parse("Hello, {{.}}!")), } - c.X().echo.SetRenderer(tpl) + c.Context().echo.SetRenderer(tpl) err := c.Render(http.StatusOK, "hello", "Joe") if assert.NoError(t, err) { assert.Equal(t, http.StatusOK, rec.Status()) assert.Equal(t, "Hello, Joe!", rec.Body.String()) } - c.X().echo.renderer = nil + c.Context().echo.renderer = nil err = c.Render(http.StatusOK, "hello", "Joe") assert.Error(t, err) @@ -226,12 +226,12 @@ func TestContext(t *testing.T) { // Error rec = test.NewResponseRecorder() - c = NewContext(req, rec, e).X() + c = NewContext(req, rec, e).Context() c.Error(errors.New("error")) assert.Equal(t, http.StatusInternalServerError, c.Response().Status()) // reset - c.X().reset(req, test.NewResponseRecorder(), e) + c.Context().reset(req, test.NewResponseRecorder(), e) } func TestContextPath(t *testing.T) { diff --git a/echo.go b/echo.go index 4865d572..2a7d607f 100644 --- a/echo.go +++ b/echo.go @@ -554,8 +554,23 @@ func (e *Echo) SetEngine(t engine.Type) { } // Run runs a server. -func (e *Echo) Run(address string) { - config := &engine.Config{Address: address} +func (e *Echo) Run(addr string) { + c := &engine.Config{Address: addr} + e.RunWithConfig(c) +} + +// RunTLS runs a server with TLS configuration. +func (e *Echo) RunTLS(addr, certfile, keyfile string) { + c := &engine.Config{ + Address: addr, + TLSCertfile: certfile, + TLSKeyfile: keyfile, + } + e.RunWithConfig(c) +} + +// RunWithConfig runs a server with engine configuration. +func (e *Echo) RunWithConfig(config *engine.Config) { handler := func(req engine.Request, res engine.Response) { if e.hook != nil { e.hook(req, res) @@ -585,38 +600,6 @@ func (e *Echo) Run(address string) { } e.engine.Start() - - // e.run(e.Server(addr)) -} - -// RunTLS runs a server with TLS configuration. -func (e *Echo) RunTLS(addr, crtFile, keyFile string) { - // e.run(e.Server(addr), crtFile, keyFile) -} - -// RunServer runs a custom server. -func (e *Echo) RunServer(s *http.Server) { - // e.run(s) -} - -// RunTLSServer runs a custom server with TLS configuration. -func (e *Echo) RunTLSServer(s *http.Server, crtFile, keyFile string) { - // e.run(s, crtFile, keyFile) -} - -func (e *Echo) run(s *http.Server, files ...string) { - // s.Handler = e - // // TODO: Remove in Go 1.6+ - // if e.http2 { - // http2.ConfigureServer(s, nil) - // } - // if len(files) == 0 { - // e.logger.Fatal(s.ListenAndServe()) - // } else if len(files) == 2 { - // e.logger.Fatal(s.ListenAndServeTLS(files[0], files[1])) - // } else { - // e.logger.Fatal("invalid TLS configuration") - // } } func NewHTTPError(code int, msg ...string) *HTTPError { diff --git a/echo_test.go b/echo_test.go index d5290255..002a6a2e 100644 --- a/echo_test.go +++ b/echo_test.go @@ -307,9 +307,9 @@ func TestEchoGroup(t *testing.T) { func TestEchoNotFound(t *testing.T) { e := New() req := test.NewRequest(GET, "/files", nil) - res := test.NewResponseRecorder() - e.ServeHTTP(req, res) - assert.Equal(t, http.StatusNotFound, res.Status()) + rec := test.NewResponseRecorder() + e.ServeHTTP(req, rec) + assert.Equal(t, http.StatusNotFound, rec.Status()) } func TestEchoMethodNotAllowed(t *testing.T) { @@ -318,9 +318,9 @@ func TestEchoMethodNotAllowed(t *testing.T) { return c.String(http.StatusOK, "Echo!") }) req := test.NewRequest(POST, "/", nil) - res := test.NewResponseRecorder() - e.ServeHTTP(req, res) - assert.Equal(t, http.StatusMethodNotAllowed, res.Status()) + rec := test.NewResponseRecorder() + e.ServeHTTP(req, rec) + assert.Equal(t, http.StatusMethodNotAllowed, rec.Status()) } func TestEchoHTTPError(t *testing.T) { @@ -349,8 +349,8 @@ func TestEchoHook(t *testing.T) { } }) req := test.NewRequest(GET, "/test/", nil) - res := test.NewResponseRecorder() - e.ServeHTTP(req, res) + rec := test.NewResponseRecorder() + e.ServeHTTP(req, rec) assert.Equal(t, req.URL().Path(), "/test") } @@ -370,7 +370,7 @@ func testMethod(t *testing.T, method, path string, e *Echo) { func request(method, path string, e *Echo) (int, string) { req := test.NewRequest(method, path, nil) - res := test.NewResponseRecorder() - e.ServeHTTP(req, res) - return res.Status(), res.Body.String() + rec := test.NewResponseRecorder() + e.ServeHTTP(req, rec) + return rec.Status(), rec.Body.String() } diff --git a/engine/engine.go b/engine/engine.go index 566a5cc8..b058355a 100644 --- a/engine/engine.go +++ b/engine/engine.go @@ -1,6 +1,9 @@ package engine -import "io" +import ( + "io" + "time" +) type ( Type uint8 @@ -31,6 +34,8 @@ type ( Status() int Size() int64 Committed() bool + SetWriter(io.Writer) + Writer() io.Writer } Header interface { @@ -49,7 +54,11 @@ type ( } Config struct { - Address string + Address string + ReadTimeout time.Duration + WriteTimeout time.Duration + TLSCertfile string + TLSKeyfile string } ) diff --git a/engine/fasthttp/response.go b/engine/fasthttp/response.go index f927dd3a..b2f4c344 100644 --- a/engine/fasthttp/response.go +++ b/engine/fasthttp/response.go @@ -1,6 +1,8 @@ package fasthttp import ( + "io" + "github.com/labstack/echo/engine" "github.com/valyala/fasthttp" ) @@ -12,6 +14,7 @@ type ( status int size int64 committed bool + writer io.Writer } ) @@ -38,3 +41,11 @@ func (r *Response) Size() int64 { func (r *Response) Committed() bool { return r.committed } + +func (r *Response) SetWriter(w io.Writer) { + r.writer = w +} + +func (r *Response) Writer() io.Writer { + return r.writer +} diff --git a/engine/fasthttp/server.go b/engine/fasthttp/server.go index 3a74afc0..a4b0ad28 100644 --- a/engine/fasthttp/server.go +++ b/engine/fasthttp/server.go @@ -1,8 +1,9 @@ package fasthttp import ( - "log" "net/http" + + "github.com/labstack/gommon/log" ) import ( "github.com/labstack/echo/engine" @@ -27,7 +28,6 @@ func NewServer(config *engine.Config, handler engine.HandlerFunc) *Server { func (s *Server) Start() { fasthttp.ListenAndServe(s.config.Address, func(ctx *fasthttp.RequestCtx) { - println("FastHTTP") req := &Request{ context: ctx, url: &URL{ctx.URI()}, diff --git a/engine/standard/header.go b/engine/standard/header.go index 5a7d725a..893905b3 100644 --- a/engine/standard/header.go +++ b/engine/standard/header.go @@ -4,22 +4,26 @@ import "net/http" type ( Header struct { - http.Header + header http.Header } ) func (h *Header) Add(key, val string) { - h.Header.Add(key, val) + h.header.Add(key, val) } func (h *Header) Del(key string) { - h.Header.Del(key) + h.header.Del(key) } func (h *Header) Get(key string) string { - return h.Header.Get(key) + return h.header.Get(key) } func (h *Header) Set(key, val string) { - h.Header.Set(key, val) + h.header.Set(key, val) +} + +func (h *Header) reset(hdr http.Header) { + h.header = hdr } diff --git a/engine/standard/request.go b/engine/standard/request.go index eff21a91..eabb3d12 100644 --- a/engine/standard/request.go +++ b/engine/standard/request.go @@ -18,7 +18,7 @@ type ( func NewRequest(r *http.Request) *Request { return &Request{ request: r, - url: NewURL(r.URL), + url: &URL{url: r.URL}, header: &Header{r.Header}, } } @@ -54,3 +54,9 @@ func (r *Request) Body() io.ReadCloser { func (r *Request) FormValue(name string) string { return r.request.FormValue(name) } + +func (r *Request) reset(req *http.Request, h engine.Header, u engine.URL) { + r.request = req + r.header = h + r.url = u +} diff --git a/engine/standard/response.go b/engine/standard/response.go index 49cbb1d2..0da2c3d5 100644 --- a/engine/standard/response.go +++ b/engine/standard/response.go @@ -1,7 +1,11 @@ package standard -import "net/http" -import "github.com/labstack/echo/engine" +import ( + "io" + "net/http" + + "github.com/labstack/echo/engine" +) type ( Response struct { @@ -10,6 +14,7 @@ type ( status int size int64 committed bool + writer io.Writer } ) @@ -17,6 +22,7 @@ func NewResponse(w http.ResponseWriter) *Response { return &Response{ response: w, header: &Header{w.Header()}, + writer: w, } } @@ -35,7 +41,7 @@ func (r *Response) WriteHeader(code int) { } func (r *Response) Write(b []byte) (n int, err error) { - n, err = r.response.Write(b) + n, err = r.writer.Write(b) r.size += int64(n) return } @@ -51,3 +57,20 @@ func (r *Response) Size() int64 { func (r *Response) Committed() bool { return r.committed } + +func (r *Response) SetWriter(w io.Writer) { + r.writer = w +} + +func (r *Response) Writer() io.Writer { + return r.writer +} + +func (r *Response) reset(w http.ResponseWriter, h engine.Header) { + r.response = w + r.header = h + r.status = http.StatusOK + r.size = 0 + r.committed = false + r.writer = w +} diff --git a/engine/standard/server.go b/engine/standard/server.go index adb45004..9c527d0b 100644 --- a/engine/standard/server.go +++ b/engine/standard/server.go @@ -3,6 +3,7 @@ package standard import ( "log" "net/http" + "sync" "github.com/labstack/echo/engine" ) @@ -12,6 +13,14 @@ type ( *http.Server config *engine.Config handler engine.HandlerFunc + pool *Pool + } + + Pool struct { + request sync.Pool + response sync.Pool + header sync.Pool + url sync.Pool } ) @@ -20,13 +29,54 @@ func NewServer(config *engine.Config, handler engine.HandlerFunc) *Server { Server: new(http.Server), config: config, handler: handler, + pool: &Pool{ + request: sync.Pool{ + New: func() interface{} { + return &Request{} + }, + }, + response: sync.Pool{ + New: func() interface{} { + return &Response{} + }, + }, + header: sync.Pool{ + New: func() interface{} { + return &Header{} + }, + }, + url: sync.Pool{ + New: func() interface{} { + return &URL{} + }, + }, + }, } } func (s *Server) Start() { s.Addr = s.config.Address s.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - s.handler(NewRequest(r), NewResponse(w)) + // Request + req := s.pool.request.Get().(*Request) + reqHdr := s.pool.request.Get().(*Header) + reqURL := s.pool.request.Get().(*URL) + reqHdr.reset(r.Header) + reqURL.reset(r.URL) + req.reset(r, reqHdr, reqURL) + + // Response + res := s.pool.request.Get().(*Response) + resHdr := s.pool.request.Get().(*Header) + res.reset(w, reqHdr) + + s.handler(req, res) + + s.pool.request.Put(req) + s.pool.header.Put(reqHdr) + s.pool.url.Put(reqURL) + s.pool.response.Put(res) + s.pool.header.Put(resHdr) }) log.Fatal(s.ListenAndServe()) } diff --git a/engine/standard/url.go b/engine/standard/url.go index 3eba3c98..e9a5efaf 100644 --- a/engine/standard/url.go +++ b/engine/standard/url.go @@ -9,10 +9,6 @@ type ( } ) -func NewURL(u *url.URL) *URL { - return &URL{url: u} -} - func (u *URL) URL() *url.URL { return u.url } @@ -39,3 +35,7 @@ func (u *URL) QueryValue(name string) string { } return u.query.Get(name) } + +func (u *URL) reset(url *url.URL) { + u.url = url +} diff --git a/middleware/compress.go b/middleware/compress.go index b8d05e67..397787af 100644 --- a/middleware/compress.go +++ b/middleware/compress.go @@ -1,74 +1,74 @@ package middleware -// -// import ( -// "bufio" -// "compress/gzip" -// "io" -// "io/ioutil" -// "net" -// "net/http" -// "strings" -// "sync" -// -// "github.com/labstack/echo" -// ) -// -// type ( -// gzipWriter struct { -// io.Writer -// http.ResponseWriter -// } -// ) -// -// func (w gzipWriter) Write(b []byte) (int, error) { -// if w.Header().Get(echo.ContentType) == "" { -// w.Header().Set(echo.ContentType, http.DetectContentType(b)) -// } -// return w.Writer.Write(b) -// } -// -// func (w gzipWriter) Flush() error { -// return w.Writer.(*gzip.Writer).Flush() -// } -// -// func (w gzipWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { -// return w.ResponseWriter.(http.Hijacker).Hijack() -// } -// -// func (w *gzipWriter) CloseNotify() <-chan bool { -// return w.ResponseWriter.(http.CloseNotifier).CloseNotify() -// } -// -// var writerPool = sync.Pool{ -// New: func() interface{} { -// return gzip.NewWriter(ioutil.Discard) -// }, -// } -// -// // Gzip returns a middleware which compresses HTTP response using gzip compression -// // scheme. -// func Gzip() echo.MiddlewareFunc { -// scheme := "gzip" -// -// return func(h echo.HandlerFunc) echo.HandlerFunc { -// return func(c echo.Context) error { -// c.Response().Header().Add(echo.Vary, echo.AcceptEncoding) -// if strings.Contains(c.Request().Header().Get(echo.AcceptEncoding), scheme) { -// w := writerPool.Get().(*gzip.Writer) -// w.Reset(c.Response().Writer()) -// defer func() { -// w.Close() -// writerPool.Put(w) -// }() -// gw := gzipWriter{Writer: w, ResponseWriter: c.Response().Writer()} -// c.Response().Header().Set(echo.ContentEncoding, scheme) -// c.Response().SetWriter(gw) -// } -// if err := h(c); err != nil { -// c.Error(err) -// } -// return nil -// } -// } -// } +import ( + "bufio" + "compress/gzip" + "io" + "io/ioutil" + "net" + "net/http" + "strings" + "sync" + + "github.com/labstack/echo" + "github.com/labstack/echo/engine" +) + +type ( + gzipWriter struct { + io.Writer + engine.Response + } +) + +func (w gzipWriter) Write(b []byte) (int, error) { + if w.Header().Get(echo.ContentType) == "" { + w.Header().Set(echo.ContentType, http.DetectContentType(b)) + } + return w.Writer.Write(b) +} + +func (w gzipWriter) Flush() error { + return w.Writer.(*gzip.Writer).Flush() +} + +func (w gzipWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return w.Response.(http.Hijacker).Hijack() +} + +func (w *gzipWriter) CloseNotify() <-chan bool { + return w.Response.(http.CloseNotifier).CloseNotify() +} + +var writerPool = sync.Pool{ + New: func() interface{} { + return gzip.NewWriter(ioutil.Discard) + }, +} + +// Gzip returns a middleware which compresses HTTP response using gzip compression +// scheme. +func Gzip() echo.MiddlewareFunc { + scheme := "gzip" + + return func(h echo.HandlerFunc) echo.HandlerFunc { + return func(c echo.Context) error { + c.Response().Header().Add(echo.Vary, echo.AcceptEncoding) + if strings.Contains(c.Request().Header().Get(echo.AcceptEncoding), scheme) { + w := writerPool.Get().(*gzip.Writer) + w.Reset(c.Response().Writer()) + defer func() { + w.Close() + writerPool.Put(w) + }() + gw := gzipWriter{Writer: w, Response: c.Response()} + c.Response().Header().Set(echo.ContentEncoding, scheme) + c.Response().SetWriter(gw) + } + if err := h(c); err != nil { + c.Error(err) + } + return nil + } + } +} diff --git a/middleware/compress_test.go b/middleware/compress_test.go index ff4f354c..97b2df97 100644 --- a/middleware/compress_test.go +++ b/middleware/compress_test.go @@ -1,73 +1,69 @@ package middleware -// -// import ( -// "bytes" -// "compress/gzip" -// "net/http" -// "net/http/httptest" -// "testing" -// "time" -// -// "github.com/labstack/echo" -// "github.com/labstack/echo/test" -// "github.com/stretchr/testify/assert" -// ) -// -// type closeNotifyingRecorder struct { -// *httptest.ResponseRecorder -// closed chan bool -// } -// -// func newCloseNotifyingRecorder() *closeNotifyingRecorder { -// return &closeNotifyingRecorder{ -// test.NewResponseRecorder(), -// make(chan bool, 1), -// } -// } -// -// func (c *closeNotifyingRecorder) close() { -// c.closed <- true -// } -// -// func (c *closeNotifyingRecorder) CloseNotify() <-chan bool { -// return c.closed -// } -// -// func TestGzip(t *testing.T) { -// e := echo.New() -// req := test.NewRequest(echo.GET, "/", nil) -// res := test.NewResponseRecorder() -// c := echo.NewContext(req, res, e) -// h := func(c echo.Context) error { -// c.Response().Write([]byte("test")) // For Content-Type sniffing -// return nil -// } -// -// // Skip if no Accept-Encoding header -// Gzip()(h)(c) -// assert.Equal(t, http.StatusOK, res.Status()) -// assert.Equal(t, "test", res.Body().String()) -// -// req = test.NewRequest(echo.GET, "/", nil) -// req.Header.Set(echo.AcceptEncoding, "gzip") -// res = test.NewResponseRecorder() -// c = echo.NewContext(req, res, e) -// -// // Gzip -// Gzip()(h)(c) -// assert.Equal(t, http.StatusOK, res.Status()) -// assert.Equal(t, "gzip", res.Header().Get(echo.ContentEncoding)) -// assert.Contains(t, res.Header().Get(echo.ContentType), echo.TextPlain) -// r, err := gzip.NewReader(res.Body()) -// defer r.Close() -// if assert.NoError(t, err) { -// buf := new(bytes.Buffer) -// buf.ReadFrom(r) -// assert.Equal(t, "test", buf.String()) -// } -// } -// +import ( + "bytes" + "compress/gzip" + "testing" + + "github.com/labstack/echo" + "github.com/labstack/echo/test" + "github.com/stretchr/testify/assert" +) + +type closeNotifyingRecorder struct { + *test.ResponseRecorder + closed chan bool +} + +func newCloseNotifyingRecorder() *closeNotifyingRecorder { + return &closeNotifyingRecorder{ + test.NewResponseRecorder(), + make(chan bool, 1), + } +} + +func (c *closeNotifyingRecorder) close() { + c.closed <- true +} + +func (c *closeNotifyingRecorder) CloseNotify() <-chan bool { + return c.closed +} + +func TestGzip(t *testing.T) { + e := echo.New() + req := test.NewRequest(echo.GET, "/", nil) + rec := test.NewResponseRecorder() + c := echo.NewContext(req, rec, e) + h := func(c echo.Context) error { + c.Response().Write([]byte("test")) // For Content-Type sniffing + return nil + } + + // Skip if no Accept-Encoding header + Gzip()(h)(c) + // assert.Equal(t, http.StatusOK, rec.Status()) + assert.Equal(t, "test", rec.Body.String()) + + req = test.NewRequest(echo.GET, "/", nil) + req.Header().Set(echo.AcceptEncoding, "gzip") + rec = test.NewResponseRecorder() + c = echo.NewContext(req, rec, e) + + // Gzip + Gzip()(h)(c) + // assert.Equal(t, http.StatusOK, rec.Status()) + assert.Equal(t, "gzip", rec.Header().Get(echo.ContentEncoding)) + assert.Contains(t, rec.Header().Get(echo.ContentType), echo.TextPlain) + r, err := gzip.NewReader(rec.Body) + defer r.Close() + if assert.NoError(t, err) { + buf := new(bytes.Buffer) + buf.ReadFrom(r) + assert.Equal(t, "test", buf.String()) + } +} + // func TestGzipFlush(t *testing.T) { // res := test.NewResponseRecorder() // buf := new(bytes.Buffer) @@ -104,7 +100,7 @@ package middleware // t.Fatal("Flush didn't flush any data") // } // } -// + // func TestGzipCloseNotify(t *testing.T) { // rec := newCloseNotifyingRecorder() // buf := new(bytes.Buffer) diff --git a/middleware/logger_test.go b/middleware/logger_test.go index e6afa868..b485ce95 100644 --- a/middleware/logger_test.go +++ b/middleware/logger_test.go @@ -15,8 +15,8 @@ func TestLogger(t *testing.T) { // Note: Just for the test coverage, not a real test. e := echo.New() req := test.NewRequest(echo.GET, "/", nil) - res := test.NewResponseRecorder() - c := echo.NewContext(req, res, e) + rec := test.NewResponseRecorder() + c := echo.NewContext(req, rec, e) // Status 2xx h := func(c echo.Context) error { @@ -25,16 +25,16 @@ func TestLogger(t *testing.T) { Logger()(h)(c) // Status 3xx - res = test.NewResponseRecorder() - c = echo.NewContext(req, res, e) + rec = test.NewResponseRecorder() + c = echo.NewContext(req, rec, e) h = func(c echo.Context) error { return c.String(http.StatusTemporaryRedirect, "test") } Logger()(h)(c) // Status 4xx - res = test.NewResponseRecorder() - c = echo.NewContext(req, res, e) + rec = test.NewResponseRecorder() + c = echo.NewContext(req, rec, e) h = func(c echo.Context) error { return c.String(http.StatusNotFound, "test") } @@ -42,8 +42,8 @@ func TestLogger(t *testing.T) { // Status 5xx with empty path req = test.NewRequest(echo.GET, "", nil) - res = test.NewResponseRecorder() - c = echo.NewContext(req, res, e) + rec = test.NewResponseRecorder() + c = echo.NewContext(req, rec, e) h = func(c echo.Context) error { return errors.New("error") } @@ -53,8 +53,8 @@ func TestLogger(t *testing.T) { func TestLoggerIPAddress(t *testing.T) { e := echo.New() req := test.NewRequest(echo.GET, "/", nil) - res := test.NewResponseRecorder() - c := echo.NewContext(req, res, e) + rec := test.NewResponseRecorder() + c := echo.NewContext(req, rec, e) buf := new(bytes.Buffer) e.Logger().SetOutput(buf) ip := "127.0.0.1" diff --git a/middleware/recover_test.go b/middleware/recover_test.go index ddd3f682..b272f361 100644 --- a/middleware/recover_test.go +++ b/middleware/recover_test.go @@ -13,12 +13,12 @@ func TestRecover(t *testing.T) { e := echo.New() e.SetDebug(true) req := test.NewRequest(echo.GET, "/", nil) - res := test.NewResponseRecorder() - c := echo.NewContext(req, res, e) + rec := test.NewResponseRecorder() + c := echo.NewContext(req, rec, e) h := func(c echo.Context) error { panic("test") } Recover()(h)(c) - assert.Equal(t, http.StatusInternalServerError, res.Status()) - assert.Contains(t, res.Body.String(), "panic recover") + assert.Equal(t, http.StatusInternalServerError, rec.Status()) + assert.Contains(t, rec.Body.String(), "panic recover") } diff --git a/router.go b/router.go index 226586c7..d355b5b3 100644 --- a/router.go +++ b/router.go @@ -274,7 +274,7 @@ func (n *node) check405() HandlerFunc { } func (r *Router) Find(method, path string, context Context) (h HandlerFunc, e *Echo) { - x := context.X() + x := context.Context() h = notFoundHandler e = r.echo cn := r.tree // Current node as root diff --git a/router_test.go b/router_test.go index ebbd27ff..5da88a20 100644 --- a/router_test.go +++ b/router_test.go @@ -529,16 +529,16 @@ func TestRouterParamNames(t *testing.T) { // Route > /users/:id h, _ = r.Find(GET, "/users/1", c) if assert.NotNil(t, h) { - assert.Equal(t, "id", c.X().pnames[0]) + assert.Equal(t, "id", c.Context().pnames[0]) assert.Equal(t, "1", c.P(0)) } // Route > /users/:uid/files/:fid h, _ = r.Find(GET, "/users/1/files/1", c) if assert.NotNil(t, h) { - assert.Equal(t, "uid", c.X().pnames[0]) + assert.Equal(t, "uid", c.Context().pnames[0]) assert.Equal(t, "1", c.P(0)) - assert.Equal(t, "fid", c.X().pnames[1]) + assert.Equal(t, "fid", c.Context().pnames[1]) assert.Equal(t, "1", c.P(1)) } } @@ -556,7 +556,7 @@ func TestRouterAPI(t *testing.T) { for _, route := range api { h, _ := r.Find(route.Method, route.Path, c) if assert.NotNil(t, h) { - for i, n := range c.X().pnames { + for i, n := range c.Context().pnames { if assert.NotEmpty(t, n) { assert.Equal(t, ":"+n, c.P(i)) }