diff --git a/.travis.yml b/.travis.yml index 00393750..b38adcb1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,22 +1,20 @@ language: go sudo: false -go: - - 1.6.x - - 1.7.x - - 1.8.x - - 1.9.x - - 1.10.x - - 1.11.x - - 1.12.x - - master matrix: fast_finish: true include: + - go: 1.6.x + - go: 1.7.x + - go: 1.8.x + - go: 1.9.x + - go: 1.10.x - go: 1.11.x env: GO111MODULE=on - go: 1.12.x env: GO111MODULE=on + - go: master + env: GO111MODULE=on git: depth: 10 diff --git a/README.md b/README.md index 470809e7..f9c10b22 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Gin is a web framework written in Go (Golang). It features a martini-like API with much better performance, up to 40 times faster thanks to [httprouter](https://github.com/julienschmidt/httprouter). If you need performance and good productivity, you will love Gin. -The key features of Gin are: +**The key features of Gin are:** - Zero allocation router - Fast diff --git a/logger.go b/logger.go index dc639975..2ecaed7d 100644 --- a/logger.go +++ b/logger.go @@ -66,6 +66,8 @@ type LogFormatterParams struct { IsTerm bool // BodySize is the size of the Response Body BodySize int + // Keys are the keys set on the request's context. + Keys map[string]interface{} } // StatusCodeColor is the ANSI color for appropriately logging http status code to a terminal. @@ -227,6 +229,7 @@ func LoggerWithConfig(conf LoggerConfig) HandlerFunc { param := LogFormatterParams{ Request: c.Request, IsTerm: isTerm, + Keys: c.Keys, } // Stop timer diff --git a/logger_test.go b/logger_test.go index c551677a..36231371 100644 --- a/logger_test.go +++ b/logger_test.go @@ -181,6 +181,7 @@ func TestLoggerWithFormatter(t *testing.T) { func TestLoggerWithConfigFormatting(t *testing.T) { var gotParam LogFormatterParams + var gotKeys map[string]interface{} buffer := new(bytes.Buffer) router := New() @@ -204,6 +205,7 @@ func TestLoggerWithConfigFormatting(t *testing.T) { router.GET("/example", func(c *Context) { // set dummy ClientIP c.Request.Header.Set("X-Forwarded-For", "20.20.20.20") + gotKeys = c.Keys }) performRequest(router, "GET", "/example?a=100") @@ -223,6 +225,7 @@ func TestLoggerWithConfigFormatting(t *testing.T) { assert.Equal(t, "GET", gotParam.Method) assert.Equal(t, "/example?a=100", gotParam.Path) assert.Empty(t, gotParam.ErrorMessage) + assert.Equal(t, gotKeys, gotParam.Keys) } diff --git a/routergroup.go b/routergroup.go index 297d3574..a1e6c928 100644 --- a/routergroup.go +++ b/routergroup.go @@ -195,7 +195,7 @@ func (group *RouterGroup) createStaticHandler(relativePath string, fs http.FileS // Check if file exists and/or if we have permission to access it if _, err := fs.Open(file); err != nil { c.Writer.WriteHeader(http.StatusNotFound) - c.handlers = group.engine.allNoRoute + c.handlers = group.engine.noRoute // Reset index c.index = -1 return diff --git a/routes_test.go b/routes_test.go index a842704f..de363a8c 100644 --- a/routes_test.go +++ b/routes_test.go @@ -429,7 +429,6 @@ func TestRouterNotFound(t *testing.T) { func TestRouterStaticFSNotFound(t *testing.T) { router := New() - router.StaticFS("/", http.FileSystem(http.Dir("/thisreallydoesntexist/"))) router.NoRoute(func(c *Context) { c.String(404, "non existent") @@ -452,6 +451,27 @@ func TestRouterStaticFSFileNotFound(t *testing.T) { }) } +// Reproduction test for the bug of issue #1805 +func TestMiddlewareCalledOnceByRouterStaticFSNotFound(t *testing.T) { + router := New() + + // Middleware must be called just only once by per request. + middlewareCalledNum := 0 + router.Use(func(c *Context) { + middlewareCalledNum += 1 + }) + + router.StaticFS("/", http.FileSystem(http.Dir("/thisreallydoesntexist/"))) + + // First access + performRequest(router, "GET", "/nonexistent") + assert.Equal(t, 1, middlewareCalledNum) + + // Second access + performRequest(router, "HEAD", "/nonexistent") + assert.Equal(t, 2, middlewareCalledNum) +} + func TestRouteRawPath(t *testing.T) { route := New() route.UseRawPath = true diff --git a/testdata/assets/console.png b/testdata/assets/console.png new file mode 100644 index 00000000..7a695718 Binary files /dev/null and b/testdata/assets/console.png differ