Ver Fonte

fix many redirects (#1760) (#1764)

* fix many redirects (#1760)

* fix @thinkerou review
Dmitry Kutakov há 6 anos atrás
pai
commit
a768f064d5
2 ficheiros alterados com 42 adições e 0 exclusões
  1. 3 0
      gin.go
  2. 39 0
      gin_test.go

+ 3 - 0
gin.go

@@ -355,8 +355,11 @@ func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
 // This can be done by setting c.Request.URL.Path to your new target.
 // Disclaimer: You can loop yourself to death with this, use wisely.
 func (engine *Engine) HandleContext(c *Context) {
+	oldIndexValue := c.index
 	c.reset()
 	engine.handleHTTPRequest(c)
+
+	c.index = oldIndexValue
 }
 
 func (engine *Engine) handleHTTPRequest(c *Context) {

+ 39 - 0
gin_test.go

@@ -12,6 +12,8 @@ import (
 	"net/http"
 	"net/http/httptest"
 	"reflect"
+	"strconv"
+	"sync/atomic"
 	"testing"
 	"time"
 
@@ -488,6 +490,43 @@ func TestEngineHandleContext(t *testing.T) {
 	})
 }
 
+func TestEngineHandleContextManyReEntries(t *testing.T) {
+	expectValue := 10000
+
+	var handlerCounter, middlewareCounter int64
+
+	r := New()
+	r.Use(func(c *Context) {
+		atomic.AddInt64(&middlewareCounter, 1)
+	})
+	r.GET("/:count", func(c *Context) {
+		countStr := c.Param("count")
+		count, err := strconv.Atoi(countStr)
+		assert.NoError(t, err)
+
+		n, err := c.Writer.Write([]byte("."))
+		assert.NoError(t, err)
+		assert.Equal(t, 1, n)
+
+		switch {
+		case count > 0:
+			c.Request.URL.Path = "/" + strconv.Itoa(count-1)
+			r.HandleContext(c)
+		}
+	}, func(c *Context) {
+		atomic.AddInt64(&handlerCounter, 1)
+	})
+
+	assert.NotPanics(t, func() {
+		w := performRequest(r, "GET", "/"+strconv.Itoa(expectValue-1)) // include 0 value
+		assert.Equal(t, 200, w.Code)
+		assert.Equal(t, expectValue, w.Body.Len())
+	})
+
+	assert.Equal(t, int64(expectValue), handlerCounter)
+	assert.Equal(t, int64(expectValue), middlewareCounter)
+}
+
 func assertRoutePresent(t *testing.T, gotRoutes RoutesInfo, wantRoute RouteInfo) {
 	for _, gotRoute := range gotRoutes {
 		if gotRoute.Path == wantRoute.Path && gotRoute.Method == wantRoute.Method {