gin icon indicating copy to clipboard operation
gin copied to clipboard

With RedirectFixedPath enabled, the request execution panics when a 404 is expected

Open kpacha opened this issue 2 years ago • 1 comments

Description

When a request to a path doesn't match any registered patterns and the RedirectFixedPath flag is set to true, the request execution panics (invalid node type). This is the line throwing the panic: https://github.com/gin-gonic/gin/blob/v1.7.7/tree.go#L851

If the panic is commented, everything seems to work as expected with the exception of the test TestTreeInvalidNodeType.

How to reproduce

Add this function to the gin_integration_test.go file

func TestRedirectFixedPath(t *testing.T) {
	router := Default()

	router.RedirectFixedPath = true

	router.GET("/aa/aa", func(c *Context) { c.String(http.StatusOK, "/aa/aa") })
	router.GET("/:bb/aa", func(c *Context) { c.String(http.StatusOK, "/:bb/aa") })

	ts := httptest.NewServer(router)
	defer ts.Close()

	testRequest(t, ts.URL+"/aa/aa", "", "/aa/aa")
	testRequest(t, ts.URL+"/bb/aa", "", "/:bb/aa")

	testRequest(t, ts.URL+"/aa", "404 Not Found") // this request makes the router panic
}

Expectations

The router should return a 404

Actual result

The router panics and the client (curl) returns

curl: (52) Empty reply from server

Environment

  • go version: 1.17.3
  • gin version (or commit ref): 1.7.7
  • operating system: linux

kpacha avatar Nov 25 '21 19:11 kpacha

Also the Same Panic For Case-Insensitive Redirect. I haven't tried it after commenting out the panic yet. So I'm not sure it is a bug or not.

testRequest(t, ts.URL+"/aa/AA", "/aa/aa")  // this request also makes the router panic

This test case should be returned as /aa/aa, if I have understood the following explanation correctly.

gin.go:line 74	// For example /FOO and /..//Foo could be redirected to /foo.

Environment

  • go version: 1.17.3
  • gin version: 1.7.4
  • os: windows

LawyZheng avatar Jan 10 '22 01:01 LawyZheng

@appleboy , it looks like this issue is still happening on v1.9.0. You just need to add this test to reproduce (as I suggested on the bug report).

func TestRedirectFixedPath(t *testing.T) {
	router := gin.Default()

	router.RedirectFixedPath = true

	router.GET("/aa/aa", func(c *gin.Context) { c.String(http.StatusOK, "/aa/aa") })
	router.GET("/:bb/aa", func(c *gin.Context) { c.String(http.StatusOK, "/:bb/aa") })

	ts := httptest.NewServer(router)
	defer ts.Close()

	testRequest(t, ts.URL+"/aa/aa", "", "/aa/aa")
	testRequest(t, ts.URL+"/bb/aa", "", "/:bb/aa")

	// the following requests panic if the RedirectFixedPath flag is enabled
	testRequest(t, ts.URL+"/aa", "404 Not Found")
	testRequest(t, ts.URL+"/aa/aa/aa/aa", "404 Not Found")
	testRequest(t, ts.URL+"/aa/AA", "/aa/aa")
}

this is the result of that test

$ go test -run TestRedirectFixedPath .
[GIN] 2023/03/21 - 17:19:12 | 200 |        7.62µs |       127.0.0.1 | GET      "/aa/aa"
[GIN] 2023/03/21 - 17:19:12 | 200 |       33.66µs |       127.0.0.1 | GET      "/bb/aa"
2023/03/21 17:19:12 http: panic serving 127.0.0.1:59078: invalid node type
goroutine 81 [running]:
net/http.(*conn).serve.func1()
	/usr/lib/go-1.20/src/net/http/server.go:1854 +0xbf
panic({0xac0620, 0xca9de0})
	/usr/lib/go-1.20/src/runtime/panic.go:890 +0x263
github.com/gin-gonic/gin.(*node).findCaseInsensitivePathRec(0x0?, {0xc00002e0b4?, 0x0?}, {0xc0000c2180?, 0xc000416c39?, 0x1?}, {0x0, 0x0, 0x0, 0x0}, ...)
	/<redacted>/gin/tree.go:862 +0xa9d
github.com/gin-gonic/gin.(*node).findCaseInsensitivePath(0xc00002e0b4?, {0xc00002e0b4, 0x3}, 0x18?)
	/<redacted>/gin/tree.go:669 +0x9c
github.com/gin-gonic/gin.redirectFixedPath(0xc0005a4000, 0xc00002e0b4?, 0x58?)
	/<redacted>/gin/gin.go:691 +0x5b
github.com/gin-gonic/gin.(*Engine).handleHTTPRequest(0xc00045a000, 0xc0005a4000)
	/<redacted>/gin/gin.go:629 +0x3aa
github.com/gin-gonic/gin.(*Engine).ServeHTTP(0xc00045a000, {0xcb1650?, 0xc00014c0e0}, 0xc0001e6000)
	/<redacted>/gin/gin.go:576 +0x1dd
net/http.serverHandler.ServeHTTP({0xc000626060?}, {0xcb1650, 0xc00014c0e0}, 0xc0001e6000)
	/usr/lib/go-1.20/src/net/http/server.go:2936 +0x316
net/http.(*conn).serve(0xc0001203f0, {0xcb1fc0, 0xc0001100c0})
	/usr/lib/go-1.20/src/net/http/server.go:1995 +0x612
created by net/http.(*Server).Serve
	/usr/lib/go-1.20/src/net/http/server.go:3089 +0x5ed
--- FAIL: TestRedirectFixedPath (0.00s)
    gin_integration_test.go:43: 
        	Error Trace:	/<redacted>/gin/gin_integration_test.go:43
        	            				/<redacted>/gin/gin_integration_test.go:576
        	Error:      	Received unexpected error:
        	            	Get "http://127.0.0.1:40013/aa": EOF
        	Test:       	TestRedirectFixedPath
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
	panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x40 pc=0xa37402]

goroutine 6 [running]:
testing.tRunner.func1.2({0xaedf20, 0x10f4b00})
	/usr/lib/go-1.20/src/testing/testing.go:1526 +0x24e
testing.tRunner.func1()
	/usr/lib/go-1.20/src/testing/testing.go:1529 +0x39f
panic({0xaedf20, 0x10f4b00})
	/usr/lib/go-1.20/src/runtime/panic.go:884 +0x213
github.com/gin-gonic/gin.testRequest(0xc0000e5ba0, {0xc0000ddf08, 0x2, 0xb97d4c?})
	/<redacted>/gin/gin_integration_test.go:44 +0x182
github.com/gin-gonic/gin.TestRedirectFixedPath(0x0?)
	/<redacted>/gin/gin_integration_test.go:576 +0x28f
testing.tRunner(0xc0000e5ba0, 0xbf20c8)
	/usr/lib/go-1.20/src/testing/testing.go:1576 +0x10b
created by testing.(*T).Run
	/usr/lib/go-1.20/src/testing/testing.go:1629 +0x3ea
FAIL	github.com/gin-gonic/gin	0.011s
FAIL

Will you reopen this or should I create a new one?

kpacha avatar Mar 21 '23 16:03 kpacha

krakend uses gin-gonic (v1.9.0?) and logs these errors:

2023/05/23 14:42:00 http: panic serving 169.254.1.1:60572: invalid node type
goroutine 362961 [running]:
net/http.(*conn).serve.func1()
	/usr/local/go/src/net/http/server.go:1854 +0xbf
panic({0x291e7e0, 0x35156d0})
	/usr/local/go/src/runtime/panic.go:890 +0x263
github.com/gin-gonic/gin.(*node).findCaseInsensitivePathRec(0xc005783640?, {0xc00b799bde?, 0xc005783680?}, {0xc000a57680?, 0x10169d3?, 0xf06f65?}, {0x31, 0x0, 0x0, 0x0}, ...)
	/go/pkg/mod/github.com/gin-gonic/[email protected]/tree.go:862 +0xa9d
github.com/gin-gonic/gin.(*node).findCaseInsensitivePathRec(0x1280f45?, {0xc00b799bdd?, 0xc001f36120?}, {0xc000a57680?, 0x7?, 0xc005783830?}, {0x31, 0x0, 0x0, 0x0}, ...)
	/go/pkg/mod/github.com/gin-gonic/[email protected]/tree.go:778 +0x45d
github.com/gin-gonic/gin.(*node).findCaseInsensitivePathRec(0x0?, {0xc00b799bdc?, 0x0?}, {0xc000a57680?, 0xc000930010?, 0xf087d0?}, {0x76, 0x0, 0x0, 0x0}, ...)
	/go/pkg/mod/github.com/gin-gonic/[email protected]/tree.go:778 +0x45d
github.com/gin-gonic/gin.(*node).findCaseInsensitivePath(0xc00b799bdc?, {0xc00b799bdc, 0xb}, 0x70?)
	/go/pkg/mod/github.com/gin-gonic/[email protected]/tree.go:669 +0x9c
github.com/gin-gonic/gin.redirectFixedPath(0xc008fc5b00, 0xc00b799bdc?, 0x0?)
	/go/pkg/mod/github.com/gin-gonic/[email protected]/gin.go:691 +0x5b
github.com/gin-gonic/gin.(*Engine).handleHTTPRequest(0xc000a5cd00, 0xc008fc5b00)
	/go/pkg/mod/github.com/gin-gonic/[email protected]/gin.go:629 +0x3aa
github.com/gin-gonic/gin.(*Engine).ServeHTTP(0xc000a5cd00, {0x3539350?, 0xc00a47fb20}, 0xc00aa3c100)
	/go/pkg/mod/github.com/gin-gonic/[email protected]/gin.go:576 +0x1dd
github.com/rs/cors.(*Cors).Handler.func1({0x3539350, 0xc00a47fb20}, 0xc00aa3c100)
	/go/pkg/mod/github.com/rs/[email protected]/cors.go:231 +0x1c4
net/http.HandlerFunc.ServeHTTP(0x0?, {0x3539350?, 0xc00a47fb20?}, 0xf60aee?)
	/usr/local/go/src/net/http/server.go:2122 +0x2f
net/http.serverHandler.ServeHTTP({0xc001f36090?}, {0x3539350, 0xc00a47fb20}, 0xc00aa3c100)
	/usr/local/go/src/net/http/server.go:2936 +0x316
net/http.(*conn).serve(0xc00b530ab0, {0x353aa78, 0xc007899e60})
	/usr/local/go/src/net/http/server.go:1995 +0x612
created by net/http.(*Server).Serve
	/usr/local/go/src/net/http/server.go:3089 +0x5ed

Could these errors be related to this issue?

pebo avatar May 23 '23 15:05 pebo

maybe I mentioned the wrong person, in that case I'll try again because there has been a new release and this was not discussed:

@thinkerou which one do you think is the best way to proceed? should I open a new issue or will you reopen this one?

I'm sorry if I mentioned the wrong person again. I just want to be sure this is reaching the right people

kpacha avatar Jun 02 '23 12:06 kpacha