6809c976 by astaxie

beego: improve performance

1 parent 675643c6
...@@ -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 }
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!