diff --git a/.travis.yml b/.travis.yml index 91129313f1..8ebae71234 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,45 +7,17 @@ matrix: env: GO111MODULE=on - go: 1.13.x - go: 1.13.x - env: - - TESTTAGS=nomsgpack - - go: 1.14.x - - go: 1.14.x - env: - - TESTTAGS=nomsgpack - - go: 1.15.x - - go: 1.15.x - env: - - TESTTAGS=nomsgpack - - go: master - # Adding ppc64le jobs - - go: 1.11.x - arch: ppc64le - env: GO111MODULE=on - - go: 1.12.x - arch: ppc64le - env: GO111MODULE=on - - go: 1.13.x - arch: ppc64le - - go: 1.13.x - arch: ppc64le env: - TESTTAGS=nomsgpack - go: 1.14.x - arch: ppc64le - go: 1.14.x - arch: ppc64le env: - TESTTAGS=nomsgpack - go: 1.15.x - arch: ppc64le - go: 1.15.x - arch: ppc64le env: - TESTTAGS=nomsgpack - go: master - arch: ppc64le - git: depth: 10 diff --git a/AUTHORS.md b/AUTHORS.md index dda19bcf3e..a477611bff 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -156,7 +156,7 @@ People and companies, who have contributed, in alphabetical order. - Fix variadic parameter in the flexible render API - Fix Corrupted plain render - Add Pluggable View Renderer Example - + **@msemenistyi (Mykyta Semenistyi)** - update Readme.md. Add code to String method diff --git a/BENCHMARKS.md b/BENCHMARKS.md index 0f59b509b3..c11ee99ae7 100644 --- a/BENCHMARKS.md +++ b/BENCHMARKS.md @@ -1,11 +1,11 @@ # Benchmark System -**VM HOST:** Travis -**Machine:** Ubuntu 16.04.6 LTS x64 -**Date:** May 04th, 2020 +**VM HOST:** Travis +**Machine:** Ubuntu 16.04.6 LTS x64 +**Date:** May 04th, 2020 **Version:** Gin v1.6.3 -**Go Version:** 1.14.2 linux/amd64 +**Go Version:** 1.14.2 linux/amd64 **Source:** [Go HTTP Router Benchmark](https://github.com/gin-gonic/go-http-routing-benchmark) **Result:** [See the gist](https://gist.github.com/appleboy/b5f2ecfaf50824ae9c64dcfb9165ae5e) or [Travis result](https://travis-ci.org/github/gin-gonic/go-http-routing-benchmark/jobs/682947061) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ac51ad357..ddf30e189b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -215,12 +215,12 @@ ## Gin 1.1 -- [NEW] Implement QueryArray and PostArray methods -- [NEW] Refactor GetQuery and GetPostForm -- [NEW] Add contribution guide +- [NEW] Implement QueryArray and PostArray methods +- [NEW] Refactor GetQuery and GetPostForm +- [NEW] Add contribution guide - [FIX] Corrected typos in README -- [FIX] Removed additional Iota -- [FIX] Changed imports to gopkg instead of github in README (#733) +- [FIX] Removed additional Iota +- [FIX] Changed imports to gopkg instead of github in README (#733) - [FIX] Logger: skip ANSI color commands if output is not a tty ## Gin 1.0rc2 (...) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 98d758ef1c..97daa808f0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -## Contributing +## Contributing - With issues: - Use the search tool before opening a new issue. diff --git a/README.md b/README.md index 18b19430f1..119f9452a3 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ import "net/http" ``` ## Quick start - + ```sh # assume the following codes in example.go file $ cat example.go @@ -588,44 +588,44 @@ func main() { ::1 - [Fri, 07 Dec 2018 17:04:38 JST] "GET /ping HTTP/1.1 200 122.767µs "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36" " ``` -### Controlling Log output coloring +### Controlling Log output coloring By default, logs output on console should be colorized depending on the detected TTY. -Never colorize logs: +Never colorize logs: ```go func main() { // Disable log's color gin.DisableConsoleColor() - + // Creates a gin router with default middleware: // logger and recovery (crash-free) middleware router := gin.Default() - + router.GET("/ping", func(c *gin.Context) { c.String(200, "pong") }) - + router.Run(":8080") } ``` -Always colorize logs: +Always colorize logs: ```go func main() { // Force log's color gin.ForceConsoleColor() - + // Creates a gin router with default middleware: // logger and recovery (crash-free) middleware router := gin.Default() - + router.GET("/ping", func(c *gin.Context) { c.String(200, "pong") }) - + router.Run(":8080") } ``` @@ -667,12 +667,12 @@ func main() { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } - + if json.User != "manu" || json.Password != "123" { c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"}) return - } - + } + c.JSON(http.StatusOK, gin.H{"status": "you are logged in"}) }) @@ -688,12 +688,12 @@ func main() { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } - + if xml.User != "manu" || xml.Password != "123" { c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"}) return - } - + } + c.JSON(http.StatusOK, gin.H{"status": "you are logged in"}) }) @@ -705,12 +705,12 @@ func main() { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } - + if form.User != "manu" || form.Password != "123" { c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"}) return - } - + } + c.JSON(http.StatusOK, gin.H{"status": "you are logged in"}) }) @@ -807,7 +807,7 @@ $ curl "localhost:8085/bookable?check_in=2030-03-10&check_out=2030-03-09" {"error":"Key: 'Booking.CheckOut' Error:Field validation for 'CheckOut' failed on the 'gtfield' tag"} $ curl "localhost:8085/bookable?check_in=2000-03-09&check_out=2000-03-10" -{"error":"Key: 'Booking.CheckIn' Error:Field validation for 'CheckIn' failed on the 'bookabledate' tag"}% +{"error":"Key: 'Booking.CheckIn' Error:Field validation for 'CheckIn' failed on the 'bookabledate' tag"}% ``` [Struct level validations](https://github.com/go-playground/validator/releases/tag/v8.7) can also be registered this way. @@ -1145,7 +1145,7 @@ func main() { data := gin.H{ "foo": "bar", } - + //callback is x // Will output : x({\"foo\":\"bar\"}) c.JSONP(http.StatusOK, data) @@ -1190,21 +1190,21 @@ This feature is unavailable in Go 1.6 and lower. ```go func main() { r := gin.Default() - + // Serves unicode entities r.GET("/json", func(c *gin.Context) { c.JSON(200, gin.H{ "html": "Hello, world!", }) }) - + // Serves literal characters r.GET("/purejson", func(c *gin.Context) { c.PureJSON(200, gin.H{ "html": "Hello, world!", }) }) - + // listen and serve on 0.0.0.0:8080 r.Run(":8080") } @@ -1793,8 +1793,8 @@ func main() { // Initializing the server in a goroutine so that // it won't block the graceful shutdown handling below go func() { - if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { - log.Fatalf("listen: %s\n", err) + if err := srv.ListenAndServe(); err != nil && errors.Is(err, http.ErrServerClosed) { + log.Printf("listen: %s\n", err) } }() @@ -1812,10 +1812,11 @@ func main() { // the request it is currently handling ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() + if err := srv.Shutdown(ctx); err != nil { log.Fatal("Server forced to shutdown:", err) } - + log.Println("Server exiting") } ``` diff --git a/auth.go b/auth.go index 43ad36f53b..4d8a6ce484 100644 --- a/auth.go +++ b/auth.go @@ -5,6 +5,7 @@ package gin import ( + "crypto/subtle" "encoding/base64" "net/http" "strconv" @@ -30,7 +31,7 @@ func (a authPairs) searchCredential(authValue string) (string, bool) { return "", false } for _, pair := range a { - if pair.value == authValue { + if subtle.ConstantTimeCompare([]byte(pair.value), []byte(authValue)) == 1 { return pair.user, true } } diff --git a/debug.go b/debug.go index c66ca4408f..4c7cd0c39e 100644 --- a/debug.go +++ b/debug.go @@ -12,7 +12,7 @@ import ( "strings" ) -const ginSupportMinGoVer = 10 +const ginSupportMinGoVer = 12 // IsDebugging returns true if the framework is running in debug mode. // Use SetMode(gin.ReleaseMode) to disable debug mode. @@ -67,7 +67,7 @@ func getMinVer(v string) (uint64, error) { func debugPrintWARNINGDefault() { if v, e := getMinVer(runtime.Version()); e == nil && v <= ginSupportMinGoVer { - debugPrint(`[WARNING] Now Gin requires Go 1.11 or later and Go 1.12 will be required soon. + debugPrint(`[WARNING] Now Gin requires Go 1.12+. `) } diff --git a/debug_test.go b/debug_test.go index d8cd5d1acc..c2272d0f86 100644 --- a/debug_test.go +++ b/debug_test.go @@ -104,7 +104,7 @@ func TestDebugPrintWARNINGDefault(t *testing.T) { }) m, e := getMinVer(runtime.Version()) if e == nil && m <= ginSupportMinGoVer { - assert.Equal(t, "[GIN-debug] [WARNING] Now Gin requires Go 1.11 or later and Go 1.12 will be required soon.\n\n[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.\n\n", re) + assert.Equal(t, "[GIN-debug] [WARNING] Now Gin requires Go 1.12+.\n\n[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.\n\n", re) } else { assert.Equal(t, "[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.\n\n", re) } diff --git a/gin_integration_test.go b/gin_integration_test.go index 5f508c7090..41ad98743b 100644 --- a/gin_integration_test.go +++ b/gin_integration_test.go @@ -14,6 +14,7 @@ import ( "net/http" "net/http/httptest" "os" + "path/filepath" "sync" "testing" "time" @@ -146,7 +147,7 @@ func TestRunWithPort(t *testing.T) { func TestUnixSocket(t *testing.T) { router := New() - unixTestSocket := "/tmp/unix_unit_test" + unixTestSocket := filepath.Join(os.TempDir(), "unix_unit_test") defer os.Remove(unixTestSocket) diff --git a/internal/bytesconv/bytesconv.go b/internal/bytesconv/bytesconv.go index fdad2015c4..86e4c4d44c 100644 --- a/internal/bytesconv/bytesconv.go +++ b/internal/bytesconv/bytesconv.go @@ -9,7 +9,7 @@ import ( ) // StringToBytes converts string to byte slice without a memory allocation. -func StringToBytes(s string) (b []byte) { +func StringToBytes(s string) []byte { return *(*[]byte)(unsafe.Pointer( &struct { string diff --git a/mode.go b/mode.go index 11f833e9a3..c8813aff26 100644 --- a/mode.go +++ b/mode.go @@ -63,7 +63,7 @@ func SetMode(value string) { case TestMode: ginMode = testCode default: - panic("gin mode unknown: " + value) + panic("gin mode unknown: " + value + " (available mode: debug release test)") } modeName = value