984b0cbf by astaxie

1. :all param default expr change from (.+) to (.*)

2. add hookfunc to support appstart hook
1 parent ecfd11ad
...@@ -13,6 +13,13 @@ import ( ...@@ -13,6 +13,13 @@ import (
13 // beego web framework version. 13 // beego web framework version.
14 const VERSION = "1.0.1" 14 const VERSION = "1.0.1"
15 15
16 type hookfunc func() error //hook function to run
17 var hooks []hookfunc //hook function slice to store the hookfunc
18
19 func init() {
20 hooks = make([]hookfunc, 0)
21 }
22
16 // Router adds a patterned controller handler to BeeApp. 23 // Router adds a patterned controller handler to BeeApp.
17 // it's an alias method of App.Router. 24 // it's an alias method of App.Router.
18 func Router(rootpath string, c ControllerInterface, mappingMethods ...string) *App { 25 func Router(rootpath string, c ControllerInterface, mappingMethods ...string) *App {
...@@ -87,6 +94,12 @@ func InsertFilter(pattern string, pos int, filter FilterFunc) *App { ...@@ -87,6 +94,12 @@ func InsertFilter(pattern string, pos int, filter FilterFunc) *App {
87 return BeeApp 94 return BeeApp
88 } 95 }
89 96
97 // The hookfunc will run in beego.Run()
98 // such as sessionInit, middlerware start, buildtemplate, admin start
99 func AddAPPStartHook(hf hookfunc) {
100 hooks = append(hooks, hf)
101 }
102
90 // Run beego application. 103 // Run beego application.
91 // it's alias of App.Run. 104 // it's alias of App.Run.
92 func Run() { 105 func Run() {
...@@ -102,6 +115,14 @@ func Run() { ...@@ -102,6 +115,14 @@ func Run() {
102 //init mime 115 //init mime
103 initMime() 116 initMime()
104 117
118 // do hooks function
119 for _, hk := range hooks {
120 err := hk()
121 if err != nil {
122 panic(err)
123 }
124 }
125
105 if SessionOn { 126 if SessionOn {
106 GlobalSessions, _ = session.NewManager(SessionProvider, 127 GlobalSessions, _ = session.NewManager(SessionProvider,
107 SessionName, 128 SessionName,
......
...@@ -28,6 +28,12 @@ func (mr *FilterRouter) ValidRouter(router string) (bool, map[string]string) { ...@@ -28,6 +28,12 @@ func (mr *FilterRouter) ValidRouter(router string) (bool, map[string]string) {
28 if router == mr.pattern { 28 if router == mr.pattern {
29 return true, nil 29 return true, nil
30 } 30 }
31 //pattern /admin router /admin/ match
32 //pattern /admin/ router /admin don't match, because url will 301 in router
33 if n := len(router); n > 1 && router[n-1] == '/' && router[:n-2] == mr.pattern {
34 return true, nil
35 }
36
31 if mr.hasregex { 37 if mr.hasregex {
32 if !mr.regex.MatchString(router) { 38 if !mr.regex.MatchString(router) {
33 return false, nil 39 return false, nil
...@@ -46,7 +52,7 @@ func (mr *FilterRouter) ValidRouter(router string) (bool, map[string]string) { ...@@ -46,7 +52,7 @@ func (mr *FilterRouter) ValidRouter(router string) (bool, map[string]string) {
46 return false, nil 52 return false, nil
47 } 53 }
48 54
49 func buildFilter(pattern string, filter FilterFunc) *FilterRouter { 55 func buildFilter(pattern string, filter FilterFunc) (*FilterRouter, error) {
50 mr := new(FilterRouter) 56 mr := new(FilterRouter)
51 mr.params = make(map[int]string) 57 mr.params = make(map[int]string)
52 mr.filterFunc = filter 58 mr.filterFunc = filter
...@@ -54,7 +60,7 @@ func buildFilter(pattern string, filter FilterFunc) *FilterRouter { ...@@ -54,7 +60,7 @@ func buildFilter(pattern string, filter FilterFunc) *FilterRouter {
54 j := 0 60 j := 0
55 for i, part := range parts { 61 for i, part := range parts {
56 if strings.HasPrefix(part, ":") { 62 if strings.HasPrefix(part, ":") {
57 expr := "(.+)" 63 expr := "(.*)"
58 //a user may choose to override the default expression 64 //a user may choose to override the default expression
59 // similar to expressjs: ‘/user/:id([0-9]+)’ 65 // similar to expressjs: ‘/user/:id([0-9]+)’
60 if index := strings.Index(part, "("); index != -1 { 66 if index := strings.Index(part, "("); index != -1 {
...@@ -77,7 +83,7 @@ func buildFilter(pattern string, filter FilterFunc) *FilterRouter { ...@@ -77,7 +83,7 @@ func buildFilter(pattern string, filter FilterFunc) *FilterRouter {
77 j++ 83 j++
78 } 84 }
79 if strings.HasPrefix(part, "*") { 85 if strings.HasPrefix(part, "*") {
80 expr := "(.+)" 86 expr := "(.*)"
81 if part == "*.*" { 87 if part == "*.*" {
82 mr.params[j] = ":path" 88 mr.params[j] = ":path"
83 parts[i] = "([^.]+).([^.]+)" 89 parts[i] = "([^.]+).([^.]+)"
...@@ -137,12 +143,11 @@ func buildFilter(pattern string, filter FilterFunc) *FilterRouter { ...@@ -137,12 +143,11 @@ func buildFilter(pattern string, filter FilterFunc) *FilterRouter {
137 pattern = strings.Join(parts, "/") 143 pattern = strings.Join(parts, "/")
138 regex, regexErr := regexp.Compile(pattern) 144 regex, regexErr := regexp.Compile(pattern)
139 if regexErr != nil { 145 if regexErr != nil {
140 //TODO add error handling here to avoid panic 146 return nil, regexErr
141 panic(regexErr)
142 } 147 }
143 mr.regex = regex 148 mr.regex = regex
144 mr.hasregex = true 149 mr.hasregex = true
145 } 150 }
146 mr.pattern = pattern 151 mr.pattern = pattern
147 return mr 152 return mr, nil
148 } 153 }
......
...@@ -23,3 +23,32 @@ func TestFilter(t *testing.T) { ...@@ -23,3 +23,32 @@ func TestFilter(t *testing.T) {
23 t.Errorf("user define func can't run") 23 t.Errorf("user define func can't run")
24 } 24 }
25 } 25 }
26
27 var FilterAdminUser = func(ctx *context.Context) {
28 ctx.Output.Body([]byte("i am admin"))
29 }
30
31 // Filter pattern /admin/:all
32 // all url like /admin/ /admin/xie will all get filter
33
34 func TestPatternTwo(t *testing.T) {
35 r, _ := http.NewRequest("GET", "/admin/", nil)
36 w := httptest.NewRecorder()
37 handler := NewControllerRegistor()
38 handler.AddFilter("/admin/:all", "AfterStatic", FilterAdminUser)
39 handler.ServeHTTP(w, r)
40 if w.Body.String() != "i am admin" {
41 t.Errorf("filter /admin/ can't run")
42 }
43 }
44
45 func TestPatternThree(t *testing.T) {
46 r, _ := http.NewRequest("GET", "/admin/astaxie", nil)
47 w := httptest.NewRecorder()
48 handler := NewControllerRegistor()
49 handler.AddFilter("/admin/:all", "AfterStatic", FilterAdminUser)
50 handler.ServeHTTP(w, r)
51 if w.Body.String() != "i am admin" {
52 t.Errorf("filter /admin/astaxie can't run")
53 }
54 }
......
...@@ -77,7 +77,7 @@ func (p *ControllerRegistor) Add(pattern string, c ControllerInterface, mappingM ...@@ -77,7 +77,7 @@ func (p *ControllerRegistor) Add(pattern string, c ControllerInterface, mappingM
77 params := make(map[int]string) 77 params := make(map[int]string)
78 for i, part := range parts { 78 for i, part := range parts {
79 if strings.HasPrefix(part, ":") { 79 if strings.HasPrefix(part, ":") {
80 expr := "(.+)" 80 expr := "(.*)"
81 //a user may choose to override the defult expression 81 //a user may choose to override the defult expression
82 // similar to expressjs: ‘/user/:id([0-9]+)’ 82 // similar to expressjs: ‘/user/:id([0-9]+)’
83 if index := strings.Index(part, "("); index != -1 { 83 if index := strings.Index(part, "("); index != -1 {
...@@ -100,7 +100,7 @@ func (p *ControllerRegistor) Add(pattern string, c ControllerInterface, mappingM ...@@ -100,7 +100,7 @@ func (p *ControllerRegistor) Add(pattern string, c ControllerInterface, mappingM
100 j++ 100 j++
101 } 101 }
102 if strings.HasPrefix(part, "*") { 102 if strings.HasPrefix(part, "*") {
103 expr := "(.+)" 103 expr := "(.*)"
104 if part == "*.*" { 104 if part == "*.*" {
105 params[j] = ":path" 105 params[j] = ":path"
106 parts[i] = "([^.]+).([^.]+)" 106 parts[i] = "([^.]+).([^.]+)"
...@@ -238,8 +238,11 @@ func (p *ControllerRegistor) AddAuto(c ControllerInterface) { ...@@ -238,8 +238,11 @@ func (p *ControllerRegistor) AddAuto(c ControllerInterface) {
238 238
239 // [Deprecated] use InsertFilter. 239 // [Deprecated] use InsertFilter.
240 // Add FilterFunc with pattern for action. 240 // Add FilterFunc with pattern for action.
241 func (p *ControllerRegistor) AddFilter(pattern, action string, filter FilterFunc) { 241 func (p *ControllerRegistor) AddFilter(pattern, action string, filter FilterFunc) error {
242 mr := buildFilter(pattern, filter) 242 mr, err := buildFilter(pattern, filter)
243 if err != nil {
244 return err
245 }
243 switch action { 246 switch action {
244 case "BeforeRouter": 247 case "BeforeRouter":
245 p.filters[BeforeRouter] = append(p.filters[BeforeRouter], mr) 248 p.filters[BeforeRouter] = append(p.filters[BeforeRouter], mr)
...@@ -253,13 +256,18 @@ func (p *ControllerRegistor) AddFilter(pattern, action string, filter FilterFunc ...@@ -253,13 +256,18 @@ func (p *ControllerRegistor) AddFilter(pattern, action string, filter FilterFunc
253 p.filters[FinishRouter] = append(p.filters[FinishRouter], mr) 256 p.filters[FinishRouter] = append(p.filters[FinishRouter], mr)
254 } 257 }
255 p.enableFilter = true 258 p.enableFilter = true
259 return nil
256 } 260 }
257 261
258 // Add a FilterFunc with pattern rule and action constant. 262 // Add a FilterFunc with pattern rule and action constant.
259 func (p *ControllerRegistor) InsertFilter(pattern string, pos int, filter FilterFunc) { 263 func (p *ControllerRegistor) InsertFilter(pattern string, pos int, filter FilterFunc) error {
260 mr := buildFilter(pattern, filter) 264 mr, err := buildFilter(pattern, filter)
265 if err != nil {
266 return err
267 }
261 p.filters[pos] = append(p.filters[pos], mr) 268 p.filters[pos] = append(p.filters[pos], mr)
262 p.enableFilter = true 269 p.enableFilter = true
270 return nil
263 } 271 }
264 272
265 // UrlFor does another controller handler in this request function. 273 // UrlFor does another controller handler in this request function.
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!