Description
When I try to use gin.CreateTestContext()
, it create a context that cannot be used to serve http requests. Indeed, it takes a http.ResponseWriter
as a parameter, which is incompatible with http.CloseNotifier
, causing a panic.
How to reproduce
func Test(t *testing.T) {
c, _ := gin.CreateTestContext(httptest.NewRecorder())
request, err := http.NewRequest("GET", "/ping", nil)
if err != nil {
panic(err)
}
url, _ := url.Parse("http://localhost:8080")
proxy := httputil.NewSingleHostReverseProxy(url)
proxy.ServeHTTP(c.Writer, request)
}
Expectations
gin.CreateTestContext()
should take as parameter an interface compatible with the http.CloseNotifier
interface and should not produce a panic.
Actual result
The code panics.
--- FAIL: Test (0.00s)
panic: interface conversion: *httptest.ResponseRecorder is not http.CloseNotifier: missing method CloseNotify [recovered]
panic: interface conversion: *httptest.ResponseRecorder is not http.CloseNotifier: missing method CloseNotify
goroutine 35 [running]:
testing.tRunner.func1.2(0xa79ba0, 0xc0003838f0)
/home/linuxbrew/.linuxbrew/Cellar/go/1.16.6/libexec/src/testing/testing.go:1143 +0x332
testing.tRunner.func1(0xc0003c0300)
/home/linuxbrew/.linuxbrew/Cellar/go/1.16.6/libexec/src/testing/testing.go:1146 +0x4b6
panic(0xa79ba0, 0xc0003838f0)
/home/linuxbrew/.linuxbrew/Cellar/go/1.16.6/libexec/src/runtime/panic.go:965 +0x1b9
github.com/gin-gonic/gin.(*responseWriter).CloseNotify(0xc00040c300, 0xc000126010)
/home/paul/go/pkg/mod/github.com/gin-gonic/gin@v1.7.3/response_writer.go:112 +0x45
net/http/httputil.(*ReverseProxy).ServeHTTP(0xc000398780, 0x7f853e3e8970, 0xc00040c300, 0xc00040c400)
/home/linuxbrew/.linuxbrew/Cellar/go/1.16.6/libexec/src/net/http/httputil/reverseproxy.go:223 +0x1693
gitlab.enix.io/products/docker-cache-registry/internal/proxy.Test(0xc0003c0300)
/home/paul/dev/internal/docker-cache-registry/internal/proxy/server_test.go:38 +0x1b1
testing.tRunner(0xc0003c0300, 0xb5bc48)
/home/linuxbrew/.linuxbrew/Cellar/go/1.16.6/libexec/src/testing/testing.go:1193 +0xef
created by testing.(*T).Run
/home/linuxbrew/.linuxbrew/Cellar/go/1.16.6/libexec/src/testing/testing.go:1238 +0x2b3
FAIL gitlab.enix.io/products/docker-cache-registry/internal/proxy 0.007s
FAIL
```
## Environment
- go version: go1.16.6 linux/amd64
- gin version (or commit ref): v1.7.3
- operating system: ubuntu 20.04
## Notes
The issue is coming from `responseWriter.CloseNotify()`:
// CloseNotify implements the http.CloseNotify interface. func (w *responseWriter) CloseNotify() <-chan bool { return w.ResponseWriter.(http.CloseNotifier).CloseNotify() } ```
w.ResponseWriter
is casted without verification to http.CloseNotifier
. However, the httptest.ResponseRecorder
interface returned by gin.CreateTestContext()
is incompatible with http.CloseNotifier
.
Comment From: myzhan
Yes, I met the same issue when using gin as a reverse proxy.