Pārlūkot izejas kodu

Router optimizations

benchmark            old ns/op     new ns/op     delta
Benchmark404         249           237           -4.82%
Benchmark404Many     454           390           -14.10%
Manu Mtz-Almeida 10 gadi atpakaļ
vecāks
revīzija
b7a15d3554
1 mainītis faili ar 46 papildinājumiem un 38 dzēšanām
  1. 46 38
      gin.go

+ 46 - 38
gin.go

@@ -228,8 +228,9 @@ func (engine *Engine) handleHTTPRequest(context *Context) {
 	t := engine.trees
 	t := engine.trees
 	for i, tl := 0, len(t); i < tl; i++ {
 	for i, tl := 0, len(t); i < tl; i++ {
 		if t[i].method == httpMethod {
 		if t[i].method == httpMethod {
+			root := t[i].root
 			// Find route in tree
 			// Find route in tree
-			handlers, params, tsr := t[i].root.getValue(path, context.Params)
+			handlers, params, tsr := root.getValue(path, context.Params)
 			if handlers != nil {
 			if handlers != nil {
 				context.handlers = handlers
 				context.handlers = handlers
 				context.Params = params
 				context.Params = params
@@ -238,7 +239,11 @@ func (engine *Engine) handleHTTPRequest(context *Context) {
 				return
 				return
 
 
 			} else if httpMethod != "CONNECT" && path != "/" {
 			} else if httpMethod != "CONNECT" && path != "/" {
-				if engine.serveAutoRedirect(context, t[i].root, tsr) {
+				if tsr && engine.RedirectFixedPath {
+					redirectTrailingSlash(context)
+					return
+				}
+				if engine.RedirectFixedPath && redirectFixedPath(context, root, engine.RedirectFixedPath) {
 					return
 					return
 				}
 				}
 			}
 			}
@@ -261,7 +266,22 @@ func (engine *Engine) handleHTTPRequest(context *Context) {
 	serveError(context, 404, default404Body)
 	serveError(context, 404, default404Body)
 }
 }
 
 
-func (engine *Engine) serveAutoRedirect(c *Context, root *node, tsr bool) bool {
+var mimePlain = []string{MIMEPlain}
+
+func serveError(c *Context, code int, defaultMessage []byte) {
+	c.writermem.status = code
+	c.Next()
+	if !c.writermem.Written() {
+		if c.writermem.Status() == code {
+			c.writermem.Header()["Content-Type"] = mimePlain
+			c.Writer.Write(defaultMessage)
+		} else {
+			c.writermem.WriteHeaderNow()
+		}
+	}
+}
+
+func redirectTrailingSlash(c *Context) {
 	req := c.Request
 	req := c.Request
 	path := req.URL.Path
 	path := req.URL.Path
 	code := 301 // Permanent redirect, request with GET method
 	code := 301 // Permanent redirect, request with GET method
@@ -269,46 +289,34 @@ func (engine *Engine) serveAutoRedirect(c *Context, root *node, tsr bool) bool {
 		code = 307
 		code = 307
 	}
 	}
 
 
-	if tsr && engine.RedirectTrailingSlash {
-		if len(path) > 1 && path[len(path)-1] == '/' {
-			req.URL.Path = path[:len(path)-1]
-		} else {
-			req.URL.Path = path + "/"
+	if len(path) > 1 && path[len(path)-1] == '/' {
+		req.URL.Path = path[:len(path)-1]
+	} else {
+		req.URL.Path = path + "/"
+	}
+	debugPrint("redirecting request %d: %s --> %s", code, path, req.URL.String())
+	http.Redirect(c.Writer, req, req.URL.String(), code)
+	c.writermem.WriteHeaderNow()
+}
+
+func redirectFixedPath(c *Context, root *node, trailingSlash bool) bool {
+	req := c.Request
+	path := req.URL.Path
+
+	fixedPath, found := root.findCaseInsensitivePath(
+		cleanPath(path),
+		trailingSlash,
+	)
+	if found {
+		code := 301 // Permanent redirect, request with GET method
+		if req.Method != "GET" {
+			code = 307
 		}
 		}
+		req.URL.Path = string(fixedPath)
 		debugPrint("redirecting request %d: %s --> %s", code, path, req.URL.String())
 		debugPrint("redirecting request %d: %s --> %s", code, path, req.URL.String())
 		http.Redirect(c.Writer, req, req.URL.String(), code)
 		http.Redirect(c.Writer, req, req.URL.String(), code)
 		c.writermem.WriteHeaderNow()
 		c.writermem.WriteHeaderNow()
 		return true
 		return true
 	}
 	}
-
-	// Try to fix the request path
-	if engine.RedirectFixedPath {
-		fixedPath, found := root.findCaseInsensitivePath(
-			cleanPath(path),
-			engine.RedirectTrailingSlash,
-		)
-		if found {
-			req.URL.Path = string(fixedPath)
-			debugPrint("redirecting request %d: %s --> %s", code, path, req.URL.String())
-			http.Redirect(c.Writer, req, req.URL.String(), code)
-			c.writermem.WriteHeaderNow()
-			return true
-		}
-	}
 	return false
 	return false
 }
 }
-
-var mimePlain = []string{MIMEPlain}
-
-func serveError(c *Context, code int, defaultMessage []byte) {
-	c.writermem.status = code
-	c.Next()
-	if !c.writermem.Written() {
-		if c.writermem.Status() == code {
-			c.writermem.Header()["Content-Type"] = mimePlain
-			c.Writer.Write(defaultMessage)
-		} else {
-			c.writermem.WriteHeaderNow()
-		}
-	}
-}