54c89c0d by slene

Merge branch 'master' of github.com:astaxie/beego

2 parents 1c52f683 c3bc2bed
...@@ -16,7 +16,6 @@ type Context struct { ...@@ -16,7 +16,6 @@ type Context struct {
16 func (ctx *Context) Redirect(status int, localurl string) { 16 func (ctx *Context) Redirect(status int, localurl string) {
17 ctx.Output.Header("Location", localurl) 17 ctx.Output.Header("Location", localurl)
18 ctx.Output.SetStatus(status) 18 ctx.Output.SetStatus(status)
19 ctx.Output.Body([]byte(" "))
20 } 19 }
21 20
22 func (ctx *Context) Abort(status int, body string) { 21 func (ctx *Context) Abort(status int, body string) {
......
...@@ -24,10 +24,15 @@ import ( ...@@ -24,10 +24,15 @@ import (
24 "github.com/astaxie/beego/session" 24 "github.com/astaxie/beego/session"
25 ) 25 )
26 26
27 var (
28 USERSTOPRUN = errors.New("User stop run")
29 )
30
27 type Controller struct { 31 type Controller struct {
28 Ctx *context.Context 32 Ctx *context.Context
29 Data map[interface{}]interface{} 33 Data map[interface{}]interface{}
30 ChildName string 34 controllerName string
35 actionName string
31 TplNames string 36 TplNames string
32 Layout string 37 Layout string
33 TplExt string 38 TplExt string
...@@ -39,7 +44,7 @@ type Controller struct { ...@@ -39,7 +44,7 @@ type Controller struct {
39 } 44 }
40 45
41 type ControllerInterface interface { 46 type ControllerInterface interface {
42 Init(ct *context.Context, childName string, app interface{}) 47 Init(ct *context.Context, controllerName, actionName string, app interface{})
43 Prepare() 48 Prepare()
44 Get() 49 Get()
45 Post() 50 Post()
...@@ -52,11 +57,12 @@ type ControllerInterface interface { ...@@ -52,11 +57,12 @@ type ControllerInterface interface {
52 Render() error 57 Render() error
53 } 58 }
54 59
55 func (c *Controller) Init(ctx *context.Context, childName string, app interface{}) { 60 func (c *Controller) Init(ctx *context.Context, controllerName, actionName string, app interface{}) {
56 c.Data = make(map[interface{}]interface{}) 61 c.Data = make(map[interface{}]interface{})
57 c.Layout = "" 62 c.Layout = ""
58 c.TplNames = "" 63 c.TplNames = ""
59 c.ChildName = childName 64 c.controllerName = controllerName
65 c.actionName = actionName
60 c.Ctx = ctx 66 c.Ctx = ctx
61 c.TplExt = "tpl" 67 c.TplExt = "tpl"
62 c.AppController = app 68 c.AppController = app
...@@ -119,7 +125,7 @@ func (c *Controller) RenderBytes() ([]byte, error) { ...@@ -119,7 +125,7 @@ func (c *Controller) RenderBytes() ([]byte, error) {
119 //if the controller has set layout, then first get the tplname's content set the content to the layout 125 //if the controller has set layout, then first get the tplname's content set the content to the layout
120 if c.Layout != "" { 126 if c.Layout != "" {
121 if c.TplNames == "" { 127 if c.TplNames == "" {
122 c.TplNames = c.ChildName + "/" + strings.ToLower(c.Ctx.Request.Method) + "." + c.TplExt 128 c.TplNames = strings.ToLower(c.controllerName) + "/" + strings.ToLower(c.actionName) + "." + c.TplExt
123 } 129 }
124 if RunMode == "dev" { 130 if RunMode == "dev" {
125 BuildTemplate(ViewsPath) 131 BuildTemplate(ViewsPath)
...@@ -146,7 +152,7 @@ func (c *Controller) RenderBytes() ([]byte, error) { ...@@ -146,7 +152,7 @@ func (c *Controller) RenderBytes() ([]byte, error) {
146 return icontent, nil 152 return icontent, nil
147 } else { 153 } else {
148 if c.TplNames == "" { 154 if c.TplNames == "" {
149 c.TplNames = c.ChildName + "/" + strings.ToLower(c.Ctx.Request.Method) + "." + c.TplExt 155 c.TplNames = strings.ToLower(c.controllerName) + "/" + strings.ToLower(c.actionName) + "." + c.TplExt
150 } 156 }
151 if RunMode == "dev" { 157 if RunMode == "dev" {
152 BuildTemplate(ViewsPath) 158 BuildTemplate(ViewsPath)
...@@ -181,7 +187,7 @@ func (c *Controller) Abort(code string) { ...@@ -181,7 +187,7 @@ func (c *Controller) Abort(code string) {
181 } 187 }
182 188
183 func (c *Controller) StopRun() { 189 func (c *Controller) StopRun() {
184 panic("") 190 panic(USERSTOPRUN)
185 } 191 }
186 192
187 func (c *Controller) UrlFor(endpoint string, values ...string) string { 193 func (c *Controller) UrlFor(endpoint string, values ...string) string {
......
...@@ -211,6 +211,7 @@ func (p *ControllerRegistor) Add(pattern string, c ControllerInterface, mappingM ...@@ -211,6 +211,7 @@ func (p *ControllerRegistor) Add(pattern string, c ControllerInterface, mappingM
211 } 211 }
212 } 212 }
213 213
214 // add auto router to controller
214 func (p *ControllerRegistor) AddAuto(c ControllerInterface) { 215 func (p *ControllerRegistor) AddAuto(c ControllerInterface) {
215 p.enableAuto = true 216 p.enableAuto = true
216 reflectVal := reflect.ValueOf(c) 217 reflectVal := reflect.ValueOf(c)
...@@ -369,6 +370,9 @@ func (p *ControllerRegistor) UrlFor(endpoint string, values ...string) string { ...@@ -369,6 +370,9 @@ func (p *ControllerRegistor) UrlFor(endpoint string, values ...string) string {
369 func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) { 370 func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
370 defer func() { 371 defer func() {
371 if err := recover(); err != nil { 372 if err := recover(); err != nil {
373 if err == USERSTOPRUN {
374 return
375 }
372 if _, ok := err.(middleware.HTTPException); ok { 376 if _, ok := err.(middleware.HTTPException); ok {
373 // catch intented errors, only for HTTP 4XX and 5XX 377 // catch intented errors, only for HTTP 4XX and 5XX
374 } else { 378 } else {
...@@ -421,8 +425,9 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) ...@@ -421,8 +425,9 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
421 425
422 starttime := time.Now() 426 starttime := time.Now()
423 requestPath := r.URL.Path 427 requestPath := r.URL.Path
424 var runrouter *controllerInfo 428 var runrouter reflect.Type
425 var findrouter bool 429 var findrouter bool
430 var runMethod string
426 params := make(map[string]string) 431 params := make(map[string]string)
427 432
428 w := &responseWriter{writer: rw} 433 w := &responseWriter{writer: rw}
...@@ -547,8 +552,9 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) ...@@ -547,8 +552,9 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
547 for _, route := range p.fixrouters { 552 for _, route := range p.fixrouters {
548 n := len(requestPath) 553 n := len(requestPath)
549 if requestPath == route.pattern { 554 if requestPath == route.pattern {
550 runrouter = route 555 runrouter = route.controllerType
551 findrouter = true 556 findrouter = true
557 runMethod = p.getRunMethod(r.Method, route)
552 break 558 break
553 } 559 }
554 // pattern /admin url /admin 200 /admin/ 404 560 // pattern /admin url /admin 200 /admin/ 404
...@@ -588,176 +594,20 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) ...@@ -588,176 +594,20 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
588 //reassemble query params and add to RawQuery 594 //reassemble query params and add to RawQuery
589 r.URL.RawQuery = url.Values(values).Encode() 595 r.URL.RawQuery = url.Values(values).Encode()
590 } 596 }
591 runrouter = route 597 runrouter = route.controllerType
592 findrouter = true 598 findrouter = true
593 break
594 }
595 }
596
597 context.Input.Params = params 599 context.Input.Params = params
598 600 runMethod = p.getRunMethod(r.Method, route)
599 if runrouter != nil { 601 break
600 if r.Method == "POST" {
601 r.ParseMultipartForm(MaxMemory)
602 }
603 //execute middleware filters
604 if do_filter(BeforeExec) {
605 goto Admin
606 }
607
608 //Invoke the request handler
609 vc := reflect.New(runrouter.controllerType)
610
611 //call the controller init function
612 method := vc.MethodByName("Init")
613 in := make([]reflect.Value, 3)
614 in[0] = reflect.ValueOf(context)
615 in[1] = reflect.ValueOf(runrouter.controllerType.Name())
616 in[2] = reflect.ValueOf(vc.Interface())
617 method.Call(in)
618
619 //if XSRF is Enable then check cookie where there has any cookie in the request's cookie _csrf
620 if EnableXSRF {
621 in = make([]reflect.Value, 0)
622 method = vc.MethodByName("XsrfToken")
623 method.Call(in)
624 if r.Method == "POST" || r.Method == "DELETE" || r.Method == "PUT" ||
625 (r.Method == "POST" && (r.Form.Get("_method") == "delete" || r.Form.Get("_method") == "put")) {
626 method = vc.MethodByName("CheckXsrfCookie")
627 method.Call(in)
628 }
629 }
630
631 //call prepare function
632 in = make([]reflect.Value, 0)
633 method = vc.MethodByName("Prepare")
634 method.Call(in)
635
636 //if response has written,yes don't run next
637 if !w.started {
638 if r.Method == "GET" {
639 if runrouter.hasMethod {
640 if m, ok := runrouter.methods["get"]; ok {
641 method = vc.MethodByName(m)
642 } else if m, ok = runrouter.methods["*"]; ok {
643 method = vc.MethodByName(m)
644 } else {
645 method = vc.MethodByName("Get")
646 }
647 } else {
648 method = vc.MethodByName("Get")
649 }
650 method.Call(in)
651 } else if r.Method == "HEAD" {
652 if runrouter.hasMethod {
653 if m, ok := runrouter.methods["head"]; ok {
654 method = vc.MethodByName(m)
655 } else if m, ok = runrouter.methods["*"]; ok {
656 method = vc.MethodByName(m)
657 } else {
658 method = vc.MethodByName("Head")
659 }
660 } else {
661 method = vc.MethodByName("Head")
662 }
663
664 method.Call(in)
665 } else if r.Method == "DELETE" || (r.Method == "POST" && r.Form.Get("_method") == "delete") {
666 if runrouter.hasMethod {
667 if m, ok := runrouter.methods["delete"]; ok {
668 method = vc.MethodByName(m)
669 } else if m, ok = runrouter.methods["*"]; ok {
670 method = vc.MethodByName(m)
671 } else {
672 method = vc.MethodByName("Delete")
673 }
674 } else {
675 method = vc.MethodByName("Delete")
676 }
677 method.Call(in)
678 } else if r.Method == "PUT" || (r.Method == "POST" && r.Form.Get("_method") == "put") {
679 if runrouter.hasMethod {
680 if m, ok := runrouter.methods["put"]; ok {
681 method = vc.MethodByName(m)
682 } else if m, ok = runrouter.methods["*"]; ok {
683 method = vc.MethodByName(m)
684 } else {
685 method = vc.MethodByName("Put")
686 }
687 } else {
688 method = vc.MethodByName("Put")
689 }
690 method.Call(in)
691 } else if r.Method == "POST" {
692 if runrouter.hasMethod {
693 if m, ok := runrouter.methods["post"]; ok {
694 method = vc.MethodByName(m)
695 } else if m, ok = runrouter.methods["*"]; ok {
696 method = vc.MethodByName(m)
697 } else {
698 method = vc.MethodByName("Post")
699 }
700 } else {
701 method = vc.MethodByName("Post")
702 }
703 method.Call(in)
704 } else if r.Method == "PATCH" {
705 if runrouter.hasMethod {
706 if m, ok := runrouter.methods["patch"]; ok {
707 method = vc.MethodByName(m)
708 } else if m, ok = runrouter.methods["*"]; ok {
709 method = vc.MethodByName(m)
710 } else {
711 method = vc.MethodByName("Patch")
712 }
713 } else {
714 method = vc.MethodByName("Patch")
715 }
716 method.Call(in)
717 } else if r.Method == "OPTIONS" {
718 if runrouter.hasMethod {
719 if m, ok := runrouter.methods["options"]; ok {
720 method = vc.MethodByName(m)
721 } else if m, ok = runrouter.methods["*"]; ok {
722 method = vc.MethodByName(m)
723 } else {
724 method = vc.MethodByName("Options")
725 }
726 } else {
727 method = vc.MethodByName("Options")
728 }
729 method.Call(in)
730 }
731 gotofunc := vc.Elem().FieldByName("gotofunc").String()
732 if gotofunc != "" {
733 method = vc.MethodByName(gotofunc)
734 if method.IsValid() {
735 method.Call(in)
736 } else {
737 panic("gotofunc is exists:" + gotofunc)
738 }
739 }
740 if !w.started && !context.Input.IsWebsocket() {
741 if AutoRender {
742 method = vc.MethodByName("Render")
743 callMethodWithError(method, in)
744 }
745 }
746 }
747
748 method = vc.MethodByName("Finish")
749 method.Call(in)
750
751 //execute middleware filters
752 if do_filter(AfterExec) {
753 goto Admin
754 } 602 }
755 } 603 }
756 604
757 //start autorouter 605 if !findrouter && p.enableAuto {
758 606 // deal with url with diffirent ext
759 if p.enableAuto { 607 // /controller/simple
760 if !findrouter { 608 // /controller/simple.html
609 // /controller/simple.json
610 // /controller/simple.rss
761 lastindex := strings.LastIndex(requestPath, "/") 611 lastindex := strings.LastIndex(requestPath, "/")
762 lastsub := requestPath[lastindex+1:] 612 lastsub := requestPath[lastindex+1:]
763 if subindex := strings.LastIndex(lastsub, "."); subindex != -1 { 613 if subindex := strings.LastIndex(lastsub, "."); subindex != -1 {
...@@ -767,57 +617,64 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) ...@@ -767,57 +617,64 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
767 requestPath = requestPath[:len(requestPath)-len(lastsub[subindex:])] 617 requestPath = requestPath[:len(requestPath)-len(lastsub[subindex:])]
768 } 618 }
769 for cName, methodmap := range p.autoRouter { 619 for cName, methodmap := range p.autoRouter {
770 620 // if prev already find the router break
621 if findrouter {
622 break
623 }
771 if strings.ToLower(requestPath) == "/"+cName { 624 if strings.ToLower(requestPath) == "/"+cName {
772 http.Redirect(w, r, requestPath+"/", 301) 625 http.Redirect(w, r, requestPath+"/", 301)
773 goto Admin 626 goto Admin
774 } 627 }
775 628 // if there's no action, set the default action to index
776 if strings.ToLower(requestPath) == "/"+cName+"/" { 629 if strings.ToLower(requestPath) == "/"+cName+"/" {
777 requestPath = requestPath + "index" 630 requestPath = requestPath + "index"
778 } 631 }
632 // if the request path start with controllerName
779 if strings.HasPrefix(strings.ToLower(requestPath), "/"+cName+"/") { 633 if strings.HasPrefix(strings.ToLower(requestPath), "/"+cName+"/") {
780 for mName, controllerType := range methodmap { 634 for mName, controllerType := range methodmap {
781 if strings.ToLower(requestPath) == "/"+cName+"/"+strings.ToLower(mName) || 635 if strings.ToLower(requestPath) == "/"+cName+"/"+strings.ToLower(mName) ||
782 (strings.HasPrefix(strings.ToLower(requestPath), "/"+cName+"/"+strings.ToLower(mName)) && 636 (strings.HasPrefix(strings.ToLower(requestPath), "/"+cName+"/"+strings.ToLower(mName)) &&
783 requestPath[len("/"+cName+"/"+strings.ToLower(mName)):len("/"+cName+"/"+strings.ToLower(mName))+1] == "/") { 637 requestPath[len("/"+cName+"/"+strings.ToLower(mName)):len("/"+cName+"/"+strings.ToLower(mName))+1] == "/") {
638 runrouter = controllerType
639 runMethod = mName
640 findrouter = true
641 break
642 }
643 }
644 }
645 }
646 }
647
648 //if no matches to url, throw a not found exception
649 if !findrouter {
650 middleware.Exception("404", rw, r, "")
651 goto Admin
652 }
653
654 if findrouter {
784 if r.Method == "POST" { 655 if r.Method == "POST" {
785 r.ParseMultipartForm(MaxMemory) 656 r.ParseMultipartForm(MaxMemory)
786 } 657 }
787 // set find
788 findrouter = true
789
790 //execute middleware filters 658 //execute middleware filters
791 if do_filter(BeforeExec) { 659 if do_filter(BeforeExec) {
792 goto Admin 660 goto Admin
793 } 661 }
794 662
795 //parse params
796 otherurl := requestPath[len("/"+cName+"/"+strings.ToLower(mName)):]
797 if len(otherurl) > 1 {
798 plist := strings.Split(otherurl, "/")
799 for k, v := range plist[1:] {
800 params[strconv.Itoa(k)] = v
801 }
802 }
803 //Invoke the request handler 663 //Invoke the request handler
804 vc := reflect.New(controllerType) 664 vc := reflect.New(runrouter)
805 665
806 //call the controller init function 666 //call the controller init function
807 init := vc.MethodByName("Init") 667 method := vc.MethodByName("Init")
808 in := make([]reflect.Value, 3) 668 in := make([]reflect.Value, 4)
809 in[0] = reflect.ValueOf(context) 669 in[0] = reflect.ValueOf(context)
810 in[1] = reflect.ValueOf(controllerType.Name()) 670 in[1] = reflect.ValueOf(runrouter.Name())
811 in[2] = reflect.ValueOf(vc.Interface()) 671 in[2] = reflect.ValueOf(runMethod)
812 init.Call(in) 672 in[3] = reflect.ValueOf(vc.Interface())
813 //call prepare function
814 in = make([]reflect.Value, 0)
815 method := vc.MethodByName("Prepare")
816 method.Call(in)
817 method = vc.MethodByName(mName)
818 method.Call(in) 673 method.Call(in)
674
819 //if XSRF is Enable then check cookie where there has any cookie in the request's cookie _csrf 675 //if XSRF is Enable then check cookie where there has any cookie in the request's cookie _csrf
820 if EnableXSRF { 676 if EnableXSRF {
677 in = make([]reflect.Value, 0)
821 method = vc.MethodByName("XsrfToken") 678 method = vc.MethodByName("XsrfToken")
822 method.Call(in) 679 method.Call(in)
823 if r.Method == "POST" || r.Method == "DELETE" || r.Method == "PUT" || 680 if r.Method == "POST" || r.Method == "DELETE" || r.Method == "PUT" ||
...@@ -826,12 +683,27 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) ...@@ -826,12 +683,27 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
826 method.Call(in) 683 method.Call(in)
827 } 684 }
828 } 685 }
686
687 //call prepare function
688 in = make([]reflect.Value, 0)
689 method = vc.MethodByName("Prepare")
690 method.Call(in)
691
692 if !w.started {
693 //exec main logic
694 method = vc.MethodByName(runMethod)
695 method.Call(in)
696
697 //render template
829 if !w.started && !context.Input.IsWebsocket() { 698 if !w.started && !context.Input.IsWebsocket() {
830 if AutoRender { 699 if AutoRender {
831 method = vc.MethodByName("Render") 700 method = vc.MethodByName("Render")
832 callMethodWithError(method, in) 701 callMethodWithError(method, in)
833 } 702 }
834 } 703 }
704 }
705
706 // finish all runrouter. release resource
835 method = vc.MethodByName("Finish") 707 method = vc.MethodByName("Finish")
836 method.Call(in) 708 method.Call(in)
837 709
...@@ -839,18 +711,6 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) ...@@ -839,18 +711,6 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
839 if do_filter(AfterExec) { 711 if do_filter(AfterExec) {
840 goto Admin 712 goto Admin
841 } 713 }
842
843 goto Admin
844 }
845 }
846 }
847 }
848 }
849 }
850
851 //if no matches to url, throw a not found exception
852 if !findrouter {
853 middleware.Exception("404", rw, r, "")
854 } 714 }
855 715
856 Admin: 716 Admin:
...@@ -861,7 +721,7 @@ Admin: ...@@ -861,7 +721,7 @@ Admin:
861 timeend := time.Since(starttime) 721 timeend := time.Since(starttime)
862 if FilterMonitorFunc(r.Method, requestPath, timeend) { 722 if FilterMonitorFunc(r.Method, requestPath, timeend) {
863 if runrouter != nil { 723 if runrouter != nil {
864 go toolbox.StatisticsMap.AddStatistics(r.Method, requestPath, runrouter.controllerType.Name(), timeend) 724 go toolbox.StatisticsMap.AddStatistics(r.Method, requestPath, runrouter.Name(), timeend)
865 } else { 725 } else {
866 go toolbox.StatisticsMap.AddStatistics(r.Method, requestPath, "", timeend) 726 go toolbox.StatisticsMap.AddStatistics(r.Method, requestPath, "", timeend)
867 } 727 }
...@@ -887,6 +747,21 @@ func (p *ControllerRegistor) getErrorHandler(errorCode string) func(rw http.Resp ...@@ -887,6 +747,21 @@ func (p *ControllerRegistor) getErrorHandler(errorCode string) func(rw http.Resp
887 return handler 747 return handler
888 } 748 }
889 749
750 func (p *ControllerRegistor) getRunMethod(method string, router *controllerInfo) string {
751 method = strings.ToLower(method)
752 if router.hasMethod {
753 if m, ok := router.methods[method]; ok {
754 return m
755 } else if m, ok = router.methods["*"]; ok {
756 return m
757 } else {
758 return strings.Title(method)
759 }
760 } else {
761 return strings.Title(method)
762 }
763 }
764
890 //responseWriter is a wrapper for the http.ResponseWriter 765 //responseWriter is a wrapper for the http.ResponseWriter
891 //started set to true if response was written to then don't execute other handler 766 //started set to true if response was written to then don't execute other handler
892 type responseWriter struct { 767 type responseWriter struct {
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!