Compare commits

..

1 Commits

Author SHA1 Message Date
Ludovico Cavedon 1a7a8d5163
Merge 929794596f into f05f966a08 2024-09-22 21:05:40 +08:00
25 changed files with 489 additions and 543 deletions

View File

@ -26,7 +26,7 @@ jobs:
- name: Setup golangci-lint
uses: golangci/golangci-lint-action@v6
with:
version: v1.61.0
version: v1.58.1
args: --verbose
test:
needs: lint

View File

@ -16,10 +16,8 @@ linters:
- nakedret
- nilerr
- nolintlint
- perfsprint
- revive
- testifylint
- usestdlibvars
- wastedassign
linters-settings:
@ -36,13 +34,6 @@ linters-settings:
- G112
- G201
- G203
perfsprint:
err-error: true
errorf: true
fiximports: true
int-conversion: true
sprintf1: true
strconcat: true
testifylint:
enable-all: true

View File

@ -102,7 +102,6 @@ The documentation is also available on [gin-gonic.com](https://gin-gonic.com) in
- [한국어](https://gin-gonic.com/ko-kr/docs/)
- [Turkish](https://gin-gonic.com/tr/docs/)
- [Persian](https://gin-gonic.com/fa/docs/)
- [Português](https://gin-gonic.com/pt/docs/)
### Articles

View File

@ -90,7 +90,7 @@ func TestBasicAuthSucceed(t *testing.T) {
})
w := httptest.NewRecorder()
req, _ := http.NewRequest(http.MethodGet, "/login", nil)
req, _ := http.NewRequest("GET", "/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(http.MethodGet, "/login", nil)
req, _ := http.NewRequest("GET", "/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(http.MethodGet, "/login", nil)
req, _ := http.NewRequest("GET", "/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(http.MethodGet, "/test", nil)
req, _ := http.NewRequest("GET", "/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(http.MethodGet, "/test", nil)
req, _ := http.NewRequest("GET", "/test", nil)
req.Header.Set("Proxy-Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte("admin:password")))
router.ServeHTTP(w, req)

View File

@ -14,21 +14,21 @@ import (
func BenchmarkOneRoute(B *testing.B) {
router := New()
router.GET("/ping", func(c *Context) {})
runRequest(B, router, http.MethodGet, "/ping")
runRequest(B, router, "GET", "/ping")
}
func BenchmarkRecoveryMiddleware(B *testing.B) {
router := New()
router.Use(Recovery())
router.GET("/", func(c *Context) {})
runRequest(B, router, http.MethodGet, "/")
runRequest(B, router, "GET", "/")
}
func BenchmarkLoggerMiddleware(B *testing.B) {
router := New()
router.Use(LoggerWithWriter(newMockWriter()))
router.GET("/", func(c *Context) {})
runRequest(B, router, http.MethodGet, "/")
runRequest(B, router, "GET", "/")
}
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, http.MethodGet, "/ping")
runRequest(B, router, "GET", "/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, http.MethodGet, "/param/path/to/parameter/john/12345")
runRequest(B, router, "GET", "/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, http.MethodGet, "/json")
runRequest(B, router, "GET", "/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, http.MethodGet, "/html")
runRequest(B, router, "GET", "/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, http.MethodGet, "/ping")
runRequest(B, router, "GET", "/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, http.MethodGet, "/text")
runRequest(B, router, "GET", "/text")
}
func BenchmarkManyRoutesFist(B *testing.B) {
router := New()
router.Any("/ping", func(c *Context) {})
runRequest(B, router, http.MethodGet, "/ping")
runRequest(B, router, "GET", "/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, http.MethodGet, "/ping")
runRequest(B, router, "GET", "/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, http.MethodGet, "/viewfake")
runRequest(B, router, "GET", "/viewfake")
}
type mockWriter struct {

View File

@ -8,7 +8,6 @@ package binding
import (
"bytes"
"net/http"
"testing"
"github.com/stretchr/testify/assert"
@ -40,20 +39,20 @@ func testMsgPackBodyBinding(t *testing.T, b Binding, name, path, badPath, body,
assert.Equal(t, name, b.Name())
obj := FooStruct{}
req := requestWithBody(http.MethodPost, path, body)
req := requestWithBody("POST", 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(http.MethodPost, badPath, badBody)
req = requestWithBody("POST", 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(http.MethodPost, MIMEMSGPACK))
assert.Equal(t, MsgPack, Default(http.MethodPut, MIMEMSGPACK2))
assert.Equal(t, MsgPack, Default("POST", MIMEMSGPACK))
assert.Equal(t, MsgPack, Default("PUT", MIMEMSGPACK2))
}

View File

@ -145,31 +145,31 @@ type FooStructForMapPtrType struct {
}
func TestBindingDefault(t *testing.T) {
assert.Equal(t, Form, Default(http.MethodGet, ""))
assert.Equal(t, Form, Default(http.MethodGet, MIMEJSON))
assert.Equal(t, Form, Default("GET", ""))
assert.Equal(t, Form, Default("GET", MIMEJSON))
assert.Equal(t, JSON, Default(http.MethodPost, MIMEJSON))
assert.Equal(t, JSON, Default(http.MethodPut, MIMEJSON))
assert.Equal(t, JSON, Default("POST", MIMEJSON))
assert.Equal(t, JSON, Default("PUT", MIMEJSON))
assert.Equal(t, XML, Default(http.MethodPost, MIMEXML))
assert.Equal(t, XML, Default(http.MethodPut, MIMEXML2))
assert.Equal(t, XML, Default("POST", MIMEXML))
assert.Equal(t, XML, Default("PUT", MIMEXML2))
assert.Equal(t, Form, Default(http.MethodPost, MIMEPOSTForm))
assert.Equal(t, Form, Default(http.MethodPut, MIMEPOSTForm))
assert.Equal(t, Form, Default("POST", MIMEPOSTForm))
assert.Equal(t, Form, Default("PUT", MIMEPOSTForm))
assert.Equal(t, FormMultipart, Default(http.MethodPost, MIMEMultipartPOSTForm))
assert.Equal(t, FormMultipart, Default(http.MethodPut, MIMEMultipartPOSTForm))
assert.Equal(t, FormMultipart, Default("POST", MIMEMultipartPOSTForm))
assert.Equal(t, FormMultipart, Default("PUT", MIMEMultipartPOSTForm))
assert.Equal(t, ProtoBuf, Default(http.MethodPost, MIMEPROTOBUF))
assert.Equal(t, ProtoBuf, Default(http.MethodPut, MIMEPROTOBUF))
assert.Equal(t, ProtoBuf, Default("POST", MIMEPROTOBUF))
assert.Equal(t, ProtoBuf, Default("PUT", MIMEPROTOBUF))
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, 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, TOML, Default(http.MethodPost, MIMETOML))
assert.Equal(t, TOML, Default(http.MethodPut, MIMETOML))
assert.Equal(t, TOML, Default("POST", MIMETOML))
assert.Equal(t, TOML, Default("PUT", MIMETOML))
}
func TestBindingJSONNilBody(t *testing.T) {
@ -227,137 +227,137 @@ func TestBindingJSONStringMap(t *testing.T) {
}
func TestBindingForm(t *testing.T) {
testFormBinding(t, http.MethodPost,
testFormBinding(t, "POST",
"/", "/",
"foo=bar&bar=foo", "bar2=foo")
}
func TestBindingForm2(t *testing.T) {
testFormBinding(t, http.MethodGet,
testFormBinding(t, "GET",
"/?foo=bar&bar=foo", "/?bar2=foo",
"", "")
}
func TestBindingFormEmbeddedStruct(t *testing.T) {
testFormBindingEmbeddedStruct(t, http.MethodPost,
testFormBindingEmbeddedStruct(t, "POST",
"/", "/",
"page=1&size=2&appkey=test-appkey", "bar2=foo")
}
func TestBindingFormEmbeddedStruct2(t *testing.T) {
testFormBindingEmbeddedStruct(t, http.MethodGet,
testFormBindingEmbeddedStruct(t, "GET",
"/?page=1&size=2&appkey=test-appkey", "/?bar2=foo",
"", "")
}
func TestBindingFormDefaultValue(t *testing.T) {
testFormBindingDefaultValue(t, http.MethodPost,
testFormBindingDefaultValue(t, "POST",
"/", "/",
"foo=bar", "bar2=foo")
}
func TestBindingFormDefaultValue2(t *testing.T) {
testFormBindingDefaultValue(t, http.MethodGet,
testFormBindingDefaultValue(t, "GET",
"/?foo=bar", "/?bar2=foo",
"", "")
}
func TestBindingFormForTime(t *testing.T) {
testFormBindingForTime(t, http.MethodPost,
testFormBindingForTime(t, "POST",
"/", "/",
"time_foo=2017-11-15&time_bar=&createTime=1562400033000000123&unixTime=1562400033", "bar2=foo")
testFormBindingForTimeNotUnixFormat(t, http.MethodPost,
testFormBindingForTimeNotUnixFormat(t, "POST",
"/", "/",
"time_foo=2017-11-15&createTime=bad&unixTime=bad", "bar2=foo")
testFormBindingForTimeNotFormat(t, http.MethodPost,
testFormBindingForTimeNotFormat(t, "POST",
"/", "/",
"time_foo=2017-11-15", "bar2=foo")
testFormBindingForTimeFailFormat(t, http.MethodPost,
testFormBindingForTimeFailFormat(t, "POST",
"/", "/",
"time_foo=2017-11-15", "bar2=foo")
testFormBindingForTimeFailLocation(t, http.MethodPost,
testFormBindingForTimeFailLocation(t, "POST",
"/", "/",
"time_foo=2017-11-15", "bar2=foo")
}
func TestBindingFormForTime2(t *testing.T) {
testFormBindingForTime(t, http.MethodGet,
testFormBindingForTime(t, "GET",
"/?time_foo=2017-11-15&time_bar=&createTime=1562400033000000123&unixTime=1562400033", "/?bar2=foo",
"", "")
testFormBindingForTimeNotUnixFormat(t, http.MethodPost,
testFormBindingForTimeNotUnixFormat(t, "POST",
"/", "/",
"time_foo=2017-11-15&createTime=bad&unixTime=bad", "bar2=foo")
testFormBindingForTimeNotFormat(t, http.MethodGet,
testFormBindingForTimeNotFormat(t, "GET",
"/?time_foo=2017-11-15", "/?bar2=foo",
"", "")
testFormBindingForTimeFailFormat(t, http.MethodGet,
testFormBindingForTimeFailFormat(t, "GET",
"/?time_foo=2017-11-15", "/?bar2=foo",
"", "")
testFormBindingForTimeFailLocation(t, http.MethodGet,
testFormBindingForTimeFailLocation(t, "GET",
"/?time_foo=2017-11-15", "/?bar2=foo",
"", "")
}
func TestFormBindingIgnoreField(t *testing.T) {
testFormBindingIgnoreField(t, http.MethodPost,
testFormBindingIgnoreField(t, "POST",
"/", "/",
"-=bar", "")
}
func TestBindingFormInvalidName(t *testing.T) {
testFormBindingInvalidName(t, http.MethodPost,
testFormBindingInvalidName(t, "POST",
"/", "/",
"test_name=bar", "bar2=foo")
}
func TestBindingFormInvalidName2(t *testing.T) {
testFormBindingInvalidName2(t, http.MethodPost,
testFormBindingInvalidName2(t, "POST",
"/", "/",
"map_foo=bar", "bar2=foo")
}
func TestBindingFormForType(t *testing.T) {
testFormBindingForType(t, http.MethodPost,
testFormBindingForType(t, "POST",
"/", "/",
"map_foo={\"bar\":123}", "map_foo=1", "Map")
testFormBindingForType(t, http.MethodPost,
testFormBindingForType(t, "POST",
"/", "/",
"slice_foo=1&slice_foo=2", "bar2=1&bar2=2", "Slice")
testFormBindingForType(t, http.MethodGet,
testFormBindingForType(t, "GET",
"/?slice_foo=1&slice_foo=2", "/?bar2=1&bar2=2",
"", "", "Slice")
testFormBindingForType(t, http.MethodPost,
testFormBindingForType(t, "POST",
"/", "/",
"slice_map_foo=1&slice_map_foo=2", "bar2=1&bar2=2", "SliceMap")
testFormBindingForType(t, http.MethodGet,
testFormBindingForType(t, "GET",
"/?slice_map_foo=1&slice_map_foo=2", "/?bar2=1&bar2=2",
"", "", "SliceMap")
testFormBindingForType(t, http.MethodPost,
testFormBindingForType(t, "POST",
"/", "/",
"ptr_bar=test", "bar2=test", "Ptr")
testFormBindingForType(t, http.MethodGet,
testFormBindingForType(t, "GET",
"/?ptr_bar=test", "/?bar2=test",
"", "", "Ptr")
testFormBindingForType(t, http.MethodPost,
testFormBindingForType(t, "POST",
"/", "/",
"idx=123", "id1=1", "Struct")
testFormBindingForType(t, http.MethodGet,
testFormBindingForType(t, "GET",
"/?idx=123", "/?id1=1",
"", "", "Struct")
testFormBindingForType(t, http.MethodPost,
testFormBindingForType(t, "POST",
"/", "/",
"name=thinkerou", "name1=ou", "StructPointer")
testFormBindingForType(t, http.MethodGet,
testFormBindingForType(t, "GET",
"/?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(http.MethodPost, "/", "foo=something&foo=bar&hello=world")
req := requestWithBody("POST", "/", "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(http.MethodPost, "/", "foo=something&foo=bar&hello=world")
req = requestWithBody("POST", "/", "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, http.MethodPost,
testQueryBinding(t, "POST",
"/?foo=bar&bar=foo", "/",
"foo=unused", "bar2=foo")
}
func TestBindingQuery2(t *testing.T) {
testQueryBinding(t, http.MethodGet,
testQueryBinding(t, "GET",
"/?foo=bar&bar=foo", "/?bar2=foo",
"foo=unused", "")
}
func TestBindingQueryFail(t *testing.T) {
testQueryBindingFail(t, http.MethodPost,
testQueryBindingFail(t, "POST",
"/?map_foo=", "/",
"map_foo=unused", "bar2=foo")
}
func TestBindingQueryFail2(t *testing.T) {
testQueryBindingFail(t, http.MethodGet,
testQueryBindingFail(t, "GET",
"/?map_foo=", "/?bar2=foo",
"map_foo=unused", "")
}
func TestBindingQueryBoolFail(t *testing.T) {
testQueryBindingBoolFail(t, http.MethodGet,
testQueryBindingBoolFail(t, "GET",
"/?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(http.MethodGet, "/?foo=bar&hello=world", "")
req := requestWithBody("GET", "/?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(http.MethodGet, "/?foo=bar&foo=2&hello=world", "") // should pick last
req = requestWithBody("GET", "/?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(http.MethodPost, "/?foo=getfoo&bar=getbar", bytes.NewBufferString("foo=bar&bar=foo"))
req, err := http.NewRequest("POST", "/?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(http.MethodPost, "/?foo=getfoo&bar=getbar", bytes.NewBufferString("foo=bar"))
req, err := http.NewRequest("POST", "/?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(http.MethodPost, "/?map_foo=getfoo", bytes.NewBufferString("map_foo={\"bar\":123}"))
req, err := http.NewRequest("POST", "/?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(http.MethodPost, "/?map_foo=getfoo", bytes.NewBufferString("map_foo=hello"))
req, err := http.NewRequest("POST", "/?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(http.MethodPost, "/?foo=getfoo&bar=getbar", body)
req, err2 := http.NewRequest("POST", "/?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(http.MethodPost, "/?foo=getfoo&bar=getbar", body)
req, err2 := http.NewRequest("POST", "/?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(http.MethodPost, "/?foo=getfoo&bar=getbar", body)
req, err := http.NewRequest("POST", "/?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(http.MethodPost, "/?map_foo=getfoo", body)
req, err := http.NewRequest("POST", "/?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(http.MethodPost, "/?map_foo=getfoo", body)
req, err := http.NewRequest("POST", "/?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(http.MethodPost, "/", `{"bar": "foo"}`)
req := requestWithBody("POST", "/", `{"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(http.MethodPost, "/", `{"bar": "foo"}`)
req := requestWithBody("POST", "/", `{"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(http.MethodPost, "/", `{"hoge": 0}`)
req := requestWithBody("POST", "/", `{"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(http.MethodPost, "/", `{"boen": 0}`)
req := requestWithBody("POST", "/", `{"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(http.MethodGet, "/", "")
req := requestWithBody("GET", "/", "")
req.Header.Add("limit", "1000")
require.NoError(t, h.Bind(req, &theader))
assert.Equal(t, 1000, theader.Limit)
req = requestWithBody(http.MethodGet, "/", "")
req = requestWithBody("GET", "/", "")
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 == http.MethodPost {
if method == "POST" {
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 == http.MethodPost {
if method == "POST" {
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 == http.MethodPost {
if method == "POST" {
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(http.MethodPost, "/", nil)
req, _ := http.NewRequest("POST", "/", nil)
err := b.Bind(req, &obj)
require.Error(t, err)
}
func TestFormBindingMultipartFail(t *testing.T) {
obj := FooBarStruct{}
req, err := http.NewRequest(http.MethodPost, "/", strings.NewReader("foo=bar"))
req, err := http.NewRequest("POST", "/", 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(http.MethodPost, "/", nil)
req, _ := http.NewRequest("POST", "/", 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(http.MethodPost, "/", nil)
req, _ := http.NewRequest("POST", "/", 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 == http.MethodPost {
if method == "POST" {
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 == http.MethodPost {
if method == "POST" {
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 == http.MethodPost {
if method == "POST" {
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 == http.MethodPost {
if method == "POST" {
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 == http.MethodPost {
if method == "POST" {
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 == http.MethodPost {
if method == "POST" {
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 == http.MethodPost {
if method == "POST" {
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 == http.MethodPost {
if method == "POST" {
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 == http.MethodPost {
if method == "POST" {
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 == http.MethodPost {
if method == "POST" {
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 == http.MethodPost {
if method == "POST" {
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 == http.MethodPost {
if method == "POST" {
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(http.MethodPost, path, body)
req := requestWithBody("POST", path, body)
err := b.Bind(req, &obj)
require.NoError(t, err)
assert.Equal(t, "bar", obj.Foo)
obj = FooStruct{}
req = requestWithBody(http.MethodPost, badPath, badBody)
req = requestWithBody("POST", 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(http.MethodPost, path, body)
req := requestWithBody("POST", path, body)
err := b.Bind(req, &obj1)
require.NoError(t, err)
var obj2 []FooStruct
req = requestWithBody(http.MethodPost, badPath, badBody)
req = requestWithBody("POST", 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(http.MethodPost, path, body)
req := requestWithBody("POST", 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(http.MethodPost, badPath, badBody)
req = requestWithBody("POST", badPath, badBody)
err = b.Bind(req, &obj)
require.Error(t, err)
}
objInt := make(map[string]int)
req = requestWithBody(http.MethodPost, path, body)
req = requestWithBody("POST", 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(http.MethodPost, path, body)
req := requestWithBody("POST", 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(http.MethodPost, badPath, badBody)
req = requestWithBody("POST", 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(http.MethodPost, path, body)
req := requestWithBody("POST", 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(http.MethodPost, badPath, badBody)
req = requestWithBody("POST", 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(http.MethodPost, path, body)
req := requestWithBody("POST", path, body)
err := b.Bind(req, &obj)
require.NoError(t, err)
assert.Equal(t, "bar", obj.Foo)
obj = FooStructDisallowUnknownFields{}
req = requestWithBody(http.MethodPost, badPath, badBody)
req = requestWithBody("POST", 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(http.MethodPost, path, body)
req := requestWithBody("POST", path, body)
err := b.Bind(req, &obj)
require.Error(t, err)
assert.Equal(t, "", obj.Foo)
obj = FooStruct{}
req = requestWithBody(http.MethodPost, badPath, badBody)
req = requestWithBody("POST", 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(http.MethodPost, path, body)
req := requestWithBody("POST", 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(http.MethodPost, badPath, badBody)
req = requestWithBody("POST", 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(http.MethodPost, "/", "test string")
req := requestWithBody("POST", "/", "test string")
require.NoError(t, p.Bind(req, &s))
assert.Equal(t, "test string", s)
var bs []byte
req = requestWithBody(http.MethodPost, "/", "test []byte")
req = requestWithBody("POST", "/", "test []byte")
require.NoError(t, p.Bind(req, &bs))
assert.Equal(t, bs, []byte("test []byte"))
var i int
req = requestWithBody(http.MethodPost, "/", "test fail")
req = requestWithBody("POST", "/", "test fail")
require.Error(t, p.Bind(req, &i))
req = requestWithBody(http.MethodPost, "/", "")
req = requestWithBody("POST", "/", "")
req.Body = &failRead{}
require.Error(t, p.Bind(req, &s))
req = requestWithBody(http.MethodPost, "/", "")
req = requestWithBody("POST", "/", "")
require.NoError(t, p.Bind(req, nil))
var ptr *string
req = requestWithBody(http.MethodPost, "/", "")
req = requestWithBody("POST", "/", "")
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(http.MethodPost, path, body)
req := requestWithBody("POST", 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(http.MethodPost, badPath, badBody)
req = requestWithBody("POST", badPath, badBody)
req.Header.Add("Content-Type", MIMEPROTOBUF)
err = ProtoBuf.Bind(req, &obj)
require.Error(t, err)

View File

@ -6,7 +6,7 @@ package binding
import (
"encoding/hex"
"errors"
"fmt"
"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 errors.New("invalid format")
return fmt.Errorf("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 errors.New("invalid format")
return fmt.Errorf("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, errors.New("invalid format")
return nilObjectID, fmt.Errorf("invalid format")
}
var oid [12]byte

View File

@ -116,7 +116,7 @@ func createRequestMultipartFiles(t *testing.T, files ...testFile) *http.Request
err := mw.Close()
require.NoError(t, err)
req, err := http.NewRequest(http.MethodPost, "/", &body)
req, err := http.NewRequest("POST", "/", &body)
require.NoError(t, err)
req.Header.Set("Content-Type", MIMEMultipartPOSTForm+"; boundary="+mw.Boundary())

View File

@ -7,7 +7,6 @@ package gin
import (
"errors"
"io"
"io/fs"
"log"
"math"
"mime/multipart"
@ -187,9 +186,10 @@ func (c *Context) FullPath() string {
func (c *Context) Next() {
c.index++
for c.index < int8(len(c.handlers)) {
if c.handlers[c.index] != nil {
c.handlers[c.index](c)
if c.handlers[c.index] == nil {
continue
}
c.handlers[c.index](c)
c.index++
}
}
@ -291,171 +291,248 @@ func (c *Context) MustGet(key string) any {
panic("Key \"" + key + "\" does not exist")
}
func getTyped[T any](c *Context, key string) (res T) {
// GetString returns the value associated with the key as a string.
func (c *Context) GetString(key string) (s string) {
if val, ok := c.Get(key); ok && val != nil {
res, _ = val.(T)
s, _ = val.(string)
}
return
}
// GetString returns the value associated with the key as a string.
func (c *Context) GetString(key string) (s string) {
return getTyped[string](c, key)
}
// GetBool returns the value associated with the key as a boolean.
func (c *Context) GetBool(key string) (b bool) {
return getTyped[bool](c, key)
if val, ok := c.Get(key); ok && val != nil {
b, _ = val.(bool)
}
return
}
// GetInt returns the value associated with the key as an integer.
func (c *Context) GetInt(key string) (i int) {
return getTyped[int](c, key)
if val, ok := c.Get(key); ok && val != nil {
i, _ = val.(int)
}
return
}
// GetInt8 returns the value associated with the key as an integer 8.
func (c *Context) GetInt8(key string) (i8 int8) {
return getTyped[int8](c, key)
if val, ok := c.Get(key); ok && val != nil {
i8, _ = val.(int8)
}
return
}
// GetInt16 returns the value associated with the key as an integer 16.
func (c *Context) GetInt16(key string) (i16 int16) {
return getTyped[int16](c, key)
if val, ok := c.Get(key); ok && val != nil {
i16, _ = val.(int16)
}
return
}
// GetInt32 returns the value associated with the key as an integer 32.
func (c *Context) GetInt32(key string) (i32 int32) {
return getTyped[int32](c, key)
if val, ok := c.Get(key); ok && val != nil {
i32, _ = val.(int32)
}
return
}
// GetInt64 returns the value associated with the key as an integer 64.
func (c *Context) GetInt64(key string) (i64 int64) {
return getTyped[int64](c, key)
if val, ok := c.Get(key); ok && val != nil {
i64, _ = val.(int64)
}
return
}
// GetUint returns the value associated with the key as an unsigned integer.
func (c *Context) GetUint(key string) (ui uint) {
return getTyped[uint](c, key)
if val, ok := c.Get(key); ok && val != nil {
ui, _ = val.(uint)
}
return
}
// GetUint8 returns the value associated with the key as an unsigned integer 8.
func (c *Context) GetUint8(key string) (ui8 uint8) {
return getTyped[uint8](c, key)
if val, ok := c.Get(key); ok && val != nil {
ui8, _ = val.(uint8)
}
return
}
// GetUint16 returns the value associated with the key as an unsigned integer 16.
func (c *Context) GetUint16(key string) (ui16 uint16) {
return getTyped[uint16](c, key)
if val, ok := c.Get(key); ok && val != nil {
ui16, _ = val.(uint16)
}
return
}
// GetUint32 returns the value associated with the key as an unsigned integer 32.
func (c *Context) GetUint32(key string) (ui32 uint32) {
return getTyped[uint32](c, key)
if val, ok := c.Get(key); ok && val != nil {
ui32, _ = val.(uint32)
}
return
}
// GetUint64 returns the value associated with the key as an unsigned integer 64.
func (c *Context) GetUint64(key string) (ui64 uint64) {
return getTyped[uint64](c, key)
if val, ok := c.Get(key); ok && val != nil {
ui64, _ = val.(uint64)
}
return
}
// GetFloat32 returns the value associated with the key as a float32.
func (c *Context) GetFloat32(key string) (f32 float32) {
return getTyped[float32](c, key)
if val, ok := c.Get(key); ok && val != nil {
f32, _ = val.(float32)
}
return
}
// GetFloat64 returns the value associated with the key as a float64.
func (c *Context) GetFloat64(key string) (f64 float64) {
return getTyped[float64](c, key)
if val, ok := c.Get(key); ok && val != nil {
f64, _ = val.(float64)
}
return
}
// GetTime returns the value associated with the key as time.
func (c *Context) GetTime(key string) (t time.Time) {
return getTyped[time.Time](c, key)
if val, ok := c.Get(key); ok && val != nil {
t, _ = val.(time.Time)
}
return
}
// GetDuration returns the value associated with the key as a duration.
func (c *Context) GetDuration(key string) (d time.Duration) {
return getTyped[time.Duration](c, key)
if val, ok := c.Get(key); ok && val != nil {
d, _ = val.(time.Duration)
}
return
}
// GetIntSlice returns the value associated with the key as a slice of integers.
func (c *Context) GetIntSlice(key string) (is []int) {
return getTyped[[]int](c, key)
if val, ok := c.Get(key); ok && val != nil {
is, _ = val.([]int)
}
return
}
// GetInt8Slice returns the value associated with the key as a slice of int8 integers.
func (c *Context) GetInt8Slice(key string) (i8s []int8) {
return getTyped[[]int8](c, key)
if val, ok := c.Get(key); ok && val != nil {
i8s, _ = val.([]int8)
}
return
}
// GetInt16Slice returns the value associated with the key as a slice of int16 integers.
func (c *Context) GetInt16Slice(key string) (i16s []int16) {
return getTyped[[]int16](c, key)
if val, ok := c.Get(key); ok && val != nil {
i16s, _ = val.([]int16)
}
return
}
// GetInt32Slice returns the value associated with the key as a slice of int32 integers.
func (c *Context) GetInt32Slice(key string) (i32s []int32) {
return getTyped[[]int32](c, key)
if val, ok := c.Get(key); ok && val != nil {
i32s, _ = val.([]int32)
}
return
}
// GetInt64Slice returns the value associated with the key as a slice of int64 integers.
func (c *Context) GetInt64Slice(key string) (i64s []int64) {
return getTyped[[]int64](c, key)
if val, ok := c.Get(key); ok && val != nil {
i64s, _ = val.([]int64)
}
return
}
// GetUintSlice returns the value associated with the key as a slice of unsigned integers.
func (c *Context) GetUintSlice(key string) (uis []uint) {
return getTyped[[]uint](c, key)
if val, ok := c.Get(key); ok && val != nil {
uis, _ = val.([]uint)
}
return
}
// GetUint8Slice returns the value associated with the key as a slice of uint8 integers.
func (c *Context) GetUint8Slice(key string) (ui8s []uint8) {
return getTyped[[]uint8](c, key)
if val, ok := c.Get(key); ok && val != nil {
ui8s, _ = val.([]uint8)
}
return
}
// GetUint16Slice returns the value associated with the key as a slice of uint16 integers.
func (c *Context) GetUint16Slice(key string) (ui16s []uint16) {
return getTyped[[]uint16](c, key)
if val, ok := c.Get(key); ok && val != nil {
ui16s, _ = val.([]uint16)
}
return
}
// GetUint32Slice returns the value associated with the key as a slice of uint32 integers.
func (c *Context) GetUint32Slice(key string) (ui32s []uint32) {
return getTyped[[]uint32](c, key)
if val, ok := c.Get(key); ok && val != nil {
ui32s, _ = val.([]uint32)
}
return
}
// GetUint64Slice returns the value associated with the key as a slice of uint64 integers.
func (c *Context) GetUint64Slice(key string) (ui64s []uint64) {
return getTyped[[]uint64](c, key)
if val, ok := c.Get(key); ok && val != nil {
ui64s, _ = val.([]uint64)
}
return
}
// GetFloat32Slice returns the value associated with the key as a slice of float32 numbers.
func (c *Context) GetFloat32Slice(key string) (f32s []float32) {
return getTyped[[]float32](c, key)
if val, ok := c.Get(key); ok && val != nil {
f32s, _ = val.([]float32)
}
return
}
// GetFloat64Slice returns the value associated with the key as a slice of float64 numbers.
func (c *Context) GetFloat64Slice(key string) (f64s []float64) {
return getTyped[[]float64](c, key)
if val, ok := c.Get(key); ok && val != nil {
f64s, _ = val.([]float64)
}
return
}
// GetStringSlice returns the value associated with the key as a slice of strings.
func (c *Context) GetStringSlice(key string) (ss []string) {
return getTyped[[]string](c, key)
if val, ok := c.Get(key); ok && val != nil {
ss, _ = val.([]string)
}
return
}
// GetStringMap returns the value associated with the key as a map of interfaces.
func (c *Context) GetStringMap(key string) (sm map[string]any) {
return getTyped[map[string]any](c, key)
if val, ok := c.Get(key); ok && val != nil {
sm, _ = val.(map[string]any)
}
return
}
// GetStringMapString returns the value associated with the key as a map of strings.
func (c *Context) GetStringMapString(key string) (sms map[string]string) {
return getTyped[map[string]string](c, key)
if val, ok := c.Get(key); ok && val != nil {
sms, _ = val.(map[string]string)
}
return
}
// GetStringMapStringSlice returns the value associated with the key as a map to a slice of strings.
func (c *Context) GetStringMapStringSlice(key string) (smss map[string][]string) {
return getTyped[map[string][]string](c, key)
if val, ok := c.Get(key); ok && val != nil {
smss, _ = val.(map[string][]string)
}
return
}
/************************************/
@ -677,22 +754,14 @@ func (c *Context) MultipartForm() (*multipart.Form, error) {
}
// SaveUploadedFile uploads the form file to specific dst.
func (c *Context) SaveUploadedFile(file *multipart.FileHeader, dst string, perm ...fs.FileMode) error {
func (c *Context) SaveUploadedFile(file *multipart.FileHeader, dst string) error {
src, err := file.Open()
if err != nil {
return err
}
defer src.Close()
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 {
if err = os.MkdirAll(filepath.Dir(dst), 0o750); err != nil {
return err
}
@ -882,7 +951,7 @@ func (c *Context) ShouldBindBodyWithTOML(obj any) error {
return c.ShouldBindBodyWith(obj, binding.TOML)
}
// ShouldBindBodyWithPlain is a shortcut for c.ShouldBindBodyWith(obj, binding.Plain).
// ShouldBindBodyWithJSON is a shortcut for c.ShouldBindBodyWith(obj, binding.JSON).
func (c *Context) ShouldBindBodyWithPlain(obj any) error {
return c.ShouldBindBodyWith(obj, binding.Plain)
}

View File

@ -11,16 +11,13 @@ 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"
@ -62,7 +59,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(http.MethodPost, "/", body)
req, err := http.NewRequest("POST", "/", body)
must(err)
req.Header.Set("Content-Type", MIMEMultipartPOSTForm+"; boundary="+boundary)
return req
@ -83,7 +80,7 @@ func TestContextFormFile(t *testing.T) {
require.NoError(t, err)
mw.Close()
c, _ := CreateTestContext(httptest.NewRecorder())
c.Request, _ = http.NewRequest(http.MethodPost, "/", buf)
c.Request, _ = http.NewRequest("POST", "/", buf)
c.Request.Header.Set("Content-Type", mw.FormDataContentType())
f, err := c.FormFile("file")
require.NoError(t, err)
@ -97,7 +94,7 @@ func TestContextFormFileFailed(t *testing.T) {
mw := multipart.NewWriter(buf)
mw.Close()
c, _ := CreateTestContext(httptest.NewRecorder())
c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
c.Request, _ = http.NewRequest("POST", "/", nil)
c.Request.Header.Set("Content-Type", mw.FormDataContentType())
c.engine.MaxMultipartMemory = 8 << 20
f, err := c.FormFile("file")
@ -115,7 +112,7 @@ func TestContextMultipartForm(t *testing.T) {
require.NoError(t, err)
mw.Close()
c, _ := CreateTestContext(httptest.NewRecorder())
c.Request, _ = http.NewRequest(http.MethodPost, "/", buf)
c.Request, _ = http.NewRequest("POST", "/", buf)
c.Request.Header.Set("Content-Type", mw.FormDataContentType())
f, err := c.MultipartForm()
require.NoError(t, err)
@ -130,7 +127,7 @@ func TestSaveUploadedOpenFailed(t *testing.T) {
mw.Close()
c, _ := CreateTestContext(httptest.NewRecorder())
c.Request, _ = http.NewRequest(http.MethodPost, "/", buf)
c.Request, _ = http.NewRequest("POST", "/", buf)
c.Request.Header.Set("Content-Type", mw.FormDataContentType())
f := &multipart.FileHeader{
@ -148,7 +145,7 @@ func TestSaveUploadedCreateFailed(t *testing.T) {
require.NoError(t, err)
mw.Close()
c, _ := CreateTestContext(httptest.NewRecorder())
c.Request, _ = http.NewRequest(http.MethodPost, "/", buf)
c.Request, _ = http.NewRequest("POST", "/", buf)
c.Request.Header.Set("Content-Type", mw.FormDataContentType())
f, err := c.FormFile("file")
require.NoError(t, err)
@ -157,45 +154,6 @@ 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)
@ -365,7 +323,7 @@ func TestContextGetFloat32(t *testing.T) {
key := "float32"
value := float32(3.14)
c.Set(key, value)
assert.InDelta(t, value, c.GetFloat32(key), 0.01)
assert.Equal(t, value, c.GetFloat32(key))
}
func TestContextGetFloat64(t *testing.T) {
@ -522,7 +480,7 @@ func TestContextGetStringMapStringSlice(t *testing.T) {
func TestContextCopy(t *testing.T) {
c, _ := CreateTestContext(httptest.NewRecorder())
c.index = 2
c.Request, _ = http.NewRequest(http.MethodPost, "/hola", nil)
c.Request, _ = http.NewRequest("POST", "/hola", nil)
c.handlers = HandlersChain{func(c *Context) {}}
c.Params = Params{Param{Key: "foo", Value: "bar"}}
c.Set("foo", "bar")
@ -579,7 +537,7 @@ func TestContextHandler(t *testing.T) {
func TestContextQuery(t *testing.T) {
c, _ := CreateTestContext(httptest.NewRecorder())
c.Request, _ = http.NewRequest(http.MethodGet, "http://example.com/?foo=bar&page=10&id=", nil)
c.Request, _ = http.NewRequest("GET", "http://example.com/?foo=bar&page=10&id=", nil)
value, ok := c.GetQuery("foo")
assert.True(t, ok)
@ -652,6 +610,7 @@ func TestContextInitQueryCache(t *testing.T) {
assert.Equal(t, test.expectedQueryCache, test.testContext.queryCache)
})
}
}
func TestContextDefaultQueryOnEmptyRequest(t *testing.T) {
@ -672,7 +631,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(http.MethodPost,
c.Request, _ = http.NewRequest("POST",
"/?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)
@ -692,7 +651,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, http.MethodGet, c.Query("both"), http.MethodGet)
assert.Equal(t, "GET", c.Query("both"), "GET")
value, ok = c.GetQuery("id")
assert.True(t, ok)
@ -740,7 +699,7 @@ func TestContextQueryAndPostForm(t *testing.T) {
values = c.QueryArray("both")
assert.Len(t, values, 1)
assert.Equal(t, http.MethodGet, values[0])
assert.Equal(t, "GET", values[0])
dicts, ok := c.GetQueryMap("ids")
assert.True(t, ok)
@ -882,7 +841,7 @@ func TestContextSetCookieWithSpace(t *testing.T) {
func TestContextGetCookie(t *testing.T) {
c, _ := CreateTestContext(httptest.NewRecorder())
c.Request, _ = http.NewRequest(http.MethodGet, "/get", nil)
c.Request, _ = http.NewRequest("GET", "/get", nil)
c.Request.Header.Set("Cookie", "user=gin")
cookie, _ := c.Cookie("user")
assert.Equal(t, "gin", cookie)
@ -934,7 +893,7 @@ func TestContextRenderJSON(t *testing.T) {
func TestContextRenderJSONP(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodGet, "http://example.com/?callback=x", nil)
c.Request, _ = http.NewRequest("GET", "http://example.com/?callback=x", nil)
c.JSONP(http.StatusCreated, H{"foo": "bar"})
@ -948,7 +907,7 @@ func TestContextRenderJSONP(t *testing.T) {
func TestContextRenderJSONPWithoutCallback(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodGet, "http://example.com", nil)
c.Request, _ = http.NewRequest("GET", "http://example.com", nil)
c.JSONP(http.StatusCreated, H{"foo": "bar"})
@ -1091,7 +1050,7 @@ func TestContextRenderHTML2(t *testing.T) {
c, router := CreateTestContext(w)
// print debug warning log when Engine.trees > 0
router.addRoute(http.MethodGet, "/", HandlersChain{func(_ *Context) {}})
router.addRoute("GET", "/", HandlersChain{func(_ *Context) {}})
assert.Len(t, router.trees, 1)
templ := template.Must(template.New("t").Parse(`Hello {{.name}}`))
@ -1201,7 +1160,7 @@ func TestContextRenderNoContentHTMLString(t *testing.T) {
assert.Equal(t, "text/html; charset=utf-8", w.Header().Get("Content-Type"))
}
// TestContextRenderData tests that the response can be written from `bytestring`
// TestContextData tests that the response can be written from `bytestring`
// with specified MIME type
func TestContextRenderData(t *testing.T) {
w := httptest.NewRecorder()
@ -1247,7 +1206,7 @@ func TestContextRenderFile(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodGet, "/", nil)
c.Request, _ = http.NewRequest("GET", "/", nil)
c.File("./gin.go")
assert.Equal(t, http.StatusOK, w.Code)
@ -1261,7 +1220,7 @@ func TestContextRenderFileFromFS(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodGet, "/some/path", nil)
c.Request, _ = http.NewRequest("GET", "/some/path", nil)
c.FileFromFS("./gin.go", Dir(".", false))
assert.Equal(t, http.StatusOK, w.Code)
@ -1277,7 +1236,7 @@ func TestContextRenderAttachment(t *testing.T) {
c, _ := CreateTestContext(w)
newFilename := "new_filename.go"
c.Request, _ = http.NewRequest(http.MethodGet, "/", nil)
c.Request, _ = http.NewRequest("GET", "/", nil)
c.FileAttachment("./gin.go", newFilename)
assert.Equal(t, 200, w.Code)
@ -1291,7 +1250,7 @@ func TestContextRenderAndEscapeAttachment(t *testing.T) {
maliciousFilename := "tampering_field.sh\"; \\\"; dummy=.go"
actualEscapedResponseFilename := "tampering_field.sh\\\"; \\\\\\\"; dummy=.go"
c.Request, _ = http.NewRequest(http.MethodGet, "/", nil)
c.Request, _ = http.NewRequest("GET", "/", nil)
c.FileAttachment("./gin.go", maliciousFilename)
assert.Equal(t, 200, w.Code)
@ -1304,7 +1263,7 @@ func TestContextRenderUTF8Attachment(t *testing.T) {
c, _ := CreateTestContext(w)
newFilename := "new🧡_filename.go"
c.Request, _ = http.NewRequest(http.MethodGet, "/", nil)
c.Request, _ = http.NewRequest("GET", "/", nil)
c.FileAttachment("./gin.go", newFilename)
assert.Equal(t, 200, w.Code)
@ -1383,7 +1342,7 @@ func TestContextRenderRedirectWithRelativePath(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodPost, "http://example.com", nil)
c.Request, _ = http.NewRequest("POST", "http://example.com", nil)
assert.Panics(t, func() { c.Redirect(299, "/new_path") })
assert.Panics(t, func() { c.Redirect(309, "/new_path") })
@ -1397,7 +1356,7 @@ func TestContextRenderRedirectWithAbsolutePath(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodPost, "http://example.com", nil)
c.Request, _ = http.NewRequest("POST", "http://example.com", nil)
c.Redirect(http.StatusFound, "http://google.com")
c.Writer.WriteHeaderNow()
@ -1409,7 +1368,7 @@ func TestContextRenderRedirectWith201(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodPost, "http://example.com", nil)
c.Request, _ = http.NewRequest("POST", "http://example.com", nil)
c.Redirect(http.StatusCreated, "/resource")
c.Writer.WriteHeaderNow()
@ -1419,7 +1378,7 @@ func TestContextRenderRedirectWith201(t *testing.T) {
func TestContextRenderRedirectAll(t *testing.T) {
c, _ := CreateTestContext(httptest.NewRecorder())
c.Request, _ = http.NewRequest(http.MethodPost, "http://example.com", nil)
c.Request, _ = http.NewRequest("POST", "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") })
@ -1431,7 +1390,7 @@ func TestContextRenderRedirectAll(t *testing.T) {
func TestContextNegotiationWithJSON(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodPost, "", nil)
c.Request, _ = http.NewRequest("POST", "", nil)
c.Negotiate(http.StatusOK, Negotiate{
Offered: []string{MIMEJSON, MIMEXML, MIMEYAML, MIMEYAML2},
@ -1446,7 +1405,7 @@ func TestContextNegotiationWithJSON(t *testing.T) {
func TestContextNegotiationWithXML(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodPost, "", nil)
c.Request, _ = http.NewRequest("POST", "", nil)
c.Negotiate(http.StatusOK, Negotiate{
Offered: []string{MIMEXML, MIMEJSON, MIMEYAML, MIMEYAML2},
@ -1461,7 +1420,7 @@ func TestContextNegotiationWithXML(t *testing.T) {
func TestContextNegotiationWithYAML(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodPost, "", nil)
c.Request, _ = http.NewRequest("POST", "", nil)
c.Negotiate(http.StatusOK, Negotiate{
Offered: []string{MIMEYAML, MIMEXML, MIMEJSON, MIMETOML, MIMEYAML2},
@ -1476,7 +1435,7 @@ func TestContextNegotiationWithYAML(t *testing.T) {
func TestContextNegotiationWithTOML(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodPost, "", nil)
c.Request, _ = http.NewRequest("POST", "", nil)
c.Negotiate(http.StatusOK, Negotiate{
Offered: []string{MIMETOML, MIMEXML, MIMEJSON, MIMEYAML, MIMEYAML2},
@ -1491,7 +1450,7 @@ func TestContextNegotiationWithTOML(t *testing.T) {
func TestContextNegotiationWithHTML(t *testing.T) {
w := httptest.NewRecorder()
c, router := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodPost, "", nil)
c.Request, _ = http.NewRequest("POST", "", nil)
templ := template.Must(template.New("t").Parse(`Hello {{.name}}`))
router.SetHTMLTemplate(templ)
@ -1509,7 +1468,7 @@ func TestContextNegotiationWithHTML(t *testing.T) {
func TestContextNegotiationNotSupport(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodPost, "", nil)
c.Request, _ = http.NewRequest("POST", "", nil)
c.Negotiate(http.StatusOK, Negotiate{
Offered: []string{MIMEPOSTForm},
@ -1522,7 +1481,7 @@ func TestContextNegotiationNotSupport(t *testing.T) {
func TestContextNegotiationFormat(t *testing.T) {
c, _ := CreateTestContext(httptest.NewRecorder())
c.Request, _ = http.NewRequest(http.MethodPost, "", nil)
c.Request, _ = http.NewRequest("POST", "", nil)
assert.Panics(t, func() { c.NegotiateFormat() })
assert.Equal(t, MIMEJSON, c.NegotiateFormat(MIMEJSON, MIMEXML))
@ -1531,7 +1490,7 @@ func TestContextNegotiationFormat(t *testing.T) {
func TestContextNegotiationFormatWithAccept(t *testing.T) {
c, _ := CreateTestContext(httptest.NewRecorder())
c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
c.Request, _ = http.NewRequest("POST", "/", 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))
@ -1541,7 +1500,7 @@ func TestContextNegotiationFormatWithAccept(t *testing.T) {
func TestContextNegotiationFormatWithWildcardAccept(t *testing.T) {
c, _ := CreateTestContext(httptest.NewRecorder())
c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
c.Request, _ = http.NewRequest("POST", "/", nil)
c.Request.Header.Add("Accept", "*/*")
assert.Equal(t, "*/*", c.NegotiateFormat("*/*"))
@ -1552,7 +1511,7 @@ func TestContextNegotiationFormatWithWildcardAccept(t *testing.T) {
assert.Equal(t, MIMEHTML, c.NegotiateFormat(MIMEHTML))
c, _ = CreateTestContext(httptest.NewRecorder())
c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
c.Request, _ = http.NewRequest("POST", "/", nil)
c.Request.Header.Add("Accept", "text/*")
assert.Equal(t, "*/*", c.NegotiateFormat("*/*"))
@ -1565,7 +1524,7 @@ func TestContextNegotiationFormatWithWildcardAccept(t *testing.T) {
func TestContextNegotiationFormatCustom(t *testing.T) {
c, _ := CreateTestContext(httptest.NewRecorder())
c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
c.Request, _ = http.NewRequest("POST", "/", nil)
c.Request.Header.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8")
c.Accepted = nil
@ -1578,7 +1537,7 @@ func TestContextNegotiationFormatCustom(t *testing.T) {
func TestContextNegotiationFormat2(t *testing.T) {
c, _ := CreateTestContext(httptest.NewRecorder())
c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
c.Request, _ = http.NewRequest("POST", "/", nil)
c.Request.Header.Add("Accept", "image/tiff-fx")
assert.Equal(t, "", c.NegotiateFormat("image/tiff"))
@ -1598,7 +1557,7 @@ func TestContextIsAborted(t *testing.T) {
assert.True(t, c.IsAborted())
}
// TestContextAbortWithStatus tests that the response can be written from `bytestring`
// TestContextData tests that the response can be written from `bytestring`
// with specified MIME type
func TestContextAbortWithStatus(t *testing.T) {
w := httptest.NewRecorder()
@ -1706,7 +1665,7 @@ func TestContextAbortWithError(t *testing.T) {
func TestContextClientIP(t *testing.T) {
c, _ := CreateTestContext(httptest.NewRecorder())
c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
c.Request, _ = http.NewRequest("POST", "/", nil)
c.engine.trustedCIDRs, _ = c.engine.prepareTrustedCIDRs()
resetContextForClientIPTests(c)
@ -1849,7 +1808,7 @@ func resetContextForClientIPTests(c *Context) {
func TestContextContentType(t *testing.T) {
c, _ := CreateTestContext(httptest.NewRecorder())
c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
c.Request, _ = http.NewRequest("POST", "/", nil)
c.Request.Header.Set("Content-Type", "application/json; charset=utf-8")
assert.Equal(t, "application/json", c.ContentType())
@ -1857,7 +1816,7 @@ func TestContextContentType(t *testing.T) {
func TestContextAutoBindJSON(t *testing.T) {
c, _ := CreateTestContext(httptest.NewRecorder())
c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString("{\"foo\":\"bar\", \"bar\":\"foo\"}"))
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString("{\"foo\":\"bar\", \"bar\":\"foo\"}"))
c.Request.Header.Add("Content-Type", MIMEJSON)
var obj struct {
@ -1874,7 +1833,7 @@ func TestContextBindWithJSON(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString("{\"foo\":\"bar\", \"bar\":\"foo\"}"))
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString("{\"foo\":\"bar\", \"bar\":\"foo\"}"))
c.Request.Header.Add("Content-Type", MIMEXML) // set fake content-type
var obj struct {
@ -1891,7 +1850,7 @@ func TestContextBindWithXML(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString(`<?xml version="1.0" encoding="UTF-8"?>
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(`<?xml version="1.0" encoding="UTF-8"?>
<root>
<foo>FOO</foo>
<bar>BAR</bar>
@ -1912,7 +1871,7 @@ func TestContextBindPlain(t *testing.T) {
// string
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString(`test string`))
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(`test string`))
c.Request.Header.Add("Content-Type", MIMEPlain)
var s string
@ -1922,7 +1881,7 @@ func TestContextBindPlain(t *testing.T) {
assert.Equal(t, 0, w.Body.Len())
// []byte
c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString(`test []byte`))
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(`test []byte`))
c.Request.Header.Add("Content-Type", MIMEPlain)
var bs []byte
@ -1936,7 +1895,7 @@ func TestContextBindHeader(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
c.Request, _ = http.NewRequest("POST", "/", nil)
c.Request.Header.Add("rate", "8000")
c.Request.Header.Add("domain", "music")
c.Request.Header.Add("limit", "1000")
@ -1958,7 +1917,7 @@ func TestContextBindWithQuery(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodPost, "/?foo=bar&bar=foo", bytes.NewBufferString("foo=unused"))
c.Request, _ = http.NewRequest("POST", "/?foo=bar&bar=foo", bytes.NewBufferString("foo=unused"))
var obj struct {
Foo string `form:"foo"`
@ -1974,7 +1933,7 @@ func TestContextBindWithYAML(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString("foo: bar\nbar: foo"))
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString("foo: bar\nbar: foo"))
c.Request.Header.Add("Content-Type", MIMEXML) // set fake content-type
var obj struct {
@ -1991,7 +1950,7 @@ func TestContextBindWithTOML(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString("foo = 'bar'\nbar = 'foo'"))
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString("foo = 'bar'\nbar = 'foo'"))
c.Request.Header.Add("Content-Type", MIMEXML) // set fake content-type
var obj struct {
@ -2008,7 +1967,7 @@ func TestContextBadAutoBind(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodPost, "http://example.com", bytes.NewBufferString("\"foo\":\"bar\", \"bar\":\"foo\"}"))
c.Request, _ = http.NewRequest("POST", "http://example.com", bytes.NewBufferString("\"foo\":\"bar\", \"bar\":\"foo\"}"))
c.Request.Header.Add("Content-Type", MIMEJSON)
var obj struct {
Foo string `json:"foo"`
@ -2027,7 +1986,7 @@ func TestContextBadAutoBind(t *testing.T) {
func TestContextAutoShouldBindJSON(t *testing.T) {
c, _ := CreateTestContext(httptest.NewRecorder())
c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString("{\"foo\":\"bar\", \"bar\":\"foo\"}"))
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString("{\"foo\":\"bar\", \"bar\":\"foo\"}"))
c.Request.Header.Add("Content-Type", MIMEJSON)
var obj struct {
@ -2044,7 +2003,7 @@ func TestContextShouldBindWithJSON(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString("{\"foo\":\"bar\", \"bar\":\"foo\"}"))
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString("{\"foo\":\"bar\", \"bar\":\"foo\"}"))
c.Request.Header.Add("Content-Type", MIMEXML) // set fake content-type
var obj struct {
@ -2061,7 +2020,7 @@ func TestContextShouldBindWithXML(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString(`<?xml version="1.0" encoding="UTF-8"?>
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(`<?xml version="1.0" encoding="UTF-8"?>
<root>
<foo>FOO</foo>
<bar>BAR</bar>
@ -2082,7 +2041,7 @@ func TestContextShouldBindPlain(t *testing.T) {
// string
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString(`test string`))
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(`test string`))
c.Request.Header.Add("Content-Type", MIMEPlain)
var s string
@ -2092,7 +2051,7 @@ func TestContextShouldBindPlain(t *testing.T) {
assert.Equal(t, 0, w.Body.Len())
// []byte
c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString(`test []byte`))
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(`test []byte`))
c.Request.Header.Add("Content-Type", MIMEPlain)
var bs []byte
@ -2106,7 +2065,7 @@ func TestContextShouldBindHeader(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
c.Request, _ = http.NewRequest("POST", "/", nil)
c.Request.Header.Add("rate", "8000")
c.Request.Header.Add("domain", "music")
c.Request.Header.Add("limit", "1000")
@ -2128,7 +2087,7 @@ func TestContextShouldBindWithQuery(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodPost, "/?foo=bar&bar=foo&Foo=bar1&Bar=foo1", bytes.NewBufferString("foo=unused"))
c.Request, _ = http.NewRequest("POST", "/?foo=bar&bar=foo&Foo=bar1&Bar=foo1", bytes.NewBufferString("foo=unused"))
var obj struct {
Foo string `form:"foo"`
@ -2148,7 +2107,7 @@ func TestContextShouldBindWithYAML(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString("foo: bar\nbar: foo"))
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString("foo: bar\nbar: foo"))
c.Request.Header.Add("Content-Type", MIMEXML) // set fake content-type
var obj struct {
@ -2165,7 +2124,7 @@ func TestContextShouldBindWithTOML(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString("foo='bar'\nbar= 'foo'"))
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString("foo='bar'\nbar= 'foo'"))
c.Request.Header.Add("Content-Type", MIMETOML) // set fake content-type
var obj struct {
@ -2182,7 +2141,7 @@ func TestContextBadAutoShouldBind(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodPost, "http://example.com", bytes.NewBufferString("\"foo\":\"bar\", \"bar\":\"foo\"}"))
c.Request, _ = http.NewRequest("POST", "http://example.com", bytes.NewBufferString("\"foo\":\"bar\", \"bar\":\"foo\"}"))
c.Request.Header.Add("Content-Type", MIMEJSON)
var obj struct {
Foo string `json:"foo"`
@ -2246,7 +2205,7 @@ func TestContextShouldBindBodyWith(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(
http.MethodPost, "http://example.com", bytes.NewBufferString(tt.bodyA),
"POST", "http://example.com", bytes.NewBufferString(tt.bodyA),
)
// When it binds to typeA and typeB, it finds the body is
// not typeB but typeA.
@ -2264,7 +2223,7 @@ func TestContextShouldBindBodyWith(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(
http.MethodPost, "http://example.com", bytes.NewBufferString(tt.bodyB),
"POST", "http://example.com", bytes.NewBufferString(tt.bodyB),
)
objA := typeA{}
require.Error(t, c.ShouldBindBodyWith(&objA, tt.bindingA))
@ -2311,7 +2270,7 @@ func TestContextShouldBindBodyWithJSON(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString(tt.body))
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(tt.body))
type typeJSON struct {
Foo string `json:"foo" binding:"required"`
@ -2375,7 +2334,7 @@ func TestContextShouldBindBodyWithXML(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString(tt.body))
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(tt.body))
type typeXML struct {
Foo string `xml:"foo" binding:"required"`
@ -2439,7 +2398,7 @@ func TestContextShouldBindBodyWithYAML(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString(tt.body))
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(tt.body))
type typeYAML struct {
Foo string `yaml:"foo" binding:"required"`
@ -2504,7 +2463,7 @@ func TestContextShouldBindBodyWithTOML(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString(tt.body))
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(tt.body))
type typeTOML struct {
Foo string `toml:"foo" binding:"required"`
@ -2573,7 +2532,7 @@ func TestContextShouldBindBodyWithPlain(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString(tt.body))
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(tt.body))
type typeJSON struct {
Foo string `json:"foo" binding:"required"`
@ -2610,7 +2569,7 @@ func TestContextShouldBindBodyWithPlain(t *testing.T) {
func TestContextGolangContext(t *testing.T) {
c, _ := CreateTestContext(httptest.NewRecorder())
c.Request, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString("{\"foo\":\"bar\", \"bar\":\"foo\"}"))
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString("{\"foo\":\"bar\", \"bar\":\"foo\"}"))
require.NoError(t, c.Err())
assert.Nil(t, c.Done())
ti, ok := c.Deadline()
@ -2628,7 +2587,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(http.MethodGet, "/chat", nil)
c.Request, _ = http.NewRequest("GET", "/chat", nil)
c.Request.Header.Set("Host", "server.example.com")
c.Request.Header.Set("Upgrade", "websocket")
c.Request.Header.Set("Connection", "Upgrade")
@ -2641,7 +2600,7 @@ func TestWebsocketsRequired(t *testing.T) {
// Normal request, no websocket required.
c, _ = CreateTestContext(httptest.NewRecorder())
c.Request, _ = http.NewRequest(http.MethodGet, "/chat", nil)
c.Request, _ = http.NewRequest("GET", "/chat", nil)
c.Request.Header.Set("Host", "server.example.com")
assert.False(t, c.IsWebsocket())
@ -2649,7 +2608,7 @@ func TestWebsocketsRequired(t *testing.T) {
func TestGetRequestHeaderValue(t *testing.T) {
c, _ := CreateTestContext(httptest.NewRecorder())
c.Request, _ = http.NewRequest(http.MethodGet, "/chat", nil)
c.Request, _ = http.NewRequest("GET", "/chat", nil)
c.Request.Header.Set("Gin-Version", "1.0.0")
assert.Equal(t, "1.0.0", c.GetHeader("Gin-Version"))
@ -2659,7 +2618,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(http.MethodPost, "/", body)
c.Request, _ = http.NewRequest("POST", "/", body)
c.Request.Header.Add("Content-Type", MIMEPOSTForm)
data, err := c.GetRawData()
@ -2682,7 +2641,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, strconv.FormatInt(contentLength, 10), w.Header().Get("Content-Length"))
assert.Equal(t, fmt.Sprintf("%d", contentLength), w.Header().Get("Content-Length"))
assert.Equal(t, extraHeaders["Content-Disposition"], w.Header().Get("Content-Disposition"))
}
@ -2700,7 +2659,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, strconv.FormatInt(contentLength, 10), w.Header().Get("Content-Length"))
assert.Equal(t, fmt.Sprintf("%d", contentLength), w.Header().Get("Content-Length"))
}
type TestResponseRecorder struct {
@ -2788,8 +2747,8 @@ func TestRaceParamsContextCopy(t *testing.T) {
}(c.Copy(), c.Param("name"))
})
}
PerformRequest(router, http.MethodGet, "/name1/api")
PerformRequest(router, http.MethodGet, "/name2/api")
PerformRequest(router, "GET", "/name1/api")
PerformRequest(router, "GET", "/name2/api")
wg.Wait()
}
@ -2808,7 +2767,7 @@ func TestContextWithKeysMutex(t *testing.T) {
func TestRemoteIPFail(t *testing.T) {
c, _ := CreateTestContext(httptest.NewRecorder())
c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
c.Request, _ = http.NewRequest("POST", "/", nil)
c.Request.RemoteAddr = "[:::]:80"
ip := net.ParseIP(c.RemoteIP())
trust := c.engine.isTrustedProxy(ip)
@ -2905,12 +2864,11 @@ func TestContextWithFallbackValueFromRequestContext(t *testing.T) {
{
name: "c with struct context key",
getContextAndKey: func() (*Context, any) {
type KeyStruct struct{} // https://staticcheck.dev/docs/checks/#SA1029
var key KeyStruct
var key struct{}
c, _ := CreateTestContext(httptest.NewRecorder())
// enable ContextWithFallback feature flag
c.engine.ContextWithFallback = true
c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
c.Request, _ = http.NewRequest("POST", "/", nil)
c.Request = c.Request.WithContext(context.WithValue(context.TODO(), key, "value"))
return c, key
},
@ -2922,7 +2880,7 @@ func TestContextWithFallbackValueFromRequestContext(t *testing.T) {
c, _ := CreateTestContext(httptest.NewRecorder())
// enable ContextWithFallback feature flag
c.engine.ContextWithFallback = true
c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
c.Request, _ = http.NewRequest("POST", "/", nil)
c.Request = c.Request.WithContext(context.WithValue(context.TODO(), contextKey("key"), "value"))
return c, contextKey("key")
},
@ -2945,7 +2903,7 @@ func TestContextWithFallbackValueFromRequestContext(t *testing.T) {
c, _ := CreateTestContext(httptest.NewRecorder())
// enable ContextWithFallback feature flag
c.engine.ContextWithFallback = true
c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
c.Request, _ = http.NewRequest("POST", "/", nil)
return c, "key"
},
value: nil,
@ -3077,7 +3035,7 @@ func TestInterceptedHeader(t *testing.T) {
c.Header("X-Test-2", "present")
c.String(http.StatusOK, "hello world")
})
c.Request = httptest.NewRequest(http.MethodGet, "/", nil)
c.Request = httptest.NewRequest("GET", "/", 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
@ -3086,47 +3044,3 @@ 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)
}

View File

@ -10,7 +10,6 @@ import (
"html/template"
"io"
"log"
"net/http"
"os"
"runtime"
"strings"
@ -61,7 +60,7 @@ func TestDebugPrintError(t *testing.T) {
func TestDebugPrintRoutes(t *testing.T) {
re := captureOutput(t, func() {
SetMode(DebugMode)
debugPrintRoute(http.MethodGet, "/path/to/route/:param", HandlersChain{func(c *Context) {}, handlerNameTest})
debugPrintRoute("GET", "/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)
@ -73,7 +72,7 @@ func TestDebugPrintRouteFunc(t *testing.T) {
}
re := captureOutput(t, func() {
SetMode(DebugMode)
debugPrintRoute(http.MethodGet, "/path/to/route/:param1/:param2", HandlersChain{func(c *Context) {}, handlerNameTest})
debugPrintRoute("GET", "/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)

View File

@ -18,7 +18,7 @@ func TestBindWith(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest(http.MethodPost, "/?foo=bar&bar=foo", bytes.NewBufferString("foo=unused"))
c.Request, _ = http.NewRequest("POST", "/?foo=bar&bar=foo", bytes.NewBufferString("foo=unused"))
var obj struct {
Foo string `form:"foo"`

View File

@ -172,7 +172,7 @@ func main() {
router := gin.Default()
// Query string parameters are parsed using the existing underlying request object.
// The request responds to an url matching: /welcome?firstname=Jane&lastname=Doe
// The request responds to an url matching: /welcome?firstname=Jane&lastname=Doe
router.GET("/welcome", func(c *gin.Context) {
firstname := c.DefaultQuery("firstname", "Guest")
lastname := c.Query("lastname") // shortcut for c.Request.URL.Query().Get("lastname")
@ -516,19 +516,19 @@ Sample Output
```go
func main() {
router := gin.New()
// skip logging for desired paths by setting SkipPaths in LoggerConfig
loggerConfig := gin.LoggerConfig{SkipPaths: []string{"/metrics"}}
// skip logging based on your logic by setting Skip func in LoggerConfig
loggerConfig.Skip = func(c *gin.Context) bool {
// as an example skip non server side errors
return c.Writer.Status() < http.StatusInternalServerError
}
router.Use(gin.LoggerWithConfig(loggerConfig))
router.Use(gin.Recovery())
// skipped
router.GET("/metrics", func(c *gin.Context) {
c.Status(http.StatusNotImplemented)
@ -543,7 +543,7 @@ func main() {
router.GET("/data", func(c *gin.Context) {
c.Status(http.StatusNotImplemented)
})
router.Run(":8080")
}
@ -615,7 +615,7 @@ You can also specify that specific fields are required. If a field is decorated
```go
// Binding from JSON
type Login struct {
User string `form:"user" json:"user" xml:"user" binding:"required"`
User string `form:"user" json:"user" xml:"user" binding:"required"`
Password string `form:"password" json:"password" xml:"password" binding:"required"`
}
@ -1252,7 +1252,7 @@ func main() {
#### JSONP
Using JSONP to request data from a server in a different domain. Add callback to response body if the query parameter callback exists.
Using JSONP to request data from a server in a different domain. Add callback to response body if the query parameter callback exists.
```go
func main() {
@ -1301,7 +1301,7 @@ func main() {
#### PureJSON
Normally, JSON replaces special HTML characters with their unicode entities, e.g. `<` becomes `\u003c`. If you want to encode such characters literally, you can use PureJSON instead.
Normally, JSON replaces special HTML characters with their unicode entities, e.g. `<` becomes `\u003c`. If you want to encode such characters literally, you can use PureJSON instead.
This feature is unavailable in Go 1.6 and lower.
```go
@ -1336,7 +1336,7 @@ func main() {
router.StaticFS("/more_static", http.Dir("my_file_system"))
router.StaticFile("/favicon.ico", "./resources/favicon.ico")
router.StaticFileFS("/more_favicon.ico", "more_favicon.ico", http.Dir("my_file_system"))
// Listen and serve on 0.0.0.0:8080
router.Run(":8080")
}
@ -2320,7 +2320,7 @@ or network CIDRs from where clients which their request headers related to clien
IP can be trusted. They can be IPv4 addresses, IPv4 CIDRs, IPv6 addresses or
IPv6 CIDRs.
**Attention:** Gin trust all proxies by default if you don't specify a trusted
**Attention:** Gin trust all proxies by default if you don't specify a trusted
proxy using the function above, **this is NOT safe**. At the same time, if you don't
use any proxy, you can disable this feature by using `Engine.SetTrustedProxies(nil)`,
then `Context.ClientIP()` will return the remote address directly to avoid some
@ -2349,7 +2349,7 @@ func main() {
```
**Notice:** If you are using a CDN service, you can set the `Engine.TrustedPlatform`
to skip TrustedProxies check, it has a higher priority than TrustedProxies.
to skip TrustedProxies check, it has a higher priority than TrustedProxies.
Look at the example below:
```go

2
gin.go
View File

@ -598,7 +598,7 @@ func (engine *Engine) RunQUIC(addr, certFile, keyFile string) (err error) {
if engine.isUnsafeTrustedProxies() {
debugPrint("[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.\n" +
"Please check https://github.com/gin-gonic/gin/blob/master/docs/doc.md#dont-trust-all-proxies for details.")
"Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.")
}
err = http3.ListenAndServeQUIC(addr, certFile, keyFile, engine.Handler())

View File

@ -73,7 +73,7 @@ func TestLoadHTMLGlobDebugMode(t *testing.T) {
)
defer ts.Close()
res, err := http.Get(ts.URL + "/test")
res, err := http.Get(fmt.Sprintf("%s/test", ts.URL))
if err != nil {
t.Error(err)
}
@ -131,7 +131,7 @@ func TestLoadHTMLGlobTestMode(t *testing.T) {
)
defer ts.Close()
res, err := http.Get(ts.URL + "/test")
res, err := http.Get(fmt.Sprintf("%s/test", ts.URL))
if err != nil {
t.Error(err)
}
@ -151,7 +151,7 @@ func TestLoadHTMLGlobReleaseMode(t *testing.T) {
)
defer ts.Close()
res, err := http.Get(ts.URL + "/test")
res, err := http.Get(fmt.Sprintf("%s/test", ts.URL))
if err != nil {
t.Error(err)
}
@ -178,7 +178,7 @@ func TestLoadHTMLGlobUsingTLS(t *testing.T) {
},
}
client := &http.Client{Transport: tr}
res, err := client.Get(ts.URL + "/test")
res, err := client.Get(fmt.Sprintf("%s/test", ts.URL))
if err != nil {
t.Error(err)
}
@ -198,7 +198,7 @@ func TestLoadHTMLGlobFromFuncMap(t *testing.T) {
)
defer ts.Close()
res, err := http.Get(ts.URL + "/raw")
res, err := http.Get(fmt.Sprintf("%s/raw", ts.URL))
if err != nil {
t.Error(err)
}
@ -229,7 +229,7 @@ func TestLoadHTMLFilesTestMode(t *testing.T) {
)
defer ts.Close()
res, err := http.Get(ts.URL + "/test")
res, err := http.Get(fmt.Sprintf("%s/test", ts.URL))
if err != nil {
t.Error(err)
}
@ -249,7 +249,7 @@ func TestLoadHTMLFilesDebugMode(t *testing.T) {
)
defer ts.Close()
res, err := http.Get(ts.URL + "/test")
res, err := http.Get(fmt.Sprintf("%s/test", ts.URL))
if err != nil {
t.Error(err)
}
@ -269,7 +269,7 @@ func TestLoadHTMLFilesReleaseMode(t *testing.T) {
)
defer ts.Close()
res, err := http.Get(ts.URL + "/test")
res, err := http.Get(fmt.Sprintf("%s/test", ts.URL))
if err != nil {
t.Error(err)
}
@ -296,7 +296,7 @@ func TestLoadHTMLFilesUsingTLS(t *testing.T) {
},
}
client := &http.Client{Transport: tr}
res, err := client.Get(ts.URL + "/test")
res, err := client.Get(fmt.Sprintf("%s/test", ts.URL))
if err != nil {
t.Error(err)
}
@ -316,7 +316,7 @@ func TestLoadHTMLFilesFuncMap(t *testing.T) {
)
defer ts.Close()
res, err := http.Get(ts.URL + "/raw")
res, err := http.Get(fmt.Sprintf("%s/raw", ts.URL))
if err != nil {
t.Error(err)
}
@ -327,31 +327,31 @@ func TestLoadHTMLFilesFuncMap(t *testing.T) {
func TestAddRoute(t *testing.T) {
router := New()
router.addRoute(http.MethodGet, "/", HandlersChain{func(_ *Context) {}})
router.addRoute("GET", "/", HandlersChain{func(_ *Context) {}})
assert.Len(t, router.trees, 1)
assert.NotNil(t, router.trees.get(http.MethodGet))
assert.Nil(t, router.trees.get(http.MethodPost))
assert.NotNil(t, router.trees.get("GET"))
assert.Nil(t, router.trees.get("POST"))
router.addRoute(http.MethodPost, "/", HandlersChain{func(_ *Context) {}})
router.addRoute("POST", "/", HandlersChain{func(_ *Context) {}})
assert.Len(t, router.trees, 2)
assert.NotNil(t, router.trees.get(http.MethodGet))
assert.NotNil(t, router.trees.get(http.MethodPost))
assert.NotNil(t, router.trees.get("GET"))
assert.NotNil(t, router.trees.get("POST"))
router.addRoute(http.MethodPost, "/post", HandlersChain{func(_ *Context) {}})
router.addRoute("POST", "/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(http.MethodGet, "a", HandlersChain{func(_ *Context) {}}) })
assert.Panics(t, func() { router.addRoute(http.MethodGet, "/", HandlersChain{}) })
assert.Panics(t, func() { router.addRoute("GET", "a", HandlersChain{func(_ *Context) {}}) })
assert.Panics(t, func() { router.addRoute("GET", "/", HandlersChain{}) })
router.addRoute(http.MethodPost, "/post", HandlersChain{func(_ *Context) {}})
router.addRoute("POST", "/post", HandlersChain{func(_ *Context) {}})
assert.Panics(t, func() {
router.addRoute(http.MethodPost, "/post", HandlersChain{func(_ *Context) {}})
router.addRoute("POST", "/post", HandlersChain{func(_ *Context) {}})
})
}
@ -493,27 +493,27 @@ func TestListOfRoutes(t *testing.T) {
assert.Len(t, list, 7)
assertRoutePresent(t, list, RouteInfo{
Method: http.MethodGet,
Method: "GET",
Path: "/favicon.ico",
Handler: "^(.*/vendor/)?github.com/gin-gonic/gin.handlerTest1$",
})
assertRoutePresent(t, list, RouteInfo{
Method: http.MethodGet,
Method: "GET",
Path: "/",
Handler: "^(.*/vendor/)?github.com/gin-gonic/gin.handlerTest1$",
})
assertRoutePresent(t, list, RouteInfo{
Method: http.MethodGet,
Method: "GET",
Path: "/users/",
Handler: "^(.*/vendor/)?github.com/gin-gonic/gin.handlerTest2$",
})
assertRoutePresent(t, list, RouteInfo{
Method: http.MethodGet,
Method: "GET",
Path: "/users/:id",
Handler: "^(.*/vendor/)?github.com/gin-gonic/gin.handlerTest1$",
})
assertRoutePresent(t, list, RouteInfo{
Method: http.MethodPost,
Method: "POST",
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, http.MethodGet, "/")
w := PerformRequest(r, "GET", "/")
assert.Equal(t, 301, w.Code)
})
}
@ -564,7 +564,7 @@ func TestEngineHandleContextManyReEntries(t *testing.T) {
})
assert.NotPanics(t, func() {
w := PerformRequest(r, http.MethodGet, "/"+strconv.Itoa(expectValue-1)) // include 0 value
w := PerformRequest(r, "GET", "/"+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: 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"})
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"})
}
func TestWithOptionFunc(t *testing.T) {
@ -729,8 +729,8 @@ func TestWithOptionFunc(t *testing.T) {
})
routes := r.Routes()
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"})
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"})
}
type Birthday string
@ -749,7 +749,7 @@ func TestCustomUnmarshalStruct(t *testing.T) {
_ = ctx.BindQuery(&request)
ctx.JSON(200, request.Birthday)
})
req := httptest.NewRequest(http.MethodGet, "/test?birthday=2000-01-01", nil)
req := httptest.NewRequest("GET", "/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(http.MethodGet, "/", nil)
req := httptest.NewRequest("GET", "/", nil)
resp := httptest.NewRecorder()
assert.NotPanics(t, func() { g.ServeHTTP(resp, req) })
assert.Equal(t, http.StatusNotFound, resp.Code)

View File

@ -10,7 +10,6 @@ import (
"net/http"
"net/http/httptest"
"os"
"strconv"
"strings"
"testing"
@ -412,7 +411,7 @@ func exampleFromPath(path string) (string, Params) {
}
if start >= 0 {
if c == '/' {
value := strconv.Itoa(rand.Intn(100000))
value := fmt.Sprint(rand.Intn(100000))
params = append(params, Param{
Key: path[start:i],
Value: value,
@ -426,7 +425,7 @@ func exampleFromPath(path string) (string, Params) {
}
}
if start >= 0 {
value := strconv.Itoa(rand.Intn(100000))
value := fmt.Sprint(rand.Intn(100000))
params = append(params, Param{
Key: path[start:],
Value: value,

View File

@ -31,9 +31,9 @@ func TestLogger(t *testing.T) {
router.HEAD("/example", func(c *Context) {})
router.OPTIONS("/example", func(c *Context) {})
PerformRequest(router, http.MethodGet, "/example?a=100")
PerformRequest(router, "GET", "/example?a=100")
assert.Contains(t, buffer.String(), "200")
assert.Contains(t, buffer.String(), http.MethodGet)
assert.Contains(t, buffer.String(), "GET")
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, http.MethodPost, "/example")
PerformRequest(router, "POST", "/example")
assert.Contains(t, buffer.String(), "200")
assert.Contains(t, buffer.String(), http.MethodPost)
assert.Contains(t, buffer.String(), "POST")
assert.Contains(t, buffer.String(), "/example")
buffer.Reset()
PerformRequest(router, http.MethodPut, "/example")
PerformRequest(router, "PUT", "/example")
assert.Contains(t, buffer.String(), "200")
assert.Contains(t, buffer.String(), http.MethodPut)
assert.Contains(t, buffer.String(), "PUT")
assert.Contains(t, buffer.String(), "/example")
buffer.Reset()
PerformRequest(router, http.MethodDelete, "/example")
PerformRequest(router, "DELETE", "/example")
assert.Contains(t, buffer.String(), "200")
assert.Contains(t, buffer.String(), http.MethodDelete)
assert.Contains(t, buffer.String(), "DELETE")
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, http.MethodGet, "/notfound")
PerformRequest(router, "GET", "/notfound")
assert.Contains(t, buffer.String(), "404")
assert.Contains(t, buffer.String(), http.MethodGet)
assert.Contains(t, buffer.String(), "GET")
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, http.MethodGet, "/example?a=100")
PerformRequest(router, "GET", "/example?a=100")
assert.Contains(t, buffer.String(), "200")
assert.Contains(t, buffer.String(), http.MethodGet)
assert.Contains(t, buffer.String(), "GET")
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, http.MethodPost, "/example")
PerformRequest(router, "POST", "/example")
assert.Contains(t, buffer.String(), "200")
assert.Contains(t, buffer.String(), http.MethodPost)
assert.Contains(t, buffer.String(), "POST")
assert.Contains(t, buffer.String(), "/example")
buffer.Reset()
PerformRequest(router, http.MethodPut, "/example")
PerformRequest(router, "PUT", "/example")
assert.Contains(t, buffer.String(), "200")
assert.Contains(t, buffer.String(), http.MethodPut)
assert.Contains(t, buffer.String(), "PUT")
assert.Contains(t, buffer.String(), "/example")
buffer.Reset()
PerformRequest(router, http.MethodDelete, "/example")
PerformRequest(router, "DELETE", "/example")
assert.Contains(t, buffer.String(), "200")
assert.Contains(t, buffer.String(), http.MethodDelete)
assert.Contains(t, buffer.String(), "DELETE")
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, http.MethodGet, "/notfound")
PerformRequest(router, "GET", "/notfound")
assert.Contains(t, buffer.String(), "404")
assert.Contains(t, buffer.String(), http.MethodGet)
assert.Contains(t, buffer.String(), "GET")
assert.Contains(t, buffer.String(), "/notfound")
}
@ -169,12 +169,12 @@ func TestLoggerWithFormatter(t *testing.T) {
)
}))
router.GET("/example", func(c *Context) {})
PerformRequest(router, http.MethodGet, "/example?a=100")
PerformRequest(router, "GET", "/example?a=100")
// output test
assert.Contains(t, buffer.String(), "[FORMATTER TEST]")
assert.Contains(t, buffer.String(), "200")
assert.Contains(t, buffer.String(), http.MethodGet)
assert.Contains(t, buffer.String(), "GET")
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, http.MethodGet, "/example?a=100")
PerformRequest(router, "GET", "/example?a=100")
// output test
assert.Contains(t, buffer.String(), "[FORMATTER TEST]")
assert.Contains(t, buffer.String(), "200")
assert.Contains(t, buffer.String(), http.MethodGet)
assert.Contains(t, buffer.String(), "GET")
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, http.MethodGet, gotParam.Method)
assert.Equal(t, "GET", gotParam.Method)
assert.Equal(t, "/example?a=100", gotParam.Path)
assert.Empty(t, gotParam.ErrorMessage)
assert.Equal(t, gotKeys, gotParam.Keys)
@ -239,7 +239,7 @@ func TestDefaultLogFormatter(t *testing.T) {
StatusCode: 200,
Latency: time.Second * 5,
ClientIP: "20.20.20.20",
Method: http.MethodGet,
Method: "GET",
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: http.MethodGet,
Method: "GET",
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: http.MethodGet,
Method: "GET",
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: http.MethodGet,
Method: "GET",
Path: "/",
ErrorMessage: "",
isTerm: false,
@ -292,10 +292,10 @@ func TestColorForMethod(t *testing.T) {
return p.MethodColor()
}
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, 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, 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, http.MethodGet, "/error")
w := PerformRequest(router, "GET", "/error")
assert.Equal(t, http.StatusOK, w.Code)
assert.Equal(t, "{\"error\":\"this is an error\"}", w.Body.String())
w = PerformRequest(router, http.MethodGet, "/abort")
w = PerformRequest(router, "GET", "/abort")
assert.Equal(t, http.StatusUnauthorized, w.Code)
assert.Equal(t, "{\"error\":\"no authorized\"}", w.Body.String())
w = PerformRequest(router, http.MethodGet, "/print")
w = PerformRequest(router, "GET", "/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, http.MethodGet, "/logged")
PerformRequest(router, "GET", "/logged")
assert.Contains(t, buffer.String(), "200")
buffer.Reset()
PerformRequest(router, http.MethodGet, "/skipped")
PerformRequest(router, "GET", "/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, http.MethodGet, "/logged")
PerformRequest(router, "GET", "/logged")
assert.Contains(t, buffer.String(), "200")
buffer.Reset()
PerformRequest(router, http.MethodGet, "/skipped")
PerformRequest(router, "GET", "/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, http.MethodGet, "/logged")
PerformRequest(router, "GET", "/logged")
assert.Contains(t, buffer.String(), "200")
buffer.Reset()
PerformRequest(router, http.MethodGet, "/skipped")
PerformRequest(router, "GET", "/skipped")
assert.Contains(t, buffer.String(), "")
}

View File

@ -35,7 +35,7 @@ func TestMiddlewareGeneralCase(t *testing.T) {
signature += " XX "
})
// RUN
w := PerformRequest(router, http.MethodGet, "/")
w := PerformRequest(router, "GET", "/")
// TEST
assert.Equal(t, http.StatusOK, w.Code)
@ -71,7 +71,7 @@ func TestMiddlewareNoRoute(t *testing.T) {
signature += " X "
})
// RUN
w := PerformRequest(router, http.MethodGet, "/")
w := PerformRequest(router, "GET", "/")
// TEST
assert.Equal(t, http.StatusNotFound, w.Code)
@ -108,7 +108,7 @@ func TestMiddlewareNoMethodEnabled(t *testing.T) {
signature += " XX "
})
// RUN
w := PerformRequest(router, http.MethodGet, "/")
w := PerformRequest(router, "GET", "/")
// TEST
assert.Equal(t, http.StatusMethodNotAllowed, w.Code)
@ -149,7 +149,7 @@ func TestMiddlewareNoMethodDisabled(t *testing.T) {
})
// RUN
w := PerformRequest(router, http.MethodGet, "/")
w := PerformRequest(router, "GET", "/")
// TEST
assert.Equal(t, http.StatusNotFound, w.Code)
@ -175,7 +175,7 @@ func TestMiddlewareAbort(t *testing.T) {
})
// RUN
w := PerformRequest(router, http.MethodGet, "/")
w := PerformRequest(router, "GET", "/")
// TEST
assert.Equal(t, http.StatusUnauthorized, w.Code)
@ -196,7 +196,7 @@ func TestMiddlewareAbortHandlersChainAndNext(t *testing.T) {
c.Next()
})
// RUN
w := PerformRequest(router, http.MethodGet, "/")
w := PerformRequest(router, "GET", "/")
// TEST
assert.Equal(t, http.StatusGone, w.Code)
@ -219,7 +219,7 @@ func TestMiddlewareFailHandlersChain(t *testing.T) {
signature += "C"
})
// RUN
w := PerformRequest(router, http.MethodGet, "/")
w := PerformRequest(router, "GET", "/")
// TEST
assert.Equal(t, http.StatusInternalServerError, w.Code)
@ -246,7 +246,7 @@ func TestMiddlewareWrite(t *testing.T) {
})
})
w := PerformRequest(router, http.MethodGet, "/")
w := PerformRequest(router, "GET", "/")
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))

View File

@ -5,6 +5,7 @@
package gin
import (
"fmt"
"net"
"net/http"
"os"
@ -25,14 +26,14 @@ func TestPanicClean(t *testing.T) {
panic("Oupps, Houston, we have a problem")
})
// RUN
w := PerformRequest(router, http.MethodGet, "/recovery",
w := PerformRequest(router, "GET", "/recovery",
header{
Key: "Host",
Value: "www.google.com",
},
header{
Key: "Authorization",
Value: "Bearer " + password,
Value: fmt.Sprintf("Bearer %s", password),
},
header{
Key: "Content-Type",
@ -55,7 +56,7 @@ func TestPanicInHandler(t *testing.T) {
panic("Oupps, Houston, we have a problem")
})
// RUN
w := PerformRequest(router, http.MethodGet, "/recovery")
w := PerformRequest(router, "GET", "/recovery")
// TEST
assert.Equal(t, http.StatusInternalServerError, w.Code)
assert.Contains(t, buffer.String(), "panic recovered")
@ -66,7 +67,7 @@ func TestPanicInHandler(t *testing.T) {
// Debug mode prints the request
SetMode(DebugMode)
// RUN
w = PerformRequest(router, http.MethodGet, "/recovery")
w = PerformRequest(router, "GET", "/recovery")
// TEST
assert.Equal(t, http.StatusInternalServerError, w.Code)
assert.Contains(t, buffer.String(), "GET /recovery")
@ -83,7 +84,7 @@ func TestPanicWithAbort(t *testing.T) {
panic("Oupps, Houston, we have a problem")
})
// RUN
w := PerformRequest(router, http.MethodGet, "/recovery")
w := PerformRequest(router, "GET", "/recovery")
// TEST
assert.Equal(t, http.StatusBadRequest, w.Code)
}
@ -134,7 +135,7 @@ func TestPanicWithBrokenPipe(t *testing.T) {
panic(e)
})
// RUN
w := PerformRequest(router, http.MethodGet, "/recovery")
w := PerformRequest(router, "GET", "/recovery")
// TEST
assert.Equal(t, expectCode, w.Code)
assert.Contains(t, strings.ToLower(buf.String()), expectMsg)
@ -155,7 +156,7 @@ func TestCustomRecoveryWithWriter(t *testing.T) {
panic("Oupps, Houston, we have a problem")
})
// RUN
w := PerformRequest(router, http.MethodGet, "/recovery")
w := PerformRequest(router, "GET", "/recovery")
// TEST
assert.Equal(t, http.StatusBadRequest, w.Code)
assert.Contains(t, buffer.String(), "panic recovered")
@ -166,7 +167,7 @@ func TestCustomRecoveryWithWriter(t *testing.T) {
// Debug mode prints the request
SetMode(DebugMode)
// RUN
w = PerformRequest(router, http.MethodGet, "/recovery")
w = PerformRequest(router, "GET", "/recovery")
// TEST
assert.Equal(t, http.StatusBadRequest, w.Code)
assert.Contains(t, buffer.String(), "GET /recovery")
@ -190,7 +191,7 @@ func TestCustomRecovery(t *testing.T) {
panic("Oupps, Houston, we have a problem")
})
// RUN
w := PerformRequest(router, http.MethodGet, "/recovery")
w := PerformRequest(router, "GET", "/recovery")
// TEST
assert.Equal(t, http.StatusBadRequest, w.Code)
assert.Contains(t, buffer.String(), "panic recovered")
@ -201,7 +202,7 @@ func TestCustomRecovery(t *testing.T) {
// Debug mode prints the request
SetMode(DebugMode)
// RUN
w = PerformRequest(router, http.MethodGet, "/recovery")
w = PerformRequest(router, "GET", "/recovery")
// TEST
assert.Equal(t, http.StatusBadRequest, w.Code)
assert.Contains(t, buffer.String(), "GET /recovery")
@ -225,7 +226,7 @@ func TestRecoveryWithWriterWithCustomRecovery(t *testing.T) {
panic("Oupps, Houston, we have a problem")
})
// RUN
w := PerformRequest(router, http.MethodGet, "/recovery")
w := PerformRequest(router, "GET", "/recovery")
// TEST
assert.Equal(t, http.StatusBadRequest, w.Code)
assert.Contains(t, buffer.String(), "panic recovered")
@ -236,7 +237,7 @@ func TestRecoveryWithWriterWithCustomRecovery(t *testing.T) {
// Debug mode prints the request
SetMode(DebugMode)
// RUN
w = PerformRequest(router, http.MethodGet, "/recovery")
w = PerformRequest(router, "GET", "/recovery")
// TEST
assert.Equal(t, http.StatusBadRequest, w.Code)
assert.Contains(t, buffer.String(), "GET /recovery")

View File

@ -369,7 +369,7 @@ func TestRenderXML(t *testing.T) {
}
func TestRenderRedirect(t *testing.T) {
req, err := http.NewRequest(http.MethodGet, "/test-redirect", nil)
req, err := http.NewRequest("GET", "/test-redirect", nil)
require.NoError(t, err)
data1 := Redirect{

View File

@ -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, http.MethodGet)
assert.Contains(t, allowed, http.MethodPost)
assert.Contains(t, allowed, "GET")
assert.Contains(t, allowed, "POST")
}
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, http.MethodGet, tr.route)
w := PerformRequest(router, "GET", tr.route)
assert.Equal(t, tr.code, w.Code)
if w.Code != http.StatusNotFound {
assert.Equal(t, tr.location, w.Header().Get("Location"))
assert.Equal(t, tr.location, fmt.Sprint(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, w.Header().Get("Location"))
assert.Equal(t, tr.location, fmt.Sprint(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, http.MethodGet, "/base/v1/user/groups")
w := PerformRequest(r, "GET", "/base/v1/user/groups")
assert.Equal(t, http.StatusNotFound, w.Code)
}

View File

@ -369,7 +369,7 @@ func (n *node) insertChild(path string, fullPath string, handlers HandlersChain)
// currently fixed width 1 for '/'
i--
if i < 0 || path[i] != '/' {
if path[i] != '/' {
panic("no / before catch-all in path '" + fullPath + "'")
}

View File

@ -993,28 +993,3 @@ func TestTreeInvalidEscape(t *testing.T) {
}
}
}
func TestWildcardInvalidSlash(t *testing.T) {
const panicMsgPrefix = "no / before catch-all in path"
routes := map[string]bool{
"/foo/bar": true,
"/foo/x*zy": false,
"/foo/b*r": false,
}
for route, valid := range routes {
tree := &node{}
recv := catchPanic(func() {
tree.addRoute(route, nil)
})
if recv == nil != valid {
t.Fatalf("%s should be %t but got %v", route, valid, recv)
}
if rs, ok := recv.(string); recv != nil && (!ok || !strings.HasPrefix(rs, panicMsgPrefix)) {
t.Fatalf(`"Expected panic "%s" for route '%s', got "%v"`, panicMsgPrefix, route, recv)
}
}
}

View File

@ -29,7 +29,7 @@ type testStruct struct {
}
func (t *testStruct) ServeHTTP(w http.ResponseWriter, req *http.Request) {
assert.Equal(t.T, http.MethodPost, req.Method)
assert.Equal(t.T, "POST", 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, http.MethodGet, req.Method)
assert.Equal(t, "GET", req.Method)
assert.Equal(t, "/path2", req.URL.Path)
w.WriteHeader(http.StatusBadRequest)
fmt.Fprint(w, "hola!")
}))
w := PerformRequest(router, http.MethodPost, "/path")
w := PerformRequest(router, "POST", "/path")
assert.Equal(t, http.StatusInternalServerError, w.Code)
assert.Equal(t, "hello", w.Body.String())
w = PerformRequest(router, http.MethodGet, "/path2")
w = PerformRequest(router, "GET", "/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, http.MethodGet, "/?foo=hola&bar=10")
PerformRequest(router, "GET", "/?foo=hola&bar=10")
assert.True(t, called)
assert.Equal(t, "hola", value.Foo)
assert.Equal(t, 10, value.Bar)
called = false
PerformRequest(router, http.MethodGet, "/?foo=hola&bar=1")
PerformRequest(router, "GET", "/?foo=hola&bar=1")
assert.False(t, called)
assert.Panics(t, func() {