mirror of
https://github.com/astaxie/beego.git
synced 2024-11-25 17:20:55 +00:00
beego: improve performance
This commit is contained in:
parent
675643c68d
commit
6809c97611
4
beego.go
4
beego.go
@ -379,6 +379,10 @@ func initBeforeHttpRun() {
|
|||||||
middleware.VERSION = VERSION
|
middleware.VERSION = VERSION
|
||||||
middleware.AppName = AppName
|
middleware.AppName = AppName
|
||||||
middleware.RegisterErrorHandler()
|
middleware.RegisterErrorHandler()
|
||||||
|
|
||||||
|
for u, _ := range StaticDir {
|
||||||
|
Get(u, serverStaticRouter)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// this function is for test package init
|
// this function is for test package init
|
||||||
|
77
router.go
77
router.go
@ -43,7 +43,17 @@ const (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
// supported http methods.
|
// supported http methods.
|
||||||
HTTPMETHOD = []string{"get", "post", "put", "delete", "patch", "options", "head", "trace", "connect"}
|
HTTPMETHOD = map[string]string{
|
||||||
|
"GET": "GET",
|
||||||
|
"POST": "POST",
|
||||||
|
"PUT": "PUT",
|
||||||
|
"DELETE": "DELETE",
|
||||||
|
"PATCH": "PATCH",
|
||||||
|
"OPTIONS": "OPTIONS",
|
||||||
|
"HEAD": "HEAD",
|
||||||
|
"TRACE": "TRACE",
|
||||||
|
"CONNECT": "CONNECT",
|
||||||
|
}
|
||||||
// these beego.Controller's methods shouldn't reflect to AutoRouter
|
// these beego.Controller's methods shouldn't reflect to AutoRouter
|
||||||
exceptMethod = []string{"Init", "Prepare", "Finish", "Render", "RenderString",
|
exceptMethod = []string{"Init", "Prepare", "Finish", "Render", "RenderString",
|
||||||
"RenderBytes", "Redirect", "Abort", "StopRun", "UrlFor", "ServeJson", "ServeJsonp",
|
"RenderBytes", "Redirect", "Abort", "StopRun", "UrlFor", "ServeJson", "ServeJsonp",
|
||||||
@ -106,9 +116,9 @@ func (p *ControllerRegistor) Add(pattern string, c ControllerInterface, mappingM
|
|||||||
}
|
}
|
||||||
comma := strings.Split(colon[0], ",")
|
comma := strings.Split(colon[0], ",")
|
||||||
for _, m := range comma {
|
for _, m := range comma {
|
||||||
if m == "*" || utils.InSlice(strings.ToLower(m), HTTPMETHOD) {
|
if _, ok := HTTPMETHOD[strings.ToUpper(m)]; m == "*" || ok {
|
||||||
if val := reflectVal.MethodByName(colon[1]); val.IsValid() {
|
if val := reflectVal.MethodByName(colon[1]); val.IsValid() {
|
||||||
methods[strings.ToLower(m)] = colon[1]
|
methods[strings.ToUpper(m)] = colon[1]
|
||||||
} else {
|
} else {
|
||||||
panic(colon[1] + " method doesn't exist in the controller " + t.Name())
|
panic(colon[1] + " method doesn't exist in the controller " + t.Name())
|
||||||
}
|
}
|
||||||
@ -271,7 +281,7 @@ func (p *ControllerRegistor) Any(pattern string, f FilterFunc) {
|
|||||||
// ctx.Output.Body("hello world")
|
// ctx.Output.Body("hello world")
|
||||||
// })
|
// })
|
||||||
func (p *ControllerRegistor) AddMethod(method, pattern string, f FilterFunc) {
|
func (p *ControllerRegistor) AddMethod(method, pattern string, f FilterFunc) {
|
||||||
if method != "*" && !utils.InSlice(strings.ToLower(method), HTTPMETHOD) {
|
if _, ok := HTTPMETHOD[strings.ToUpper(method)]; method != "*" && !ok {
|
||||||
panic("not support http method: " + method)
|
panic("not support http method: " + method)
|
||||||
}
|
}
|
||||||
route := &controllerInfo{}
|
route := &controllerInfo{}
|
||||||
@ -284,7 +294,7 @@ func (p *ControllerRegistor) AddMethod(method, pattern string, f FilterFunc) {
|
|||||||
methods[val] = val
|
methods[val] = val
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
methods[method] = method
|
methods[strings.ToUpper(method)] = strings.ToUpper(method)
|
||||||
}
|
}
|
||||||
route.methods = methods
|
route.methods = methods
|
||||||
for k, _ := range methods {
|
for k, _ := range methods {
|
||||||
@ -417,8 +427,8 @@ func (p *ControllerRegistor) geturl(t *Tree, url, controllName, methodName strin
|
|||||||
if c, ok := t.leaf.runObject.(*controllerInfo); ok {
|
if c, ok := t.leaf.runObject.(*controllerInfo); ok {
|
||||||
if c.routerType == routerTypeBeego && c.controllerType.Name() == controllName {
|
if c.routerType == routerTypeBeego && c.controllerType.Name() == controllName {
|
||||||
find := false
|
find := false
|
||||||
if utils.InSlice(strings.ToLower(methodName), HTTPMETHOD) {
|
if _, ok := HTTPMETHOD[strings.ToUpper(methodName)]; ok {
|
||||||
if m, ok := c.methods[strings.ToLower(methodName)]; ok && m != methodName {
|
if m, ok := c.methods[strings.ToUpper(methodName)]; ok && m != strings.ToUpper(methodName) {
|
||||||
return false, ""
|
return false, ""
|
||||||
} else if m, ok = c.methods["*"]; ok && m != methodName {
|
} else if m, ok = c.methods["*"]; ok && m != methodName {
|
||||||
return false, ""
|
return false, ""
|
||||||
@ -508,8 +518,6 @@ func (p *ControllerRegistor) geturl(t *Tree, url, controllName, methodName strin
|
|||||||
func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||||
defer p.recoverPanic(rw, r)
|
defer p.recoverPanic(rw, r)
|
||||||
starttime := time.Now()
|
starttime := time.Now()
|
||||||
requestPath := r.URL.Path
|
|
||||||
method := strings.ToLower(r.Method)
|
|
||||||
var runrouter reflect.Type
|
var runrouter reflect.Type
|
||||||
var findrouter bool
|
var findrouter bool
|
||||||
var runMethod string
|
var runMethod string
|
||||||
@ -559,12 +567,12 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
if !utils.InSlice(method, HTTPMETHOD) {
|
if _, ok := HTTPMETHOD[r.Method]; !ok {
|
||||||
http.Error(w, "Method Not Allowed", 405)
|
http.Error(w, "Method Not Allowed", 405)
|
||||||
goto Admin
|
goto Admin
|
||||||
}
|
}
|
||||||
|
|
||||||
if !context.Input.IsGet() && !context.Input.IsHead() {
|
if r.Method != "GET" && r.Method != "HEAD" {
|
||||||
if CopyRequestBody && !context.Input.IsUpload() {
|
if CopyRequestBody && !context.Input.IsUpload() {
|
||||||
context.Input.CopyBody()
|
context.Input.CopyBody()
|
||||||
}
|
}
|
||||||
@ -575,11 +583,6 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
|
|||||||
goto Admin
|
goto Admin
|
||||||
}
|
}
|
||||||
|
|
||||||
//static file server
|
|
||||||
if serverStaticRouter(context) {
|
|
||||||
goto Admin
|
|
||||||
}
|
|
||||||
|
|
||||||
if context.Input.RunController != nil && context.Input.RunMethod != "" {
|
if context.Input.RunController != nil && context.Input.RunMethod != "" {
|
||||||
findrouter = true
|
findrouter = true
|
||||||
runMethod = context.Input.RunMethod
|
runMethod = context.Input.RunMethod
|
||||||
@ -587,8 +590,8 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !findrouter {
|
if !findrouter {
|
||||||
if t, ok := p.routers[method]; ok {
|
if t, ok := p.routers[r.Method]; ok {
|
||||||
runObject, p := t.Match(requestPath)
|
runObject, p := t.Match(r.URL.Path)
|
||||||
if r, ok := runObject.(*controllerInfo); ok {
|
if r, ok := runObject.(*controllerInfo); ok {
|
||||||
routerInfo = r
|
routerInfo = r
|
||||||
findrouter = true
|
findrouter = true
|
||||||
@ -618,7 +621,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
|
|||||||
isRunable := false
|
isRunable := false
|
||||||
if routerInfo != nil {
|
if routerInfo != nil {
|
||||||
if routerInfo.routerType == routerTypeRESTFul {
|
if routerInfo.routerType == routerTypeRESTFul {
|
||||||
if _, ok := routerInfo.methods[strings.ToLower(r.Method)]; ok {
|
if _, ok := routerInfo.methods[r.Method]; ok {
|
||||||
isRunable = true
|
isRunable = true
|
||||||
routerInfo.runfunction(context)
|
routerInfo.runfunction(context)
|
||||||
} else {
|
} else {
|
||||||
@ -630,19 +633,19 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
|
|||||||
routerInfo.handler.ServeHTTP(rw, r)
|
routerInfo.handler.ServeHTTP(rw, r)
|
||||||
} else {
|
} else {
|
||||||
runrouter = routerInfo.controllerType
|
runrouter = routerInfo.controllerType
|
||||||
method := strings.ToLower(r.Method)
|
method := r.Method
|
||||||
if method == "post" && strings.ToLower(context.Input.Query("_method")) == "put" {
|
if r.Method == "POST" && context.Input.Query("_method") == "PUT" {
|
||||||
method = "put"
|
method = "PUT"
|
||||||
}
|
}
|
||||||
if method == "post" && strings.ToLower(context.Input.Query("_method")) == "delete" {
|
if r.Method == "POST" && context.Input.Query("_method") == "DELETE" {
|
||||||
method = "delete"
|
method = "DELETE"
|
||||||
}
|
}
|
||||||
if m, ok := routerInfo.methods[method]; ok {
|
if m, ok := routerInfo.methods[method]; ok {
|
||||||
runMethod = m
|
runMethod = m
|
||||||
} else if m, ok = routerInfo.methods["*"]; ok {
|
} else if m, ok = routerInfo.methods["*"]; ok {
|
||||||
runMethod = m
|
runMethod = m
|
||||||
} else {
|
} else {
|
||||||
runMethod = strings.Title(method)
|
runMethod = method
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -676,19 +679,19 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
|
|||||||
if !w.started {
|
if !w.started {
|
||||||
//exec main logic
|
//exec main logic
|
||||||
switch runMethod {
|
switch runMethod {
|
||||||
case "Get":
|
case "GET":
|
||||||
execController.Get()
|
execController.Get()
|
||||||
case "Post":
|
case "POST":
|
||||||
execController.Post()
|
execController.Post()
|
||||||
case "Delete":
|
case "DELETE":
|
||||||
execController.Delete()
|
execController.Delete()
|
||||||
case "Put":
|
case "PUT":
|
||||||
execController.Put()
|
execController.Put()
|
||||||
case "Head":
|
case "HEAD":
|
||||||
execController.Head()
|
execController.Head()
|
||||||
case "Patch":
|
case "PATCH":
|
||||||
execController.Patch()
|
execController.Patch()
|
||||||
case "Options":
|
case "OPTIONS":
|
||||||
execController.Options()
|
execController.Options()
|
||||||
default:
|
default:
|
||||||
if !execController.HandlerFunc(runMethod) {
|
if !execController.HandlerFunc(runMethod) {
|
||||||
@ -725,20 +728,20 @@ Admin:
|
|||||||
timeend := time.Since(starttime)
|
timeend := time.Since(starttime)
|
||||||
//admin module record QPS
|
//admin module record QPS
|
||||||
if EnableAdmin {
|
if EnableAdmin {
|
||||||
if FilterMonitorFunc(r.Method, requestPath, timeend) {
|
if FilterMonitorFunc(r.Method, r.URL.Path, timeend) {
|
||||||
if runrouter != nil {
|
if runrouter != nil {
|
||||||
go toolbox.StatisticsMap.AddStatistics(r.Method, requestPath, runrouter.Name(), timeend)
|
go toolbox.StatisticsMap.AddStatistics(r.Method, r.URL.Path, runrouter.Name(), timeend)
|
||||||
} else {
|
} else {
|
||||||
go toolbox.StatisticsMap.AddStatistics(r.Method, requestPath, "", timeend)
|
go toolbox.StatisticsMap.AddStatistics(r.Method, r.URL.Path, "", timeend)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if RunMode == "dev" {
|
if RunMode == "dev" {
|
||||||
if findrouter {
|
if findrouter {
|
||||||
Info("beego: router defined " + routerInfo.pattern + " " + requestPath + " +" + timeend.String())
|
Info("beego: router defined " + routerInfo.pattern + " " + r.URL.Path + " +" + timeend.String())
|
||||||
} else {
|
} else {
|
||||||
Info("beego:" + requestPath + " 404" + " +" + timeend.String())
|
Info("beego:" + r.URL.Path + " 404" + " +" + timeend.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ import (
|
|||||||
"github.com/astaxie/beego/utils"
|
"github.com/astaxie/beego/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func serverStaticRouter(ctx *context.Context) bool {
|
func serverStaticRouter(ctx *context.Context) {
|
||||||
requestPath := path.Clean(ctx.Input.Request.URL.Path)
|
requestPath := path.Clean(ctx.Input.Request.URL.Path)
|
||||||
for prefix, staticDir := range StaticDir {
|
for prefix, staticDir := range StaticDir {
|
||||||
if len(prefix) == 0 {
|
if len(prefix) == 0 {
|
||||||
@ -28,7 +28,7 @@ func serverStaticRouter(ctx *context.Context) bool {
|
|||||||
file := path.Join(staticDir, requestPath)
|
file := path.Join(staticDir, requestPath)
|
||||||
if utils.FileExists(file) {
|
if utils.FileExists(file) {
|
||||||
http.ServeFile(ctx.ResponseWriter, ctx.Request, file)
|
http.ServeFile(ctx.ResponseWriter, ctx.Request, file)
|
||||||
return true
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(requestPath, prefix) {
|
if strings.HasPrefix(requestPath, prefix) {
|
||||||
@ -37,7 +37,7 @@ func serverStaticRouter(ctx *context.Context) bool {
|
|||||||
}
|
}
|
||||||
if requestPath == prefix && prefix[len(prefix)-1] != '/' {
|
if requestPath == prefix && prefix[len(prefix)-1] != '/' {
|
||||||
http.Redirect(ctx.ResponseWriter, ctx.Request, requestPath+"/", 302)
|
http.Redirect(ctx.ResponseWriter, ctx.Request, requestPath+"/", 302)
|
||||||
return true
|
return
|
||||||
}
|
}
|
||||||
file := path.Join(staticDir, requestPath[len(prefix):])
|
file := path.Join(staticDir, requestPath[len(prefix):])
|
||||||
finfo, err := os.Stat(file)
|
finfo, err := os.Stat(file)
|
||||||
@ -46,12 +46,12 @@ func serverStaticRouter(ctx *context.Context) bool {
|
|||||||
Warn(err)
|
Warn(err)
|
||||||
}
|
}
|
||||||
http.NotFound(ctx.ResponseWriter, ctx.Request)
|
http.NotFound(ctx.ResponseWriter, ctx.Request)
|
||||||
return true
|
return
|
||||||
}
|
}
|
||||||
//if the request is dir and DirectoryIndex is false then
|
//if the request is dir and DirectoryIndex is false then
|
||||||
if finfo.IsDir() && !DirectoryIndex {
|
if finfo.IsDir() && !DirectoryIndex {
|
||||||
middleware.Exception("403", ctx.ResponseWriter, ctx.Request, "403 Forbidden")
|
middleware.Exception("403", ctx.ResponseWriter, ctx.Request, "403 Forbidden")
|
||||||
return true
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//This block obtained from (https://github.com/smithfox/beego) - it should probably get merged into astaxie/beego after a pull request
|
//This block obtained from (https://github.com/smithfox/beego) - it should probably get merged into astaxie/beego after a pull request
|
||||||
@ -73,7 +73,7 @@ func serverStaticRouter(ctx *context.Context) bool {
|
|||||||
|
|
||||||
memzipfile, err := openMemZipFile(file, contentEncoding)
|
memzipfile, err := openMemZipFile(file, contentEncoding)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return true
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if contentEncoding == "gzip" {
|
if contentEncoding == "gzip" {
|
||||||
@ -89,8 +89,7 @@ func serverStaticRouter(ctx *context.Context) bool {
|
|||||||
} else {
|
} else {
|
||||||
http.ServeFile(ctx.ResponseWriter, ctx.Request, file)
|
http.ServeFile(ctx.ResponseWriter, ctx.Request, file)
|
||||||
}
|
}
|
||||||
return true
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user