mirror of
https://github.com/labstack/echo.git
synced 2025-03-19 21:17:58 +02:00
Logging middleware fixes
Signed-off-by: Vishal Rana <vr@labstack.com>
This commit is contained in:
parent
703174e58f
commit
a66162a3d2
22
context.go
22
context.go
@ -157,10 +157,10 @@ const (
|
||||
)
|
||||
|
||||
// NewContext creates a Context object.
|
||||
func NewContext(req engine.Request, res engine.Response, e *Echo) Context {
|
||||
func NewContext(rq engine.Request, rs engine.Response, e *Echo) Context {
|
||||
return &context{
|
||||
request: req,
|
||||
response: res,
|
||||
request: rq,
|
||||
response: rs,
|
||||
echo: e,
|
||||
pvalues: make([]string, *e.maxParam),
|
||||
store: make(store),
|
||||
@ -408,11 +408,11 @@ func (c *context) Object() *context {
|
||||
|
||||
// ServeContent sends a response from `io.Reader`. It automatically sets the `Content-Type`
|
||||
// and `Last-Modified` headers.
|
||||
func ServeContent(req engine.Request, res engine.Response, f http.File, fi os.FileInfo) error {
|
||||
res.Header().Set(ContentType, detectContentType(fi.Name()))
|
||||
res.Header().Set(LastModified, fi.ModTime().UTC().Format(http.TimeFormat))
|
||||
res.WriteHeader(http.StatusOK)
|
||||
_, err := io.Copy(res, f)
|
||||
func ServeContent(rq engine.Request, rs engine.Response, f http.File, fi os.FileInfo) error {
|
||||
rs.Header().Set(ContentType, detectContentType(fi.Name()))
|
||||
rs.Header().Set(LastModified, fi.ModTime().UTC().Format(http.TimeFormat))
|
||||
rs.WriteHeader(http.StatusOK)
|
||||
_, err := io.Copy(rs, f)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -423,10 +423,10 @@ func detectContentType(name string) (t string) {
|
||||
return
|
||||
}
|
||||
|
||||
func (c *context) Reset(req engine.Request, res engine.Response) {
|
||||
func (c *context) Reset(rq engine.Request, rs engine.Response) {
|
||||
c.netContext = nil
|
||||
c.request = req
|
||||
c.response = res
|
||||
c.request = rq
|
||||
c.response = rs
|
||||
c.query = nil
|
||||
c.store = nil
|
||||
c.handler = notFoundHandler
|
||||
|
@ -34,9 +34,9 @@ func TestContext(t *testing.T) {
|
||||
invalidContent := "invalid content"
|
||||
|
||||
e := New()
|
||||
req := test.NewRequest(POST, "/", strings.NewReader(userJSON))
|
||||
rq := test.NewRequest(POST, "/", strings.NewReader(userJSON))
|
||||
rec := test.NewResponseRecorder()
|
||||
c := NewContext(req, rec, e)
|
||||
c := NewContext(rq, rec, e)
|
||||
|
||||
// Request
|
||||
assert.NotNil(t, c.Request())
|
||||
@ -98,7 +98,7 @@ func TestContext(t *testing.T) {
|
||||
|
||||
// JSON
|
||||
rec = test.NewResponseRecorder()
|
||||
c = NewContext(req, rec, e)
|
||||
c = NewContext(rq, rec, e)
|
||||
err = c.JSON(http.StatusOK, user{"1", "Joe"})
|
||||
if assert.NoError(t, err) {
|
||||
assert.Equal(t, http.StatusOK, rec.Status())
|
||||
@ -108,13 +108,13 @@ func TestContext(t *testing.T) {
|
||||
|
||||
// JSON (error)
|
||||
rec = test.NewResponseRecorder()
|
||||
c = NewContext(req, rec, e)
|
||||
c = NewContext(rq, rec, e)
|
||||
err = c.JSON(http.StatusOK, make(chan bool))
|
||||
assert.Error(t, err)
|
||||
|
||||
// JSONP
|
||||
rec = test.NewResponseRecorder()
|
||||
c = NewContext(req, rec, e)
|
||||
c = NewContext(rq, rec, e)
|
||||
callback := "callback"
|
||||
err = c.JSONP(http.StatusOK, callback, user{"1", "Joe"})
|
||||
if assert.NoError(t, err) {
|
||||
@ -125,7 +125,7 @@ func TestContext(t *testing.T) {
|
||||
|
||||
// XML
|
||||
rec = test.NewResponseRecorder()
|
||||
c = NewContext(req, rec, e)
|
||||
c = NewContext(rq, rec, e)
|
||||
err = c.XML(http.StatusOK, user{"1", "Joe"})
|
||||
if assert.NoError(t, err) {
|
||||
assert.Equal(t, http.StatusOK, rec.Status())
|
||||
@ -135,13 +135,13 @@ func TestContext(t *testing.T) {
|
||||
|
||||
// XML (error)
|
||||
rec = test.NewResponseRecorder()
|
||||
c = NewContext(req, rec, e)
|
||||
c = NewContext(rq, rec, e)
|
||||
err = c.XML(http.StatusOK, make(chan bool))
|
||||
assert.Error(t, err)
|
||||
|
||||
// String
|
||||
rec = test.NewResponseRecorder()
|
||||
c = NewContext(req, rec, e)
|
||||
c = NewContext(rq, rec, e)
|
||||
err = c.String(http.StatusOK, "Hello, World!")
|
||||
if assert.NoError(t, err) {
|
||||
assert.Equal(t, http.StatusOK, rec.Status())
|
||||
@ -151,7 +151,7 @@ func TestContext(t *testing.T) {
|
||||
|
||||
// HTML
|
||||
rec = test.NewResponseRecorder()
|
||||
c = NewContext(req, rec, e)
|
||||
c = NewContext(rq, rec, e)
|
||||
err = c.HTML(http.StatusOK, "Hello, <strong>World!</strong>")
|
||||
if assert.NoError(t, err) {
|
||||
assert.Equal(t, http.StatusOK, rec.Status())
|
||||
@ -161,7 +161,7 @@ func TestContext(t *testing.T) {
|
||||
|
||||
// Attachment
|
||||
rec = test.NewResponseRecorder()
|
||||
c = NewContext(req, rec, e)
|
||||
c = NewContext(rq, rec, e)
|
||||
file, err := os.Open("_fixture/images/walle.png")
|
||||
if assert.NoError(t, err) {
|
||||
err = c.Attachment(file, "walle.png")
|
||||
@ -174,25 +174,25 @@ func TestContext(t *testing.T) {
|
||||
|
||||
// NoContent
|
||||
rec = test.NewResponseRecorder()
|
||||
c = NewContext(req, rec, e)
|
||||
c = NewContext(rq, rec, e)
|
||||
c.NoContent(http.StatusOK)
|
||||
assert.Equal(t, http.StatusOK, rec.Status())
|
||||
|
||||
// Redirect
|
||||
rec = test.NewResponseRecorder()
|
||||
c = NewContext(req, rec, e)
|
||||
c = NewContext(rq, rec, e)
|
||||
assert.Equal(t, nil, c.Redirect(http.StatusMovedPermanently, "http://labstack.github.io/echo"))
|
||||
assert.Equal(t, "http://labstack.github.io/echo", rec.Header().Get(Location))
|
||||
assert.Equal(t, http.StatusMovedPermanently, rec.Status())
|
||||
|
||||
// Error
|
||||
rec = test.NewResponseRecorder()
|
||||
c = NewContext(req, rec, e)
|
||||
c = NewContext(rq, rec, e)
|
||||
c.Error(errors.New("error"))
|
||||
assert.Equal(t, http.StatusInternalServerError, rec.Status())
|
||||
|
||||
// Reset
|
||||
c.Object().Reset(req, test.NewResponseRecorder())
|
||||
c.Object().Reset(rq, test.NewResponseRecorder())
|
||||
}
|
||||
|
||||
func TestContextPath(t *testing.T) {
|
||||
@ -214,8 +214,8 @@ func TestContextQueryParam(t *testing.T) {
|
||||
q := make(url.Values)
|
||||
q.Set("name", "joe")
|
||||
q.Set("email", "joe@labstack.com")
|
||||
req := test.NewRequest(GET, "/?"+q.Encode(), nil)
|
||||
c := NewContext(req, nil, New())
|
||||
rq := test.NewRequest(GET, "/?"+q.Encode(), nil)
|
||||
c := NewContext(rq, nil, New())
|
||||
assert.Equal(t, "joe", c.QueryParam("name"))
|
||||
assert.Equal(t, "joe@labstack.com", c.QueryParam("email"))
|
||||
}
|
||||
@ -225,10 +225,10 @@ func TestContextFormValue(t *testing.T) {
|
||||
f.Set("name", "joe")
|
||||
f.Set("email", "joe@labstack.com")
|
||||
|
||||
req := test.NewRequest(POST, "/", strings.NewReader(f.Encode()))
|
||||
req.Header().Add(ContentType, ApplicationForm)
|
||||
rq := test.NewRequest(POST, "/", strings.NewReader(f.Encode()))
|
||||
rq.Header().Add(ContentType, ApplicationForm)
|
||||
|
||||
c := NewContext(req, nil, New())
|
||||
c := NewContext(rq, nil, New())
|
||||
assert.Equal(t, "joe", c.FormValue("name"))
|
||||
assert.Equal(t, "joe@labstack.com", c.FormValue("email"))
|
||||
}
|
||||
|
12
echo.go
12
echo.go
@ -496,9 +496,9 @@ func (e *Echo) PutContext(c Context) {
|
||||
e.pool.Put(c)
|
||||
}
|
||||
|
||||
func (e *Echo) ServeHTTP(req engine.Request, res engine.Response) {
|
||||
func (e *Echo) ServeHTTP(rq engine.Request, rs engine.Response) {
|
||||
c := e.pool.Get().(*context)
|
||||
c.Reset(req, res)
|
||||
c.Reset(rq, rs)
|
||||
|
||||
// Execute chain
|
||||
if err := e.head.Handle(c); err != nil {
|
||||
@ -531,15 +531,15 @@ func (e *HTTPError) Error() string {
|
||||
}
|
||||
|
||||
func (binder) Bind(i interface{}, c Context) (err error) {
|
||||
req := c.Request()
|
||||
ct := req.Header().Get(ContentType)
|
||||
rq := c.Request()
|
||||
ct := rq.Header().Get(ContentType)
|
||||
err = ErrUnsupportedMediaType
|
||||
if strings.HasPrefix(ct, ApplicationJSON) {
|
||||
if err = json.NewDecoder(req.Body()).Decode(i); err != nil {
|
||||
if err = json.NewDecoder(rq.Body()).Decode(i); err != nil {
|
||||
err = NewHTTPError(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
} else if strings.HasPrefix(ct, ApplicationXML) {
|
||||
if err = xml.NewDecoder(req.Body()).Decode(i); err != nil {
|
||||
if err = xml.NewDecoder(rq.Body()).Decode(i); err != nil {
|
||||
err = NewHTTPError(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
}
|
||||
|
16
echo_test.go
16
echo_test.go
@ -24,9 +24,9 @@ type (
|
||||
|
||||
func TestEcho(t *testing.T) {
|
||||
e := New()
|
||||
req := test.NewRequest(GET, "/", nil)
|
||||
rq := test.NewRequest(GET, "/", nil)
|
||||
rec := test.NewResponseRecorder()
|
||||
c := NewContext(req, rec, e)
|
||||
c := NewContext(rq, rec, e)
|
||||
|
||||
// Router
|
||||
assert.NotNil(t, e.Router())
|
||||
@ -290,9 +290,9 @@ func TestEchoGroup(t *testing.T) {
|
||||
|
||||
func TestEchoNotFound(t *testing.T) {
|
||||
e := New()
|
||||
req := test.NewRequest(GET, "/files", nil)
|
||||
rq := test.NewRequest(GET, "/files", nil)
|
||||
rec := test.NewResponseRecorder()
|
||||
e.ServeHTTP(req, rec)
|
||||
e.ServeHTTP(rq, rec)
|
||||
assert.Equal(t, http.StatusNotFound, rec.Status())
|
||||
}
|
||||
|
||||
@ -301,9 +301,9 @@ func TestEchoMethodNotAllowed(t *testing.T) {
|
||||
e.Get("/", HandlerFunc(func(c Context) error {
|
||||
return c.String(http.StatusOK, "Echo!")
|
||||
}))
|
||||
req := test.NewRequest(POST, "/", nil)
|
||||
rq := test.NewRequest(POST, "/", nil)
|
||||
rec := test.NewResponseRecorder()
|
||||
e.ServeHTTP(req, rec)
|
||||
e.ServeHTTP(rq, rec)
|
||||
assert.Equal(t, http.StatusMethodNotAllowed, rec.Status())
|
||||
}
|
||||
|
||||
@ -329,8 +329,8 @@ 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)
|
||||
rq := test.NewRequest(method, path, nil)
|
||||
rec := test.NewResponseRecorder()
|
||||
e.ServeHTTP(req, rec)
|
||||
e.ServeHTTP(rq, rec)
|
||||
return rec.Status(), rec.Body.String()
|
||||
}
|
||||
|
@ -158,6 +158,6 @@ type (
|
||||
)
|
||||
|
||||
// ServeHTTP serves HTTP request.
|
||||
func (h HandlerFunc) ServeHTTP(req Request, res Response) {
|
||||
h(req, res)
|
||||
func (h HandlerFunc) ServeHTTP(rq Request, rs Response) {
|
||||
h(rq, rs)
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ func NewFromConfig(c engine.Config) (s *Server) {
|
||||
},
|
||||
},
|
||||
},
|
||||
handler: engine.HandlerFunc(func(req engine.Request, res engine.Response) {
|
||||
handler: engine.HandlerFunc(func(rq engine.Request, rs engine.Response) {
|
||||
s.logger.Error("handler not set, use `SetHandler()` to set it.")
|
||||
}),
|
||||
logger: log.New("echo"),
|
||||
@ -124,25 +124,25 @@ func (s *Server) startCustomListener() error {
|
||||
|
||||
func (s *Server) ServeHTTP(c *fasthttp.RequestCtx) {
|
||||
// Request
|
||||
req := s.pool.request.Get().(*Request)
|
||||
rq := s.pool.request.Get().(*Request)
|
||||
reqHdr := s.pool.requestHeader.Get().(*RequestHeader)
|
||||
reqURL := s.pool.url.Get().(*URL)
|
||||
reqHdr.reset(&c.Request.Header)
|
||||
reqURL.reset(c.URI())
|
||||
req.reset(c, reqHdr, reqURL)
|
||||
rq.reset(c, reqHdr, reqURL)
|
||||
|
||||
// Response
|
||||
res := s.pool.response.Get().(*Response)
|
||||
rs := s.pool.response.Get().(*Response)
|
||||
resHdr := s.pool.responseHeader.Get().(*ResponseHeader)
|
||||
resHdr.reset(&c.Response.Header)
|
||||
res.reset(c, resHdr)
|
||||
rs.reset(c, resHdr)
|
||||
|
||||
s.handler.ServeHTTP(req, res)
|
||||
s.handler.ServeHTTP(rq, rs)
|
||||
|
||||
s.pool.request.Put(req)
|
||||
s.pool.request.Put(rq)
|
||||
s.pool.requestHeader.Put(reqHdr)
|
||||
s.pool.url.Put(reqURL)
|
||||
s.pool.response.Put(res)
|
||||
s.pool.response.Put(rs)
|
||||
s.pool.responseHeader.Put(resHdr)
|
||||
}
|
||||
|
||||
|
@ -104,8 +104,8 @@ func (r *Request) MultipartForm() (*multipart.Form, error) {
|
||||
return r.Request.MultipartForm, err
|
||||
}
|
||||
|
||||
func (r *Request) reset(req *http.Request, h engine.Header, u engine.URL) {
|
||||
r.Request = req
|
||||
func (r *Request) reset(rq *http.Request, h engine.Header, u engine.URL) {
|
||||
r.Request = rq
|
||||
r.header = h
|
||||
r.url = u
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ func NewFromConfig(c engine.Config) (s *Server) {
|
||||
},
|
||||
},
|
||||
},
|
||||
handler: engine.HandlerFunc(func(req engine.Request, res engine.Response) {
|
||||
handler: engine.HandlerFunc(func(rq engine.Request, rs engine.Response) {
|
||||
s.logger.Error("handler not set, use `SetHandler()` to set it.")
|
||||
}),
|
||||
logger: log.New("echo"),
|
||||
@ -113,25 +113,25 @@ func (s *Server) startCustomListener() error {
|
||||
// ServeHTTP implements `http.Handler` interface.
|
||||
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
// Request
|
||||
req := s.pool.request.Get().(*Request)
|
||||
rq := s.pool.request.Get().(*Request)
|
||||
reqHdr := s.pool.header.Get().(*Header)
|
||||
reqURL := s.pool.url.Get().(*URL)
|
||||
reqHdr.reset(r.Header)
|
||||
reqURL.reset(r.URL)
|
||||
req.reset(r, reqHdr, reqURL)
|
||||
rq.reset(r, reqHdr, reqURL)
|
||||
|
||||
// Response
|
||||
res := s.pool.response.Get().(*Response)
|
||||
rs := s.pool.response.Get().(*Response)
|
||||
resHdr := s.pool.header.Get().(*Header)
|
||||
resHdr.reset(w.Header())
|
||||
res.reset(w, resHdr)
|
||||
rs.reset(w, resHdr)
|
||||
|
||||
s.handler.ServeHTTP(req, res)
|
||||
s.handler.ServeHTTP(rq, rs)
|
||||
|
||||
s.pool.request.Put(req)
|
||||
s.pool.request.Put(rq)
|
||||
s.pool.header.Put(reqHdr)
|
||||
s.pool.url.Put(reqURL)
|
||||
s.pool.response.Put(res)
|
||||
s.pool.response.Put(rs)
|
||||
s.pool.header.Put(resHdr)
|
||||
}
|
||||
|
||||
@ -152,16 +152,16 @@ func WrapHandler(h http.Handler) echo.HandlerFunc {
|
||||
func WrapMiddleware(m func(http.Handler) http.Handler) echo.MiddlewareFunc {
|
||||
return func(next echo.Handler) echo.Handler {
|
||||
return echo.HandlerFunc(func(c echo.Context) (err error) {
|
||||
req := c.Request().(*Request)
|
||||
res := c.Response().(*Response)
|
||||
rq := c.Request().(*Request)
|
||||
rs := c.Response().(*Response)
|
||||
m(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
res.ResponseWriter = &responseAdapter{
|
||||
ResponseWriter: res.ResponseWriter,
|
||||
rs.ResponseWriter = &responseAdapter{
|
||||
ResponseWriter: rs.ResponseWriter,
|
||||
writer: c.Response(),
|
||||
}
|
||||
req.Request = r
|
||||
rq.Request = r
|
||||
err = next.Handle(c)
|
||||
})).ServeHTTP(res.ResponseWriter, req.Request)
|
||||
})).ServeHTTP(rs.ResponseWriter, rq.Request)
|
||||
return
|
||||
})
|
||||
}
|
||||
|
@ -12,9 +12,9 @@ import (
|
||||
|
||||
func TestBasicAuth(t *testing.T) {
|
||||
e := echo.New()
|
||||
req := test.NewRequest(echo.GET, "/", nil)
|
||||
res := test.NewResponseRecorder()
|
||||
c := echo.NewContext(req, res, e)
|
||||
rq := test.NewRequest(echo.GET, "/", nil)
|
||||
rs := test.NewResponseRecorder()
|
||||
c := echo.NewContext(rq, rs, e)
|
||||
f := func(u, p string) bool {
|
||||
if u == "joe" && p == "secret" {
|
||||
return true
|
||||
@ -27,7 +27,7 @@ func TestBasicAuth(t *testing.T) {
|
||||
|
||||
// Valid credentials
|
||||
auth := basic + " " + base64.StdEncoding.EncodeToString([]byte("joe:secret"))
|
||||
req.Header().Set(echo.Authorization, auth)
|
||||
rq.Header().Set(echo.Authorization, auth)
|
||||
assert.NoError(t, h.Handle(c))
|
||||
|
||||
//---------------------
|
||||
@ -36,21 +36,21 @@ func TestBasicAuth(t *testing.T) {
|
||||
|
||||
// Incorrect password
|
||||
auth = basic + " " + base64.StdEncoding.EncodeToString([]byte("joe:password"))
|
||||
req.Header().Set(echo.Authorization, auth)
|
||||
rq.Header().Set(echo.Authorization, auth)
|
||||
he := h.Handle(c).(*echo.HTTPError)
|
||||
assert.Equal(t, http.StatusUnauthorized, he.Code)
|
||||
assert.Equal(t, basic+" realm=Restricted", res.Header().Get(echo.WWWAuthenticate))
|
||||
assert.Equal(t, basic+" realm=Restricted", rs.Header().Get(echo.WWWAuthenticate))
|
||||
|
||||
// Empty Authorization header
|
||||
req.Header().Set(echo.Authorization, "")
|
||||
rq.Header().Set(echo.Authorization, "")
|
||||
he = h.Handle(c).(*echo.HTTPError)
|
||||
assert.Equal(t, http.StatusUnauthorized, he.Code)
|
||||
assert.Equal(t, basic+" realm=Restricted", res.Header().Get(echo.WWWAuthenticate))
|
||||
assert.Equal(t, basic+" realm=Restricted", rs.Header().Get(echo.WWWAuthenticate))
|
||||
|
||||
// Invalid Authorization header
|
||||
auth = base64.StdEncoding.EncodeToString([]byte("invalid"))
|
||||
req.Header().Set(echo.Authorization, auth)
|
||||
rq.Header().Set(echo.Authorization, auth)
|
||||
he = h.Handle(c).(*echo.HTTPError)
|
||||
assert.Equal(t, http.StatusUnauthorized, he.Code)
|
||||
assert.Equal(t, basic+" realm=Restricted", res.Header().Get(echo.WWWAuthenticate))
|
||||
assert.Equal(t, basic+" realm=Restricted", rs.Header().Get(echo.WWWAuthenticate))
|
||||
}
|
||||
|
@ -14,9 +14,9 @@ import (
|
||||
|
||||
func TestGzip(t *testing.T) {
|
||||
e := echo.New()
|
||||
req := test.NewRequest(echo.GET, "/", nil)
|
||||
rq := test.NewRequest(echo.GET, "/", nil)
|
||||
rec := test.NewResponseRecorder()
|
||||
c := echo.NewContext(req, rec, e)
|
||||
c := echo.NewContext(rq, rec, e)
|
||||
|
||||
// Skip if no Accept-Encoding header
|
||||
h := Gzip()(echo.HandlerFunc(func(c echo.Context) error {
|
||||
@ -26,10 +26,10 @@ func TestGzip(t *testing.T) {
|
||||
h.Handle(c)
|
||||
assert.Equal(t, "test", rec.Body.String())
|
||||
|
||||
req = test.NewRequest(echo.GET, "/", nil)
|
||||
req.Header().Set(echo.AcceptEncoding, "gzip")
|
||||
rq = test.NewRequest(echo.GET, "/", nil)
|
||||
rq.Header().Set(echo.AcceptEncoding, "gzip")
|
||||
rec = test.NewResponseRecorder()
|
||||
c = echo.NewContext(req, rec, e)
|
||||
c = echo.NewContext(rq, rec, e)
|
||||
|
||||
// Gzip
|
||||
h.Handle(c)
|
||||
@ -46,9 +46,9 @@ func TestGzip(t *testing.T) {
|
||||
|
||||
func TestGzipNoContent(t *testing.T) {
|
||||
e := echo.New()
|
||||
req := test.NewRequest(echo.GET, "/", nil)
|
||||
rq := test.NewRequest(echo.GET, "/", nil)
|
||||
rec := test.NewResponseRecorder()
|
||||
c := echo.NewContext(req, rec, e)
|
||||
c := echo.NewContext(rq, rec, e)
|
||||
h := Gzip()(echo.HandlerFunc(func(c echo.Context) error {
|
||||
return c.NoContent(http.StatusOK)
|
||||
}))
|
||||
@ -68,9 +68,9 @@ func TestGzipErrorReturned(t *testing.T) {
|
||||
e.Get("/", echo.HandlerFunc(func(c echo.Context) error {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "error")
|
||||
}))
|
||||
req := test.NewRequest(echo.GET, "/", nil)
|
||||
rq := test.NewRequest(echo.GET, "/", nil)
|
||||
rec := test.NewResponseRecorder()
|
||||
e.ServeHTTP(req, rec)
|
||||
e.ServeHTTP(rq, rec)
|
||||
|
||||
assert.Empty(t, rec.Header().Get(echo.ContentEncoding))
|
||||
b, err := ioutil.ReadAll(rec.Body)
|
||||
|
@ -24,6 +24,7 @@ type (
|
||||
// Available tags:
|
||||
// - time_rfc3339
|
||||
// - remote_ip
|
||||
// - uri
|
||||
// - method
|
||||
// - path
|
||||
// - status
|
||||
@ -42,7 +43,8 @@ type (
|
||||
var (
|
||||
// DefaultLoggerConfig is the default logger middleware config.
|
||||
DefaultLoggerConfig = LoggerConfig{
|
||||
Format: "time=${time_rfc3339}, remote_ip=${remote_ip}, method=${method}, path=${path}, status=${status}, response_time=${response_time}, response_size=${response_size} bytes\n",
|
||||
Format: "time=${time_rfc3339}, remote_ip=${remote_ip}, method=${method}, " +
|
||||
"path=${path}, status=${status}, took=${response_time}, sent=t=${response_size} bytes\n",
|
||||
color: color.New(),
|
||||
Output: os.Stdout,
|
||||
}
|
||||
@ -64,58 +66,54 @@ func LoggerFromConfig(config LoggerConfig) echo.MiddlewareFunc {
|
||||
|
||||
return func(next echo.Handler) echo.Handler {
|
||||
return echo.HandlerFunc(func(c echo.Context) (err error) {
|
||||
req := c.Request()
|
||||
res := c.Response()
|
||||
remoteAddr := req.RemoteAddress()
|
||||
|
||||
if ip := req.Header().Get(echo.XRealIP); ip != "" {
|
||||
remoteAddr = ip
|
||||
} else if ip = req.Header().Get(echo.XForwardedFor); ip != "" {
|
||||
remoteAddr = ip
|
||||
} else {
|
||||
remoteAddr, _, _ = net.SplitHostPort(remoteAddr)
|
||||
}
|
||||
|
||||
rq := c.Request()
|
||||
rs := c.Response()
|
||||
start := time.Now()
|
||||
if err := next.Handle(c); err != nil {
|
||||
c.Error(err)
|
||||
}
|
||||
stop := time.Now()
|
||||
method := []byte(req.Method())
|
||||
path := req.URL().Path()
|
||||
if path == "" {
|
||||
path = "/"
|
||||
}
|
||||
took := stop.Sub(start)
|
||||
size := strconv.FormatInt(res.Size(), 10)
|
||||
|
||||
n := res.Status()
|
||||
status := color.Green(n)
|
||||
switch {
|
||||
case n >= 500:
|
||||
status = color.Red(n)
|
||||
case n >= 400:
|
||||
status = color.Yellow(n)
|
||||
case n >= 300:
|
||||
status = color.Cyan(n)
|
||||
}
|
||||
|
||||
_, err = config.template.ExecuteFunc(config.Output, func(w io.Writer, tag string) (int, error) {
|
||||
switch tag {
|
||||
case "time_rfc3339":
|
||||
return w.Write([]byte(time.Now().Format(time.RFC3339)))
|
||||
case "remote_ip":
|
||||
return w.Write([]byte(remoteAddr))
|
||||
ra := rq.RemoteAddress()
|
||||
if ip := rq.Header().Get(echo.XRealIP); ip != "" {
|
||||
ra = ip
|
||||
} else if ip = rq.Header().Get(echo.XForwardedFor); ip != "" {
|
||||
ra = ip
|
||||
} else {
|
||||
ra, _, _ = net.SplitHostPort(ra)
|
||||
}
|
||||
return w.Write([]byte(ra))
|
||||
case "uri":
|
||||
return w.Write([]byte(rq.URI()))
|
||||
case "method":
|
||||
return w.Write(method)
|
||||
return w.Write([]byte(rq.Method()))
|
||||
case "path":
|
||||
return w.Write([]byte(path))
|
||||
p := rq.URL().Path()
|
||||
if p == "" {
|
||||
p = "/"
|
||||
}
|
||||
return w.Write([]byte(p))
|
||||
case "status":
|
||||
return w.Write([]byte(status))
|
||||
n := rs.Status()
|
||||
s := color.Green(n)
|
||||
switch {
|
||||
case n >= 500:
|
||||
s = color.Red(n)
|
||||
case n >= 400:
|
||||
s = color.Yellow(n)
|
||||
case n >= 300:
|
||||
s = color.Cyan(n)
|
||||
}
|
||||
return w.Write([]byte(s))
|
||||
case "response_time":
|
||||
return w.Write([]byte(took.String()))
|
||||
return w.Write([]byte(stop.Sub(start).String()))
|
||||
case "response_size":
|
||||
return w.Write([]byte(size))
|
||||
return w.Write([]byte(strconv.FormatInt(rs.Size(), 10)))
|
||||
default:
|
||||
return w.Write([]byte(fmt.Sprintf("[unknown tag %s]", tag)))
|
||||
}
|
||||
|
@ -14,9 +14,9 @@ import (
|
||||
func TestLogger(t *testing.T) {
|
||||
// Note: Just for the test coverage, not a real test.
|
||||
e := echo.New()
|
||||
req := test.NewRequest(echo.GET, "/", nil)
|
||||
rq := test.NewRequest(echo.GET, "/", nil)
|
||||
rec := test.NewResponseRecorder()
|
||||
c := echo.NewContext(req, rec, e)
|
||||
c := echo.NewContext(rq, rec, e)
|
||||
h := Logger()(echo.HandlerFunc(func(c echo.Context) error {
|
||||
return c.String(http.StatusOK, "test")
|
||||
}))
|
||||
@ -26,7 +26,7 @@ func TestLogger(t *testing.T) {
|
||||
|
||||
// Status 3xx
|
||||
rec = test.NewResponseRecorder()
|
||||
c = echo.NewContext(req, rec, e)
|
||||
c = echo.NewContext(rq, rec, e)
|
||||
h = Logger()(echo.HandlerFunc(func(c echo.Context) error {
|
||||
return c.String(http.StatusTemporaryRedirect, "test")
|
||||
}))
|
||||
@ -34,16 +34,16 @@ func TestLogger(t *testing.T) {
|
||||
|
||||
// Status 4xx
|
||||
rec = test.NewResponseRecorder()
|
||||
c = echo.NewContext(req, rec, e)
|
||||
c = echo.NewContext(rq, rec, e)
|
||||
h = Logger()(echo.HandlerFunc(func(c echo.Context) error {
|
||||
return c.String(http.StatusNotFound, "test")
|
||||
}))
|
||||
h.Handle(c)
|
||||
|
||||
// Status 5xx with empty path
|
||||
req = test.NewRequest(echo.GET, "", nil)
|
||||
rq = test.NewRequest(echo.GET, "", nil)
|
||||
rec = test.NewResponseRecorder()
|
||||
c = echo.NewContext(req, rec, e)
|
||||
c = echo.NewContext(rq, rec, e)
|
||||
h = Logger()(echo.HandlerFunc(func(c echo.Context) error {
|
||||
return errors.New("error")
|
||||
}))
|
||||
@ -52,9 +52,9 @@ func TestLogger(t *testing.T) {
|
||||
|
||||
func TestLoggerIPAddress(t *testing.T) {
|
||||
e := echo.New()
|
||||
req := test.NewRequest(echo.GET, "/", nil)
|
||||
rq := test.NewRequest(echo.GET, "/", nil)
|
||||
rec := test.NewResponseRecorder()
|
||||
c := echo.NewContext(req, rec, e)
|
||||
c := echo.NewContext(rq, rec, e)
|
||||
buf := new(bytes.Buffer)
|
||||
e.Logger().SetOutput(buf)
|
||||
ip := "127.0.0.1"
|
||||
@ -63,18 +63,18 @@ func TestLoggerIPAddress(t *testing.T) {
|
||||
}))
|
||||
|
||||
// With X-Real-IP
|
||||
req.Header().Add(echo.XRealIP, ip)
|
||||
rq.Header().Add(echo.XRealIP, ip)
|
||||
h.Handle(c)
|
||||
assert.Contains(t, ip, buf.String())
|
||||
|
||||
// With X-Forwarded-For
|
||||
buf.Reset()
|
||||
req.Header().Del(echo.XRealIP)
|
||||
req.Header().Add(echo.XForwardedFor, ip)
|
||||
rq.Header().Del(echo.XRealIP)
|
||||
rq.Header().Add(echo.XForwardedFor, ip)
|
||||
h.Handle(c)
|
||||
assert.Contains(t, ip, buf.String())
|
||||
|
||||
// with req.RemoteAddr
|
||||
// with rq.RemoteAddr
|
||||
buf.Reset()
|
||||
h.Handle(c)
|
||||
assert.Contains(t, ip, buf.String())
|
||||
|
@ -15,9 +15,9 @@ func TestRecover(t *testing.T) {
|
||||
e.SetDebug(true)
|
||||
buf := new(bytes.Buffer)
|
||||
e.SetLogOutput(buf)
|
||||
req := test.NewRequest(echo.GET, "/", nil)
|
||||
rq := test.NewRequest(echo.GET, "/", nil)
|
||||
rec := test.NewResponseRecorder()
|
||||
c := echo.NewContext(req, rec, e)
|
||||
c := echo.NewContext(rq, rec, e)
|
||||
h := Recover()(echo.HandlerFunc(func(c echo.Context) error {
|
||||
panic("test")
|
||||
}))
|
||||
|
@ -75,9 +75,9 @@ func StaticFromConfig(config StaticConfig) echo.MiddlewareFunc {
|
||||
}
|
||||
|
||||
// Create a directory index
|
||||
res := c.Response()
|
||||
res.Header().Set(echo.ContentType, echo.TextHTMLCharsetUTF8)
|
||||
if _, err = fmt.Fprintf(res, "<pre>\n"); err != nil {
|
||||
rs := c.Response()
|
||||
rs.Header().Set(echo.ContentType, echo.TextHTMLCharsetUTF8)
|
||||
if _, err = fmt.Fprintf(rs, "<pre>\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, d := range dirs {
|
||||
@ -87,11 +87,11 @@ func StaticFromConfig(config StaticConfig) echo.MiddlewareFunc {
|
||||
color = "#e91e63"
|
||||
name += "/"
|
||||
}
|
||||
if _, err = fmt.Fprintf(res, "<a href=\"%s\" style=\"color: %s;\">%s</a>\n", name, color, name); err != nil {
|
||||
if _, err = fmt.Fprintf(rs, "<a href=\"%s\" style=\"color: %s;\">%s</a>\n", name, color, name); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
_, err = fmt.Fprintf(res, "</pre>\n")
|
||||
_, err = fmt.Fprintf(rs, "</pre>\n")
|
||||
return err
|
||||
}
|
||||
return next.Handle(c)
|
||||
|
@ -98,8 +98,8 @@ func (r *Request) MultipartForm() (*multipart.Form, error) {
|
||||
return r.request.MultipartForm, err
|
||||
}
|
||||
|
||||
func (r *Request) reset(req *http.Request, h engine.Header, u engine.URL) {
|
||||
r.request = req
|
||||
func (r *Request) reset(rq *http.Request, h engine.Header, u engine.URL) {
|
||||
r.request = rq
|
||||
r.header = h
|
||||
r.url = u
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ func NewConfig(c *engine.Config) (s *Server) {
|
||||
},
|
||||
},
|
||||
},
|
||||
handler: engine.HandlerFunc(func(req engine.Request, res engine.Response) {
|
||||
handler: engine.HandlerFunc(func(rq engine.Request, rs engine.Response) {
|
||||
s.logger.Fatal("handler not set")
|
||||
}),
|
||||
logger: log.New("echo"),
|
||||
@ -95,24 +95,24 @@ func (s *Server) Start() {
|
||||
|
||||
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
// Request
|
||||
req := s.pool.request.Get().(*Request)
|
||||
rq := s.pool.request.Get().(*Request)
|
||||
reqHdr := s.pool.header.Get().(*Header)
|
||||
reqURL := s.pool.url.Get().(*URL)
|
||||
reqHdr.reset(r.Header)
|
||||
reqURL.reset(r.URL)
|
||||
req.reset(r, reqHdr, reqURL)
|
||||
rq.reset(r, reqHdr, reqURL)
|
||||
|
||||
// Response
|
||||
res := s.pool.response.Get().(*Response)
|
||||
rs := s.pool.response.Get().(*Response)
|
||||
resHdr := s.pool.header.Get().(*Header)
|
||||
resHdr.reset(w.Header())
|
||||
res.reset(w, resHdr)
|
||||
rs.reset(w, resHdr)
|
||||
|
||||
s.handler.ServeHTTP(req, res)
|
||||
s.handler.ServeHTTP(rq, rs)
|
||||
|
||||
s.pool.request.Put(req)
|
||||
s.pool.request.Put(rq)
|
||||
s.pool.header.Put(reqHdr)
|
||||
s.pool.url.Put(reqURL)
|
||||
s.pool.response.Put(res)
|
||||
s.pool.response.Put(rs)
|
||||
s.pool.header.Put(resHdr)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user