Repository: gin-gonic/gin
Pull request #2412 (2020-06-15 11:35:54)

Prevent panic in Context.GetQuery() when there is no Request
I have an endpoint that uses an optional query parameter via DefaultQuery(). 
In one unit test case I want to test the route with that parameter.
I write that test as
```go
	w := httptest.NewRecorder()
	c, _ := gin.CreateTestContext(w)
	routeHandler(c)
```
And this panics when routeHandler() calls c.DefaultQuery() because c.Request == nil.

- With pull requests:
  - Open your pull request against `master`
  - Your pull request should have no more than two commits, if not you should squash them.
  - It should pass all tests in the available continuous integration systems such as TravisCI.
  - You should add/modify tests to cover your proposed code changes.
  - If your pull request contains a new feature, please document it on the README.



codecov[bot]: # [Codecov](https://codecov.io/gh/gin-gonic/gin/pull/2412?src=pr&el=h1) Report
> Merging [#2412](https://codecov.io/gh/gin-gonic/gin/pull/2412?src=pr&el=desc) into [master](https://codecov.io/gh/gin-gonic/gin/commit/5e40c1d49c21bf989e8d54dbd555086f06d4fb8a&el=desc) will **decrease** coverage by `0.08%`.
> The diff coverage is `50.00%`.

[![Impacted file tree graph](https://codecov.io/gh/gin-gonic/gin/pull/2412/graphs/tree.svg?width=650&height=150&src=pr&token=Qpqxhwery8)](https://codecov.io/gh/gin-gonic/gin/pull/2412?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master    #2412      +/-   ##
==========================================
- Coverage   98.72%   98.63%   -0.09%     
==========================================
  Files          41       41              
  Lines        2348     2351       +3     
==========================================
+ Hits         2318     2319       +1     
- Misses         17       18       +1     
- Partials       13       14       +1     
```


| [Impacted Files](https://codecov.io/gh/gin-gonic/gin/pull/2412?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [context.go](https://codecov.io/gh/gin-gonic/gin/pull/2412/diff?src=pr&el=tree#diff-Y29udGV4dC5nbw==) | `97.67% <50.00%> (-0.42%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/gin-gonic/gin/pull/2412?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/gin-gonic/gin/pull/2412?src=pr&el=footer). Last update [5e40c1d...fcbde60](https://codecov.io/gh/gin-gonic/gin/pull/2412?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

pofl: I have nothing to add to this PR anymore 😊

Patch:
diff --git a/context.go b/context.go
index a945883..95b1807 100644
--- a/context.go
+++ b/context.go
@@ -416,7 +416,11 @@ func (c *Context) QueryArray(key string) []string {
 
 func (c *Context) initQueryCache() {
 	if c.queryCache == nil {
-		c.queryCache = c.Request.URL.Query()
+		if c.Request != nil {
+			c.queryCache = c.Request.URL.Query()
+		} else {
+			c.queryCache = url.Values{}
+		}
 	}
 }
 


Test patch:
diff --git a/context_test.go b/context_test.go
index b53bf92..1a5a3c5 100644
--- a/context_test.go
+++ b/context_test.go
@@ -410,6 +410,21 @@ func TestContextQuery(t *testing.T) {
 	assert.Empty(t, c.PostForm("foo"))
 }
 
+func TestContextDefaultQueryOnEmptyRequest(t *testing.T) {
+	c, _ := CreateTestContext(httptest.NewRecorder()) // here c.Request == nil
+	assert.NotPanics(t, func() {
+		value, ok := c.GetQuery("NoKey")
+		assert.False(t, ok)
+		assert.Empty(t, value)
+	})
+	assert.NotPanics(t, func() {
+		assert.Equal(t, "nada", c.DefaultQuery("NoKey", "nada"))
+	})
+	assert.NotPanics(t, func() {
+		assert.Empty(t, c.Query("NoKey"))
+	})
+}
+
 func TestContextQueryAndPostForm(t *testing.T) {
 	c, _ := CreateTestContext(httptest.NewRecorder())
 	body := bytes.NewBufferString("foo=bar&page=11&both=&foo=second")