3aceaf88 by astaxie

error support controller

1 parent 71b9854f
...@@ -33,7 +33,6 @@ import ( ...@@ -33,7 +33,6 @@ import (
33 "strconv" 33 "strconv"
34 "strings" 34 "strings"
35 35
36 "github.com/astaxie/beego/middleware"
37 "github.com/astaxie/beego/session" 36 "github.com/astaxie/beego/session"
38 ) 37 )
39 38
...@@ -280,15 +279,6 @@ func Handler(rootpath string, h http.Handler, options ...interface{}) *App { ...@@ -280,15 +279,6 @@ func Handler(rootpath string, h http.Handler, options ...interface{}) *App {
280 return BeeApp 279 return BeeApp
281 } 280 }
282 281
283 // ErrorHandler registers http.HandlerFunc to each http err code string.
284 // usage:
285 // beego.ErrorHandler("404",NotFound)
286 // beego.ErrorHandler("500",InternalServerError)
287 func Errorhandler(err string, h http.HandlerFunc) *App {
288 middleware.Errorhandler(err, h)
289 return BeeApp
290 }
291
292 // SetViewsPath sets view directory path in beego application. 282 // SetViewsPath sets view directory path in beego application.
293 func SetViewsPath(path string) *App { 283 func SetViewsPath(path string) *App {
294 ViewsPath = path 284 ViewsPath = path
...@@ -402,9 +392,7 @@ func initBeforeHttpRun() { ...@@ -402,9 +392,7 @@ func initBeforeHttpRun() {
402 } 392 }
403 } 393 }
404 394
405 middleware.VERSION = VERSION 395 registerDefaultErrorHandler()
406 middleware.AppName = AppName
407 middleware.RegisterErrorHandler()
408 396
409 if EnableDocs { 397 if EnableDocs {
410 Get("/docs", serverDocs) 398 Get("/docs", serverDocs)
......
...@@ -81,6 +81,7 @@ var ( ...@@ -81,6 +81,7 @@ var (
81 AppConfigProvider string // config provider 81 AppConfigProvider string // config provider
82 EnableDocs bool // enable generate docs & server docs API Swagger 82 EnableDocs bool // enable generate docs & server docs API Swagger
83 RouterCaseSensitive bool // router case sensitive default is true 83 RouterCaseSensitive bool // router case sensitive default is true
84 AccessLogs bool // print access logs, default is false
84 ) 85 )
85 86
86 type beegoAppConfig struct { 87 type beegoAppConfig struct {
......
...@@ -31,7 +31,7 @@ import ( ...@@ -31,7 +31,7 @@ import (
31 "strings" 31 "strings"
32 "time" 32 "time"
33 33
34 "github.com/astaxie/beego/middleware" 34 "github.com/astaxie/beego"
35 "github.com/astaxie/beego/utils" 35 "github.com/astaxie/beego/utils"
36 ) 36 )
37 37
...@@ -53,24 +53,16 @@ func (ctx *Context) Redirect(status int, localurl string) { ...@@ -53,24 +53,16 @@ func (ctx *Context) Redirect(status int, localurl string) {
53 } 53 }
54 54
55 // Abort stops this request. 55 // Abort stops this request.
56 // if middleware.ErrorMaps exists, panic body. 56 // if beego.ErrorMaps exists, panic body.
57 // if middleware.HTTPExceptionMaps exists, panic HTTPException struct with status and body string.
58 func (ctx *Context) Abort(status int, body string) { 57 func (ctx *Context) Abort(status int, body string) {
59 ctx.ResponseWriter.WriteHeader(status) 58 ctx.ResponseWriter.WriteHeader(status)
60 // first panic from ErrorMaps, is is user defined error functions. 59 // first panic from ErrorMaps, is is user defined error functions.
61 if _, ok := middleware.ErrorMaps[body]; ok { 60 if _, ok := beego.ErrorMaps[body]; ok {
62 panic(body) 61 panic(body)
63 } 62 }
64 // second panic from HTTPExceptionMaps, it is system defined functions.
65 if e, ok := middleware.HTTPExceptionMaps[status]; ok {
66 if len(body) >= 1 {
67 e.Description = body
68 }
69 panic(e)
70 }
71 // last panic user string 63 // last panic user string
72 ctx.ResponseWriter.Write([]byte(body)) 64 ctx.ResponseWriter.Write([]byte(body))
73 panic("User stop run") 65 panic(beego.USERSTOPRUN)
74 } 66 }
75 67
76 // Write string to response body. 68 // Write string to response body.
......
...@@ -12,20 +12,26 @@ ...@@ -12,20 +12,26 @@
12 // See the License for the specific language governing permissions and 12 // See the License for the specific language governing permissions and
13 // limitations under the License. 13 // limitations under the License.
14 14
15 package middleware 15 package beego
16 16
17 import ( 17 import (
18 "fmt" 18 "fmt"
19 "html/template" 19 "html/template"
20 "net/http" 20 "net/http"
21 "reflect"
21 "runtime" 22 "runtime"
22 "strconv" 23 "strconv"
24 "strings"
25
26 "github.com/astaxie/beego/context"
27 "github.com/astaxie/beego/utils"
23 ) 28 )
24 29
25 var ( 30 const (
26 AppName string 31 errorTypeHandler = iota
27 VERSION string 32 errorTypeController
28 ) 33 )
34
29 var tpl = ` 35 var tpl = `
30 <!DOCTYPE html> 36 <!DOCTYPE html>
31 <html> 37 <html>
...@@ -76,18 +82,18 @@ var tpl = ` ...@@ -76,18 +82,18 @@ var tpl = `
76 ` 82 `
77 83
78 // render default application error page with error and stack string. 84 // render default application error page with error and stack string.
79 func ShowErr(err interface{}, rw http.ResponseWriter, r *http.Request, Stack string) { 85 func showErr(err interface{}, ctx *context.Context, Stack string) {
80 t, _ := template.New("beegoerrortemp").Parse(tpl) 86 t, _ := template.New("beegoerrortemp").Parse(tpl)
81 data := make(map[string]string) 87 data := make(map[string]string)
82 data["AppError"] = AppName + ":" + fmt.Sprint(err) 88 data["AppError"] = AppName + ":" + fmt.Sprint(err)
83 data["RequestMethod"] = r.Method 89 data["RequestMethod"] = ctx.Input.Method()
84 data["RequestURL"] = r.RequestURI 90 data["RequestURL"] = ctx.Input.Uri()
85 data["RemoteAddr"] = r.RemoteAddr 91 data["RemoteAddr"] = ctx.Input.IP()
86 data["Stack"] = Stack 92 data["Stack"] = Stack
87 data["BeegoVersion"] = VERSION 93 data["BeegoVersion"] = VERSION
88 data["GoVersion"] = runtime.Version() 94 data["GoVersion"] = runtime.Version()
89 rw.WriteHeader(500) 95 ctx.Output.SetStatus(500)
90 t.Execute(rw, data) 96 t.Execute(ctx.ResponseWriter, data)
91 } 97 }
92 98
93 var errtpl = ` 99 var errtpl = `
...@@ -190,11 +196,18 @@ var errtpl = ` ...@@ -190,11 +196,18 @@ var errtpl = `
190 </html> 196 </html>
191 ` 197 `
192 198
199 type errorInfo struct {
200 controllerType reflect.Type
201 handler http.HandlerFunc
202 method string
203 errorType int
204 }
205
193 // map of http handlers for each error string. 206 // map of http handlers for each error string.
194 var ErrorMaps map[string]http.HandlerFunc 207 var ErrorMaps map[string]*errorInfo
195 208
196 func init() { 209 func init() {
197 ErrorMaps = make(map[string]http.HandlerFunc) 210 ErrorMaps = make(map[string]*errorInfo)
198 } 211 }
199 212
200 // show 404 notfound error. 213 // show 404 notfound error.
...@@ -283,55 +296,115 @@ func SimpleServerError(rw http.ResponseWriter, r *http.Request) { ...@@ -283,55 +296,115 @@ func SimpleServerError(rw http.ResponseWriter, r *http.Request) {
283 http.Error(rw, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) 296 http.Error(rw, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
284 } 297 }
285 298
286 // add http handler for given error string.
287 func Errorhandler(err string, h http.HandlerFunc) {
288 ErrorMaps[err] = h
289 }
290
291 // register default error http handlers, 404,401,403,500 and 503. 299 // register default error http handlers, 404,401,403,500 and 503.
292 func RegisterErrorHandler() { 300 func registerDefaultErrorHandler() {
293 if _, ok := ErrorMaps["404"]; !ok { 301 if _, ok := ErrorMaps["404"]; !ok {
294 ErrorMaps["404"] = NotFound 302 Errorhandler("404", NotFound)
295 } 303 }
296 304
297 if _, ok := ErrorMaps["401"]; !ok { 305 if _, ok := ErrorMaps["401"]; !ok {
298 ErrorMaps["401"] = Unauthorized 306 Errorhandler("401", Unauthorized)
299 } 307 }
300 308
301 if _, ok := ErrorMaps["403"]; !ok { 309 if _, ok := ErrorMaps["403"]; !ok {
302 ErrorMaps["403"] = Forbidden 310 Errorhandler("403", Forbidden)
303 } 311 }
304 312
305 if _, ok := ErrorMaps["503"]; !ok { 313 if _, ok := ErrorMaps["503"]; !ok {
306 ErrorMaps["503"] = ServiceUnavailable 314 Errorhandler("503", ServiceUnavailable)
307 } 315 }
308 316
309 if _, ok := ErrorMaps["500"]; !ok { 317 if _, ok := ErrorMaps["500"]; !ok {
310 ErrorMaps["500"] = InternalServerError 318 Errorhandler("500", InternalServerError)
311 } 319 }
312 } 320 }
313 321
322 // ErrorHandler registers http.HandlerFunc to each http err code string.
323 // usage:
324 // beego.ErrorHandler("404",NotFound)
325 // beego.ErrorHandler("500",InternalServerError)
326 func Errorhandler(code string, h http.HandlerFunc) *App {
327 errinfo := &errorInfo{}
328 errinfo.errorType = errorTypeHandler
329 errinfo.handler = h
330 errinfo.method = code
331 ErrorMaps[code] = errinfo
332 return BeeApp
333 }
334
335 // ErrorController registers ControllerInterface to each http err code string.
336 // usage:
337 // beego.ErrorHandler(&controllers.ErrorController{})
338 func ErrorController(c ControllerInterface) *App {
339 reflectVal := reflect.ValueOf(c)
340 rt := reflectVal.Type()
341 ct := reflect.Indirect(reflectVal).Type()
342 for i := 0; i < rt.NumMethod(); i++ {
343 if !utils.InSlice(rt.Method(i).Name, exceptMethod) && strings.HasPrefix(rt.Method(i).Name, "Error") {
344 errinfo := &errorInfo{}
345 errinfo.errorType = errorTypeController
346 errinfo.controllerType = ct
347 errinfo.method = rt.Method(i).Name
348 errname := strings.TrimPrefix(rt.Method(i).Name, "Error")
349 ErrorMaps[errname] = errinfo
350 }
351 }
352 return BeeApp
353 }
354
314 // show error string as simple text message. 355 // show error string as simple text message.
315 // if error string is empty, show 500 error as default. 356 // if error string is empty, show 500 error as default.
316 func Exception(errcode string, w http.ResponseWriter, r *http.Request, msg string) { 357 func exception(errcode string, ctx *context.Context) {
358 code, err := strconv.Atoi(errcode)
359 if err != nil {
360 code = 503
361 }
362 ctx.ResponseWriter.WriteHeader(code)
317 if h, ok := ErrorMaps[errcode]; ok { 363 if h, ok := ErrorMaps[errcode]; ok {
318 isint, err := strconv.Atoi(errcode) 364 executeError(h, ctx)
319 if err != nil { 365 return
320 isint = 500 366 } else if h, ok := ErrorMaps["503"]; ok {
321 } 367 executeError(h, ctx)
322 w.Header().Set("Content-Type", "text/html; charset=utf-8")
323 w.WriteHeader(isint)
324 h(w, r)
325 return 368 return
369 } else {
370 ctx.WriteString(errcode)
326 } 371 }
327 isint, err := strconv.Atoi(errcode) 372 }
328 if err != nil { 373
329 isint = 500 374 func executeError(err *errorInfo, ctx *context.Context) {
375 if err.errorType == errorTypeHandler {
376 err.handler(ctx.ResponseWriter, ctx.Request)
377 return
330 } 378 }
331 if isint == 404 { 379 if err.errorType == errorTypeController {
332 msg = "404 page not found" 380 //Invoke the request handler
381 vc := reflect.New(err.controllerType)
382 execController, ok := vc.Interface().(ControllerInterface)
383 if !ok {
384 panic("controller is not ControllerInterface")
385 }
386 //call the controller init function
387 execController.Init(ctx, err.controllerType.Name(), err.method, vc.Interface())
388
389 //call prepare function
390 execController.Prepare()
391
392 execController.URLMapping()
393
394 in := make([]reflect.Value, 0)
395 method := vc.MethodByName(err.method)
396 method.Call(in)
397
398 //render template
399 if ctx.Output.Status == 0 {
400 if AutoRender {
401 if err := execController.Render(); err != nil {
402 panic(err)
403 }
404 }
405 }
406
407 // finish all runrouter. release resource
408 execController.Finish()
333 } 409 }
334 w.Header().Set("Content-Type", "text/plain; charset=utf-8")
335 w.WriteHeader(isint)
336 fmt.Fprintln(w, msg)
337 } 410 }
......
1 // Copyright 2014 beego Author. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 package middleware
16
17 import "fmt"
18
19 // http exceptions
20 type HTTPException struct {
21 StatusCode int // http status code 4xx, 5xx
22 Description string
23 }
24
25 // return http exception error string, e.g. "400 Bad Request".
26 func (e *HTTPException) Error() string {
27 return fmt.Sprintf("%d %s", e.StatusCode, e.Description)
28 }
29
30 // map of http exceptions for each http status code int.
31 // defined 400,401,403,404,405,500,502,503 and 504 default.
32 var HTTPExceptionMaps map[int]HTTPException
33
34 func init() {
35 HTTPExceptionMaps = make(map[int]HTTPException)
36
37 // Normal 4XX HTTP Status
38 HTTPExceptionMaps[400] = HTTPException{400, "Bad Request"}
39 HTTPExceptionMaps[401] = HTTPException{401, "Unauthorized"}
40 HTTPExceptionMaps[403] = HTTPException{403, "Forbidden"}
41 HTTPExceptionMaps[404] = HTTPException{404, "Not Found"}
42 HTTPExceptionMaps[405] = HTTPException{405, "Method Not Allowed"}
43
44 // Normal 5XX HTTP Status
45 HTTPExceptionMaps[500] = HTTPException{500, "Internal Server Error"}
46 HTTPExceptionMaps[502] = HTTPException{502, "Bad Gateway"}
47 HTTPExceptionMaps[503] = HTTPException{503, "Service Unavailable"}
48 HTTPExceptionMaps[504] = HTTPException{504, "Gateway Timeout"}
49 }
...@@ -19,7 +19,6 @@ import ( ...@@ -19,7 +19,6 @@ import (
19 "strings" 19 "strings"
20 20
21 beecontext "github.com/astaxie/beego/context" 21 beecontext "github.com/astaxie/beego/context"
22 "github.com/astaxie/beego/middleware"
23 ) 22 )
24 23
25 type namespaceCond func(*beecontext.Context) bool 24 type namespaceCond func(*beecontext.Context) bool
...@@ -57,7 +56,7 @@ func NewNamespace(prefix string, params ...innnerNamespace) *Namespace { ...@@ -57,7 +56,7 @@ func NewNamespace(prefix string, params ...innnerNamespace) *Namespace {
57 func (n *Namespace) Cond(cond namespaceCond) *Namespace { 56 func (n *Namespace) Cond(cond namespaceCond) *Namespace {
58 fn := func(ctx *beecontext.Context) { 57 fn := func(ctx *beecontext.Context) {
59 if !cond(ctx) { 58 if !cond(ctx) {
60 middleware.Exception("405", ctx.ResponseWriter, ctx.Request, "Method not allowed") 59 exception("405", ctx)
61 } 60 }
62 } 61 }
63 if v, ok := n.handlers.filters[BeforeRouter]; ok { 62 if v, ok := n.handlers.filters[BeforeRouter]; ok {
......
...@@ -30,7 +30,6 @@ import ( ...@@ -30,7 +30,6 @@ import (
30 "time" 30 "time"
31 31
32 beecontext "github.com/astaxie/beego/context" 32 beecontext "github.com/astaxie/beego/context"
33 "github.com/astaxie/beego/middleware"
34 "github.com/astaxie/beego/toolbox" 33 "github.com/astaxie/beego/toolbox"
35 "github.com/astaxie/beego/utils" 34 "github.com/astaxie/beego/utils"
36 ) 35 )
...@@ -577,7 +576,6 @@ func (p *ControllerRegistor) geturl(t *Tree, url, controllName, methodName strin ...@@ -577,7 +576,6 @@ func (p *ControllerRegistor) geturl(t *Tree, url, controllName, methodName strin
577 576
578 // Implement http.Handler interface. 577 // Implement http.Handler interface.
579 func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) { 578 func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
580 defer p.recoverPanic(rw, r)
581 starttime := time.Now() 579 starttime := time.Now()
582 var runrouter reflect.Type 580 var runrouter reflect.Type
583 var findrouter bool 581 var findrouter bool
...@@ -600,6 +598,8 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) ...@@ -600,6 +598,8 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
600 context.Output.Context = context 598 context.Output.Context = context
601 context.Output.EnableGzip = EnableGzip 599 context.Output.EnableGzip = EnableGzip
602 600
601 defer p.recoverPanic(context)
602
603 var urlPath string 603 var urlPath string
604 if !RouterCaseSensitive { 604 if !RouterCaseSensitive {
605 urlPath = strings.ToLower(r.URL.Path) 605 urlPath = strings.ToLower(r.URL.Path)
...@@ -648,7 +648,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) ...@@ -648,7 +648,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
648 context.Input.CruSession, err = GlobalSessions.SessionStart(w, r) 648 context.Input.CruSession, err = GlobalSessions.SessionStart(w, r)
649 if err != nil { 649 if err != nil {
650 Error(err) 650 Error(err)
651 middleware.Exception("503", rw, r, "") 651 exception("503", context)
652 return 652 return
653 } 653 }
654 defer func() { 654 defer func() {
...@@ -703,7 +703,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) ...@@ -703,7 +703,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
703 703
704 //if no matches to url, throw a not found exception 704 //if no matches to url, throw a not found exception
705 if !findrouter { 705 if !findrouter {
706 middleware.Exception("404", rw, r, "") 706 exception("404", context)
707 goto Admin 707 goto Admin
708 } 708 }
709 709
...@@ -719,7 +719,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) ...@@ -719,7 +719,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
719 isRunable = true 719 isRunable = true
720 routerInfo.runfunction(context) 720 routerInfo.runfunction(context)
721 } else { 721 } else {
722 middleware.Exception("405", rw, r, "Method Not Allowed") 722 exception("405", context)
723 goto Admin 723 goto Admin
724 } 724 }
725 } else if routerInfo.routerType == routerTypeHandler { 725 } else if routerInfo.routerType == routerTypeHandler {
...@@ -830,7 +830,7 @@ Admin: ...@@ -830,7 +830,7 @@ Admin:
830 } 830 }
831 } 831 }
832 832
833 if RunMode == "dev" { 833 if RunMode == "dev" || AccessLogs {
834 var devinfo string 834 var devinfo string
835 if findrouter { 835 if findrouter {
836 if routerInfo != nil { 836 if routerInfo != nil {
...@@ -852,27 +852,51 @@ Admin: ...@@ -852,27 +852,51 @@ Admin:
852 } 852 }
853 } 853 }
854 854
855 func (p *ControllerRegistor) recoverPanic(rw http.ResponseWriter, r *http.Request) { 855 func (p *ControllerRegistor) recoverPanic(context *beecontext.Context) {
856 if err := recover(); err != nil { 856 if err := recover(); err != nil {
857 if err == USERSTOPRUN { 857 if err == USERSTOPRUN {
858 return 858 return
859 } 859 }
860 if he, ok := err.(middleware.HTTPException); ok { 860 if RunMode == "dev" {
861 rw.Write([]byte(he.Description)) 861 if !RecoverPanic {
862 // catch intented errors, only for HTTP 4XX and 5XX 862 panic(err)
863 } else {
864 if ErrorsShow {
865 if handler, ok := ErrorMaps[fmt.Sprint(err)]; ok {
866 executeError(handler, context)
867 return
868 }
869 }
870 var stack string
871 Critical("the request url is ", context.Input.Url())
872 Critical("Handler crashed with error", err)
873 for i := 1; ; i++ {
874 _, file, line, ok := runtime.Caller(i)
875 if !ok {
876 break
877 }
878 Critical(fmt.Sprintf("%s:%d", file, line))
879 stack = stack + fmt.Sprintln(fmt.Sprintf("%s:%d", file, line))
880 }
881 showErr(err, context, stack)
882 }
863 } else { 883 } else {
864 if RunMode == "dev" { 884 if !RecoverPanic {
865 if !RecoverPanic { 885 panic(err)
866 panic(err) 886 } else {
867 } else { 887 // in production model show all infomation
868 if ErrorsShow { 888 if ErrorsShow {
869 if handler, ok := middleware.ErrorMaps[fmt.Sprint(err)]; ok { 889 if handler, ok := ErrorMaps[fmt.Sprint(err)]; ok {
870 handler(rw, r) 890 executeError(handler, context)
871 return 891 return
872 } 892 } else if handler, ok := ErrorMaps["503"]; ok {
893 executeError(handler, context)
894 return
895 } else {
896 context.WriteString(fmt.Sprint(err))
873 } 897 }
874 var stack string 898 } else {
875 Critical("the request url is ", r.URL.Path) 899 Critical("the request url is ", context.Input.Url())
876 Critical("Handler crashed with error", err) 900 Critical("Handler crashed with error", err)
877 for i := 1; ; i++ { 901 for i := 1; ; i++ {
878 _, file, line, ok := runtime.Caller(i) 902 _, file, line, ok := runtime.Caller(i)
...@@ -880,39 +904,9 @@ func (p *ControllerRegistor) recoverPanic(rw http.ResponseWriter, r *http.Reques ...@@ -880,39 +904,9 @@ func (p *ControllerRegistor) recoverPanic(rw http.ResponseWriter, r *http.Reques
880 break 904 break
881 } 905 }
882 Critical(fmt.Sprintf("%s:%d", file, line)) 906 Critical(fmt.Sprintf("%s:%d", file, line))
883 stack = stack + fmt.Sprintln(fmt.Sprintf("%s:%d", file, line))
884 }
885 middleware.ShowErr(err, rw, r, stack)
886 }
887 } else {
888 if !RecoverPanic {
889 panic(err)
890 } else {
891 // in production model show all infomation
892 if ErrorsShow {
893 if handler, ok := middleware.ErrorMaps[fmt.Sprint(err)]; ok {
894 handler(rw, r)
895 return
896 } else if handler, ok := middleware.ErrorMaps["503"]; ok {
897 handler(rw, r)
898 return
899 } else {
900 rw.Write([]byte(fmt.Sprint(err)))
901 }
902 } else {
903 Critical("the request url is ", r.URL.Path)
904 Critical("Handler crashed with error", err)
905 for i := 1; ; i++ {
906 _, file, line, ok := runtime.Caller(i)
907 if !ok {
908 break
909 }
910 Critical(fmt.Sprintf("%s:%d", file, line))
911 }
912 } 907 }
913 } 908 }
914 } 909 }
915
916 } 910 }
917 } 911 }
918 } 912 }
......
...@@ -22,7 +22,6 @@ import ( ...@@ -22,7 +22,6 @@ import (
22 "strings" 22 "strings"
23 23
24 "github.com/astaxie/beego/context" 24 "github.com/astaxie/beego/context"
25 "github.com/astaxie/beego/middleware"
26 "github.com/astaxie/beego/utils" 25 "github.com/astaxie/beego/utils"
27 ) 26 )
28 27
...@@ -67,7 +66,7 @@ func serverStaticRouter(ctx *context.Context) { ...@@ -67,7 +66,7 @@ func serverStaticRouter(ctx *context.Context) {
67 //if the request is dir and DirectoryIndex is false then 66 //if the request is dir and DirectoryIndex is false then
68 if finfo.IsDir() { 67 if finfo.IsDir() {
69 if !DirectoryIndex { 68 if !DirectoryIndex {
70 middleware.Exception("403", ctx.ResponseWriter, ctx.Request, "403 Forbidden") 69 exception("403", ctx)
71 return 70 return
72 } else if ctx.Input.Request.URL.Path[len(ctx.Input.Request.URL.Path)-1] != '/' { 71 } else if ctx.Input.Request.URL.Path[len(ctx.Input.Request.URL.Path)-1] != '/' {
73 http.Redirect(ctx.ResponseWriter, ctx.Request, ctx.Input.Request.URL.Path+"/", 302) 72 http.Redirect(ctx.ResponseWriter, ctx.Request, ctx.Input.Request.URL.Path+"/", 302)
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!