Skip to content

Commit 86ff4a6

Browse files
Crocmagnonunbyte
andauthored
fix(header): Allow header according to RFC 7231 (HTTP 405) (#3759)
Co-authored-by: Helios <[email protected]>
1 parent e957d1a commit 86ff4a6

File tree

2 files changed

+23
-3
lines changed

2 files changed

+23
-3
lines changed

gin.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -633,17 +633,25 @@ func (engine *Engine) handleHTTPRequest(c *Context) {
633633
}
634634

635635
if engine.HandleMethodNotAllowed {
636+
// According to RFC 7231 section 6.5.5, MUST generate an Allow header field in response
637+
// containing a list of the target resource's currently supported methods.
638+
allowed := make([]string, 0, len(t)-1)
636639
for _, tree := range engine.trees {
637640
if tree.method == httpMethod {
638641
continue
639642
}
640643
if value := tree.root.getValue(rPath, nil, c.skippedNodes, unescape); value.handlers != nil {
641-
c.handlers = engine.allNoMethod
642-
serveError(c, http.StatusMethodNotAllowed, default405Body)
643-
return
644+
allowed = append(allowed, tree.method)
644645
}
645646
}
647+
if len(allowed) > 0 {
648+
c.handlers = engine.allNoMethod
649+
c.writermem.Header().Set("Allow", strings.Join(allowed, ", "))
650+
serveError(c, http.StatusMethodNotAllowed, default405Body)
651+
return
652+
}
646653
}
654+
647655
c.handlers = engine.allNoRoute
648656
serveError(c, http.StatusNotFound, default404Body)
649657
}

routes_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,18 @@ func TestRouteNotAllowedEnabled2(t *testing.T) {
514514
assert.Equal(t, http.StatusMethodNotAllowed, w.Code)
515515
}
516516

517+
func TestRouteNotAllowedEnabled3(t *testing.T) {
518+
router := New()
519+
router.HandleMethodNotAllowed = true
520+
router.GET("/path", func(c *Context) {})
521+
router.POST("/path", func(c *Context) {})
522+
w := PerformRequest(router, http.MethodPut, "/path")
523+
assert.Equal(t, http.StatusMethodNotAllowed, w.Code)
524+
allowed := w.Header().Get("Allow")
525+
assert.Contains(t, allowed, "GET")
526+
assert.Contains(t, allowed, "POST")
527+
}
528+
517529
func TestRouteNotAllowedDisabled(t *testing.T) {
518530
router := New()
519531
router.HandleMethodNotAllowed = false

0 commit comments

Comments
 (0)