From 48cefc67678e58d2102a8870028d506b9edbc047 Mon Sep 17 00:00:00 2001 From: astaxie Date: Wed, 18 Dec 2013 21:32:25 +0800 Subject: [PATCH] improve performance change reflect to interface --- controller.go | 2 ++ router.go | 47 +++++++++++++++-------------------------------- 2 files changed, 17 insertions(+), 32 deletions(-) diff --git a/controller.go b/controller.go index eb070d34..f33d38dc 100644 --- a/controller.go +++ b/controller.go @@ -55,6 +55,8 @@ type ControllerInterface interface { Options() Finish() Render() error + XsrfToken() string + CheckXsrfCookie() bool } func (c *Controller) Init(ctx *context.Context, controllerName, actionName string, app interface{}) { diff --git a/router.go b/router.go index 17326330..248fdaaa 100644 --- a/router.go +++ b/router.go @@ -667,50 +667,45 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) //Invoke the request handler vc := reflect.New(runrouter) + execController, ok := vc.Interface().(ControllerInterface) + if !ok { + panic("controller is not ControllerInterface") + } //call the controller init function - method := vc.MethodByName("Init") - in := make([]reflect.Value, 4) - in[0] = reflect.ValueOf(context) - in[1] = reflect.ValueOf(runrouter.Name()) - in[2] = reflect.ValueOf(runMethod) - in[3] = reflect.ValueOf(vc.Interface()) - method.Call(in) + execController.Init(context, runrouter.Name(), runMethod, vc.Interface()) //if XSRF is Enable then check cookie where there has any cookie in the request's cookie _csrf if EnableXSRF { - in = make([]reflect.Value, 0) - method = vc.MethodByName("XsrfToken") - method.Call(in) + execController.XsrfToken() if r.Method == "POST" || r.Method == "DELETE" || r.Method == "PUT" || (r.Method == "POST" && (r.Form.Get("_method") == "delete" || r.Form.Get("_method") == "put")) { - method = vc.MethodByName("CheckXsrfCookie") - method.Call(in) + execController.CheckXsrfCookie() } } //call prepare function - in = make([]reflect.Value, 0) - method = vc.MethodByName("Prepare") - method.Call(in) + execController.Prepare() if !w.started { //exec main logic - method = vc.MethodByName(runMethod) + in := make([]reflect.Value, 0) + method := vc.MethodByName(runMethod) method.Call(in) //render template if !w.started && !context.Input.IsWebsocket() { if AutoRender { - method = vc.MethodByName("Render") - callMethodWithError(method, in) + if err := execController.Render(); err != nil { + panic(err) + } + } } } // finish all runrouter. release resource - method = vc.MethodByName("Finish") - method.Call(in) + execController.Finish() //execute middleware filters if do_filter(AfterExec) { @@ -805,15 +800,3 @@ func (w *responseWriter) WriteHeader(code int) { w.started = true w.writer.WriteHeader(code) } - -// call method and panic with error if error is in result params -func callMethodWithError(method reflect.Value, params []reflect.Value) { - results := method.Call(params) - if len(results) > 0 { - for _, result := range results { - if result.Type() == errorType && !result.IsNil() { - panic(result.Interface().(error)) - } - } - } -}