54fb49ed by astaxie

fix #315

1 parent fbd1c3f8
...@@ -139,6 +139,7 @@ func (input *BeegoInput) Param(key string) string { ...@@ -139,6 +139,7 @@ func (input *BeegoInput) Param(key string) string {
139 } 139 }
140 140
141 func (input *BeegoInput) Query(key string) string { 141 func (input *BeegoInput) Query(key string) string {
142 input.req.ParseForm()
142 return input.req.Form.Get(key) 143 return input.req.Form.Get(key)
143 } 144 }
144 145
......
...@@ -2,36 +2,143 @@ package beego ...@@ -2,36 +2,143 @@ package beego
2 2
3 import ( 3 import (
4 "regexp" 4 "regexp"
5 "strings"
5 ) 6 )
6 7
7 type FilterRouter struct { 8 type FilterRouter struct {
8 pattern string 9 pattern string
9 regex *regexp.Regexp 10 regex *regexp.Regexp
10 filterFunc FilterFunc 11 filterFunc FilterFunc
11 hasregex bool 12 hasregex bool
12 params map[int]string 13 params map[int]string
14 parseParams map[string]string
13 } 15 }
14 16
15 func (mr *FilterRouter) ValidRouter(router string) bool { 17 func (mr *FilterRouter) ValidRouter(router string) (bool, map[string]string) {
16 if mr.pattern == "" { 18 if mr.pattern == "" {
17 return true 19 return true, nil
18 } 20 }
19 if mr.pattern == "*" { 21 if mr.pattern == "*" {
20 return true 22 return true, nil
21 } 23 }
22 if router == mr.pattern { 24 if router == mr.pattern {
23 return true 25 return true, nil
24 } 26 }
25 if mr.hasregex { 27 if mr.hasregex {
26 if mr.regex.MatchString(router) { 28 if !mr.regex.MatchString(router) {
27 return true 29 return false, nil
28 } 30 }
29 matches := mr.regex.FindStringSubmatch(router) 31 matches := mr.regex.FindStringSubmatch(router)
30 if len(matches) > 0 { 32 if len(matches) > 0 {
31 if len(matches[0]) == len(router) { 33 if len(matches[0]) == len(router) {
32 return true 34 params := make(map[string]string)
35 for i, match := range matches[1:] {
36 params[mr.params[i]] = match
37 }
38 return true, params
33 } 39 }
34 } 40 }
35 } 41 }
36 return false 42 return false, nil
43 }
44
45 func buildFilter(pattern string, filter FilterFunc) *FilterRouter {
46 mr := new(FilterRouter)
47 mr.params = make(map[int]string)
48 mr.filterFunc = filter
49 parts := strings.Split(pattern, "/")
50 j := 0
51 for i, part := range parts {
52 if strings.HasPrefix(part, ":") {
53 expr := "(.+)"
54 //a user may choose to override the default expression
55 // similar to expressjs: ‘/user/:id([0-9]+)’
56 if index := strings.Index(part, "("); index != -1 {
57 expr = part[index:]
58 part = part[:index]
59 //match /user/:id:int ([0-9]+)
60 //match /post/:username:string ([\w]+)
61 } else if lindex := strings.LastIndex(part, ":"); lindex != 0 {
62 switch part[lindex:] {
63 case ":int":
64 expr = "([0-9]+)"
65 part = part[:lindex]
66 case ":string":
67 expr = `([\w]+)`
68 part = part[:lindex]
69 }
70 }
71 mr.params[j] = part
72 parts[i] = expr
73 j++
74 }
75 if strings.HasPrefix(part, "*") {
76 expr := "(.+)"
77 if part == "*.*" {
78 mr.params[j] = ":path"
79 parts[i] = "([^.]+).([^.]+)"
80 j++
81 mr.params[j] = ":ext"
82 j++
83 } else {
84 mr.params[j] = ":splat"
85 parts[i] = expr
86 j++
87 }
88 }
89 //url like someprefix:id(xxx).html
90 if strings.Contains(part, ":") && strings.Contains(part, "(") && strings.Contains(part, ")") {
91 var out []rune
92 var start bool
93 var startexp bool
94 var param []rune
95 var expt []rune
96 for _, v := range part {
97 if start {
98 if v != '(' {
99 param = append(param, v)
100 continue
101 }
102 }
103 if startexp {
104 if v != ')' {
105 expt = append(expt, v)
106 continue
107 }
108 }
109 if v == ':' {
110 param = make([]rune, 0)
111 param = append(param, ':')
112 start = true
113 } else if v == '(' {
114 startexp = true
115 start = false
116 mr.params[j] = string(param)
117 j++
118 expt = make([]rune, 0)
119 expt = append(expt, '(')
120 } else if v == ')' {
121 startexp = false
122 expt = append(expt, ')')
123 out = append(out, expt...)
124 } else {
125 out = append(out, v)
126 }
127 }
128 parts[i] = string(out)
129 }
130 }
131
132 if j != 0 {
133 pattern = strings.Join(parts, "/")
134 regex, regexErr := regexp.Compile(pattern)
135 if regexErr != nil {
136 //TODO add error handling here to avoid panic
137 panic(regexErr)
138 }
139 mr.regex = regex
140 mr.hasregex = true
141 }
142 mr.pattern = pattern
143 return mr
37 } 144 }
......
1 package beego
2
3 import (
4 "github.com/astaxie/beego/context"
5 "net/http"
6 "net/http/httptest"
7 "testing"
8 )
9
10 var FilterUser = func(ctx *context.Context) {
11 ctx.Output.Body([]byte("i am " + ctx.Input.Params[":last"] + ctx.Input.Params[":first"]))
12 }
13
14 func TestFilter(t *testing.T) {
15 r, _ := http.NewRequest("GET", "/person/asta/Xie", nil)
16 w := httptest.NewRecorder()
17 handler := NewControllerRegistor()
18 handler.AddFilter("/person/:last/:first", "AfterStatic", FilterUser)
19 handler.Add("/person/:last/:first", &TestController{})
20 handler.ServeHTTP(w, r)
21 if w.Body.String() != "i am astaXie" {
22 t.Errorf("user define func can't run")
23 }
24 }
...@@ -222,49 +222,6 @@ func (p *ControllerRegistor) AddAuto(c ControllerInterface) { ...@@ -222,49 +222,6 @@ func (p *ControllerRegistor) AddAuto(c ControllerInterface) {
222 } 222 }
223 } 223 }
224 224
225 func buildFilter(pattern string, filter FilterFunc) *FilterRouter {
226 mr := new(FilterRouter)
227 mr.filterFunc = filter
228 parts := strings.Split(pattern, "/")
229 j := 0
230 for i, part := range parts {
231 if strings.HasPrefix(part, ":") {
232 expr := "(.+)"
233 //a user may choose to override the default expression
234 // similar to expressjs: ‘/user/:id([0-9]+)’
235 if index := strings.Index(part, "("); index != -1 {
236 expr = part[index:]
237 part = part[:index]
238 //match /user/:id:int ([0-9]+)
239 //match /post/:username:string ([\w]+)
240 } else if lindex := strings.LastIndex(part, ":"); lindex != 0 {
241 switch part[lindex:] {
242 case ":int":
243 expr = "([0-9]+)"
244 part = part[:lindex]
245 case ":string":
246 expr = `([\w]+)`
247 part = part[:lindex]
248 }
249 }
250 parts[i] = expr
251 j++
252 }
253 }
254 if j != 0 {
255 pattern = strings.Join(parts, "/")
256 regex, regexErr := regexp.Compile(pattern)
257 if regexErr != nil {
258 //TODO add error handling here to avoid panic
259 panic(regexErr)
260 }
261 mr.regex = regex
262 mr.hasregex = true
263 }
264 mr.pattern = pattern
265 return mr
266 }
267
268 func (p *ControllerRegistor) AddFilter(pattern, action string, filter FilterFunc) { 225 func (p *ControllerRegistor) AddFilter(pattern, action string, filter FilterFunc) {
269 mr := buildFilter(pattern, filter) 226 mr := buildFilter(pattern, filter)
270 switch action { 227 switch action {
...@@ -469,7 +426,8 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) ...@@ -469,7 +426,8 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
469 if p.enableFilter { 426 if p.enableFilter {
470 if l, ok := p.filters[BeforeRouter]; ok { 427 if l, ok := p.filters[BeforeRouter]; ok {
471 for _, filterR := range l { 428 for _, filterR := range l {
472 if filterR.ValidRouter(r.URL.Path) { 429 if ok, p := filterR.ValidRouter(r.URL.Path); ok {
430 context.Input.Params = p
473 filterR.filterFunc(context) 431 filterR.filterFunc(context)
474 if w.started { 432 if w.started {
475 goto Admin 433 goto Admin
...@@ -516,7 +474,8 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) ...@@ -516,7 +474,8 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
516 if p.enableFilter { 474 if p.enableFilter {
517 if l, ok := p.filters[AfterStatic]; ok { 475 if l, ok := p.filters[AfterStatic]; ok {
518 for _, filterR := range l { 476 for _, filterR := range l {
519 if filterR.ValidRouter(r.URL.Path) { 477 if ok, p := filterR.ValidRouter(r.URL.Path); ok {
478 context.Input.Params = p
520 filterR.filterFunc(context) 479 filterR.filterFunc(context)
521 if w.started { 480 if w.started {
522 goto Admin 481 goto Admin
...@@ -591,7 +550,8 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) ...@@ -591,7 +550,8 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
591 if p.enableFilter { 550 if p.enableFilter {
592 if l, ok := p.filters[BeforeExec]; ok { 551 if l, ok := p.filters[BeforeExec]; ok {
593 for _, filterR := range l { 552 for _, filterR := range l {
594 if filterR.ValidRouter(r.URL.Path) { 553 if ok, p := filterR.ValidRouter(r.URL.Path); ok {
554 context.Input.Params = p
595 filterR.filterFunc(context) 555 filterR.filterFunc(context)
596 if w.started { 556 if w.started {
597 goto Admin 557 goto Admin
...@@ -746,7 +706,8 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) ...@@ -746,7 +706,8 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
746 if p.enableFilter { 706 if p.enableFilter {
747 if l, ok := p.filters[AfterExec]; ok { 707 if l, ok := p.filters[AfterExec]; ok {
748 for _, filterR := range l { 708 for _, filterR := range l {
749 if filterR.ValidRouter(r.URL.Path) { 709 if ok, p := filterR.ValidRouter(r.URL.Path); ok {
710 context.Input.Params = p
750 filterR.filterFunc(context) 711 filterR.filterFunc(context)
751 if w.started { 712 if w.started {
752 goto Admin 713 goto Admin
...@@ -795,7 +756,8 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) ...@@ -795,7 +756,8 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
795 if p.enableFilter { 756 if p.enableFilter {
796 if l, ok := p.filters[BeforeExec]; ok { 757 if l, ok := p.filters[BeforeExec]; ok {
797 for _, filterR := range l { 758 for _, filterR := range l {
798 if filterR.ValidRouter(r.URL.Path) { 759 if ok, p := filterR.ValidRouter(r.URL.Path); ok {
760 context.Input.Params = p
799 filterR.filterFunc(context) 761 filterR.filterFunc(context)
800 if w.started { 762 if w.started {
801 goto Admin 763 goto Admin
...@@ -850,7 +812,8 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) ...@@ -850,7 +812,8 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
850 if p.enableFilter { 812 if p.enableFilter {
851 if l, ok := p.filters[AfterExec]; ok { 813 if l, ok := p.filters[AfterExec]; ok {
852 for _, filterR := range l { 814 for _, filterR := range l {
853 if filterR.ValidRouter(r.URL.Path) { 815 if ok, p := filterR.ValidRouter(r.URL.Path); ok {
816 context.Input.Params = p
854 filterR.filterFunc(context) 817 filterR.filterFunc(context)
855 if w.started { 818 if w.started {
856 goto Admin 819 goto Admin
...@@ -878,7 +841,8 @@ Admin: ...@@ -878,7 +841,8 @@ Admin:
878 if p.enableFilter { 841 if p.enableFilter {
879 if l, ok := p.filters[FinishRouter]; ok { 842 if l, ok := p.filters[FinishRouter]; ok {
880 for _, filterR := range l { 843 for _, filterR := range l {
881 if filterR.ValidRouter(r.URL.Path) { 844 if ok, p := filterR.ValidRouter(r.URL.Path); ok {
845 context.Input.Params = p
882 filterR.filterFunc(context) 846 filterR.filterFunc(context)
883 if w.started { 847 if w.started {
884 break 848 break
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!