瀏覽代碼

Merge pull request #235 from donileo/NoMethod

Include NoMethod method to Gin to allow middleware handling of 405 errors
Javier Provecho Fernandez 10 年之前
父節點
當前提交
1921ccbaf3
共有 2 個文件被更改,包括 38 次插入9 次删除
  1. 1 1
      Godeps/Godeps.json
  2. 37 8
      gin.go

+ 1 - 1
Godeps/Godeps.json

@@ -4,7 +4,7 @@
 	"Deps": [
 		{
 			"ImportPath": "github.com/julienschmidt/httprouter",
-			"Rev": "00ce1c6a267162792c367acc43b1681a884e1872"
+			"Rev": "b428fda53bb0a764fea9c76c9413512eda291dec"
 		}
 	]
 }

+ 37 - 8
gin.go

@@ -30,12 +30,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 +52,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 +102,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 +136,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)