Selaa lähdekoodia

Include NoMethod Method to Gin to allow middlewares to handle 405 No Method Errors in the gin router

Adonis 10 vuotta sitten
vanhempi
commit
a04d9e271c
1 muutettua tiedostoa jossa 44 lisäystä ja 16 poistoa
  1. 44 16
      gin.go

+ 44 - 16
gin.go

@@ -14,14 +14,13 @@ import (
 )
 
 const (
-	AbortIndex            = math.MaxInt8 / 2
-	MIMEJSON              = "application/json"
-	MIMEHTML              = "text/html"
-	MIMEXML               = "application/xml"
-	MIMEXML2              = "text/xml"
-	MIMEPlain             = "text/plain"
-	MIMEPOSTForm          = "application/x-www-form-urlencoded"
-	MIMEMultipartPOSTForm = "multipart/form-data"
+	AbortIndex   = math.MaxInt8 / 2
+	MIMEJSON     = "application/json"
+	MIMEHTML     = "text/html"
+	MIMEXML      = "application/xml"
+	MIMEXML2     = "text/xml"
+	MIMEPlain    = "text/plain"
+	MIMEPOSTForm = "application/x-www-form-urlencoded"
 )
 
 type (
@@ -30,12 +29,14 @@ type (
 	// Represents the web framework, it wraps the blazing fast httprouter multiplexer and a list of global middlewares.
 	Engine struct {
 		*RouterGroup
-		HTMLRender     render.Render
-		Default404Body []byte
-		pool           sync.Pool
-		allNoRoute     []HandlerFunc
-		noRoute        []HandlerFunc
-		router         *httprouter.Router
+		HTMLRender         render.Render
+		Default404Body     []byte
+		Default405Body     []byte
+		pool               sync.Pool
+		allNoRouteNoMethod []HandlerFunc
+		noRoute            []HandlerFunc
+		noMethod           []HandlerFunc
+		router             *httprouter.Router
 	}
 )
 
@@ -50,7 +51,9 @@ func New() *Engine {
 	}
 	engine.router = httprouter.New()
 	engine.Default404Body = []byte("404 page not found")
+	engine.Default405Body = []byte("405 method not allowed")
 	engine.router.NotFound = engine.handle404
+	engine.router.MethodNotAllowed = engine.handle405
 	engine.pool.New = func() interface{} {
 		c := &Context{Engine: engine}
 		c.Writer = &c.writermem
@@ -98,17 +101,27 @@ func (engine *Engine) NoRoute(handlers ...HandlerFunc) {
 	engine.rebuild404Handlers()
 }
 
+func (engine *Engine) NoMethod(handlers ...HandlerFunc) {
+	engine.noMethod = handlers
+	engine.rebuild405Handlers()
+}
+
 func (engine *Engine) Use(middlewares ...HandlerFunc) {
 	engine.RouterGroup.Use(middlewares...)
 	engine.rebuild404Handlers()
+	engine.rebuild405Handlers()
 }
 
 func (engine *Engine) rebuild404Handlers() {
-	engine.allNoRoute = engine.combineHandlers(engine.noRoute)
+	engine.allNoRouteNoMethod = engine.combineHandlers(engine.noRoute)
+}
+
+func (engine *Engine) rebuild405Handlers() {
+	engine.allNoRouteNoMethod = engine.combineHandlers(engine.noMethod)
 }
 
 func (engine *Engine) handle404(w http.ResponseWriter, req *http.Request) {
-	c := engine.createContext(w, req, nil, engine.allNoRoute)
+	c := engine.createContext(w, req, nil, engine.allNoRouteNoMethod)
 	// set 404 by default, useful for logging
 	c.Writer.WriteHeader(404)
 	c.Next()
@@ -122,6 +135,21 @@ func (engine *Engine) handle404(w http.ResponseWriter, req *http.Request) {
 	engine.reuseContext(c)
 }
 
+func (engine *Engine) handle405(w http.ResponseWriter, req *http.Request) {
+	c := engine.createContext(w, req, nil, engine.allNoRouteNoMethod)
+	// set 405 by default, useful for logging
+	c.Writer.WriteHeader(405)
+	c.Next()
+	if !c.Writer.Written() {
+		if c.Writer.Status() == 405 {
+			c.Data(-1, MIMEPlain, engine.Default405Body)
+		} else {
+			c.Writer.WriteHeaderNow()
+		}
+	}
+	engine.reuseContext(c)
+}
+
 // ServeHTTP makes the router implement the http.Handler interface.
 func (engine *Engine) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
 	engine.router.ServeHTTP(writer, request)