Repository: gin-gonic/gin
Pull request #4088 (2024-11-07 06:32:16)

refactor(context): (reupload) Added an optional permission parameter to the SaveUploadedFile method (#4068)
The SaveUploadedFile method previously set folder permissions to 0o750 by default when creating directories. A third parameter, ...fs.FileMode, has been added to allow customizable permissions. This update enables users to optionally set folder permissions when creating directories and files with the SaveUploadedFile method.

``` go
// example
func SaveFile(ctx *gin.Context) error {
	file, err := ctx.FormFile("file")
	if err != nil {
		return err
	}

	var perm fs.FileMode = 0o755
	return ctx.SaveUploadedFile(file, "/asset/file", perm)
}
```


![image](https://github.com/user-attachments/assets/824413af-60af-46ab-8202-ed44a0e3ff61)

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/gin-gonic/gin/pull/4088?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=gin-gonic) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 98.92%. Comparing base [(`3dc1cd6`)](https://app.codecov.io/gh/gin-gonic/gin/commit/3dc1cd6572b4e3a0cd170a15debe546c2c72294f?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=gin-gonic) to head [(`62a6522`)](https://app.codecov.io/gh/gin-gonic/gin/commit/62a652295c520ff3492b6ad67e369242ddac9fc5?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=gin-gonic).
> Report is 79 commits behind head on master.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##           master    #4088      +/-   ##
==========================================
- Coverage   99.21%   98.92%   -0.29%     
==========================================
  Files          42       41       -1     
  Lines        3182     3347     +165     
==========================================
+ Hits         3157     3311     +154     
- Misses         17       25       +8     
- Partials        8       11       +3     
```

| [Flag](https://app.codecov.io/gh/gin-gonic/gin/pull/4088/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=gin-gonic) | Coverage Δ | |
|---|---|---|
| [](https://app.codecov.io/gh/gin-gonic/gin/pull/4088/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=gin-gonic) | `?` | |
| [-tags nomsgpack](https://app.codecov.io/gh/gin-gonic/gin/pull/4088/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=gin-gonic) | `98.92% <100.00%> (?)` | |
| [go-1.18](https://app.codecov.io/gh/gin-gonic/gin/pull/4088/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=gin-gonic) | `?` | |
| [go-1.19](https://app.codecov.io/gh/gin-gonic/gin/pull/4088/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=gin-gonic) | `?` | |
| [go-1.20](https://app.codecov.io/gh/gin-gonic/gin/pull/4088/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=gin-gonic) | `?` | |
| [go-1.21](https://app.codecov.io/gh/gin-gonic/gin/pull/4088/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=gin-gonic) | `98.92% <100.00%> (-0.29%)` | :arrow_down: |
| [go-1.22](https://app.codecov.io/gh/gin-gonic/gin/pull/4088/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=gin-gonic) | `98.92% <100.00%> (?)` | |
| [macos-latest](https://app.codecov.io/gh/gin-gonic/gin/pull/4088/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=gin-gonic) | `98.92% <100.00%> (-0.29%)` | :arrow_down: |
| [ubuntu-latest](https://app.codecov.io/gh/gin-gonic/gin/pull/4088/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=gin-gonic) | `98.92% <100.00%> (-0.29%)` | :arrow_down: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=gin-gonic#carryforward-flags-in-the-pull-request-comment) to find out more.

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/gin-gonic/gin/pull/4088?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=gin-gonic).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=gin-gonic).


Patch:
diff --git a/.golangci.yml b/.golangci.yml
index 8d58c98..ccb2668 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -16,8 +16,10 @@ linters:
     - nakedret
     - nilerr
     - nolintlint
+    - perfsprint
     - revive
     - testifylint
+    - usestdlibvars
     - wastedassign
 
 linters-settings:
@@ -34,6 +36,13 @@ linters-settings:
       - G112
       - G201
       - G203
+  perfsprint:
+    err-error: true
+    errorf: true
+    fiximports: true
+    int-conversion: true
+    sprintf1: true
+    strconcat: true
   testifylint:
     enable-all: true
 
diff --git a/context.go b/context.go
index 1e8c8e2..c724daf 100644
--- a/context.go
+++ b/context.go
@@ -7,6 +7,7 @@ package gin
 import (
 	"errors"
 	"io"
+	"io/fs"
 	"log"
 	"math"
 	"mime/multipart"
@@ -186,10 +187,9 @@ func (c *Context) FullPath() string {
 func (c *Context) Next() {
 	c.index++
 	for c.index < int8(len(c.handlers)) {
-		if c.handlers[c.index] == nil {
-			continue
+		if c.handlers[c.index] != nil {
+			c.handlers[c.index](c)
 		}
-		c.handlers[c.index](c)
 		c.index++
 	}
 }
@@ -677,14 +677,22 @@ func (c *Context) MultipartForm() (*multipart.Form, error) {
 }
 
 // SaveUploadedFile uploads the form file to specific dst.
-func (c *Context) SaveUploadedFile(file *multipart.FileHeader, dst string) error {
+func (c *Context) SaveUploadedFile(file *multipart.FileHeader, dst string, perm ...fs.FileMode) error {
 	src, err := file.Open()
 	if err != nil {
 		return err
 	}
 	defer src.Close()
 
-	if err = os.MkdirAll(filepath.Dir(dst), 0o750); err != nil {
+	if len(perm) <= 0 {
+		perm = append(perm, 0o750)
+	}
+
+	if err = os.MkdirAll(filepath.Dir(dst), perm[0]); err != nil {
+		return err
+	}
+
+	if err = os.Chmod(filepath.Dir(dst), perm[0]); err != nil {
 		return err
 	}
 


Test patch:
diff --git a/auth_test.go b/auth_test.go
index f717592..9166e3b 100644
--- a/auth_test.go
+++ b/auth_test.go
@@ -90,7 +90,7 @@ func TestBasicAuthSucceed(t *testing.T) {
 	})
 
 	w := httptest.NewRecorder()
-	req, _ := http.NewRequest("GET", "/login", nil)
+	req, _ := http.NewRequest(http.MethodGet, "/login", nil)
 	req.Header.Set("Authorization", authorizationHeader("admin", "password"))
 	router.ServeHTTP(w, req)
 
@@ -109,7 +109,7 @@ func TestBasicAuth401(t *testing.T) {
 	})
 
 	w := httptest.NewRecorder()
-	req, _ := http.NewRequest("GET", "/login", nil)
+	req, _ := http.NewRequest(http.MethodGet, "/login", nil)
 	req.Header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte("admin:password")))
 	router.ServeHTTP(w, req)
 
@@ -129,7 +129,7 @@ func TestBasicAuth401WithCustomRealm(t *testing.T) {
 	})
 
 	w := httptest.NewRecorder()
-	req, _ := http.NewRequest("GET", "/login", nil)
+	req, _ := http.NewRequest(http.MethodGet, "/login", nil)
 	req.Header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte("admin:password")))
 	router.ServeHTTP(w, req)
 
@@ -147,7 +147,7 @@ func TestBasicAuthForProxySucceed(t *testing.T) {
 	})
 
 	w := httptest.NewRecorder()
-	req, _ := http.NewRequest("GET", "/test", nil)
+	req, _ := http.NewRequest(http.MethodGet, "/test", nil)
 	req.Header.Set("Proxy-Authorization", authorizationHeader("admin", "password"))
 	router.ServeHTTP(w, req)
 
@@ -166,7 +166,7 @@ func TestBasicAuthForProxy407(t *testing.T) {
 	})
 
 	w := httptest.NewRecorder()
-	req, _ := http.NewRequest("GET", "/test", nil)
+	req, _ := http.NewRequest(http.MethodGet, "/test", nil)
 	req.Header.Set("Proxy-Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte("admin:password")))
 	router.ServeHTTP(w, req)
 
diff --git a/benchmarks_test.go b/benchmarks_test.go
index 5b7929b..3a8d53f 100644
--- a/benchmarks_test.go
+++ b/benchmarks_test.go
@@ -14,21 +14,21 @@ import (
 func BenchmarkOneRoute(B *testing.B) {
 	router := New()
 	router.GET("/ping", func(c *Context) {})
-	runRequest(B, router, "GET", "/ping")
+	runRequest(B, router, http.MethodGet, "/ping")
 }
 
 func BenchmarkRecoveryMiddleware(B *testing.B) {
 	router := New()
 	router.Use(Recovery())
 	router.GET("/", func(c *Context) {})
-	runRequest(B, router, "GET", "/")
+	runRequest(B, router, http.MethodGet, "/")
 }
 
 func BenchmarkLoggerMiddleware(B *testing.B) {
 	router := New()
 	router.Use(LoggerWithWriter(newMockWriter()))
 	router.GET("/", func(c *Context) {})
-	runRequest(B, router, "GET", "/")
+	runRequest(B, router, http.MethodGet, "/")
 }
 
 func BenchmarkManyHandlers(B *testing.B) {
@@ -37,7 +37,7 @@ func BenchmarkManyHandlers(B *testing.B) {
 	router.Use(func(c *Context) {})
 	router.Use(func(c *Context) {})
 	router.GET("/ping", func(c *Context) {})
-	runRequest(B, router, "GET", "/ping")
+	runRequest(B, router, http.MethodGet, "/ping")
 }
 
 func Benchmark5Params(B *testing.B) {
@@ -45,7 +45,7 @@ func Benchmark5Params(B *testing.B) {
 	router := New()
 	router.Use(func(c *Context) {})
 	router.GET("/param/:param1/:params2/:param3/:param4/:param5", func(c *Context) {})
-	runRequest(B, router, "GET", "/param/path/to/parameter/john/12345")
+	runRequest(B, router, http.MethodGet, "/param/path/to/parameter/john/12345")
 }
 
 func BenchmarkOneRouteJSON(B *testing.B) {
@@ -56,7 +56,7 @@ func BenchmarkOneRouteJSON(B *testing.B) {
 	router.GET("/json", func(c *Context) {
 		c.JSON(http.StatusOK, data)
 	})
-	runRequest(B, router, "GET", "/json")
+	runRequest(B, router, http.MethodGet, "/json")
 }
 
 func BenchmarkOneRouteHTML(B *testing.B) {
@@ -68,7 +68,7 @@ func BenchmarkOneRouteHTML(B *testing.B) {
 	router.GET("/html", func(c *Context) {
 		c.HTML(http.StatusOK, "index", "hola")
 	})
-	runRequest(B, router, "GET", "/html")
+	runRequest(B, router, http.MethodGet, "/html")
 }
 
 func BenchmarkOneRouteSet(B *testing.B) {
@@ -76,7 +76,7 @@ func BenchmarkOneRouteSet(B *testing.B) {
 	router.GET("/ping", func(c *Context) {
 		c.Set("key", "value")
 	})
-	runRequest(B, router, "GET", "/ping")
+	runRequest(B, router, http.MethodGet, "/ping")
 }
 
 func BenchmarkOneRouteString(B *testing.B) {
@@ -84,13 +84,13 @@ func BenchmarkOneRouteString(B *testing.B) {
 	router.GET("/text", func(c *Context) {
 		c.String(http.StatusOK, "this is a plain text")
 	})
-	runRequest(B, router, "GET", "/text")
+	runRequest(B, router, http.MethodGet, "/text")
 }
 
 func BenchmarkManyRoutesFist(B *testing.B) {
 	router := New()
 	router.Any("/ping", func(c *Context) {})
-	runRequest(B, router, "GET", "/ping")
+	runRequest(B, router, http.MethodGet, "/ping")
 }
 
 func BenchmarkManyRoutesLast(B *testing.B) {
@@ -103,7 +103,7 @@ func Benchmark404(B *testing.B) {
 	router := New()
 	router.Any("/something", func(c *Context) {})
 	router.NoRoute(func(c *Context) {})
-	runRequest(B, router, "GET", "/ping")
+	runRequest(B, router, http.MethodGet, "/ping")
 }
 
 func Benchmark404Many(B *testing.B) {
@@ -118,7 +118,7 @@ func Benchmark404Many(B *testing.B) {
 	router.GET("/user/:id/:mode", func(c *Context) {})
 
 	router.NoRoute(func(c *Context) {})
-	runRequest(B, router, "GET", "/viewfake")
+	runRequest(B, router, http.MethodGet, "/viewfake")
 }
 
 type mockWriter struct {
diff --git a/binding/binding_msgpack_test.go b/binding/binding_msgpack_test.go
index a811639..7a5db34 100644
--- a/binding/binding_msgpack_test.go
+++ b/binding/binding_msgpack_test.go
@@ -8,6 +8,7 @@ package binding
 
 import (
 	"bytes"
+	"net/http"
 	"testing"
 
 	"github.com/stretchr/testify/assert"
@@ -39,20 +40,20 @@ func testMsgPackBodyBinding(t *testing.T, b Binding, name, path, badPath, body,
 	assert.Equal(t, name, b.Name())
 
 	obj := FooStruct{}
-	req := requestWithBody("POST", path, body)
+	req := requestWithBody(http.MethodPost, path, body)
 	req.Header.Add("Content-Type", MIMEMSGPACK)
 	err := b.Bind(req, &obj)
 	require.NoError(t, err)
 	assert.Equal(t, "bar", obj.Foo)
 
 	obj = FooStruct{}
-	req = requestWithBody("POST", badPath, badBody)
+	req = requestWithBody(http.MethodPost, badPath, badBody)
 	req.Header.Add("Content-Type", MIMEMSGPACK)
 	err = MsgPack.Bind(req, &obj)
 	require.Error(t, err)
 }
 
 func TestBindingDefaultMsgPack(t *testing.T) {
-	assert.Equal(t, MsgPack, Default("POST", MIMEMSGPACK))
-	assert.Equal(t, MsgPack, Default("PUT", MIMEMSGPACK2))
+	assert.Equal(t, MsgPack, Default(http.MethodPost, MIMEMSGPACK))
+	assert.Equal(t, MsgPack, Default(http.MethodPut, MIMEMSGPACK2))
 }
diff --git a/binding/binding_test.go b/binding/binding_test.go
index 2036b59..901e974 100644
--- a/binding/binding_test.go
+++ b/binding/binding_test.go
@@ -145,31 +145,31 @@ type FooStructForMapPtrType struct {
 }
 
 func TestBindingDefault(t *testing.T) {
-	assert.Equal(t, Form, Default("GET", ""))
-	assert.Equal(t, Form, Default("GET", MIMEJSON))
+	assert.Equal(t, Form, Default(http.MethodGet, ""))
+	assert.Equal(t, Form, Default(http.MethodGet, MIMEJSON))
 
-	assert.Equal(t, JSON, Default("POST", MIMEJSON))
-	assert.Equal(t, JSON, Default("PUT", MIMEJSON))
+	assert.Equal(t, JSON, Default(http.MethodPost, MIMEJSON))
+	assert.Equal(t, JSON, Default(http.MethodPut, MIMEJSON))
 
-	assert.Equal(t, XML, Default("POST", MIMEXML))
-	assert.Equal(t, XML, Default("PUT", MIMEXML2))
+	assert.Equal(t, XML, Default(http.MethodPost, MIMEXML))
+	assert.Equal(t, XML, Default(http.MethodPut, MIMEXML2))
 
-	assert.Equal(t, Form, Default("POST", MIMEPOSTForm))
-	assert.Equal(t, Form, Default("PUT", MIMEPOSTForm))
+	assert.Equal(t, Form, Default(http.MethodPost, MIMEPOSTForm))
+	assert.Equal(t, Form, Default(http.MethodPut, MIMEPOSTForm))
 
-	assert.Equal(t, FormMultipart, Default("POST", MIMEMultipartPOSTForm))
-	assert.Equal(t, FormMultipart, Default("PUT", MIMEMultipartPOSTForm))
+	assert.Equal(t, FormMultipart, Default(http.MethodPost, MIMEMultipartPOSTForm))
+	assert.Equal(t, FormMultipart, Default(http.MethodPut, MIMEMultipartPOSTForm))
 
-	assert.Equal(t, ProtoBuf, Default("POST", MIMEPROTOBUF))
-	assert.Equal(t, ProtoBuf, Default("PUT", MIMEPROTOBUF))
+	assert.Equal(t, ProtoBuf, Default(http.MethodPost, MIMEPROTOBUF))
+	assert.Equal(t, ProtoBuf, Default(http.MethodPut, MIMEPROTOBUF))
 
-	assert.Equal(t, YAML, Default("POST", MIMEYAML))
-	assert.Equal(t, YAML, Default("PUT", MIMEYAML))
-	assert.Equal(t, YAML, Default("POST", MIMEYAML2))
-	assert.Equal(t, YAML, Default("PUT", MIMEYAML2))
+	assert.Equal(t, YAML, Default(http.MethodPost, MIMEYAML))
+	assert.Equal(t, YAML, Default(http.MethodPut, MIMEYAML))
+	assert.Equal(t, YAML, Default(http.MethodPost, MIMEYAML2))
+	assert.Equal(t, YAML, Default(http.MethodPut, MIMEYAML2))
 
-	assert.Equal(t, TOML, Default("POST", MIMETOML))
-	assert.Equal(t, TOML, Default("PUT", MIMETOML))
+	assert.Equal(t, TOML, Default(http.MethodPost, MIMETOML))
+	assert.Equal(t, TOML, Default(http.MethodPut, MIMETOML))
 }
 
 func TestBindingJSONNilBody(t *testing.T) {
@@ -227,137 +227,137 @@ func TestBindingJSONStringMap(t *testing.T) {
 }
 
 func TestBindingForm(t *testing.T) {
-	testFormBinding(t, "POST",
+	testFormBinding(t, http.MethodPost,
 		"/", "/",
 		"foo=bar&bar=foo", "bar2=foo")
 }
 
 func TestBindingForm2(t *testing.T) {
-	testFormBinding(t, "GET",
+	testFormBinding(t, http.MethodGet,
 		"/?foo=bar&bar=foo", "/?bar2=foo",
 		"", "")
 }
 
 func TestBindingFormEmbeddedStruct(t *testing.T) {
-	testFormBindingEmbeddedStruct(t, "POST",
+	testFormBindingEmbeddedStruct(t, http.MethodPost,
 		"/", "/",
 		"page=1&size=2&appkey=test-appkey", "bar2=foo")
 }
 
 func TestBindingFormEmbeddedStruct2(t *testing.T) {
-	testFormBindingEmbeddedStruct(t, "GET",
+	testFormBindingEmbeddedStruct(t, http.MethodGet,
 		"/?page=1&size=2&appkey=test-appkey", "/?bar2=foo",
 		"", "")
 }
 
 func TestBindingFormDefaultValue(t *testing.T) {
-	testFormBindingDefaultValue(t, "POST",
+	testFormBindingDefaultValue(t, http.MethodPost,
 		"/", "/",
 		"foo=bar", "bar2=foo")
 }
 
 func TestBindingFormDefaultValue2(t *testing.T) {
-	testFormBindingDefaultValue(t, "GET",
+	testFormBindingDefaultValue(t, http.MethodGet,
 		"/?foo=bar", "/?bar2=foo",
 		"", "")
 }
 
 func TestBindingFormForTime(t *testing.T) {
-	testFormBindingForTime(t, "POST",
+	testFormBindingForTime(t, http.MethodPost,
 		"/", "/",
 		"time_foo=2017-11-15&time_bar=&createTime=1562400033000000123&unixTime=1562400033", "bar2=foo")
-	testFormBindingForTimeNotUnixFormat(t, "POST",
+	testFormBindingForTimeNotUnixFormat(t, http.MethodPost,
 		"/", "/",
 		"time_foo=2017-11-15&createTime=bad&unixTime=bad", "bar2=foo")
-	testFormBindingForTimeNotFormat(t, "POST",
+	testFormBindingForTimeNotFormat(t, http.MethodPost,
 		"/", "/",
 		"time_foo=2017-11-15", "bar2=foo")
-	testFormBindingForTimeFailFormat(t, "POST",
+	testFormBindingForTimeFailFormat(t, http.MethodPost,
 		"/", "/",
 		"time_foo=2017-11-15", "bar2=foo")
-	testFormBindingForTimeFailLocation(t, "POST",
+	testFormBindingForTimeFailLocation(t, http.MethodPost,
 		"/", "/",
 		"time_foo=2017-11-15", "bar2=foo")
 }
 
 func TestBindingFormForTime2(t *testing.T) {
-	testFormBindingForTime(t, "GET",
+	testFormBindingForTime(t, http.MethodGet,
 		"/?time_foo=2017-11-15&time_bar=&createTime=1562400033000000123&unixTime=1562400033", "/?bar2=foo",
 		"", "")
-	testFormBindingForTimeNotUnixFormat(t, "POST",
+	testFormBindingForTimeNotUnixFormat(t, http.MethodPost,
 		"/", "/",
 		"time_foo=2017-11-15&createTime=bad&unixTime=bad", "bar2=foo")
-	testFormBindingForTimeNotFormat(t, "GET",
+	testFormBindingForTimeNotFormat(t, http.MethodGet,
 		"/?time_foo=2017-11-15", "/?bar2=foo",
 		"", "")
-	testFormBindingForTimeFailFormat(t, "GET",
+	testFormBindingForTimeFailFormat(t, http.MethodGet,
 		"/?time_foo=2017-11-15", "/?bar2=foo",
 		"", "")
-	testFormBindingForTimeFailLocation(t, "GET",
+	testFormBindingForTimeFailLocation(t, http.MethodGet,
 		"/?time_foo=2017-11-15", "/?bar2=foo",
 		"", "")
 }
 
 func TestFormBindingIgnoreField(t *testing.T) {
-	testFormBindingIgnoreField(t, "POST",
+	testFormBindingIgnoreField(t, http.MethodPost,
 		"/", "/",
 		"-=bar", "")
 }
 
 func TestBindingFormInvalidName(t *testing.T) {
-	testFormBindingInvalidName(t, "POST",
+	testFormBindingInvalidName(t, http.MethodPost,
 		"/", "/",
 		"test_name=bar", "bar2=foo")
 }
 
 func TestBindingFormInvalidName2(t *testing.T) {
-	testFormBindingInvalidName2(t, "POST",
+	testFormBindingInvalidName2(t, http.MethodPost,
 		"/", "/",
 		"map_foo=bar", "bar2=foo")
 }
 
 func TestBindingFormForType(t *testing.T) {
-	testFormBindingForType(t, "POST",
+	testFormBindingForType(t, http.MethodPost,
 		"/", "/",
 		"map_foo={\"bar\":123}", "map_foo=1", "Map")
 
-	testFormBindingForType(t, "POST",
+	testFormBindingForType(t, http.MethodPost,
 		"/", "/",
 		"slice_foo=1&slice_foo=2", "bar2=1&bar2=2", "Slice")
 
-	testFormBindingForType(t, "GET",
+	testFormBindingForType(t, http.MethodGet,
 		"/?slice_foo=1&slice_foo=2", "/?bar2=1&bar2=2",
 		"", "", "Slice")
 
-	testFormBindingForType(t, "POST",
+	testFormBindingForType(t, http.MethodPost,
 		"/", "/",
 		"slice_map_foo=1&slice_map_foo=2", "bar2=1&bar2=2", "SliceMap")
 
-	testFormBindingForType(t, "GET",
+	testFormBindingForType(t, http.MethodGet,
 		"/?slice_map_foo=1&slice_map_foo=2", "/?bar2=1&bar2=2",
 		"", "", "SliceMap")
 
-	testFormBindingForType(t, "POST",
+	testFormBindingForType(t, http.MethodPost,
 		"/", "/",
 		"ptr_bar=test", "bar2=test", "Ptr")
 
-	testFormBindingForType(t, "GET",
+	testFormBindingForType(t, http.MethodGet,
 		"/?ptr_bar=test", "/?bar2=test",
 		"", "", "Ptr")
 
-	testFormBindingForType(t, "POST",
+	testFormBindingForType(t, http.MethodPost,
 		"/", "/",
 		"idx=123", "id1=1", "Struct")
 
-	testFormBindingForType(t, "GET",
+	testFormBindingForType(t, http.MethodGet,
 		"/?idx=123", "/?id1=1",
 		"", "", "Struct")
 
-	testFormBindingForType(t, "POST",
+	testFormBindingForType(t, http.MethodPost,
 		"/", "/",
 		"name=thinkerou", "name1=ou", "StructPointer")
 
-	testFormBindingForType(t, "GET",
+	testFormBindingForType(t, http.MethodGet,
 		"/?name=thinkerou", "/?name1=ou",
 		"", "", "StructPointer")
 }
@@ -374,7 +374,7 @@ func TestBindingFormStringMap(t *testing.T) {
 
 func TestBindingFormStringSliceMap(t *testing.T) {
 	obj := make(map[string][]string)
-	req := requestWithBody("POST", "/", "foo=something&foo=bar&hello=world")
+	req := requestWithBody(http.MethodPost, "/", "foo=something&foo=bar&hello=world")
 	req.Header.Add("Content-Type", MIMEPOSTForm)
 	err := Form.Bind(req, &obj)
 	require.NoError(t, err)
@@ -387,38 +387,38 @@ func TestBindingFormStringSliceMap(t *testing.T) {
 	assert.True(t, reflect.DeepEqual(obj, target))
 
 	objInvalid := make(map[string][]int)
-	req = requestWithBody("POST", "/", "foo=something&foo=bar&hello=world")
+	req = requestWithBody(http.MethodPost, "/", "foo=something&foo=bar&hello=world")
 	req.Header.Add("Content-Type", MIMEPOSTForm)
 	err = Form.Bind(req, &objInvalid)
 	require.Error(t, err)
 }
 
 func TestBindingQuery(t *testing.T) {
-	testQueryBinding(t, "POST",
+	testQueryBinding(t, http.MethodPost,
 		"/?foo=bar&bar=foo", "/",
 		"foo=unused", "bar2=foo")
 }
 
 func TestBindingQuery2(t *testing.T) {
-	testQueryBinding(t, "GET",
+	testQueryBinding(t, http.MethodGet,
 		"/?foo=bar&bar=foo", "/?bar2=foo",
 		"foo=unused", "")
 }
 
 func TestBindingQueryFail(t *testing.T) {
-	testQueryBindingFail(t, "POST",
+	testQueryBindingFail(t, http.MethodPost,
 		"/?map_foo=", "/",
 		"map_foo=unused", "bar2=foo")
 }
 
 func TestBindingQueryFail2(t *testing.T) {
-	testQueryBindingFail(t, "GET",
+	testQueryBindingFail(t, http.MethodGet,
 		"/?map_foo=", "/?bar2=foo",
 		"map_foo=unused", "")
 }
 
 func TestBindingQueryBoolFail(t *testing.T) {
-	testQueryBindingBoolFail(t, "GET",
+	testQueryBindingBoolFail(t, http.MethodGet,
 		"/?bool_foo=fasl", "/?bar2=foo",
 		"bool_foo=unused", "")
 }
@@ -427,7 +427,7 @@ func TestBindingQueryStringMap(t *testing.T) {
 	b := Query
 
 	obj := make(map[string]string)
-	req := requestWithBody("GET", "/?foo=bar&hello=world", "")
+	req := requestWithBody(http.MethodGet, "/?foo=bar&hello=world", "")
 	err := b.Bind(req, &obj)
 	require.NoError(t, err)
 	assert.NotNil(t, obj)
@@ -436,7 +436,7 @@ func TestBindingQueryStringMap(t *testing.T) {
 	assert.Equal(t, "world", obj["hello"])
 
 	obj = make(map[string]string)
-	req = requestWithBody("GET", "/?foo=bar&foo=2&hello=world", "") // should pick last
+	req = requestWithBody(http.MethodGet, "/?foo=bar&foo=2&hello=world", "") // should pick last
 	err = b.Bind(req, &obj)
 	require.NoError(t, err)
 	assert.NotNil(t, obj)
@@ -495,28 +495,28 @@ func TestBindingYAMLFail(t *testing.T) {
 }
 
 func createFormPostRequest(t *testing.T) *http.Request {
-	req, err := http.NewRequest("POST", "/?foo=getfoo&bar=getbar", bytes.NewBufferString("foo=bar&bar=foo"))
+	req, err := http.NewRequest(http.MethodPost, "/?foo=getfoo&bar=getbar", bytes.NewBufferString("foo=bar&bar=foo"))
 	require.NoError(t, err)
 	req.Header.Set("Content-Type", MIMEPOSTForm)
 	return req
 }
 
 func createDefaultFormPostRequest(t *testing.T) *http.Request {
-	req, err := http.NewRequest("POST", "/?foo=getfoo&bar=getbar", bytes.NewBufferString("foo=bar"))
+	req, err := http.NewRequest(http.MethodPost, "/?foo=getfoo&bar=getbar", bytes.NewBufferString("foo=bar"))
 	require.NoError(t, err)
 	req.Header.Set("Content-Type", MIMEPOSTForm)
 	return req
 }
 
 func createFormPostRequestForMap(t *testing.T) *http.Request {
-	req, err := http.NewRequest("POST", "/?map_foo=getfoo", bytes.NewBufferString("map_foo={\"bar\":123}"))
+	req, err := http.NewRequest(http.MethodPost, "/?map_foo=getfoo", bytes.NewBufferString("map_foo={\"bar\":123}"))
 	require.NoError(t, err)
 	req.Header.Set("Content-Type", MIMEPOSTForm)
 	return req
 }
 
 func createFormPostRequestForMapFail(t *testing.T) *http.Request {
-	req, err := http.NewRequest("POST", "/?map_foo=getfoo", bytes.NewBufferString("map_foo=hello"))
+	req, err := http.NewRequest(http.MethodPost, "/?map_foo=getfoo", bytes.NewBufferString("map_foo=hello"))
 	require.NoError(t, err)
 	req.Header.Set("Content-Type", MIMEPOSTForm)
 	return req
@@ -540,7 +540,7 @@ func createFormFilesMultipartRequest(t *testing.T) *http.Request {
 	_, err = io.Copy(fw, f)
 	require.NoError(t, err)
 
-	req, err2 := http.NewRequest("POST", "/?foo=getfoo&bar=getbar", body)
+	req, err2 := http.NewRequest(http.MethodPost, "/?foo=getfoo&bar=getbar", body)
 	require.NoError(t, err2)
 	req.Header.Set("Content-Type", MIMEMultipartPOSTForm+"; boundary="+boundary)
 
@@ -565,7 +565,7 @@ func createFormFilesMultipartRequestFail(t *testing.T) *http.Request {
 	_, err = io.Copy(fw, f)
 	require.NoError(t, err)
 
-	req, err2 := http.NewRequest("POST", "/?foo=getfoo&bar=getbar", body)
+	req, err2 := http.NewRequest(http.MethodPost, "/?foo=getfoo&bar=getbar", body)
 	require.NoError(t, err2)
 	req.Header.Set("Content-Type", MIMEMultipartPOSTForm+"; boundary="+boundary)
 
@@ -581,7 +581,7 @@ func createFormMultipartRequest(t *testing.T) *http.Request {
 	require.NoError(t, mw.SetBoundary(boundary))
 	require.NoError(t, mw.WriteField("foo", "bar"))
 	require.NoError(t, mw.WriteField("bar", "foo"))
-	req, err := http.NewRequest("POST", "/?foo=getfoo&bar=getbar", body)
+	req, err := http.NewRequest(http.MethodPost, "/?foo=getfoo&bar=getbar", body)
 	require.NoError(t, err)
 	req.Header.Set("Content-Type", MIMEMultipartPOSTForm+"; boundary="+boundary)
 	return req
@@ -595,7 +595,7 @@ func createFormMultipartRequestForMap(t *testing.T) *http.Request {
 
 	require.NoError(t, mw.SetBoundary(boundary))
 	require.NoError(t, mw.WriteField("map_foo", "{\"bar\":123, \"name\":\"thinkerou\", \"pai\": 3.14}"))
-	req, err := http.NewRequest("POST", "/?map_foo=getfoo", body)
+	req, err := http.NewRequest(http.MethodPost, "/?map_foo=getfoo", body)
 	require.NoError(t, err)
 	req.Header.Set("Content-Type", MIMEMultipartPOSTForm+"; boundary="+boundary)
 	return req
@@ -609,7 +609,7 @@ func createFormMultipartRequestForMapFail(t *testing.T) *http.Request {
 
 	require.NoError(t, mw.SetBoundary(boundary))
 	require.NoError(t, mw.WriteField("map_foo", "3.14"))
-	req, err := http.NewRequest("POST", "/?map_foo=getfoo", body)
+	req, err := http.NewRequest(http.MethodPost, "/?map_foo=getfoo", body)
 	require.NoError(t, err)
 	req.Header.Set("Content-Type", MIMEMultipartPOSTForm+"; boundary="+boundary)
 	return req
@@ -731,7 +731,7 @@ func TestBindingProtoBufFail(t *testing.T) {
 
 func TestValidationFails(t *testing.T) {
 	var obj FooStruct
-	req := requestWithBody("POST", "/", `{"bar": "foo"}`)
+	req := requestWithBody(http.MethodPost, "/", `{"bar": "foo"}`)
 	err := JSON.Bind(req, &obj)
 	require.Error(t, err)
 }
@@ -742,7 +742,7 @@ func TestValidationDisabled(t *testing.T) {
 	defer func() { Validator = backup }()
 
 	var obj FooStruct
-	req := requestWithBody("POST", "/", `{"bar": "foo"}`)
+	req := requestWithBody(http.MethodPost, "/", `{"bar": "foo"}`)
 	err := JSON.Bind(req, &obj)
 	require.NoError(t, err)
 }
@@ -753,7 +753,7 @@ func TestRequiredSucceeds(t *testing.T) {
 	}
 
 	var obj HogeStruct
-	req := requestWithBody("POST", "/", `{"hoge": 0}`)
+	req := requestWithBody(http.MethodPost, "/", `{"hoge": 0}`)
 	err := JSON.Bind(req, &obj)
 	require.NoError(t, err)
 }
@@ -764,7 +764,7 @@ func TestRequiredFails(t *testing.T) {
 	}
 
 	var obj HogeStruct
-	req := requestWithBody("POST", "/", `{"boen": 0}`)
+	req := requestWithBody(http.MethodPost, "/", `{"boen": 0}`)
 	err := JSON.Bind(req, &obj)
 	require.Error(t, err)
 }
@@ -778,12 +778,12 @@ func TestHeaderBinding(t *testing.T) {
 	}
 
 	var theader tHeader
-	req := requestWithBody("GET", "/", "")
+	req := requestWithBody(http.MethodGet, "/", "")
 	req.Header.Add("limit", "1000")
 	require.NoError(t, h.Bind(req, &theader))
 	assert.Equal(t, 1000, theader.Limit)
 
-	req = requestWithBody("GET", "/", "")
+	req = requestWithBody(http.MethodGet, "/", "")
 	req.Header.Add("fail", `{fail:fail}`)
 
 	type failStruct struct {
@@ -843,7 +843,7 @@ func testFormBindingEmbeddedStruct(t *testing.T, method, path, badPath, body, ba
 
 	obj := QueryTest{}
 	req := requestWithBody(method, path, body)
-	if method == "POST" {
+	if method == http.MethodPost {
 		req.Header.Add("Content-Type", MIMEPOSTForm)
 	}
 	err := b.Bind(req, &obj)
@@ -859,7 +859,7 @@ func testFormBinding(t *testing.T, method, path, badPath, body, badBody string)
 
 	obj := FooBarStruct{}
 	req := requestWithBody(method, path, body)
-	if method == "POST" {
+	if method == http.MethodPost {
 		req.Header.Add("Content-Type", MIMEPOSTForm)
 	}
 	err := b.Bind(req, &obj)
@@ -879,7 +879,7 @@ func testFormBindingDefaultValue(t *testing.T, method, path, badPath, body, badB
 
 	obj := FooDefaultBarStruct{}
 	req := requestWithBody(method, path, body)
-	if method == "POST" {
+	if method == http.MethodPost {
 		req.Header.Add("Content-Type", MIMEPOSTForm)
 	}
 	err := b.Bind(req, &obj)
@@ -898,14 +898,14 @@ func TestFormBindingFail(t *testing.T) {
 	assert.Equal(t, "form", b.Name())
 
 	obj := FooBarStruct{}
-	req, _ := http.NewRequest("POST", "/", nil)
+	req, _ := http.NewRequest(http.MethodPost, "/", nil)
 	err := b.Bind(req, &obj)
 	require.Error(t, err)
 }
 
 func TestFormBindingMultipartFail(t *testing.T) {
 	obj := FooBarStruct{}
-	req, err := http.NewRequest("POST", "/", strings.NewReader("foo=bar"))
+	req, err := http.NewRequest(http.MethodPost, "/", strings.NewReader("foo=bar"))
 	require.NoError(t, err)
 	req.Header.Set("Content-Type", MIMEMultipartPOSTForm+";boundary=testboundary")
 	_, err = req.MultipartReader()
@@ -919,7 +919,7 @@ func TestFormPostBindingFail(t *testing.T) {
 	assert.Equal(t, "form-urlencoded", b.Name())
 
 	obj := FooBarStruct{}
-	req, _ := http.NewRequest("POST", "/", nil)
+	req, _ := http.NewRequest(http.MethodPost, "/", nil)
 	err := b.Bind(req, &obj)
 	require.Error(t, err)
 }
@@ -929,7 +929,7 @@ func TestFormMultipartBindingFail(t *testing.T) {
 	assert.Equal(t, "multipart/form-data", b.Name())
 
 	obj := FooBarStruct{}
-	req, _ := http.NewRequest("POST", "/", nil)
+	req, _ := http.NewRequest(http.MethodPost, "/", nil)
 	err := b.Bind(req, &obj)
 	require.Error(t, err)
 }
@@ -940,7 +940,7 @@ func testFormBindingForTime(t *testing.T, method, path, badPath, body, badBody s
 
 	obj := FooBarStructForTimeType{}
 	req := requestWithBody(method, path, body)
-	if method == "POST" {
+	if method == http.MethodPost {
 		req.Header.Add("Content-Type", MIMEPOSTForm)
 	}
 	err := b.Bind(req, &obj)
@@ -965,7 +965,7 @@ func testFormBindingForTimeNotUnixFormat(t *testing.T, method, path, badPath, bo
 
 	obj := FooStructForTimeTypeNotUnixFormat{}
 	req := requestWithBody(method, path, body)
-	if method == "POST" {
+	if method == http.MethodPost {
 		req.Header.Add("Content-Type", MIMEPOSTForm)
 	}
 	err := b.Bind(req, &obj)
@@ -983,7 +983,7 @@ func testFormBindingForTimeNotFormat(t *testing.T, method, path, badPath, body,
 
 	obj := FooStructForTimeTypeNotFormat{}
 	req := requestWithBody(method, path, body)
-	if method == "POST" {
+	if method == http.MethodPost {
 		req.Header.Add("Content-Type", MIMEPOSTForm)
 	}
 	err := b.Bind(req, &obj)
@@ -1001,7 +1001,7 @@ func testFormBindingForTimeFailFormat(t *testing.T, method, path, badPath, body,
 
 	obj := FooStructForTimeTypeFailFormat{}
 	req := requestWithBody(method, path, body)
-	if method == "POST" {
+	if method == http.MethodPost {
 		req.Header.Add("Content-Type", MIMEPOSTForm)
 	}
 	err := b.Bind(req, &obj)
@@ -1019,7 +1019,7 @@ func testFormBindingForTimeFailLocation(t *testing.T, method, path, badPath, bod
 
 	obj := FooStructForTimeTypeFailLocation{}
 	req := requestWithBody(method, path, body)
-	if method == "POST" {
+	if method == http.MethodPost {
 		req.Header.Add("Content-Type", MIMEPOSTForm)
 	}
 	err := b.Bind(req, &obj)
@@ -1037,7 +1037,7 @@ func testFormBindingIgnoreField(t *testing.T, method, path, badPath, body, badBo
 
 	obj := FooStructForIgnoreFormTag{}
 	req := requestWithBody(method, path, body)
-	if method == "POST" {
+	if method == http.MethodPost {
 		req.Header.Add("Content-Type", MIMEPOSTForm)
 	}
 	err := b.Bind(req, &obj)
@@ -1052,7 +1052,7 @@ func testFormBindingInvalidName(t *testing.T, method, path, badPath, body, badBo
 
 	obj := InvalidNameType{}
 	req := requestWithBody(method, path, body)
-	if method == "POST" {
+	if method == http.MethodPost {
 		req.Header.Add("Content-Type", MIMEPOSTForm)
 	}
 	err := b.Bind(req, &obj)
@@ -1071,7 +1071,7 @@ func testFormBindingInvalidName2(t *testing.T, method, path, badPath, body, badB
 
 	obj := InvalidNameMapType{}
 	req := requestWithBody(method, path, body)
-	if method == "POST" {
+	if method == http.MethodPost {
 		req.Header.Add("Content-Type", MIMEPOSTForm)
 	}
 	err := b.Bind(req, &obj)
@@ -1088,7 +1088,7 @@ func testFormBindingForType(t *testing.T, method, path, badPath, body, badBody s
 	assert.Equal(t, "form", b.Name())
 
 	req := requestWithBody(method, path, body)
-	if method == "POST" {
+	if method == http.MethodPost {
 		req.Header.Add("Content-Type", MIMEPOSTForm)
 	}
 	switch typ {
@@ -1159,7 +1159,7 @@ func testQueryBinding(t *testing.T, method, path, badPath, body, badBody string)
 
 	obj := FooBarStruct{}
 	req := requestWithBody(method, path, body)
-	if method == "POST" {
+	if method == http.MethodPost {
 		req.Header.Add("Content-Type", MIMEPOSTForm)
 	}
 	err := b.Bind(req, &obj)
@@ -1174,7 +1174,7 @@ func testQueryBindingFail(t *testing.T, method, path, badPath, body, badBody str
 
 	obj := FooStructForMapType{}
 	req := requestWithBody(method, path, body)
-	if method == "POST" {
+	if method == http.MethodPost {
 		req.Header.Add("Content-Type", MIMEPOSTForm)
 	}
 	err := b.Bind(req, &obj)
@@ -1187,7 +1187,7 @@ func testQueryBindingBoolFail(t *testing.T, method, path, badPath, body, badBody
 
 	obj := FooStructForBoolType{}
 	req := requestWithBody(method, path, body)
-	if method == "POST" {
+	if method == http.MethodPost {
 		req.Header.Add("Content-Type", MIMEPOSTForm)
 	}
 	err := b.Bind(req, &obj)
@@ -1198,13 +1198,13 @@ func testBodyBinding(t *testing.T, b Binding, name, path, badPath, body, badBody
 	assert.Equal(t, name, b.Name())
 
 	obj := FooStruct{}
-	req := requestWithBody("POST", path, body)
+	req := requestWithBody(http.MethodPost, path, body)
 	err := b.Bind(req, &obj)
 	require.NoError(t, err)
 	assert.Equal(t, "bar", obj.Foo)
 
 	obj = FooStruct{}
-	req = requestWithBody("POST", badPath, badBody)
+	req = requestWithBody(http.MethodPost, badPath, badBody)
 	err = JSON.Bind(req, &obj)
 	require.Error(t, err)
 }
@@ -1213,19 +1213,19 @@ func testBodyBindingSlice(t *testing.T, b Binding, name, path, badPath, body, ba
 	assert.Equal(t, name, b.Name())
 
 	var obj1 []FooStruct
-	req := requestWithBody("POST", path, body)
+	req := requestWithBody(http.MethodPost, path, body)
 	err := b.Bind(req, &obj1)
 	require.NoError(t, err)
 
 	var obj2 []FooStruct
-	req = requestWithBody("POST", badPath, badBody)
+	req = requestWithBody(http.MethodPost, badPath, badBody)
 	err = JSON.Bind(req, &obj2)
 	require.Error(t, err)
 }
 
 func testBodyBindingStringMap(t *testing.T, b Binding, path, badPath, body, badBody string) {
 	obj := make(map[string]string)
-	req := requestWithBody("POST", path, body)
+	req := requestWithBody(http.MethodPost, path, body)
 	if b.Name() == "form" {
 		req.Header.Add("Content-Type", MIMEPOSTForm)
 	}
@@ -1238,13 +1238,13 @@ func testBodyBindingStringMap(t *testing.T, b Binding, path, badPath, body, badB
 
 	if badPath != "" && badBody != "" {
 		obj = make(map[string]string)
-		req = requestWithBody("POST", badPath, badBody)
+		req = requestWithBody(http.MethodPost, badPath, badBody)
 		err = b.Bind(req, &obj)
 		require.Error(t, err)
 	}
 
 	objInt := make(map[string]int)
-	req = requestWithBody("POST", path, body)
+	req = requestWithBody(http.MethodPost, path, body)
 	err = b.Bind(req, &objInt)
 	require.Error(t, err)
 }
@@ -1253,7 +1253,7 @@ func testBodyBindingUseNumber(t *testing.T, b Binding, name, path, badPath, body
 	assert.Equal(t, name, b.Name())
 
 	obj := FooStructUseNumber{}
-	req := requestWithBody("POST", path, body)
+	req := requestWithBody(http.MethodPost, path, body)
 	EnableDecoderUseNumber = true
 	err := b.Bind(req, &obj)
 	require.NoError(t, err)
@@ -1263,7 +1263,7 @@ func testBodyBindingUseNumber(t *testing.T, b Binding, name, path, badPath, body
 	assert.Equal(t, int64(123), v)
 
 	obj = FooStructUseNumber{}
-	req = requestWithBody("POST", badPath, badBody)
+	req = requestWithBody(http.MethodPost, badPath, badBody)
 	err = JSON.Bind(req, &obj)
 	require.Error(t, err)
 }
@@ -1272,7 +1272,7 @@ func testBodyBindingUseNumber2(t *testing.T, b Binding, name, path, badPath, bod
 	assert.Equal(t, name, b.Name())
 
 	obj := FooStructUseNumber{}
-	req := requestWithBody("POST", path, body)
+	req := requestWithBody(http.MethodPost, path, body)
 	EnableDecoderUseNumber = false
 	err := b.Bind(req, &obj)
 	require.NoError(t, err)
@@ -1281,7 +1281,7 @@ func testBodyBindingUseNumber2(t *testing.T, b Binding, name, path, badPath, bod
 	assert.InDelta(t, float64(123), obj.Foo, 0.01)
 
 	obj = FooStructUseNumber{}
-	req = requestWithBody("POST", badPath, badBody)
+	req = requestWithBody(http.MethodPost, badPath, badBody)
 	err = JSON.Bind(req, &obj)
 	require.Error(t, err)
 }
@@ -1293,13 +1293,13 @@ func testBodyBindingDisallowUnknownFields(t *testing.T, b Binding, path, badPath
 	}()
 
 	obj := FooStructDisallowUnknownFields{}
-	req := requestWithBody("POST", path, body)
+	req := requestWithBody(http.MethodPost, path, body)
 	err := b.Bind(req, &obj)
 	require.NoError(t, err)
 	assert.Equal(t, "bar", obj.Foo)
 
 	obj = FooStructDisallowUnknownFields{}
-	req = requestWithBody("POST", badPath, badBody)
+	req = requestWithBody(http.MethodPost, badPath, badBody)
 	err = JSON.Bind(req, &obj)
 	require.Error(t, err)
 	assert.Contains(t, err.Error(), "what")
@@ -1309,13 +1309,13 @@ func testBodyBindingFail(t *testing.T, b Binding, name, path, badPath, body, bad
 	assert.Equal(t, name, b.Name())
 
 	obj := FooStruct{}
-	req := requestWithBody("POST", path, body)
+	req := requestWithBody(http.MethodPost, path, body)
 	err := b.Bind(req, &obj)
 	require.Error(t, err)
 	assert.Equal(t, "", obj.Foo)
 
 	obj = FooStruct{}
-	req = requestWithBody("POST", badPath, badBody)
+	req = requestWithBody(http.MethodPost, badPath, badBody)
 	err = JSON.Bind(req, &obj)
 	require.Error(t, err)
 }
@@ -1324,14 +1324,14 @@ func testProtoBodyBinding(t *testing.T, b Binding, name, path, badPath, body, ba
 	assert.Equal(t, name, b.Name())
 
 	obj := protoexample.Test{}
-	req := requestWithBody("POST", path, body)
+	req := requestWithBody(http.MethodPost, path, body)
 	req.Header.Add("Content-Type", MIMEPROTOBUF)
 	err := b.Bind(req, &obj)
 	require.NoError(t, err)
 	assert.Equal(t, "yes", *obj.Label)
 
 	obj = protoexample.Test{}
-	req = requestWithBody("POST", badPath, badBody)
+	req = requestWithBody(http.MethodPost, badPath, badBody)
 	req.Header.Add("Content-Type", MIMEPROTOBUF)
 	err = ProtoBuf.Bind(req, &obj)
 	require.Error(t, err)
@@ -1358,28 +1358,28 @@ func TestPlainBinding(t *testing.T) {
 	assert.Equal(t, "plain", p.Name())
 
 	var s string
-	req := requestWithBody("POST", "/", "test string")
+	req := requestWithBody(http.MethodPost, "/", "test string")
 	require.NoError(t, p.Bind(req, &s))
 	assert.Equal(t, "test string", s)
 
 	var bs []byte
-	req = requestWithBody("POST", "/", "test []byte")
+	req = requestWithBody(http.MethodPost, "/", "test []byte")
 	require.NoError(t, p.Bind(req, &bs))
 	assert.Equal(t, bs, []byte("test []byte"))
 
 	var i int
-	req = requestWithBody("POST", "/", "test fail")
+	req = requestWithBody(http.MethodPost, "/", "test fail")
 	require.Error(t, p.Bind(req, &i))
 
-	req = requestWithBody("POST", "/", "")
+	req = requestWithBody(http.MethodPost, "/", "")
 	req.Body = &failRead{}
 	require.Error(t, p.Bind(req, &s))
 
-	req = requestWithBody("POST", "/", "")
+	req = requestWithBody(http.MethodPost, "/", "")
 	require.NoError(t, p.Bind(req, nil))
 
 	var ptr *string
-	req = requestWithBody("POST", "/", "")
+	req = requestWithBody(http.MethodPost, "/", "")
 	require.NoError(t, p.Bind(req, ptr))
 }
 
@@ -1387,7 +1387,7 @@ func testProtoBodyBindingFail(t *testing.T, b Binding, name, path, badPath, body
 	assert.Equal(t, name, b.Name())
 
 	obj := protoexample.Test{}
-	req := requestWithBody("POST", path, body)
+	req := requestWithBody(http.MethodPost, path, body)
 
 	req.Body = io.NopCloser(&hook{})
 	req.Header.Add("Content-Type", MIMEPROTOBUF)
@@ -1402,7 +1402,7 @@ func testProtoBodyBindingFail(t *testing.T, b Binding, name, path, badPath, body
 	assert.Equal(t, "obj is not ProtoMessage", err.Error())
 
 	obj = protoexample.Test{}
-	req = requestWithBody("POST", badPath, badBody)
+	req = requestWithBody(http.MethodPost, badPath, badBody)
 	req.Header.Add("Content-Type", MIMEPROTOBUF)
 	err = ProtoBuf.Bind(req, &obj)
 	require.Error(t, err)
diff --git a/binding/form_mapping_test.go b/binding/form_mapping_test.go
index 810315b..1277fd5 100644
--- a/binding/form_mapping_test.go
+++ b/binding/form_mapping_test.go
@@ -6,7 +6,7 @@ package binding
 
 import (
 	"encoding/hex"
-	"fmt"
+	"errors"
 	"mime/multipart"
 	"reflect"
 	"strconv"
@@ -494,7 +494,7 @@ type customUnmarshalParamType struct {
 func (f *customUnmarshalParamType) UnmarshalParam(param string) error {
 	parts := strings.Split(param, ":")
 	if len(parts) != 3 {
-		return fmt.Errorf("invalid format")
+		return errors.New("invalid format")
 	}
 	f.Protocol = parts[0]
 	f.Path = parts[1]
@@ -556,7 +556,7 @@ func (p *customPath) UnmarshalParam(param string) error {
 	elems := strings.Split(param, "/")
 	n := len(elems)
 	if n < 2 {
-		return fmt.Errorf("invalid format")
+		return errors.New("invalid format")
 	}
 
 	*p = elems
@@ -600,7 +600,7 @@ func (o *objectID) UnmarshalParam(param string) error {
 func convertTo(s string) (objectID, error) {
 	var nilObjectID objectID
 	if len(s) != 24 {
-		return nilObjectID, fmt.Errorf("invalid format")
+		return nilObjectID, errors.New("invalid format")
 	}
 
 	var oid [12]byte
diff --git a/binding/multipart_form_mapping_test.go b/binding/multipart_form_mapping_test.go
index 9782b81..c93f214 100644
--- a/binding/multipart_form_mapping_test.go
+++ b/binding/multipart_form_mapping_test.go
@@ -116,7 +116,7 @@ func createRequestMultipartFiles(t *testing.T, files ...testFile) *http.Request
 	err := mw.Close()
 	require.NoError(t, err)
 
-	req, err := http.NewRequest("POST", "/", &body)
+	req, err := http.NewRequest(http.MethodPost, "/", &body)
 	require.NoError(t, err)
 
 	req.Header.Set("Content-Type", MIMEMultipartPOSTForm+"; boundary="+mw.Boundary())
diff --git a/context_test.go b/context_test.go
index 62a1e14..5b63a64 100644
--- a/context_test.go
+++ b/context_test.go
@@ -11,13 +11,16 @@ import (
 	"fmt"
 	"html/template"
 	"io"
+	"io/fs"
 	"mime/multipart"
 	"net"
 	"net/http"
 	"net/http/httptest"
 	"net/url"
 	"os"
+	"path/filepath"
 	"reflect"
+	"strconv"
 	"strings"
 	"sync"
 	"testing"
@@ -59,7 +62,7 @@ func createMultipartRequest() *http.Request {
 	must(mw.WriteField("time_location", "31/12/2016 14:55"))
 	must(mw.WriteField("names[a]", "thinkerou"))
 	must(mw.WriteField("names[b]", "tianou"))
-	req, err := http.NewRequest("POST", "/", body)
+	req, err := http.NewRequest(http.MethodPost, "/", body)
 	must(err)
 	req.Header.Set("Content-Type", MIMEMultipartPOSTForm+"; boundary="+boundary)
 	return req
@@ -80,7 +83,7 @@ func TestContextFormFile(t *testing.T) {
 	require.NoError(t, err)
 	mw.Close()
 	c, _ := CreateTestContext(httptest.NewRecorder())
-	c.Request, _ = http.NewRequest("POST", "/", buf)
+	c.Request, _ = http.NewRequest(http.MethodPost, "/", buf)
 	c.Request.Header.Set("Content-Type", mw.FormDataContentType())
 	f, err := c.FormFile("file")
 	require.NoError(t, err)
@@ -94,7 +97,7 @@ func TestContextFormFileFailed(t *testing.T) {
 	mw := multipart.NewWriter(buf)
 	mw.Close()
 	c, _ := CreateTestContext(httptest.NewRecorder())
-	c.Request, _ = http.NewRequest("POST", "/", nil)
+	c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
 	c.Request.Header.Set("Content-Type", mw.FormDataContentType())
 	c.engine.MaxMultipartMemory = 8 << 20
 	f, err := c.FormFile("file")
@@ -112,7 +115,7 @@ func TestContextMultipartForm(t *testing.T) {
 	require.NoError(t, err)
 	mw.Close()
 	c, _ := CreateTestContext(httptest.NewRecorder())
-	c.Request, _ = http.NewRequest("POST", "/", buf)
+	c.Request, _ = http.NewRequest(http.MethodPost, "/", buf)
 	c.Request.Header.Set("Content-Type", mw.FormDataContentType())
 	f, err := c.MultipartForm()
 	require.NoError(t, err)
@@ -127,7 +130,7 @@ func TestSaveUploadedOpenFailed(t *testing.T) {
 	mw.Close()
 
 	c, _ := CreateTestContext(httptest.NewRecorder())
-	c.Request, _ = http.NewRequest("POST", "/", buf)
+	c.Request, _ = http.NewRequest(http.MethodPost, "/", buf)
 	c.Request.Header.Set("Content-Type", mw.FormDataContentType())
 
 	f := &multipart.FileHeader{
@@ -145,7 +148,7 @@ func TestSaveUploadedCreateFailed(t *testing.T) {
 	require.NoError(t, err)
 	mw.Close()
 	c, _ := CreateTestContext(httptest.NewRecorder())
-	c.Request, _ = http.NewRequest("POST", "/", buf)
+	c.Request, _ = http.NewRequest(http.MethodPost, "/", buf)
 	c.Request.Header.Set("Content-Type", mw.FormDataContentType())
 	f, err := c.FormFile("file")
 	require.NoError(t, err)
@@ -154,6 +157,45 @@ func TestSaveUploadedCreateFailed(t *testing.T) {
 	require.Error(t, c.SaveUploadedFile(f, "/"))
 }
 
+func TestSaveUploadedFileWithPermission(t *testing.T) {
+	buf := new(bytes.Buffer)
+	mw := multipart.NewWriter(buf)
+	w, err := mw.CreateFormFile("file", "permission_test")
+	require.NoError(t, err)
+	_, err = w.Write([]byte("permission_test"))
+	require.NoError(t, err)
+	mw.Close()
+	c, _ := CreateTestContext(httptest.NewRecorder())
+	c.Request, _ = http.NewRequest("POST", "/", buf)
+	c.Request.Header.Set("Content-Type", mw.FormDataContentType())
+	f, err := c.FormFile("file")
+	require.NoError(t, err)
+	assert.Equal(t, "permission_test", f.Filename)
+	var mode fs.FileMode = 0o755
+	require.NoError(t, c.SaveUploadedFile(f, "permission_test", mode))
+	info, err := os.Stat(filepath.Dir("permission_test"))
+	require.NoError(t, err)
+	assert.Equal(t, info.Mode().Perm(), mode)
+}
+
+func TestSaveUploadedFileWithPermissionFailed(t *testing.T) {
+	buf := new(bytes.Buffer)
+	mw := multipart.NewWriter(buf)
+	w, err := mw.CreateFormFile("file", "permission_test")
+	require.NoError(t, err)
+	_, err = w.Write([]byte("permission_test"))
+	require.NoError(t, err)
+	mw.Close()
+	c, _ := CreateTestContext(httptest.NewRecorder())
+	c.Request, _ = http.NewRequest("POST", "/", buf)
+	c.Request.Header.Set("Content-Type", mw.FormDataContentType())
+	f, err := c.FormFile("file")
+	require.NoError(t, err)
+	assert.Equal(t, "permission_test", f.Filename)
+	var mode fs.FileMode = 0o644
+	require.Error(t, c.SaveUploadedFile(f, "test/permission_test", mode))
+}
+
 func TestContextReset(t *testing.T) {
 	router := New()
 	c := router.allocateContext(0)
@@ -480,7 +522,7 @@ func TestContextGetStringMapStringSlice(t *testing.T) {
 func TestContextCopy(t *testing.T) {
 	c, _ := CreateTestContext(httptest.NewRecorder())
 	c.index = 2
-	c.Request, _ = http.NewRequest("POST", "/hola", nil)
+	c.Request, _ = http.NewRequest(http.MethodPost, "/hola", nil)
 	c.handlers = HandlersChain{func(c *Context) {}}
 	c.Params = Params{Param{Key: "foo", Value: "bar"}}
 	c.Set("foo", "bar")
@@ -537,7 +579,7 @@ func TestContextHandler(t *testing.T) {
 
 func TestContextQuery(t *testing.T) {
 	c, _ := CreateTestContext(httptest.NewRecorder())
-	c.Request, _ = http.NewRequest("GET", "http://example.com/?foo=bar&page=10&id=", nil)
+	c.Request, _ = http.NewRequest(http.MethodGet, "http://example.com/?foo=bar&page=10&id=", nil)
 
 	value, ok := c.GetQuery("foo")
 	assert.True(t, ok)
@@ -610,7 +652,6 @@ func TestContextInitQueryCache(t *testing.T) {
 			assert.Equal(t, test.expectedQueryCache, test.testContext.queryCache)
 		})
 	}
-
 }
 
 func TestContextDefaultQueryOnEmptyRequest(t *testing.T) {
@@ -631,7 +672,7 @@ func TestContextDefaultQueryOnEmptyRequest(t *testing.T) {
 func TestContextQueryAndPostForm(t *testing.T) {
 	c, _ := CreateTestContext(httptest.NewRecorder())
 	body := bytes.NewBufferString("foo=bar&page=11&both=&foo=second")
-	c.Request, _ = http.NewRequest("POST",
+	c.Request, _ = http.NewRequest(http.MethodPost,
 		"/?both=GET&id=main&id=omit&array[]=first&array[]=second&ids[a]=hi&ids[b]=3.14", body)
 	c.Request.Header.Add("Content-Type", MIMEPOSTForm)
 
@@ -651,7 +692,7 @@ func TestContextQueryAndPostForm(t *testing.T) {
 	assert.Empty(t, value)
 	assert.Empty(t, c.PostForm("both"))
 	assert.Empty(t, c.DefaultPostForm("both", "nothing"))
-	assert.Equal(t, "GET", c.Query("both"), "GET")
+	assert.Equal(t, http.MethodGet, c.Query("both"), http.MethodGet)
 
 	value, ok = c.GetQuery("id")
 	assert.True(t, ok)
@@ -699,7 +740,7 @@ func TestContextQueryAndPostForm(t *testing.T) {
 
 	values = c.QueryArray("both")
 	assert.Len(t, values, 1)
-	assert.Equal(t, "GET", values[0])
+	assert.Equal(t, http.MethodGet, values[0])
 
 	dicts, ok := c.GetQueryMap("ids")
 	assert.True(t, ok)
@@ -834,7 +875,7 @@ func TestContextSetCookiePathEmpty(t *testing.T) {
 
 func TestContextGetCookie(t *testing.T) {
 	c, _ := CreateTestContext(httptest.NewRecorder())
-	c.Request, _ = http.NewRequest("GET", "/get", nil)
+	c.Request, _ = http.NewRequest(http.MethodGet, "/get", nil)
 	c.Request.Header.Set("Cookie", "user=gin")
 	cookie, _ := c.Cookie("user")
 	assert.Equal(t, "gin", cookie)
@@ -886,7 +927,7 @@ func TestContextRenderJSON(t *testing.T) {
 func TestContextRenderJSONP(t *testing.T) {
 	w := httptest.NewRecorder()
 	c, _ := CreateTestContext(w)
-	c.Request, _ = http.NewRequest("GET", "http://example.com/?callback=x", nil)
+	c.Request, _ = http.NewRequest(http.MethodGet, "http://example.com/?callback=x", nil)
 
 	c.JSONP(http.StatusCreated, H{"foo": "bar"})
 
@@ -900,7 +941,7 @@ func TestContextRenderJSONP(t *testing.T) {
 func TestContextRenderJSONPWithoutCallback(t *testing.T) {
 	w := httptest.NewRecorder()
 	c, _ := CreateTestContext(w)
-	c.Request, _ = http.NewRequest("GET", "http://example.com", nil)
+	c.Request, _ = http.NewRequest(http.MethodGet, "http://example.com", nil)
 
 	c.JSONP(http.StatusCreated, H{"foo": "bar"})
 
@@ -1043,7 +1084,7 @@ func TestContextRenderHTML2(t *testing.T) {
 	c, router := CreateTestContext(w)
 
 	// print debug warning log when Engine.trees > 0
-	router.addRoute("GET", "/", HandlersChain{func(_ *Context) {}})
+	router.addRoute(http.MethodGet, "/", HandlersChain{func(_ *Context) {}})
 	assert.Len(t, router.trees, 1)
 
 	templ := template.Must(template.New("t").Parse(`Hello {{.name}}`))
@@ -1199,7 +1240,7 @@ func TestContextRenderFile(t *testing.T) {
 	w := httptest.NewRecorder()
 	c, _ := CreateTestContext(w)
 
-	c.Request, _ = http.NewRequest("GET", "/", nil)
+	c.Request, _ = http.NewRequest(http.MethodGet, "/", nil)
 	c.File("./gin.go")
 
 	assert.Equal(t, http.StatusOK, w.Code)
@@ -1213,7 +1254,7 @@ func TestContextRenderFileFromFS(t *testing.T) {
 	w := httptest.NewRecorder()
 	c, _ := CreateTestContext(w)
 
-	c.Request, _ = http.NewRequest("GET", "/some/path", nil)
+	c.Request, _ = http.NewRequest(http.MethodGet, "/some/path", nil)
 	c.FileFromFS("./gin.go", Dir(".", false))
 
 	assert.Equal(t, http.StatusOK, w.Code)
@@ -1229,7 +1270,7 @@ func TestContextRenderAttachment(t *testing.T) {
 	c, _ := CreateTestContext(w)
 	newFilename := "new_filename.go"
 
-	c.Request, _ = http.NewRequest("GET", "/", nil)
+	c.Request, _ = http.NewRequest(http.MethodGet, "/", nil)
 	c.FileAttachment("./gin.go", newFilename)
 
 	assert.Equal(t, 200, w.Code)
@@ -1243,7 +1284,7 @@ func TestContextRenderAndEscapeAttachment(t *testing.T) {
 	maliciousFilename := "tampering_field.sh\"; \\\"; dummy=.go"
 	actualEscapedResponseFilename := "tampering_field.sh\\\"; \\\\\\\"; dummy=.go"
 
-	c.Request, _ = http.NewRequest("GET", "/", nil)
+	c.Request, _ = http.NewRequest(http.MethodGet, "/", nil)
 	c.FileAttachment("./gin.go", maliciousFilename)
 
 	assert.Equal(t, 200, w.Code)
@@ -1256,7 +1297,7 @@ func TestContextRenderUTF8Attachment(t *testing.T) {
 	c, _ := CreateTestContext(w)
 	newFilename := "new🧡_filename.go"
 
-	c.Request, _ = http.NewRequest("GET", "/", nil)
+	c.Request, _ = http.NewRequest(http.MethodGet, "/", nil)
 	c.FileAttachment("./gin.go", newFilename)
 
 	assert.Equal(t, 200, w.Code)
@@ -1335,7 +1376,7 @@ func TestContextRenderRedirectWithRelativePath(t *testing.T) {
 	w := httptest.NewRecorder()
 	c, _ := CreateTestContext(w)
 
-	c.Request, _ = http.NewRequest("POST", "http://example.com", nil)
+	c.Request, _ = http.NewRequest(http.MethodPost, "http://example.com", nil)
 	assert.Panics(t, func() { c.Redirect(299, "/new_path") })
 	assert.Panics(t, func() { c.Redirect(309, "/new_path") })
 
@@ -1349,7 +1390,7 @@ func TestContextRenderRedirectWithAbsolutePath(t *testing.T) {
 	w := httptest.NewRecorder()
 	c, _ := CreateTestContext(w)
 
-	c.Request, _ = http.NewRequest("POST", "http://example.com", nil)
+	c.Request, _ = http.NewRequest(http.MethodPost, "http://example.com", nil)
 	c.Redirect(http.StatusFound, "http://google.com")
 	c.Writer.WriteHeaderNow()
 
@@ -1361,7 +1402,7 @@ func TestContextRenderRedirectWith201(t *testing.T) {
 	w := httptest.NewRecorder()
 	c, _ := CreateTestContext(w)
 
-	c.Request, _ = http.NewRequest("POST", "http://example.com", nil)
+	c.Request, _ = http.NewRequest(http.MethodPost, "http://example.com", nil)
 	c.Redirect(http.StatusCreated, "/resource")
 	c.Writer.WriteHeaderNow()
 
@@ -1371,7 +1412,7 @@ func TestContextRenderRedirectWith201(t *testing.T) {
 
 func TestContextRenderRedirectAll(t *testing.T) {
 	c, _ := CreateTestContext(httptest.NewRecorder())
-	c.Request, _ = http.NewRequest("POST", "http://example.com", nil)
+	c.Request, _ = http.NewRequest(http.MethodPost, "http://example.com", nil)
 	assert.Panics(t, func() { c.Redirect(http.StatusOK, "/resource") })
 	assert.Panics(t, func() { c.Redirect(http.StatusAccepted, "/resource") })
 	assert.Panics(t, func() { c.Redirect(299, "/resource") })
@@ -1383,7 +1424,7 @@ func TestContextRenderRedirectAll(t *testing.T) {
 func TestContextNegotiationWithJSON(t *testing.T) {
 	w := httptest.NewRecorder()
 	c, _ := CreateTestContext(w)
-	c.Request, _ = http.NewRequest("POST", "", nil)
+	c.Request, _ = http.NewRequest(http.MethodPost, "", nil)
 
 	c.Negotiate(http.StatusOK, Negotiate{
 		Offered: []string{MIMEJSON, MIMEXML, MIMEYAML, MIMEYAML2},
@@ -1398,7 +1439,7 @@ func TestContextNegotiationWithJSON(t *testing.T) {
 func TestContextNegotiationWithXML(t *testing.T) {
 	w := httptest.NewRecorder()
 	c, _ := CreateTestContext(w)
-	c.Request, _ = http.NewRequest("POST", "", nil)
+	c.Request, _ = http.NewRequest(http.MethodPost, "", nil)
 
 	c.Negotiate(http.StatusOK, Negotiate{
 		Offered: []string{MIMEXML, MIMEJSON, MIMEYAML, MIMEYAML2},
@@ -1413,7 +1454,7 @@ func TestContextNegotiationWithXML(t *testing.T) {
 func TestContextNegotiationWithYAML(t *testing.T) {
 	w := httptest.NewRecorder()
 	c, _ := CreateTestContext(w)
-	c.Request, _ = http.NewRequest("POST", "", nil)
+	c.Request, _ = http.NewRequest(http.MethodPost, "", nil)
 
 	c.Negotiate(http.StatusOK, Negotiate{
 		Offered: []string{MIMEYAML, MIMEXML, MIMEJSON, MIMETOML, MIMEYAML2},
@@ -1428,7 +1469,7 @@ func TestContextNegotiationWithYAML(t *testing.T) {
 func TestContextNegotiationWithTOML(t *testing.T) {
 	w := httptest.NewRecorder()
 	c, _ := CreateTestContext(w)
-	c.Request, _ = http.NewRequest("POST", "", nil)
+	c.Request, _ = http.NewRequest(http.MethodPost, "", nil)
 
 	c.Negotiate(http.StatusOK, Negotiate{
 		Offered: []string{MIMETOML, MIMEXML, MIMEJSON, MIMEYAML, MIMEYAML2},
@@ -1443,7 +1484,7 @@ func TestContextNegotiationWithTOML(t *testing.T) {
 func TestContextNegotiationWithHTML(t *testing.T) {
 	w := httptest.NewRecorder()
 	c, router := CreateTestContext(w)
-	c.Request, _ = http.NewRequest("POST", "", nil)
+	c.Request, _ = http.NewRequest(http.MethodPost, "", nil)
 	templ := template.Must(template.New("t").Parse(`Hello {{.name}}`))
 	router.SetHTMLTemplate(templ)
 
@@ -1461,7 +1502,7 @@ func TestContextNegotiationWithHTML(t *testing.T) {
 func TestContextNegotiationNotSupport(t *testing.T) {
 	w := httptest.NewRecorder()
 	c, _ := CreateTestContext(w)
-	c.Request, _ = http.NewRequest("POST", "", nil)
+	c.Request, _ = http.NewRequest(http.MethodPost, "", nil)
 
 	c.Negotiate(http.StatusOK, Negotiate{
 		Offered: []string{MIMEPOSTForm},
@@ -1474,7 +1515,7 @@ func TestContextNegotiationNotSupport(t *testing.T) {
 
 func TestContextNegotiationFormat(t *testing.T) {
 	c, _ := CreateTestContext(httptest.NewRecorder())
-	c.Request, _ = http.NewRequest("POST", "", nil)
+	c.Request, _ = http.NewRequest(http.MethodPost, "", nil)
 
 	assert.Panics(t, func() { c.NegotiateFormat() })
 	assert.Equal(t, MIMEJSON, c.NegotiateFormat(MIMEJSON, MIMEXML))
@@ -1483,7 +1524,7 @@ func TestContextNegotiationFormat(t *testing.T) {
 
 func TestContextNegotiationFormatWithAccept(t *testing.T) {
 	c, _ := CreateTestContext(httptest.NewRecorder())
-	c.Request, _ = http.NewRequest("POST", "/", nil)
+	c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
 	c.Request.Header.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8")
 
 	assert.Equal(t, MIMEXML, c.NegotiateFormat(MIMEJSON, MIMEXML))
@@ -1493,7 +1534,7 @@ func TestContextNegotiationFormatWithAccept(t *testing.T) {
 
 func TestContextNegotiationFormatWithWildcardAccept(t *testing.T) {
 	c, _ := CreateTestContext(httptest.NewRecorder())
-	c.Request, _ = http.NewRequest("POST", "/", nil)
+	c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
 	c.Request.Header.Add("Accept", "*/*")
 
 	assert.Equal(t, "*/*", c.NegotiateFormat("*/*"))
@@ -1504,7 +1545,7 @@ func TestContextNegotiationFormatWithWildcardAccept(t *testing.T) {
 	assert.Equal(t, MIMEHTML, c.NegotiateFormat(MIMEHTML))
 
 	c, _ = CreateTestContext(httptest.NewRecorder())
-	c.Request, _ = http.NewRequest("POST", "/", nil)
+	c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
 	c.Request.Header.Add("Accept", "text/*")
 
 	assert.Equal(t, "*/*", c.NegotiateFormat("*/*"))
@@ -1517,7 +1558,7 @@ func TestContextNegotiationFormatWithWildcardAccept(t *testing.T) {
 
 func TestContextNegotiationFormatCustom(t *testing.T) {
 	c, _ := CreateTestContext(httptest.NewRecorder())
-	c.Request, _ = http.NewRequest("POST", "/", nil)
+	c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
 	c.Request.Header.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8")
 
 	c.Accepted = nil
@@ -1530,7 +1571,7 @@ func TestContextNegotiationFormatCustom(t *testing.T) {
 
 func TestContextNegotiationFormat2(t *testing.T) {
 	c, _ := CreateTestContext(httptest.NewRecorder())
-	c.Request, _ = http.NewRequest("POST", "/", nil)
+	c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
 	c.Request.Header.Add("Accept", "image/tiff-fx")
 
 	assert.Equal(t, "", c.NegotiateFormat("image/tiff"))
@@ -1658,7 +1699,7 @@ func TestContextAbortWithError(t *testing.T) {
 
 func TestContextClientIP(t *testing.T) {
 	c, _ := CreateTestContext(httptest.NewRecorder())
-	c.Request, _ = http.NewRequest("POST", "/", nil)
+	c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
 	c.engine.trustedCIDRs, _ = c.engine.prepareTrustedCIDRs()
 	resetContextForClientIPTests(c)
 
@@ -1801,7 +1842,7 @@ func resetContextForClientIPTests(c *Context) {
 
 func TestContextContentType(t *testing.T) {
 	c, _ := CreateTestContext(httptest.NewRecorder())
-	c.Request, _ = http.NewRequest("POST", "/", nil)
+	c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
 	c.Request.Header.Set("Content-Type", "application/json; charset=utf-8")
 
 	assert.Equal(t, "application/json", c.ContentType())
@@ -1809,7 +1850,7 @@ func TestContextContentType(t *testing.T) {
 
 func TestContextAutoBindJSON(t *testing.T) {
 	c, _ := CreateTestContext(httptest.NewRecorder())
-	c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString("{\"foo\":\"bar\", \"bar\":\"foo\"}"))
+	c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString("{\"foo\":\"bar\", \"bar\":\"foo\"}"))
 	c.Request.Header.Add("Content-Type", MIMEJSON)
 
 	var obj struct {
@@ -1826,7 +1867,7 @@ func TestContextBindWithJSON(t *testing.T) {
 	w := httptest.NewRecorder()
 	c, _ := CreateTestContext(w)
 
-	c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString("{\"foo\":\"bar\", \"bar\":\"foo\"}"))
+	c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString("{\"foo\":\"bar\", \"bar\":\"foo\"}"))
 	c.Request.Header.Add("Content-Type", MIMEXML) // set fake content-type
 
 	var obj struct {
@@ -1843,7 +1884,7 @@ func TestContextBindWithXML(t *testing.T) {
 	w := httptest.NewRecorder()
 	c, _ := CreateTestContext(w)
 
-	c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(`<?xml version="1.0" encoding="UTF-8"?>
+	c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString(`<?xml version="1.0" encoding="UTF-8"?>
 		<root>
 			<foo>FOO</foo>
 		   	<bar>BAR</bar>
@@ -1864,7 +1905,7 @@ func TestContextBindPlain(t *testing.T) {
 	// string
 	w := httptest.NewRecorder()
 	c, _ := CreateTestContext(w)
-	c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(`test string`))
+	c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString(`test string`))
 	c.Request.Header.Add("Content-Type", MIMEPlain)
 
 	var s string
@@ -1874,7 +1915,7 @@ func TestContextBindPlain(t *testing.T) {
 	assert.Equal(t, 0, w.Body.Len())
 
 	// []byte
-	c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(`test []byte`))
+	c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString(`test []byte`))
 	c.Request.Header.Add("Content-Type", MIMEPlain)
 
 	var bs []byte
@@ -1888,7 +1929,7 @@ func TestContextBindHeader(t *testing.T) {
 	w := httptest.NewRecorder()
 	c, _ := CreateTestContext(w)
 
-	c.Request, _ = http.NewRequest("POST", "/", nil)
+	c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
 	c.Request.Header.Add("rate", "8000")
 	c.Request.Header.Add("domain", "music")
 	c.Request.Header.Add("limit", "1000")
@@ -1910,7 +1951,7 @@ func TestContextBindWithQuery(t *testing.T) {
 	w := httptest.NewRecorder()
 	c, _ := CreateTestContext(w)
 
-	c.Request, _ = http.NewRequest("POST", "/?foo=bar&bar=foo", bytes.NewBufferString("foo=unused"))
+	c.Request, _ = http.NewRequest(http.MethodPost, "/?foo=bar&bar=foo", bytes.NewBufferString("foo=unused"))
 
 	var obj struct {
 		Foo string `form:"foo"`
@@ -1926,7 +1967,7 @@ func TestContextBindWithYAML(t *testing.T) {
 	w := httptest.NewRecorder()
 	c, _ := CreateTestContext(w)
 
-	c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString("foo: bar\nbar: foo"))
+	c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString("foo: bar\nbar: foo"))
 	c.Request.Header.Add("Content-Type", MIMEXML) // set fake content-type
 
 	var obj struct {
@@ -1943,7 +1984,7 @@ func TestContextBindWithTOML(t *testing.T) {
 	w := httptest.NewRecorder()
 	c, _ := CreateTestContext(w)
 
-	c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString("foo = 'bar'\nbar = 'foo'"))
+	c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString("foo = 'bar'\nbar = 'foo'"))
 	c.Request.Header.Add("Content-Type", MIMEXML) // set fake content-type
 
 	var obj struct {
@@ -1960,7 +2001,7 @@ func TestContextBadAutoBind(t *testing.T) {
 	w := httptest.NewRecorder()
 	c, _ := CreateTestContext(w)
 
-	c.Request, _ = http.NewRequest("POST", "http://example.com", bytes.NewBufferString("\"foo\":\"bar\", \"bar\":\"foo\"}"))
+	c.Request, _ = http.NewRequest(http.MethodPost, "http://example.com", bytes.NewBufferString("\"foo\":\"bar\", \"bar\":\"foo\"}"))
 	c.Request.Header.Add("Content-Type", MIMEJSON)
 	var obj struct {
 		Foo string `json:"foo"`
@@ -1979,7 +2020,7 @@ func TestContextBadAutoBind(t *testing.T) {
 
 func TestContextAutoShouldBindJSON(t *testing.T) {
 	c, _ := CreateTestContext(httptest.NewRecorder())
-	c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString("{\"foo\":\"bar\", \"bar\":\"foo\"}"))
+	c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString("{\"foo\":\"bar\", \"bar\":\"foo\"}"))
 	c.Request.Header.Add("Content-Type", MIMEJSON)
 
 	var obj struct {
@@ -1996,7 +2037,7 @@ func TestContextShouldBindWithJSON(t *testing.T) {
 	w := httptest.NewRecorder()
 	c, _ := CreateTestContext(w)
 
-	c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString("{\"foo\":\"bar\", \"bar\":\"foo\"}"))
+	c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString("{\"foo\":\"bar\", \"bar\":\"foo\"}"))
 	c.Request.Header.Add("Content-Type", MIMEXML) // set fake content-type
 
 	var obj struct {
@@ -2013,7 +2054,7 @@ func TestContextShouldBindWithXML(t *testing.T) {
 	w := httptest.NewRecorder()
 	c, _ := CreateTestContext(w)
 
-	c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(`<?xml version="1.0" encoding="UTF-8"?>
+	c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString(`<?xml version="1.0" encoding="UTF-8"?>
 		<root>
 			<foo>FOO</foo>
 			<bar>BAR</bar>
@@ -2034,7 +2075,7 @@ func TestContextShouldBindPlain(t *testing.T) {
 	// string
 	w := httptest.NewRecorder()
 	c, _ := CreateTestContext(w)
-	c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(`test string`))
+	c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString(`test string`))
 	c.Request.Header.Add("Content-Type", MIMEPlain)
 
 	var s string
@@ -2044,7 +2085,7 @@ func TestContextShouldBindPlain(t *testing.T) {
 	assert.Equal(t, 0, w.Body.Len())
 	// []byte
 
-	c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(`test []byte`))
+	c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString(`test []byte`))
 	c.Request.Header.Add("Content-Type", MIMEPlain)
 
 	var bs []byte
@@ -2058,7 +2099,7 @@ func TestContextShouldBindHeader(t *testing.T) {
 	w := httptest.NewRecorder()
 	c, _ := CreateTestContext(w)
 
-	c.Request, _ = http.NewRequest("POST", "/", nil)
+	c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
 	c.Request.Header.Add("rate", "8000")
 	c.Request.Header.Add("domain", "music")
 	c.Request.Header.Add("limit", "1000")
@@ -2080,7 +2121,7 @@ func TestContextShouldBindWithQuery(t *testing.T) {
 	w := httptest.NewRecorder()
 	c, _ := CreateTestContext(w)
 
-	c.Request, _ = http.NewRequest("POST", "/?foo=bar&bar=foo&Foo=bar1&Bar=foo1", bytes.NewBufferString("foo=unused"))
+	c.Request, _ = http.NewRequest(http.MethodPost, "/?foo=bar&bar=foo&Foo=bar1&Bar=foo1", bytes.NewBufferString("foo=unused"))
 
 	var obj struct {
 		Foo  string `form:"foo"`
@@ -2100,7 +2141,7 @@ func TestContextShouldBindWithYAML(t *testing.T) {
 	w := httptest.NewRecorder()
 	c, _ := CreateTestContext(w)
 
-	c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString("foo: bar\nbar: foo"))
+	c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString("foo: bar\nbar: foo"))
 	c.Request.Header.Add("Content-Type", MIMEXML) // set fake content-type
 
 	var obj struct {
@@ -2117,7 +2158,7 @@ func TestContextShouldBindWithTOML(t *testing.T) {
 	w := httptest.NewRecorder()
 	c, _ := CreateTestContext(w)
 
-	c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString("foo='bar'\nbar= 'foo'"))
+	c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString("foo='bar'\nbar= 'foo'"))
 	c.Request.Header.Add("Content-Type", MIMETOML) // set fake content-type
 
 	var obj struct {
@@ -2134,7 +2175,7 @@ func TestContextBadAutoShouldBind(t *testing.T) {
 	w := httptest.NewRecorder()
 	c, _ := CreateTestContext(w)
 
-	c.Request, _ = http.NewRequest("POST", "http://example.com", bytes.NewBufferString("\"foo\":\"bar\", \"bar\":\"foo\"}"))
+	c.Request, _ = http.NewRequest(http.MethodPost, "http://example.com", bytes.NewBufferString("\"foo\":\"bar\", \"bar\":\"foo\"}"))
 	c.Request.Header.Add("Content-Type", MIMEJSON)
 	var obj struct {
 		Foo string `json:"foo"`
@@ -2198,7 +2239,7 @@ func TestContextShouldBindBodyWith(t *testing.T) {
 			w := httptest.NewRecorder()
 			c, _ := CreateTestContext(w)
 			c.Request, _ = http.NewRequest(
-				"POST", "http://example.com", bytes.NewBufferString(tt.bodyA),
+				http.MethodPost, "http://example.com", bytes.NewBufferString(tt.bodyA),
 			)
 			// When it binds to typeA and typeB, it finds the body is
 			// not typeB but typeA.
@@ -2216,7 +2257,7 @@ func TestContextShouldBindBodyWith(t *testing.T) {
 			w := httptest.NewRecorder()
 			c, _ := CreateTestContext(w)
 			c.Request, _ = http.NewRequest(
-				"POST", "http://example.com", bytes.NewBufferString(tt.bodyB),
+				http.MethodPost, "http://example.com", bytes.NewBufferString(tt.bodyB),
 			)
 			objA := typeA{}
 			require.Error(t, c.ShouldBindBodyWith(&objA, tt.bindingA))
@@ -2263,7 +2304,7 @@ func TestContextShouldBindBodyWithJSON(t *testing.T) {
 		w := httptest.NewRecorder()
 		c, _ := CreateTestContext(w)
 
-		c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(tt.body))
+		c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString(tt.body))
 
 		type typeJSON struct {
 			Foo string `json:"foo" binding:"required"`
@@ -2327,7 +2368,7 @@ func TestContextShouldBindBodyWithXML(t *testing.T) {
 		w := httptest.NewRecorder()
 		c, _ := CreateTestContext(w)
 
-		c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(tt.body))
+		c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString(tt.body))
 
 		type typeXML struct {
 			Foo string `xml:"foo" binding:"required"`
@@ -2391,7 +2432,7 @@ func TestContextShouldBindBodyWithYAML(t *testing.T) {
 		w := httptest.NewRecorder()
 		c, _ := CreateTestContext(w)
 
-		c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(tt.body))
+		c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString(tt.body))
 
 		type typeYAML struct {
 			Foo string `yaml:"foo" binding:"required"`
@@ -2456,7 +2497,7 @@ func TestContextShouldBindBodyWithTOML(t *testing.T) {
 		w := httptest.NewRecorder()
 		c, _ := CreateTestContext(w)
 
-		c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(tt.body))
+		c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString(tt.body))
 
 		type typeTOML struct {
 			Foo string `toml:"foo" binding:"required"`
@@ -2525,7 +2566,7 @@ func TestContextShouldBindBodyWithPlain(t *testing.T) {
 		w := httptest.NewRecorder()
 		c, _ := CreateTestContext(w)
 
-		c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(tt.body))
+		c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString(tt.body))
 
 		type typeJSON struct {
 			Foo string `json:"foo" binding:"required"`
@@ -2562,7 +2603,7 @@ func TestContextShouldBindBodyWithPlain(t *testing.T) {
 
 func TestContextGolangContext(t *testing.T) {
 	c, _ := CreateTestContext(httptest.NewRecorder())
-	c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString("{\"foo\":\"bar\", \"bar\":\"foo\"}"))
+	c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString("{\"foo\":\"bar\", \"bar\":\"foo\"}"))
 	require.NoError(t, c.Err())
 	assert.Nil(t, c.Done())
 	ti, ok := c.Deadline()
@@ -2580,7 +2621,7 @@ func TestContextGolangContext(t *testing.T) {
 func TestWebsocketsRequired(t *testing.T) {
 	// Example request from spec: https://tools.ietf.org/html/rfc6455#section-1.2
 	c, _ := CreateTestContext(httptest.NewRecorder())
-	c.Request, _ = http.NewRequest("GET", "/chat", nil)
+	c.Request, _ = http.NewRequest(http.MethodGet, "/chat", nil)
 	c.Request.Header.Set("Host", "server.example.com")
 	c.Request.Header.Set("Upgrade", "websocket")
 	c.Request.Header.Set("Connection", "Upgrade")
@@ -2593,7 +2634,7 @@ func TestWebsocketsRequired(t *testing.T) {
 
 	// Normal request, no websocket required.
 	c, _ = CreateTestContext(httptest.NewRecorder())
-	c.Request, _ = http.NewRequest("GET", "/chat", nil)
+	c.Request, _ = http.NewRequest(http.MethodGet, "/chat", nil)
 	c.Request.Header.Set("Host", "server.example.com")
 
 	assert.False(t, c.IsWebsocket())
@@ -2601,7 +2642,7 @@ func TestWebsocketsRequired(t *testing.T) {
 
 func TestGetRequestHeaderValue(t *testing.T) {
 	c, _ := CreateTestContext(httptest.NewRecorder())
-	c.Request, _ = http.NewRequest("GET", "/chat", nil)
+	c.Request, _ = http.NewRequest(http.MethodGet, "/chat", nil)
 	c.Request.Header.Set("Gin-Version", "1.0.0")
 
 	assert.Equal(t, "1.0.0", c.GetHeader("Gin-Version"))
@@ -2611,7 +2652,7 @@ func TestGetRequestHeaderValue(t *testing.T) {
 func TestContextGetRawData(t *testing.T) {
 	c, _ := CreateTestContext(httptest.NewRecorder())
 	body := bytes.NewBufferString("Fetch binary post data")
-	c.Request, _ = http.NewRequest("POST", "/", body)
+	c.Request, _ = http.NewRequest(http.MethodPost, "/", body)
 	c.Request.Header.Add("Content-Type", MIMEPOSTForm)
 
 	data, err := c.GetRawData()
@@ -2634,7 +2675,7 @@ func TestContextRenderDataFromReader(t *testing.T) {
 	assert.Equal(t, http.StatusOK, w.Code)
 	assert.Equal(t, body, w.Body.String())
 	assert.Equal(t, contentType, w.Header().Get("Content-Type"))
-	assert.Equal(t, fmt.Sprintf("%d", contentLength), w.Header().Get("Content-Length"))
+	assert.Equal(t, strconv.FormatInt(contentLength, 10), w.Header().Get("Content-Length"))
 	assert.Equal(t, extraHeaders["Content-Disposition"], w.Header().Get("Content-Disposition"))
 }
 
@@ -2652,7 +2693,7 @@ func TestContextRenderDataFromReaderNoHeaders(t *testing.T) {
 	assert.Equal(t, http.StatusOK, w.Code)
 	assert.Equal(t, body, w.Body.String())
 	assert.Equal(t, contentType, w.Header().Get("Content-Type"))
-	assert.Equal(t, fmt.Sprintf("%d", contentLength), w.Header().Get("Content-Length"))
+	assert.Equal(t, strconv.FormatInt(contentLength, 10), w.Header().Get("Content-Length"))
 }
 
 type TestResponseRecorder struct {
@@ -2740,8 +2781,8 @@ func TestRaceParamsContextCopy(t *testing.T) {
 			}(c.Copy(), c.Param("name"))
 		})
 	}
-	PerformRequest(router, "GET", "/name1/api")
-	PerformRequest(router, "GET", "/name2/api")
+	PerformRequest(router, http.MethodGet, "/name1/api")
+	PerformRequest(router, http.MethodGet, "/name2/api")
 	wg.Wait()
 }
 
@@ -2760,7 +2801,7 @@ func TestContextWithKeysMutex(t *testing.T) {
 
 func TestRemoteIPFail(t *testing.T) {
 	c, _ := CreateTestContext(httptest.NewRecorder())
-	c.Request, _ = http.NewRequest("POST", "/", nil)
+	c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
 	c.Request.RemoteAddr = "[:::]:80"
 	ip := net.ParseIP(c.RemoteIP())
 	trust := c.engine.isTrustedProxy(ip)
@@ -2862,7 +2903,7 @@ func TestContextWithFallbackValueFromRequestContext(t *testing.T) {
 				c, _ := CreateTestContext(httptest.NewRecorder())
 				// enable ContextWithFallback feature flag
 				c.engine.ContextWithFallback = true
-				c.Request, _ = http.NewRequest("POST", "/", nil)
+				c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
 				c.Request = c.Request.WithContext(context.WithValue(context.TODO(), key, "value"))
 				return c, key
 			},
@@ -2874,7 +2915,7 @@ func TestContextWithFallbackValueFromRequestContext(t *testing.T) {
 				c, _ := CreateTestContext(httptest.NewRecorder())
 				// enable ContextWithFallback feature flag
 				c.engine.ContextWithFallback = true
-				c.Request, _ = http.NewRequest("POST", "/", nil)
+				c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
 				c.Request = c.Request.WithContext(context.WithValue(context.TODO(), contextKey("key"), "value"))
 				return c, contextKey("key")
 			},
@@ -2897,7 +2938,7 @@ func TestContextWithFallbackValueFromRequestContext(t *testing.T) {
 				c, _ := CreateTestContext(httptest.NewRecorder())
 				// enable ContextWithFallback feature flag
 				c.engine.ContextWithFallback = true
-				c.Request, _ = http.NewRequest("POST", "/", nil)
+				c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
 				return c, "key"
 			},
 			value: nil,
@@ -3029,7 +3070,7 @@ func TestInterceptedHeader(t *testing.T) {
 		c.Header("X-Test-2", "present")
 		c.String(http.StatusOK, "hello world")
 	})
-	c.Request = httptest.NewRequest("GET", "/", nil)
+	c.Request = httptest.NewRequest(http.MethodGet, "/", nil)
 	r.HandleContext(c)
 	// Result() has headers frozen when WriteHeaderNow() has been called
 	// Compared to this time, this is when the response headers will be flushed
@@ -3038,3 +3079,47 @@ func TestInterceptedHeader(t *testing.T) {
 	assert.Equal(t, "", w.Result().Header.Get("X-Test"))
 	assert.Equal(t, "present", w.Result().Header.Get("X-Test-2"))
 }
+
+func TestContextNext(t *testing.T) {
+	c, _ := CreateTestContext(httptest.NewRecorder())
+
+	// Test with no handlers
+	c.Next()
+	assert.Equal(t, int8(0), c.index)
+
+	// Test with one handler
+	c.index = -1
+	c.handlers = HandlersChain{func(c *Context) {
+		c.Set("key", "value")
+	}}
+	c.Next()
+	assert.Equal(t, int8(1), c.index)
+	value, exists := c.Get("key")
+	assert.True(t, exists)
+	assert.Equal(t, "value", value)
+
+	// Test with multiple handlers
+	c.handlers = HandlersChain{
+		func(c *Context) {
+			c.Set("key1", "value1")
+			c.Next()
+			c.Set("key2", "value2")
+		},
+		nil,
+		func(c *Context) {
+			c.Set("key3", "value3")
+		},
+	}
+	c.index = -1
+	c.Next()
+	assert.Equal(t, int8(4), c.index)
+	value, exists = c.Get("key1")
+	assert.True(t, exists)
+	assert.Equal(t, "value1", value)
+	value, exists = c.Get("key2")
+	assert.True(t, exists)
+	assert.Equal(t, "value2", value)
+	value, exists = c.Get("key3")
+	assert.True(t, exists)
+	assert.Equal(t, "value3", value)
+}
diff --git a/debug_test.go b/debug_test.go
index edf4bb1..0efbfd7 100644
--- a/debug_test.go
+++ b/debug_test.go
@@ -10,6 +10,7 @@ import (
 	"html/template"
 	"io"
 	"log"
+	"net/http"
 	"os"
 	"runtime"
 	"strings"
@@ -60,7 +61,7 @@ func TestDebugPrintError(t *testing.T) {
 func TestDebugPrintRoutes(t *testing.T) {
 	re := captureOutput(t, func() {
 		SetMode(DebugMode)
-		debugPrintRoute("GET", "/path/to/route/:param", HandlersChain{func(c *Context) {}, handlerNameTest})
+		debugPrintRoute(http.MethodGet, "/path/to/route/:param", HandlersChain{func(c *Context) {}, handlerNameTest})
 		SetMode(TestMode)
 	})
 	assert.Regexp(t, `^\[GIN-debug\] GET    /path/to/route/:param     --> (.*/vendor/)?github.com/gin-gonic/gin.handlerNameTest \(2 handlers\)\n$`, re)
@@ -72,7 +73,7 @@ func TestDebugPrintRouteFunc(t *testing.T) {
 	}
 	re := captureOutput(t, func() {
 		SetMode(DebugMode)
-		debugPrintRoute("GET", "/path/to/route/:param1/:param2", HandlersChain{func(c *Context) {}, handlerNameTest})
+		debugPrintRoute(http.MethodGet, "/path/to/route/:param1/:param2", HandlersChain{func(c *Context) {}, handlerNameTest})
 		SetMode(TestMode)
 	})
 	assert.Regexp(t, `^\[GIN-debug\] GET    /path/to/route/:param1/:param2           --> (.*/vendor/)?github.com/gin-gonic/gin.handlerNameTest \(2 handlers\)\n$`, re)
diff --git a/deprecated_test.go b/deprecated_test.go
index 0240b2e..6c8f2a7 100644
--- a/deprecated_test.go
+++ b/deprecated_test.go
@@ -18,7 +18,7 @@ func TestBindWith(t *testing.T) {
 	w := httptest.NewRecorder()
 	c, _ := CreateTestContext(w)
 
-	c.Request, _ = http.NewRequest("POST", "/?foo=bar&bar=foo", bytes.NewBufferString("foo=unused"))
+	c.Request, _ = http.NewRequest(http.MethodPost, "/?foo=bar&bar=foo", bytes.NewBufferString("foo=unused"))
 
 	var obj struct {
 		Foo string `form:"foo"`
diff --git a/gin_test.go b/gin_test.go
index 719f63e..732da18 100644
--- a/gin_test.go
+++ b/gin_test.go
@@ -73,7 +73,7 @@ func TestLoadHTMLGlobDebugMode(t *testing.T) {
 	)
 	defer ts.Close()
 
-	res, err := http.Get(fmt.Sprintf("%s/test", ts.URL))
+	res, err := http.Get(ts.URL + "/test")
 	if err != nil {
 		t.Error(err)
 	}
@@ -131,7 +131,7 @@ func TestLoadHTMLGlobTestMode(t *testing.T) {
 	)
 	defer ts.Close()
 
-	res, err := http.Get(fmt.Sprintf("%s/test", ts.URL))
+	res, err := http.Get(ts.URL + "/test")
 	if err != nil {
 		t.Error(err)
 	}
@@ -151,7 +151,7 @@ func TestLoadHTMLGlobReleaseMode(t *testing.T) {
 	)
 	defer ts.Close()
 
-	res, err := http.Get(fmt.Sprintf("%s/test", ts.URL))
+	res, err := http.Get(ts.URL + "/test")
 	if err != nil {
 		t.Error(err)
 	}
@@ -178,7 +178,7 @@ func TestLoadHTMLGlobUsingTLS(t *testing.T) {
 		},
 	}
 	client := &http.Client{Transport: tr}
-	res, err := client.Get(fmt.Sprintf("%s/test", ts.URL))
+	res, err := client.Get(ts.URL + "/test")
 	if err != nil {
 		t.Error(err)
 	}
@@ -198,7 +198,7 @@ func TestLoadHTMLGlobFromFuncMap(t *testing.T) {
 	)
 	defer ts.Close()
 
-	res, err := http.Get(fmt.Sprintf("%s/raw", ts.URL))
+	res, err := http.Get(ts.URL + "/raw")
 	if err != nil {
 		t.Error(err)
 	}
@@ -229,7 +229,7 @@ func TestLoadHTMLFilesTestMode(t *testing.T) {
 	)
 	defer ts.Close()
 
-	res, err := http.Get(fmt.Sprintf("%s/test", ts.URL))
+	res, err := http.Get(ts.URL + "/test")
 	if err != nil {
 		t.Error(err)
 	}
@@ -249,7 +249,7 @@ func TestLoadHTMLFilesDebugMode(t *testing.T) {
 	)
 	defer ts.Close()
 
-	res, err := http.Get(fmt.Sprintf("%s/test", ts.URL))
+	res, err := http.Get(ts.URL + "/test")
 	if err != nil {
 		t.Error(err)
 	}
@@ -269,7 +269,7 @@ func TestLoadHTMLFilesReleaseMode(t *testing.T) {
 	)
 	defer ts.Close()
 
-	res, err := http.Get(fmt.Sprintf("%s/test", ts.URL))
+	res, err := http.Get(ts.URL + "/test")
 	if err != nil {
 		t.Error(err)
 	}
@@ -296,7 +296,7 @@ func TestLoadHTMLFilesUsingTLS(t *testing.T) {
 		},
 	}
 	client := &http.Client{Transport: tr}
-	res, err := client.Get(fmt.Sprintf("%s/test", ts.URL))
+	res, err := client.Get(ts.URL + "/test")
 	if err != nil {
 		t.Error(err)
 	}
@@ -316,7 +316,7 @@ func TestLoadHTMLFilesFuncMap(t *testing.T) {
 	)
 	defer ts.Close()
 
-	res, err := http.Get(fmt.Sprintf("%s/raw", ts.URL))
+	res, err := http.Get(ts.URL + "/raw")
 	if err != nil {
 		t.Error(err)
 	}
@@ -327,31 +327,31 @@ func TestLoadHTMLFilesFuncMap(t *testing.T) {
 
 func TestAddRoute(t *testing.T) {
 	router := New()
-	router.addRoute("GET", "/", HandlersChain{func(_ *Context) {}})
+	router.addRoute(http.MethodGet, "/", HandlersChain{func(_ *Context) {}})
 
 	assert.Len(t, router.trees, 1)
-	assert.NotNil(t, router.trees.get("GET"))
-	assert.Nil(t, router.trees.get("POST"))
+	assert.NotNil(t, router.trees.get(http.MethodGet))
+	assert.Nil(t, router.trees.get(http.MethodPost))
 
-	router.addRoute("POST", "/", HandlersChain{func(_ *Context) {}})
+	router.addRoute(http.MethodPost, "/", HandlersChain{func(_ *Context) {}})
 
 	assert.Len(t, router.trees, 2)
-	assert.NotNil(t, router.trees.get("GET"))
-	assert.NotNil(t, router.trees.get("POST"))
+	assert.NotNil(t, router.trees.get(http.MethodGet))
+	assert.NotNil(t, router.trees.get(http.MethodPost))
 
-	router.addRoute("POST", "/post", HandlersChain{func(_ *Context) {}})
+	router.addRoute(http.MethodPost, "/post", HandlersChain{func(_ *Context) {}})
 	assert.Len(t, router.trees, 2)
 }
 
 func TestAddRouteFails(t *testing.T) {
 	router := New()
 	assert.Panics(t, func() { router.addRoute("", "/", HandlersChain{func(_ *Context) {}}) })
-	assert.Panics(t, func() { router.addRoute("GET", "a", HandlersChain{func(_ *Context) {}}) })
-	assert.Panics(t, func() { router.addRoute("GET", "/", HandlersChain{}) })
+	assert.Panics(t, func() { router.addRoute(http.MethodGet, "a", HandlersChain{func(_ *Context) {}}) })
+	assert.Panics(t, func() { router.addRoute(http.MethodGet, "/", HandlersChain{}) })
 
-	router.addRoute("POST", "/post", HandlersChain{func(_ *Context) {}})
+	router.addRoute(http.MethodPost, "/post", HandlersChain{func(_ *Context) {}})
 	assert.Panics(t, func() {
-		router.addRoute("POST", "/post", HandlersChain{func(_ *Context) {}})
+		router.addRoute(http.MethodPost, "/post", HandlersChain{func(_ *Context) {}})
 	})
 }
 
@@ -493,27 +493,27 @@ func TestListOfRoutes(t *testing.T) {
 
 	assert.Len(t, list, 7)
 	assertRoutePresent(t, list, RouteInfo{
-		Method:  "GET",
+		Method:  http.MethodGet,
 		Path:    "/favicon.ico",
 		Handler: "^(.*/vendor/)?github.com/gin-gonic/gin.handlerTest1$",
 	})
 	assertRoutePresent(t, list, RouteInfo{
-		Method:  "GET",
+		Method:  http.MethodGet,
 		Path:    "/",
 		Handler: "^(.*/vendor/)?github.com/gin-gonic/gin.handlerTest1$",
 	})
 	assertRoutePresent(t, list, RouteInfo{
-		Method:  "GET",
+		Method:  http.MethodGet,
 		Path:    "/users/",
 		Handler: "^(.*/vendor/)?github.com/gin-gonic/gin.handlerTest2$",
 	})
 	assertRoutePresent(t, list, RouteInfo{
-		Method:  "GET",
+		Method:  http.MethodGet,
 		Path:    "/users/:id",
 		Handler: "^(.*/vendor/)?github.com/gin-gonic/gin.handlerTest1$",
 	})
 	assertRoutePresent(t, list, RouteInfo{
-		Method:  "POST",
+		Method:  http.MethodPost,
 		Path:    "/users/:id",
 		Handler: "^(.*/vendor/)?github.com/gin-gonic/gin.handlerTest2$",
 	})
@@ -531,7 +531,7 @@ func TestEngineHandleContext(t *testing.T) {
 	}
 
 	assert.NotPanics(t, func() {
-		w := PerformRequest(r, "GET", "/")
+		w := PerformRequest(r, http.MethodGet, "/")
 		assert.Equal(t, 301, w.Code)
 	})
 }
@@ -564,7 +564,7 @@ func TestEngineHandleContextManyReEntries(t *testing.T) {
 	})
 
 	assert.NotPanics(t, func() {
-		w := PerformRequest(r, "GET", "/"+strconv.Itoa(expectValue-1)) // include 0 value
+		w := PerformRequest(r, http.MethodGet, "/"+strconv.Itoa(expectValue-1)) // include 0 value
 		assert.Equal(t, 200, w.Code)
 		assert.Equal(t, expectValue, w.Body.Len())
 	})
@@ -712,8 +712,8 @@ func TestNewOptionFunc(t *testing.T) {
 	r := New(fc)
 
 	routes := r.Routes()
-	assertRoutePresent(t, routes, RouteInfo{Path: "/test1", Method: "GET", Handler: "github.com/gin-gonic/gin.handlerTest1"})
-	assertRoutePresent(t, routes, RouteInfo{Path: "/test2", Method: "GET", Handler: "github.com/gin-gonic/gin.handlerTest2"})
+	assertRoutePresent(t, routes, RouteInfo{Path: "/test1", Method: http.MethodGet, Handler: "github.com/gin-gonic/gin.handlerTest1"})
+	assertRoutePresent(t, routes, RouteInfo{Path: "/test2", Method: http.MethodGet, Handler: "github.com/gin-gonic/gin.handlerTest2"})
 }
 
 func TestWithOptionFunc(t *testing.T) {
@@ -729,8 +729,8 @@ func TestWithOptionFunc(t *testing.T) {
 	})
 
 	routes := r.Routes()
-	assertRoutePresent(t, routes, RouteInfo{Path: "/test1", Method: "GET", Handler: "github.com/gin-gonic/gin.handlerTest1"})
-	assertRoutePresent(t, routes, RouteInfo{Path: "/test2", Method: "GET", Handler: "github.com/gin-gonic/gin.handlerTest2"})
+	assertRoutePresent(t, routes, RouteInfo{Path: "/test1", Method: http.MethodGet, Handler: "github.com/gin-gonic/gin.handlerTest1"})
+	assertRoutePresent(t, routes, RouteInfo{Path: "/test2", Method: http.MethodGet, Handler: "github.com/gin-gonic/gin.handlerTest2"})
 }
 
 type Birthday string
@@ -749,7 +749,7 @@ func TestCustomUnmarshalStruct(t *testing.T) {
 		_ = ctx.BindQuery(&request)
 		ctx.JSON(200, request.Birthday)
 	})
-	req := httptest.NewRequest("GET", "/test?birthday=2000-01-01", nil)
+	req := httptest.NewRequest(http.MethodGet, "/test?birthday=2000-01-01", nil)
 	w := httptest.NewRecorder()
 	route.ServeHTTP(w, req)
 	assert.Equal(t, 200, w.Code)
@@ -761,7 +761,7 @@ func TestMethodNotAllowedNoRoute(t *testing.T) {
 	g := New()
 	g.HandleMethodNotAllowed = true
 
-	req := httptest.NewRequest("GET", "/", nil)
+	req := httptest.NewRequest(http.MethodGet, "/", nil)
 	resp := httptest.NewRecorder()
 	assert.NotPanics(t, func() { g.ServeHTTP(resp, req) })
 	assert.Equal(t, http.StatusNotFound, resp.Code)
diff --git a/githubapi_test.go b/githubapi_test.go
index 6d34878..0c86af2 100644
--- a/githubapi_test.go
+++ b/githubapi_test.go
@@ -10,6 +10,7 @@ import (
 	"net/http"
 	"net/http/httptest"
 	"os"
+	"strconv"
 	"strings"
 	"testing"
 
@@ -411,7 +412,7 @@ func exampleFromPath(path string) (string, Params) {
 		}
 		if start >= 0 {
 			if c == '/' {
-				value := fmt.Sprint(rand.Intn(100000))
+				value := strconv.Itoa(rand.Intn(100000))
 				params = append(params, Param{
 					Key:   path[start:i],
 					Value: value,
@@ -425,7 +426,7 @@ func exampleFromPath(path string) (string, Params) {
 		}
 	}
 	if start >= 0 {
-		value := fmt.Sprint(rand.Intn(100000))
+		value := strconv.Itoa(rand.Intn(100000))
 		params = append(params, Param{
 			Key:   path[start:],
 			Value: value,
diff --git a/logger_test.go b/logger_test.go
index b05df74..de00c49 100644
--- a/logger_test.go
+++ b/logger_test.go
@@ -31,9 +31,9 @@ func TestLogger(t *testing.T) {
 	router.HEAD("/example", func(c *Context) {})
 	router.OPTIONS("/example", func(c *Context) {})
 
-	PerformRequest(router, "GET", "/example?a=100")
+	PerformRequest(router, http.MethodGet, "/example?a=100")
 	assert.Contains(t, buffer.String(), "200")
-	assert.Contains(t, buffer.String(), "GET")
+	assert.Contains(t, buffer.String(), http.MethodGet)
 	assert.Contains(t, buffer.String(), "/example")
 	assert.Contains(t, buffer.String(), "a=100")
 
@@ -41,21 +41,21 @@ func TestLogger(t *testing.T) {
 	// like integration tests because they test the whole logging process rather
 	// than individual functions.  Im not sure where these should go.
 	buffer.Reset()
-	PerformRequest(router, "POST", "/example")
+	PerformRequest(router, http.MethodPost, "/example")
 	assert.Contains(t, buffer.String(), "200")
-	assert.Contains(t, buffer.String(), "POST")
+	assert.Contains(t, buffer.String(), http.MethodPost)
 	assert.Contains(t, buffer.String(), "/example")
 
 	buffer.Reset()
-	PerformRequest(router, "PUT", "/example")
+	PerformRequest(router, http.MethodPut, "/example")
 	assert.Contains(t, buffer.String(), "200")
-	assert.Contains(t, buffer.String(), "PUT")
+	assert.Contains(t, buffer.String(), http.MethodPut)
 	assert.Contains(t, buffer.String(), "/example")
 
 	buffer.Reset()
-	PerformRequest(router, "DELETE", "/example")
+	PerformRequest(router, http.MethodDelete, "/example")
 	assert.Contains(t, buffer.String(), "200")
-	assert.Contains(t, buffer.String(), "DELETE")
+	assert.Contains(t, buffer.String(), http.MethodDelete)
 	assert.Contains(t, buffer.String(), "/example")
 
 	buffer.Reset()
@@ -77,9 +77,9 @@ func TestLogger(t *testing.T) {
 	assert.Contains(t, buffer.String(), "/example")
 
 	buffer.Reset()
-	PerformRequest(router, "GET", "/notfound")
+	PerformRequest(router, http.MethodGet, "/notfound")
 	assert.Contains(t, buffer.String(), "404")
-	assert.Contains(t, buffer.String(), "GET")
+	assert.Contains(t, buffer.String(), http.MethodGet)
 	assert.Contains(t, buffer.String(), "/notfound")
 }
 
@@ -95,9 +95,9 @@ func TestLoggerWithConfig(t *testing.T) {
 	router.HEAD("/example", func(c *Context) {})
 	router.OPTIONS("/example", func(c *Context) {})
 
-	PerformRequest(router, "GET", "/example?a=100")
+	PerformRequest(router, http.MethodGet, "/example?a=100")
 	assert.Contains(t, buffer.String(), "200")
-	assert.Contains(t, buffer.String(), "GET")
+	assert.Contains(t, buffer.String(), http.MethodGet)
 	assert.Contains(t, buffer.String(), "/example")
 	assert.Contains(t, buffer.String(), "a=100")
 
@@ -105,21 +105,21 @@ func TestLoggerWithConfig(t *testing.T) {
 	// like integration tests because they test the whole logging process rather
 	// than individual functions.  Im not sure where these should go.
 	buffer.Reset()
-	PerformRequest(router, "POST", "/example")
+	PerformRequest(router, http.MethodPost, "/example")
 	assert.Contains(t, buffer.String(), "200")
-	assert.Contains(t, buffer.String(), "POST")
+	assert.Contains(t, buffer.String(), http.MethodPost)
 	assert.Contains(t, buffer.String(), "/example")
 
 	buffer.Reset()
-	PerformRequest(router, "PUT", "/example")
+	PerformRequest(router, http.MethodPut, "/example")
 	assert.Contains(t, buffer.String(), "200")
-	assert.Contains(t, buffer.String(), "PUT")
+	assert.Contains(t, buffer.String(), http.MethodPut)
 	assert.Contains(t, buffer.String(), "/example")
 
 	buffer.Reset()
-	PerformRequest(router, "DELETE", "/example")
+	PerformRequest(router, http.MethodDelete, "/example")
 	assert.Contains(t, buffer.String(), "200")
-	assert.Contains(t, buffer.String(), "DELETE")
+	assert.Contains(t, buffer.String(), http.MethodDelete)
 	assert.Contains(t, buffer.String(), "/example")
 
 	buffer.Reset()
@@ -141,9 +141,9 @@ func TestLoggerWithConfig(t *testing.T) {
 	assert.Contains(t, buffer.String(), "/example")
 
 	buffer.Reset()
-	PerformRequest(router, "GET", "/notfound")
+	PerformRequest(router, http.MethodGet, "/notfound")
 	assert.Contains(t, buffer.String(), "404")
-	assert.Contains(t, buffer.String(), "GET")
+	assert.Contains(t, buffer.String(), http.MethodGet)
 	assert.Contains(t, buffer.String(), "/notfound")
 }
 
@@ -169,12 +169,12 @@ func TestLoggerWithFormatter(t *testing.T) {
 		)
 	}))
 	router.GET("/example", func(c *Context) {})
-	PerformRequest(router, "GET", "/example?a=100")
+	PerformRequest(router, http.MethodGet, "/example?a=100")
 
 	// output test
 	assert.Contains(t, buffer.String(), "[FORMATTER TEST]")
 	assert.Contains(t, buffer.String(), "200")
-	assert.Contains(t, buffer.String(), "GET")
+	assert.Contains(t, buffer.String(), http.MethodGet)
 	assert.Contains(t, buffer.String(), "/example")
 	assert.Contains(t, buffer.String(), "a=100")
 }
@@ -210,12 +210,12 @@ func TestLoggerWithConfigFormatting(t *testing.T) {
 		gotKeys = c.Keys
 		time.Sleep(time.Millisecond)
 	})
-	PerformRequest(router, "GET", "/example?a=100")
+	PerformRequest(router, http.MethodGet, "/example?a=100")
 
 	// output test
 	assert.Contains(t, buffer.String(), "[FORMATTER TEST]")
 	assert.Contains(t, buffer.String(), "200")
-	assert.Contains(t, buffer.String(), "GET")
+	assert.Contains(t, buffer.String(), http.MethodGet)
 	assert.Contains(t, buffer.String(), "/example")
 	assert.Contains(t, buffer.String(), "a=100")
 
@@ -225,7 +225,7 @@ func TestLoggerWithConfigFormatting(t *testing.T) {
 	assert.Equal(t, 200, gotParam.StatusCode)
 	assert.NotEmpty(t, gotParam.Latency)
 	assert.Equal(t, "20.20.20.20", gotParam.ClientIP)
-	assert.Equal(t, "GET", gotParam.Method)
+	assert.Equal(t, http.MethodGet, gotParam.Method)
 	assert.Equal(t, "/example?a=100", gotParam.Path)
 	assert.Empty(t, gotParam.ErrorMessage)
 	assert.Equal(t, gotKeys, gotParam.Keys)
@@ -239,7 +239,7 @@ func TestDefaultLogFormatter(t *testing.T) {
 		StatusCode:   200,
 		Latency:      time.Second * 5,
 		ClientIP:     "20.20.20.20",
-		Method:       "GET",
+		Method:       http.MethodGet,
 		Path:         "/",
 		ErrorMessage: "",
 		isTerm:       false,
@@ -250,7 +250,7 @@ func TestDefaultLogFormatter(t *testing.T) {
 		StatusCode:   200,
 		Latency:      time.Second * 5,
 		ClientIP:     "20.20.20.20",
-		Method:       "GET",
+		Method:       http.MethodGet,
 		Path:         "/",
 		ErrorMessage: "",
 		isTerm:       true,
@@ -260,7 +260,7 @@ func TestDefaultLogFormatter(t *testing.T) {
 		StatusCode:   200,
 		Latency:      time.Millisecond * 9876543210,
 		ClientIP:     "20.20.20.20",
-		Method:       "GET",
+		Method:       http.MethodGet,
 		Path:         "/",
 		ErrorMessage: "",
 		isTerm:       true,
@@ -271,7 +271,7 @@ func TestDefaultLogFormatter(t *testing.T) {
 		StatusCode:   200,
 		Latency:      time.Millisecond * 9876543210,
 		ClientIP:     "20.20.20.20",
-		Method:       "GET",
+		Method:       http.MethodGet,
 		Path:         "/",
 		ErrorMessage: "",
 		isTerm:       false,
@@ -292,10 +292,10 @@ func TestColorForMethod(t *testing.T) {
 		return p.MethodColor()
 	}
 
-	assert.Equal(t, blue, colorForMethod("GET"), "get should be blue")
-	assert.Equal(t, cyan, colorForMethod("POST"), "post should be cyan")
-	assert.Equal(t, yellow, colorForMethod("PUT"), "put should be yellow")
-	assert.Equal(t, red, colorForMethod("DELETE"), "delete should be red")
+	assert.Equal(t, blue, colorForMethod(http.MethodGet), "get should be blue")
+	assert.Equal(t, cyan, colorForMethod(http.MethodPost), "post should be cyan")
+	assert.Equal(t, yellow, colorForMethod(http.MethodPut), "put should be yellow")
+	assert.Equal(t, red, colorForMethod(http.MethodDelete), "delete should be red")
 	assert.Equal(t, green, colorForMethod("PATCH"), "patch should be green")
 	assert.Equal(t, magenta, colorForMethod("HEAD"), "head should be magenta")
 	assert.Equal(t, white, colorForMethod("OPTIONS"), "options should be white")
@@ -369,15 +369,15 @@ func TestErrorLogger(t *testing.T) {
 		c.String(http.StatusInternalServerError, "hola!")
 	})
 
-	w := PerformRequest(router, "GET", "/error")
+	w := PerformRequest(router, http.MethodGet, "/error")
 	assert.Equal(t, http.StatusOK, w.Code)
 	assert.Equal(t, "{\"error\":\"this is an error\"}", w.Body.String())
 
-	w = PerformRequest(router, "GET", "/abort")
+	w = PerformRequest(router, http.MethodGet, "/abort")
 	assert.Equal(t, http.StatusUnauthorized, w.Code)
 	assert.Equal(t, "{\"error\":\"no authorized\"}", w.Body.String())
 
-	w = PerformRequest(router, "GET", "/print")
+	w = PerformRequest(router, http.MethodGet, "/print")
 	assert.Equal(t, http.StatusInternalServerError, w.Code)
 	assert.Equal(t, "hola!{\"error\":\"this is an error\"}", w.Body.String())
 }
@@ -389,11 +389,11 @@ func TestLoggerWithWriterSkippingPaths(t *testing.T) {
 	router.GET("/logged", func(c *Context) {})
 	router.GET("/skipped", func(c *Context) {})
 
-	PerformRequest(router, "GET", "/logged")
+	PerformRequest(router, http.MethodGet, "/logged")
 	assert.Contains(t, buffer.String(), "200")
 
 	buffer.Reset()
-	PerformRequest(router, "GET", "/skipped")
+	PerformRequest(router, http.MethodGet, "/skipped")
 	assert.Contains(t, buffer.String(), "")
 }
 
@@ -407,11 +407,11 @@ func TestLoggerWithConfigSkippingPaths(t *testing.T) {
 	router.GET("/logged", func(c *Context) {})
 	router.GET("/skipped", func(c *Context) {})
 
-	PerformRequest(router, "GET", "/logged")
+	PerformRequest(router, http.MethodGet, "/logged")
 	assert.Contains(t, buffer.String(), "200")
 
 	buffer.Reset()
-	PerformRequest(router, "GET", "/skipped")
+	PerformRequest(router, http.MethodGet, "/skipped")
 	assert.Contains(t, buffer.String(), "")
 }
 
@@ -427,11 +427,11 @@ func TestLoggerWithConfigSkipper(t *testing.T) {
 	router.GET("/logged", func(c *Context) { c.Status(http.StatusOK) })
 	router.GET("/skipped", func(c *Context) { c.Status(http.StatusNoContent) })
 
-	PerformRequest(router, "GET", "/logged")
+	PerformRequest(router, http.MethodGet, "/logged")
 	assert.Contains(t, buffer.String(), "200")
 
 	buffer.Reset()
-	PerformRequest(router, "GET", "/skipped")
+	PerformRequest(router, http.MethodGet, "/skipped")
 	assert.Contains(t, buffer.String(), "")
 }
 
diff --git a/middleware_test.go b/middleware_test.go
index acdf89c..eafc60a 100644
--- a/middleware_test.go
+++ b/middleware_test.go
@@ -35,7 +35,7 @@ func TestMiddlewareGeneralCase(t *testing.T) {
 		signature += " XX "
 	})
 	// RUN
-	w := PerformRequest(router, "GET", "/")
+	w := PerformRequest(router, http.MethodGet, "/")
 
 	// TEST
 	assert.Equal(t, http.StatusOK, w.Code)
@@ -71,7 +71,7 @@ func TestMiddlewareNoRoute(t *testing.T) {
 		signature += " X "
 	})
 	// RUN
-	w := PerformRequest(router, "GET", "/")
+	w := PerformRequest(router, http.MethodGet, "/")
 
 	// TEST
 	assert.Equal(t, http.StatusNotFound, w.Code)
@@ -108,7 +108,7 @@ func TestMiddlewareNoMethodEnabled(t *testing.T) {
 		signature += " XX "
 	})
 	// RUN
-	w := PerformRequest(router, "GET", "/")
+	w := PerformRequest(router, http.MethodGet, "/")
 
 	// TEST
 	assert.Equal(t, http.StatusMethodNotAllowed, w.Code)
@@ -149,7 +149,7 @@ func TestMiddlewareNoMethodDisabled(t *testing.T) {
 	})
 
 	// RUN
-	w := PerformRequest(router, "GET", "/")
+	w := PerformRequest(router, http.MethodGet, "/")
 
 	// TEST
 	assert.Equal(t, http.StatusNotFound, w.Code)
@@ -175,7 +175,7 @@ func TestMiddlewareAbort(t *testing.T) {
 	})
 
 	// RUN
-	w := PerformRequest(router, "GET", "/")
+	w := PerformRequest(router, http.MethodGet, "/")
 
 	// TEST
 	assert.Equal(t, http.StatusUnauthorized, w.Code)
@@ -196,7 +196,7 @@ func TestMiddlewareAbortHandlersChainAndNext(t *testing.T) {
 		c.Next()
 	})
 	// RUN
-	w := PerformRequest(router, "GET", "/")
+	w := PerformRequest(router, http.MethodGet, "/")
 
 	// TEST
 	assert.Equal(t, http.StatusGone, w.Code)
@@ -219,7 +219,7 @@ func TestMiddlewareFailHandlersChain(t *testing.T) {
 		signature += "C"
 	})
 	// RUN
-	w := PerformRequest(router, "GET", "/")
+	w := PerformRequest(router, http.MethodGet, "/")
 
 	// TEST
 	assert.Equal(t, http.StatusInternalServerError, w.Code)
@@ -246,7 +246,7 @@ func TestMiddlewareWrite(t *testing.T) {
 		})
 	})
 
-	w := PerformRequest(router, "GET", "/")
+	w := PerformRequest(router, http.MethodGet, "/")
 
 	assert.Equal(t, http.StatusBadRequest, w.Code)
 	assert.Equal(t, strings.Replace("hola\n<map><foo>bar</foo></map>{\"foo\":\"bar\"}{\"foo\":\"bar\"}event:test\ndata:message\n\n", " ", "", -1), strings.Replace(w.Body.String(), " ", "", -1))
diff --git a/recovery_test.go b/recovery_test.go
index fa8ab89..08eec1e 100644
--- a/recovery_test.go
+++ b/recovery_test.go
@@ -5,7 +5,6 @@
 package gin
 
 import (
-	"fmt"
 	"net"
 	"net/http"
 	"os"
@@ -26,14 +25,14 @@ func TestPanicClean(t *testing.T) {
 		panic("Oupps, Houston, we have a problem")
 	})
 	// RUN
-	w := PerformRequest(router, "GET", "/recovery",
+	w := PerformRequest(router, http.MethodGet, "/recovery",
 		header{
 			Key:   "Host",
 			Value: "www.google.com",
 		},
 		header{
 			Key:   "Authorization",
-			Value: fmt.Sprintf("Bearer %s", password),
+			Value: "Bearer " + password,
 		},
 		header{
 			Key:   "Content-Type",
@@ -56,7 +55,7 @@ func TestPanicInHandler(t *testing.T) {
 		panic("Oupps, Houston, we have a problem")
 	})
 	// RUN
-	w := PerformRequest(router, "GET", "/recovery")
+	w := PerformRequest(router, http.MethodGet, "/recovery")
 	// TEST
 	assert.Equal(t, http.StatusInternalServerError, w.Code)
 	assert.Contains(t, buffer.String(), "panic recovered")
@@ -67,7 +66,7 @@ func TestPanicInHandler(t *testing.T) {
 	// Debug mode prints the request
 	SetMode(DebugMode)
 	// RUN
-	w = PerformRequest(router, "GET", "/recovery")
+	w = PerformRequest(router, http.MethodGet, "/recovery")
 	// TEST
 	assert.Equal(t, http.StatusInternalServerError, w.Code)
 	assert.Contains(t, buffer.String(), "GET /recovery")
@@ -84,7 +83,7 @@ func TestPanicWithAbort(t *testing.T) {
 		panic("Oupps, Houston, we have a problem")
 	})
 	// RUN
-	w := PerformRequest(router, "GET", "/recovery")
+	w := PerformRequest(router, http.MethodGet, "/recovery")
 	// TEST
 	assert.Equal(t, http.StatusBadRequest, w.Code)
 }
@@ -135,7 +134,7 @@ func TestPanicWithBrokenPipe(t *testing.T) {
 				panic(e)
 			})
 			// RUN
-			w := PerformRequest(router, "GET", "/recovery")
+			w := PerformRequest(router, http.MethodGet, "/recovery")
 			// TEST
 			assert.Equal(t, expectCode, w.Code)
 			assert.Contains(t, strings.ToLower(buf.String()), expectMsg)
@@ -156,7 +155,7 @@ func TestCustomRecoveryWithWriter(t *testing.T) {
 		panic("Oupps, Houston, we have a problem")
 	})
 	// RUN
-	w := PerformRequest(router, "GET", "/recovery")
+	w := PerformRequest(router, http.MethodGet, "/recovery")
 	// TEST
 	assert.Equal(t, http.StatusBadRequest, w.Code)
 	assert.Contains(t, buffer.String(), "panic recovered")
@@ -167,7 +166,7 @@ func TestCustomRecoveryWithWriter(t *testing.T) {
 	// Debug mode prints the request
 	SetMode(DebugMode)
 	// RUN
-	w = PerformRequest(router, "GET", "/recovery")
+	w = PerformRequest(router, http.MethodGet, "/recovery")
 	// TEST
 	assert.Equal(t, http.StatusBadRequest, w.Code)
 	assert.Contains(t, buffer.String(), "GET /recovery")
@@ -191,7 +190,7 @@ func TestCustomRecovery(t *testing.T) {
 		panic("Oupps, Houston, we have a problem")
 	})
 	// RUN
-	w := PerformRequest(router, "GET", "/recovery")
+	w := PerformRequest(router, http.MethodGet, "/recovery")
 	// TEST
 	assert.Equal(t, http.StatusBadRequest, w.Code)
 	assert.Contains(t, buffer.String(), "panic recovered")
@@ -202,7 +201,7 @@ func TestCustomRecovery(t *testing.T) {
 	// Debug mode prints the request
 	SetMode(DebugMode)
 	// RUN
-	w = PerformRequest(router, "GET", "/recovery")
+	w = PerformRequest(router, http.MethodGet, "/recovery")
 	// TEST
 	assert.Equal(t, http.StatusBadRequest, w.Code)
 	assert.Contains(t, buffer.String(), "GET /recovery")
@@ -226,7 +225,7 @@ func TestRecoveryWithWriterWithCustomRecovery(t *testing.T) {
 		panic("Oupps, Houston, we have a problem")
 	})
 	// RUN
-	w := PerformRequest(router, "GET", "/recovery")
+	w := PerformRequest(router, http.MethodGet, "/recovery")
 	// TEST
 	assert.Equal(t, http.StatusBadRequest, w.Code)
 	assert.Contains(t, buffer.String(), "panic recovered")
@@ -237,7 +236,7 @@ func TestRecoveryWithWriterWithCustomRecovery(t *testing.T) {
 	// Debug mode prints the request
 	SetMode(DebugMode)
 	// RUN
-	w = PerformRequest(router, "GET", "/recovery")
+	w = PerformRequest(router, http.MethodGet, "/recovery")
 	// TEST
 	assert.Equal(t, http.StatusBadRequest, w.Code)
 	assert.Contains(t, buffer.String(), "GET /recovery")
diff --git a/render/render_test.go b/render/render_test.go
index 27a5065..ad633b0 100644
--- a/render/render_test.go
+++ b/render/render_test.go
@@ -369,7 +369,7 @@ func TestRenderXML(t *testing.T) {
 }
 
 func TestRenderRedirect(t *testing.T) {
-	req, err := http.NewRequest("GET", "/test-redirect", nil)
+	req, err := http.NewRequest(http.MethodGet, "/test-redirect", nil)
 	require.NoError(t, err)
 
 	data1 := Redirect{
diff --git a/routes_test.go b/routes_test.go
index d6233b0..995ff51 100644
--- a/routes_test.go
+++ b/routes_test.go
@@ -523,8 +523,8 @@ func TestRouteNotAllowedEnabled3(t *testing.T) {
 	w := PerformRequest(router, http.MethodPut, "/path")
 	assert.Equal(t, http.StatusMethodNotAllowed, w.Code)
 	allowed := w.Header().Get("Allow")
-	assert.Contains(t, allowed, "GET")
-	assert.Contains(t, allowed, "POST")
+	assert.Contains(t, allowed, http.MethodGet)
+	assert.Contains(t, allowed, http.MethodPost)
 }
 
 func TestRouteNotAllowedDisabled(t *testing.T) {
@@ -557,10 +557,10 @@ func TestRouterNotFoundWithRemoveExtraSlash(t *testing.T) {
 		{"/nope", http.StatusNotFound, ""}, // NotFound
 	}
 	for _, tr := range testRoutes {
-		w := PerformRequest(router, "GET", tr.route)
+		w := PerformRequest(router, http.MethodGet, tr.route)
 		assert.Equal(t, tr.code, w.Code)
 		if w.Code != http.StatusNotFound {
-			assert.Equal(t, tr.location, fmt.Sprint(w.Header().Get("Location")))
+			assert.Equal(t, tr.location, w.Header().Get("Location"))
 		}
 	}
 }
@@ -590,7 +590,7 @@ func TestRouterNotFound(t *testing.T) {
 		w := PerformRequest(router, http.MethodGet, tr.route)
 		assert.Equal(t, tr.code, w.Code)
 		if w.Code != http.StatusNotFound {
-			assert.Equal(t, tr.location, fmt.Sprint(w.Header().Get("Location")))
+			assert.Equal(t, tr.location, w.Header().Get("Location"))
 		}
 	}
 
@@ -786,6 +786,6 @@ func TestEngineHandleMethodNotAllowedCornerCase(t *testing.T) {
 	v1.GET("/orgs/:id", handlerTest1)
 	v1.DELETE("/orgs/:id", handlerTest1)
 
-	w := PerformRequest(r, "GET", "/base/v1/user/groups")
+	w := PerformRequest(r, http.MethodGet, "/base/v1/user/groups")
 	assert.Equal(t, http.StatusNotFound, w.Code)
 }
diff --git a/utils_test.go b/utils_test.go
index af08996..8098c68 100644
--- a/utils_test.go
+++ b/utils_test.go
@@ -29,7 +29,7 @@ type testStruct struct {
 }
 
 func (t *testStruct) ServeHTTP(w http.ResponseWriter, req *http.Request) {
-	assert.Equal(t.T, "POST", req.Method)
+	assert.Equal(t.T, http.MethodPost, req.Method)
 	assert.Equal(t.T, "/path", req.URL.Path)
 	w.WriteHeader(http.StatusInternalServerError)
 	fmt.Fprint(w, "hello")
@@ -39,17 +39,17 @@ func TestWrap(t *testing.T) {
 	router := New()
 	router.POST("/path", WrapH(&testStruct{t}))
 	router.GET("/path2", WrapF(func(w http.ResponseWriter, req *http.Request) {
-		assert.Equal(t, "GET", req.Method)
+		assert.Equal(t, http.MethodGet, req.Method)
 		assert.Equal(t, "/path2", req.URL.Path)
 		w.WriteHeader(http.StatusBadRequest)
 		fmt.Fprint(w, "hola!")
 	}))
 
-	w := PerformRequest(router, "POST", "/path")
+	w := PerformRequest(router, http.MethodPost, "/path")
 	assert.Equal(t, http.StatusInternalServerError, w.Code)
 	assert.Equal(t, "hello", w.Body.String())
 
-	w = PerformRequest(router, "GET", "/path2")
+	w = PerformRequest(router, http.MethodGet, "/path2")
 	assert.Equal(t, http.StatusBadRequest, w.Code)
 	assert.Equal(t, "hola!", w.Body.String())
 }
@@ -119,13 +119,13 @@ func TestBindMiddleware(t *testing.T) {
 		called = true
 		value = c.MustGet(BindKey).(*bindTestStruct)
 	})
-	PerformRequest(router, "GET", "/?foo=hola&bar=10")
+	PerformRequest(router, http.MethodGet, "/?foo=hola&bar=10")
 	assert.True(t, called)
 	assert.Equal(t, "hola", value.Foo)
 	assert.Equal(t, 10, value.Bar)
 
 	called = false
-	PerformRequest(router, "GET", "/?foo=hola&bar=1")
+	PerformRequest(router, http.MethodGet, "/?foo=hola&bar=1")
 	assert.False(t, called)
 
 	assert.Panics(t, func() {