forked from mirror/gin
Router optimizations
benchmark old ns/op new ns/op delta Benchmark404 249 237 -4.82% Benchmark404Many 454 390 -14.10%
This commit is contained in:
parent
02a5e0929a
commit
b7a15d3554
86
gin.go
86
gin.go
|
@ -228,8 +228,9 @@ func (engine *Engine) handleHTTPRequest(context *Context) {
|
|||
t := engine.trees
|
||||
for i, tl := 0, len(t); i < tl; i++ {
|
||||
if t[i].method == httpMethod {
|
||||
root := t[i].root
|
||||
// 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 {
|
||||
context.handlers = handlers
|
||||
context.Params = params
|
||||
|
@ -238,7 +239,11 @@ func (engine *Engine) handleHTTPRequest(context *Context) {
|
|||
return
|
||||
|
||||
} 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
|
||||
}
|
||||
}
|
||||
|
@ -261,43 +266,6 @@ func (engine *Engine) handleHTTPRequest(context *Context) {
|
|||
serveError(context, 404, default404Body)
|
||||
}
|
||||
|
||||
func (engine *Engine) serveAutoRedirect(c *Context, root *node, tsr bool) bool {
|
||||
req := c.Request
|
||||
path := req.URL.Path
|
||||
code := 301 // Permanent redirect, request with GET method
|
||||
if req.Method != "GET" {
|
||||
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 + "/"
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
var mimePlain = []string{MIMEPlain}
|
||||
|
||||
func serveError(c *Context, code int, defaultMessage []byte) {
|
||||
|
@ -312,3 +280,43 @@ func serveError(c *Context, code int, defaultMessage []byte) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func redirectTrailingSlash(c *Context) {
|
||||
req := c.Request
|
||||
path := req.URL.Path
|
||||
code := 301 // Permanent redirect, request with GET method
|
||||
if req.Method != "GET" {
|
||||
code = 307
|
||||
}
|
||||
|
||||
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())
|
||||
http.Redirect(c.Writer, req, req.URL.String(), code)
|
||||
c.writermem.WriteHeaderNow()
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue