mirror of
https://github.com/gin-gonic/gin.git
synced 2026-09-04 14:49:27 +08:00
Merge b8e1de3745a9520649676c906ec8103d5edc32b6 into dcaa4296d111981ffb31ac3eba90bb63e1eb5ab9
This commit is contained in:
commit
c50e0d90ae
10
context.go
10
context.go
@ -588,6 +588,11 @@ func (c *Context) initQueryCache() {
|
||||
// GetQueryArray returns a slice of strings for a given query key, plus
|
||||
// a boolean value whether at least one value exists for the given key.
|
||||
func (c *Context) GetQueryArray(key string) (values []string, ok bool) {
|
||||
if c.Request == nil || c.Request.URL == nil || c.Request.URL.RawQuery == "" {
|
||||
// Fast path to save unnecessary allocations when the query string is empty
|
||||
return nil, false
|
||||
}
|
||||
|
||||
c.initQueryCache()
|
||||
values, ok = c.queryCache[key]
|
||||
return
|
||||
@ -602,6 +607,11 @@ func (c *Context) QueryMap(key string) (dicts map[string]string) {
|
||||
// GetQueryMap returns a map for a given query key, plus a boolean value
|
||||
// whether at least one value exists for the given key.
|
||||
func (c *Context) GetQueryMap(key string) (map[string]string, bool) {
|
||||
if c.Request == nil || c.Request.URL == nil || c.Request.URL.RawQuery == "" {
|
||||
// Fast path to save unnecessary allocations when the query string is empty
|
||||
return nil, false
|
||||
}
|
||||
|
||||
c.initQueryCache()
|
||||
return getMapFromFormData(c.queryCache, key)
|
||||
}
|
||||
|
||||
@ -846,9 +846,38 @@ func TestContextQuery(t *testing.T) {
|
||||
assert.Empty(t, c.PostForm("foo"))
|
||||
}
|
||||
|
||||
func TestContextQueryAllocations(t *testing.T) {
|
||||
// URLs with empty query strings should not cause allocations
|
||||
c, _ := CreateTestContext(httptest.NewRecorder())
|
||||
c.Request, _ = http.NewRequest(http.MethodGet, "http://example.com/", nil)
|
||||
|
||||
allocs := testing.AllocsPerRun(100, func() {
|
||||
// Reset the query cache before each run because testing.AllocsPerRun does a warm-up for each test
|
||||
c.queryCache = nil
|
||||
_, _ = c.GetQuery("foo")
|
||||
})
|
||||
assert.Zero(t, allocs, "expected GetQuery to not cause allocations with empty query strings")
|
||||
|
||||
allocs = testing.AllocsPerRun(100, func() {
|
||||
// Reset the query cache before each run because testing.AllocsPerRun does a warm-up for each test
|
||||
c.queryCache = nil
|
||||
_, _ = c.GetQueryArray("foo")
|
||||
})
|
||||
assert.Zero(t, allocs, "expected GetQueryArray to not cause allocations with empty query strings")
|
||||
|
||||
allocs = testing.AllocsPerRun(100, func() {
|
||||
// Reset the query cache before each run because testing.AllocsPerRun does a warm-up for each test
|
||||
c.queryCache = nil
|
||||
_, _ = c.GetQueryMap("foo")
|
||||
})
|
||||
assert.Zero(t, allocs, "expected GetQueryMap to not cause allocations with empty query strings")
|
||||
}
|
||||
|
||||
func TestContextInitQueryCache(t *testing.T) {
|
||||
validURL, err := url.Parse("https://github.com/gin-gonic/gin/pull/3969?key=value&otherkey=othervalue")
|
||||
require.NoError(t, err)
|
||||
noQSURL, err := url.Parse("https://github.com/gin-gonic/gin/pull/3969")
|
||||
require.NoError(t, err)
|
||||
|
||||
tests := []struct {
|
||||
testName string
|
||||
@ -873,6 +902,13 @@ func TestContextInitQueryCache(t *testing.T) {
|
||||
testContext: &Context{Request: &http.Request{URL: nil}}, // explicit nil for readability
|
||||
expectedQueryCache: url.Values{},
|
||||
},
|
||||
{
|
||||
testName: "queryCache should be empty when URL has no query string",
|
||||
testContext: &Context{
|
||||
Request: &http.Request{URL: noQSURL},
|
||||
},
|
||||
expectedQueryCache: url.Values{},
|
||||
},
|
||||
{
|
||||
testName: "queryCache should be populated when it not yet populated and Request + Request.URL are non nil",
|
||||
testContext: &Context{Request: &http.Request{URL: validURL}}, // explicit nil for readability
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user