Skip to content

Commit

Permalink
fix: the result will be incorrect when call gin.Context.Writer.Status…
Browse files Browse the repository at this point in the history
…() in our custom gin middleware used after this middleware (#46)

Co-authored-by: zhangyi <zhangyi905@guance.com>
  • Loading branch information
zhyee and zhangyi committed Nov 24, 2023
1 parent 9e7d799 commit c0a749e
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 0 deletions.
32 changes: 32 additions & 0 deletions timeout_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"net/http"
"net/http/httptest"
"strconv"
"sync"
"testing"
"time"
Expand Down Expand Up @@ -102,6 +103,37 @@ func TestPanic(t *testing.T) {
assert.Equal(t, "", w.Body.String())
}

func TestWriter_Status(t *testing.T) {
r := gin.New()

r.Use(New(
WithTimeout(1*time.Second),
WithHandler(func(c *gin.Context) {
c.Next()
}),
WithResponse(testResponse),
))

r.Use(func(c *gin.Context) {
c.Next()
statusInMW := c.Writer.Status()
c.Request.Header.Set("X-Status-Code-MW-Set", strconv.Itoa(statusInMW))
t.Logf("[%s] %s %s %d\n", time.Now().Format(time.RFC3339), c.Request.Method, c.Request.URL, statusInMW)
})

r.GET("/test", func(c *gin.Context) {
c.Writer.WriteHeader(http.StatusInternalServerError)
})

w := httptest.NewRecorder()
req := httptest.NewRequest(http.MethodGet, "/test", nil)

r.ServeHTTP(w, req)

assert.Equal(t, w.Result().StatusCode, http.StatusInternalServerError)

Check failure on line 133 in timeout_test.go

View workflow job for this annotation

GitHub Actions / lint

response body must be closed (bodyclose)
assert.Equal(t, strconv.Itoa(http.StatusInternalServerError), req.Header.Get("X-Status-Code-MW-Set"))
}

func TestDeadlineExceeded(t *testing.T) {
var wg sync.WaitGroup
wg.Add(1)
Expand Down
10 changes: 10 additions & 0 deletions writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,16 @@ func (w *Writer) writeHeader(code int) {
w.code = code
}

// Status we must override Status func here,
// or the http status code returned by gin.Context.Writer.Status()
// will always be 200 in other custom gin middlewares.
func (w *Writer) Status() int {
if w.code == 0 || w.timeout {
return w.ResponseWriter.Status()
}
return w.code
}

// Header will get response headers
func (w *Writer) Header() http.Header {
return w.headers
Expand Down

0 comments on commit c0a749e

Please sign in to comment.