beego: improve performance
Showing
3 changed files
with
51 additions
and
45 deletions
| ... | @@ -379,6 +379,10 @@ func initBeforeHttpRun() { | ... | @@ -379,6 +379,10 @@ func initBeforeHttpRun() { |
| 379 | middleware.VERSION = VERSION | 379 | middleware.VERSION = VERSION |
| 380 | middleware.AppName = AppName | 380 | middleware.AppName = AppName |
| 381 | middleware.RegisterErrorHandler() | 381 | middleware.RegisterErrorHandler() |
| 382 | |||
| 383 | for u, _ := range StaticDir { | ||
| 384 | Get(u, serverStaticRouter) | ||
| 385 | } | ||
| 382 | } | 386 | } |
| 383 | 387 | ||
| 384 | // this function is for test package init | 388 | // this function is for test package init | ... | ... |
| ... | @@ -43,7 +43,17 @@ const ( | ... | @@ -43,7 +43,17 @@ const ( |
| 43 | 43 | ||
| 44 | var ( | 44 | var ( |
| 45 | // supported http methods. | 45 | // supported http methods. |
| 46 | HTTPMETHOD = []string{"get", "post", "put", "delete", "patch", "options", "head", "trace", "connect"} | 46 | HTTPMETHOD = map[string]string{ |
| 47 | "GET": "GET", | ||
| 48 | "POST": "POST", | ||
| 49 | "PUT": "PUT", | ||
| 50 | "DELETE": "DELETE", | ||
| 51 | "PATCH": "PATCH", | ||
| 52 | "OPTIONS": "OPTIONS", | ||
| 53 | "HEAD": "HEAD", | ||
| 54 | "TRACE": "TRACE", | ||
| 55 | "CONNECT": "CONNECT", | ||
| 56 | } | ||
| 47 | // these beego.Controller's methods shouldn't reflect to AutoRouter | 57 | // these beego.Controller's methods shouldn't reflect to AutoRouter |
| 48 | exceptMethod = []string{"Init", "Prepare", "Finish", "Render", "RenderString", | 58 | exceptMethod = []string{"Init", "Prepare", "Finish", "Render", "RenderString", |
| 49 | "RenderBytes", "Redirect", "Abort", "StopRun", "UrlFor", "ServeJson", "ServeJsonp", | 59 | "RenderBytes", "Redirect", "Abort", "StopRun", "UrlFor", "ServeJson", "ServeJsonp", |
| ... | @@ -106,9 +116,9 @@ func (p *ControllerRegistor) Add(pattern string, c ControllerInterface, mappingM | ... | @@ -106,9 +116,9 @@ func (p *ControllerRegistor) Add(pattern string, c ControllerInterface, mappingM |
| 106 | } | 116 | } |
| 107 | comma := strings.Split(colon[0], ",") | 117 | comma := strings.Split(colon[0], ",") |
| 108 | for _, m := range comma { | 118 | for _, m := range comma { |
| 109 | if m == "*" || utils.InSlice(strings.ToLower(m), HTTPMETHOD) { | 119 | if _, ok := HTTPMETHOD[strings.ToUpper(m)]; m == "*" || ok { |
| 110 | if val := reflectVal.MethodByName(colon[1]); val.IsValid() { | 120 | if val := reflectVal.MethodByName(colon[1]); val.IsValid() { |
| 111 | methods[strings.ToLower(m)] = colon[1] | 121 | methods[strings.ToUpper(m)] = colon[1] |
| 112 | } else { | 122 | } else { |
| 113 | panic(colon[1] + " method doesn't exist in the controller " + t.Name()) | 123 | panic(colon[1] + " method doesn't exist in the controller " + t.Name()) |
| 114 | } | 124 | } |
| ... | @@ -271,7 +281,7 @@ func (p *ControllerRegistor) Any(pattern string, f FilterFunc) { | ... | @@ -271,7 +281,7 @@ func (p *ControllerRegistor) Any(pattern string, f FilterFunc) { |
| 271 | // ctx.Output.Body("hello world") | 281 | // ctx.Output.Body("hello world") |
| 272 | // }) | 282 | // }) |
| 273 | func (p *ControllerRegistor) AddMethod(method, pattern string, f FilterFunc) { | 283 | func (p *ControllerRegistor) AddMethod(method, pattern string, f FilterFunc) { |
| 274 | if method != "*" && !utils.InSlice(strings.ToLower(method), HTTPMETHOD) { | 284 | if _, ok := HTTPMETHOD[strings.ToUpper(method)]; method != "*" && !ok { |
| 275 | panic("not support http method: " + method) | 285 | panic("not support http method: " + method) |
| 276 | } | 286 | } |
| 277 | route := &controllerInfo{} | 287 | route := &controllerInfo{} |
| ... | @@ -284,7 +294,7 @@ func (p *ControllerRegistor) AddMethod(method, pattern string, f FilterFunc) { | ... | @@ -284,7 +294,7 @@ func (p *ControllerRegistor) AddMethod(method, pattern string, f FilterFunc) { |
| 284 | methods[val] = val | 294 | methods[val] = val |
| 285 | } | 295 | } |
| 286 | } else { | 296 | } else { |
| 287 | methods[method] = method | 297 | methods[strings.ToUpper(method)] = strings.ToUpper(method) |
| 288 | } | 298 | } |
| 289 | route.methods = methods | 299 | route.methods = methods |
| 290 | for k, _ := range methods { | 300 | for k, _ := range methods { |
| ... | @@ -417,8 +427,8 @@ func (p *ControllerRegistor) geturl(t *Tree, url, controllName, methodName strin | ... | @@ -417,8 +427,8 @@ func (p *ControllerRegistor) geturl(t *Tree, url, controllName, methodName strin |
| 417 | if c, ok := t.leaf.runObject.(*controllerInfo); ok { | 427 | if c, ok := t.leaf.runObject.(*controllerInfo); ok { |
| 418 | if c.routerType == routerTypeBeego && c.controllerType.Name() == controllName { | 428 | if c.routerType == routerTypeBeego && c.controllerType.Name() == controllName { |
| 419 | find := false | 429 | find := false |
| 420 | if utils.InSlice(strings.ToLower(methodName), HTTPMETHOD) { | 430 | if _, ok := HTTPMETHOD[strings.ToUpper(methodName)]; ok { |
| 421 | if m, ok := c.methods[strings.ToLower(methodName)]; ok && m != methodName { | 431 | if m, ok := c.methods[strings.ToUpper(methodName)]; ok && m != strings.ToUpper(methodName) { |
| 422 | return false, "" | 432 | return false, "" |
| 423 | } else if m, ok = c.methods["*"]; ok && m != methodName { | 433 | } else if m, ok = c.methods["*"]; ok && m != methodName { |
| 424 | return false, "" | 434 | return false, "" |
| ... | @@ -508,8 +518,6 @@ func (p *ControllerRegistor) geturl(t *Tree, url, controllName, methodName strin | ... | @@ -508,8 +518,6 @@ func (p *ControllerRegistor) geturl(t *Tree, url, controllName, methodName strin |
| 508 | func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) { | 518 | func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) { |
| 509 | defer p.recoverPanic(rw, r) | 519 | defer p.recoverPanic(rw, r) |
| 510 | starttime := time.Now() | 520 | starttime := time.Now() |
| 511 | requestPath := r.URL.Path | ||
| 512 | method := strings.ToLower(r.Method) | ||
| 513 | var runrouter reflect.Type | 521 | var runrouter reflect.Type |
| 514 | var findrouter bool | 522 | var findrouter bool |
| 515 | var runMethod string | 523 | var runMethod string |
| ... | @@ -559,12 +567,12 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) | ... | @@ -559,12 +567,12 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) |
| 559 | }() | 567 | }() |
| 560 | } | 568 | } |
| 561 | 569 | ||
| 562 | if !utils.InSlice(method, HTTPMETHOD) { | 570 | if _, ok := HTTPMETHOD[r.Method]; !ok { |
| 563 | http.Error(w, "Method Not Allowed", 405) | 571 | http.Error(w, "Method Not Allowed", 405) |
| 564 | goto Admin | 572 | goto Admin |
| 565 | } | 573 | } |
| 566 | 574 | ||
| 567 | if !context.Input.IsGet() && !context.Input.IsHead() { | 575 | if r.Method != "GET" && r.Method != "HEAD" { |
| 568 | if CopyRequestBody && !context.Input.IsUpload() { | 576 | if CopyRequestBody && !context.Input.IsUpload() { |
| 569 | context.Input.CopyBody() | 577 | context.Input.CopyBody() |
| 570 | } | 578 | } |
| ... | @@ -575,11 +583,6 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) | ... | @@ -575,11 +583,6 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) |
| 575 | goto Admin | 583 | goto Admin |
| 576 | } | 584 | } |
| 577 | 585 | ||
| 578 | //static file server | ||
| 579 | if serverStaticRouter(context) { | ||
| 580 | goto Admin | ||
| 581 | } | ||
| 582 | |||
| 583 | if context.Input.RunController != nil && context.Input.RunMethod != "" { | 586 | if context.Input.RunController != nil && context.Input.RunMethod != "" { |
| 584 | findrouter = true | 587 | findrouter = true |
| 585 | runMethod = context.Input.RunMethod | 588 | runMethod = context.Input.RunMethod |
| ... | @@ -587,8 +590,8 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) | ... | @@ -587,8 +590,8 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) |
| 587 | } | 590 | } |
| 588 | 591 | ||
| 589 | if !findrouter { | 592 | if !findrouter { |
| 590 | if t, ok := p.routers[method]; ok { | 593 | if t, ok := p.routers[r.Method]; ok { |
| 591 | runObject, p := t.Match(requestPath) | 594 | runObject, p := t.Match(r.URL.Path) |
| 592 | if r, ok := runObject.(*controllerInfo); ok { | 595 | if r, ok := runObject.(*controllerInfo); ok { |
| 593 | routerInfo = r | 596 | routerInfo = r |
| 594 | findrouter = true | 597 | findrouter = true |
| ... | @@ -618,7 +621,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) | ... | @@ -618,7 +621,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) |
| 618 | isRunable := false | 621 | isRunable := false |
| 619 | if routerInfo != nil { | 622 | if routerInfo != nil { |
| 620 | if routerInfo.routerType == routerTypeRESTFul { | 623 | if routerInfo.routerType == routerTypeRESTFul { |
| 621 | if _, ok := routerInfo.methods[strings.ToLower(r.Method)]; ok { | 624 | if _, ok := routerInfo.methods[r.Method]; ok { |
| 622 | isRunable = true | 625 | isRunable = true |
| 623 | routerInfo.runfunction(context) | 626 | routerInfo.runfunction(context) |
| 624 | } else { | 627 | } else { |
| ... | @@ -630,19 +633,19 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) | ... | @@ -630,19 +633,19 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) |
| 630 | routerInfo.handler.ServeHTTP(rw, r) | 633 | routerInfo.handler.ServeHTTP(rw, r) |
| 631 | } else { | 634 | } else { |
| 632 | runrouter = routerInfo.controllerType | 635 | runrouter = routerInfo.controllerType |
| 633 | method := strings.ToLower(r.Method) | 636 | method := r.Method |
| 634 | if method == "post" && strings.ToLower(context.Input.Query("_method")) == "put" { | 637 | if r.Method == "POST" && context.Input.Query("_method") == "PUT" { |
| 635 | method = "put" | 638 | method = "PUT" |
| 636 | } | 639 | } |
| 637 | if method == "post" && strings.ToLower(context.Input.Query("_method")) == "delete" { | 640 | if r.Method == "POST" && context.Input.Query("_method") == "DELETE" { |
| 638 | method = "delete" | 641 | method = "DELETE" |
| 639 | } | 642 | } |
| 640 | if m, ok := routerInfo.methods[method]; ok { | 643 | if m, ok := routerInfo.methods[method]; ok { |
| 641 | runMethod = m | 644 | runMethod = m |
| 642 | } else if m, ok = routerInfo.methods["*"]; ok { | 645 | } else if m, ok = routerInfo.methods["*"]; ok { |
| 643 | runMethod = m | 646 | runMethod = m |
| 644 | } else { | 647 | } else { |
| 645 | runMethod = strings.Title(method) | 648 | runMethod = method |
| 646 | } | 649 | } |
| 647 | } | 650 | } |
| 648 | } | 651 | } |
| ... | @@ -676,19 +679,19 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) | ... | @@ -676,19 +679,19 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) |
| 676 | if !w.started { | 679 | if !w.started { |
| 677 | //exec main logic | 680 | //exec main logic |
| 678 | switch runMethod { | 681 | switch runMethod { |
| 679 | case "Get": | 682 | case "GET": |
| 680 | execController.Get() | 683 | execController.Get() |
| 681 | case "Post": | 684 | case "POST": |
| 682 | execController.Post() | 685 | execController.Post() |
| 683 | case "Delete": | 686 | case "DELETE": |
| 684 | execController.Delete() | 687 | execController.Delete() |
| 685 | case "Put": | 688 | case "PUT": |
| 686 | execController.Put() | 689 | execController.Put() |
| 687 | case "Head": | 690 | case "HEAD": |
| 688 | execController.Head() | 691 | execController.Head() |
| 689 | case "Patch": | 692 | case "PATCH": |
| 690 | execController.Patch() | 693 | execController.Patch() |
| 691 | case "Options": | 694 | case "OPTIONS": |
| 692 | execController.Options() | 695 | execController.Options() |
| 693 | default: | 696 | default: |
| 694 | if !execController.HandlerFunc(runMethod) { | 697 | if !execController.HandlerFunc(runMethod) { |
| ... | @@ -725,20 +728,20 @@ Admin: | ... | @@ -725,20 +728,20 @@ Admin: |
| 725 | timeend := time.Since(starttime) | 728 | timeend := time.Since(starttime) |
| 726 | //admin module record QPS | 729 | //admin module record QPS |
| 727 | if EnableAdmin { | 730 | if EnableAdmin { |
| 728 | if FilterMonitorFunc(r.Method, requestPath, timeend) { | 731 | if FilterMonitorFunc(r.Method, r.URL.Path, timeend) { |
| 729 | if runrouter != nil { | 732 | if runrouter != nil { |
| 730 | go toolbox.StatisticsMap.AddStatistics(r.Method, requestPath, runrouter.Name(), timeend) | 733 | go toolbox.StatisticsMap.AddStatistics(r.Method, r.URL.Path, runrouter.Name(), timeend) |
| 731 | } else { | 734 | } else { |
| 732 | go toolbox.StatisticsMap.AddStatistics(r.Method, requestPath, "", timeend) | 735 | go toolbox.StatisticsMap.AddStatistics(r.Method, r.URL.Path, "", timeend) |
| 733 | } | 736 | } |
| 734 | } | 737 | } |
| 735 | } | 738 | } |
| 736 | 739 | ||
| 737 | if RunMode == "dev" { | 740 | if RunMode == "dev" { |
| 738 | if findrouter { | 741 | if findrouter { |
| 739 | Info("beego: router defined " + routerInfo.pattern + " " + requestPath + " +" + timeend.String()) | 742 | Info("beego: router defined " + routerInfo.pattern + " " + r.URL.Path + " +" + timeend.String()) |
| 740 | } else { | 743 | } else { |
| 741 | Info("beego:" + requestPath + " 404" + " +" + timeend.String()) | 744 | Info("beego:" + r.URL.Path + " 404" + " +" + timeend.String()) |
| 742 | } | 745 | } |
| 743 | } | 746 | } |
| 744 | } | 747 | } | ... | ... |
| ... | @@ -18,7 +18,7 @@ import ( | ... | @@ -18,7 +18,7 @@ import ( |
| 18 | "github.com/astaxie/beego/utils" | 18 | "github.com/astaxie/beego/utils" |
| 19 | ) | 19 | ) |
| 20 | 20 | ||
| 21 | func serverStaticRouter(ctx *context.Context) bool { | 21 | func serverStaticRouter(ctx *context.Context) { |
| 22 | requestPath := path.Clean(ctx.Input.Request.URL.Path) | 22 | requestPath := path.Clean(ctx.Input.Request.URL.Path) |
| 23 | for prefix, staticDir := range StaticDir { | 23 | for prefix, staticDir := range StaticDir { |
| 24 | if len(prefix) == 0 { | 24 | if len(prefix) == 0 { |
| ... | @@ -28,7 +28,7 @@ func serverStaticRouter(ctx *context.Context) bool { | ... | @@ -28,7 +28,7 @@ func serverStaticRouter(ctx *context.Context) bool { |
| 28 | file := path.Join(staticDir, requestPath) | 28 | file := path.Join(staticDir, requestPath) |
| 29 | if utils.FileExists(file) { | 29 | if utils.FileExists(file) { |
| 30 | http.ServeFile(ctx.ResponseWriter, ctx.Request, file) | 30 | http.ServeFile(ctx.ResponseWriter, ctx.Request, file) |
| 31 | return true | 31 | return |
| 32 | } | 32 | } |
| 33 | } | 33 | } |
| 34 | if strings.HasPrefix(requestPath, prefix) { | 34 | if strings.HasPrefix(requestPath, prefix) { |
| ... | @@ -37,7 +37,7 @@ func serverStaticRouter(ctx *context.Context) bool { | ... | @@ -37,7 +37,7 @@ func serverStaticRouter(ctx *context.Context) bool { |
| 37 | } | 37 | } |
| 38 | if requestPath == prefix && prefix[len(prefix)-1] != '/' { | 38 | if requestPath == prefix && prefix[len(prefix)-1] != '/' { |
| 39 | http.Redirect(ctx.ResponseWriter, ctx.Request, requestPath+"/", 302) | 39 | http.Redirect(ctx.ResponseWriter, ctx.Request, requestPath+"/", 302) |
| 40 | return true | 40 | return |
| 41 | } | 41 | } |
| 42 | file := path.Join(staticDir, requestPath[len(prefix):]) | 42 | file := path.Join(staticDir, requestPath[len(prefix):]) |
| 43 | finfo, err := os.Stat(file) | 43 | finfo, err := os.Stat(file) |
| ... | @@ -46,12 +46,12 @@ func serverStaticRouter(ctx *context.Context) bool { | ... | @@ -46,12 +46,12 @@ func serverStaticRouter(ctx *context.Context) bool { |
| 46 | Warn(err) | 46 | Warn(err) |
| 47 | } | 47 | } |
| 48 | http.NotFound(ctx.ResponseWriter, ctx.Request) | 48 | http.NotFound(ctx.ResponseWriter, ctx.Request) |
| 49 | return true | 49 | return |
| 50 | } | 50 | } |
| 51 | //if the request is dir and DirectoryIndex is false then | 51 | //if the request is dir and DirectoryIndex is false then |
| 52 | if finfo.IsDir() && !DirectoryIndex { | 52 | if finfo.IsDir() && !DirectoryIndex { |
| 53 | middleware.Exception("403", ctx.ResponseWriter, ctx.Request, "403 Forbidden") | 53 | middleware.Exception("403", ctx.ResponseWriter, ctx.Request, "403 Forbidden") |
| 54 | return true | 54 | return |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | //This block obtained from (https://github.com/smithfox/beego) - it should probably get merged into astaxie/beego after a pull request | 57 | //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 { | ... | @@ -73,7 +73,7 @@ func serverStaticRouter(ctx *context.Context) bool { |
| 73 | 73 | ||
| 74 | memzipfile, err := openMemZipFile(file, contentEncoding) | 74 | memzipfile, err := openMemZipFile(file, contentEncoding) |
| 75 | if err != nil { | 75 | if err != nil { |
| 76 | return true | 76 | return |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | if contentEncoding == "gzip" { | 79 | if contentEncoding == "gzip" { |
| ... | @@ -89,8 +89,7 @@ func serverStaticRouter(ctx *context.Context) bool { | ... | @@ -89,8 +89,7 @@ func serverStaticRouter(ctx *context.Context) bool { |
| 89 | } else { | 89 | } else { |
| 90 | http.ServeFile(ctx.ResponseWriter, ctx.Request, file) | 90 | http.ServeFile(ctx.ResponseWriter, ctx.Request, file) |
| 91 | } | 91 | } |
| 92 | return true | 92 | return |
| 93 | } | 93 | } |
| 94 | } | 94 | } |
| 95 | return false | ||
| 96 | } | 95 | } | ... | ... |
-
Please register or sign in to post a comment