beego: support more router
//design model
beego.Get(router, beego.FilterFunc)
beego.Post(router, beego.FilterFunc)
beego.Put(router, beego.FilterFunc)
beego.Head(router, beego.FilterFunc)
beego.Options(router, beego.FilterFunc)
beego.Delete(router, beego.FilterFunc)
beego.Handler(router, http.Handler)
//example
beego.Get("/user", func(ctx *context.Context) {
ctx.Output.Body([]byte("Get userlist"))
})
beego.Post("/user", func(ctx *context.Context) {
ctx.Output.Body([]byte("add userlist"))
})
beego.Delete("/user/:id", func(ctx *context.Context) {
ctx.Output.Body([]byte([]byte(ctx.Input.Param(":id")))
})
import (
"http"
"github.com/gorilla/rpc"
"github.com/gorilla/rpc/json"
)
func init() {
s := rpc.NewServer()
s.RegisterCodec(json.NewCodec(), "application/json")
s.RegisterService(new(HelloService), "")
beego.Handler("/rpc", s)
}
Showing
4 changed files
with
388 additions
and
59 deletions
| ... | @@ -136,6 +136,60 @@ func (app *App) AutoRouterWithPrefix(prefix string, c ControllerInterface) *App | ... | @@ -136,6 +136,60 @@ func (app *App) AutoRouterWithPrefix(prefix string, c ControllerInterface) *App |
| 136 | return app | 136 | return app |
| 137 | } | 137 | } |
| 138 | 138 | ||
| 139 | // add router for Get method | ||
| 140 | func (app *App) Get(rootpath string, f FilterFunc) *App { | ||
| 141 | app.Handlers.Get(rootpath, f) | ||
| 142 | return app | ||
| 143 | } | ||
| 144 | |||
| 145 | // add router for Post method | ||
| 146 | func (app *App) Post(rootpath string, f FilterFunc) *App { | ||
| 147 | app.Handlers.Post(rootpath, f) | ||
| 148 | return app | ||
| 149 | } | ||
| 150 | |||
| 151 | // add router for Put method | ||
| 152 | func (app *App) Put(rootpath string, f FilterFunc) *App { | ||
| 153 | app.Handlers.Put(rootpath, f) | ||
| 154 | return app | ||
| 155 | } | ||
| 156 | |||
| 157 | // add router for Delete method | ||
| 158 | func (app *App) Delete(rootpath string, f FilterFunc) *App { | ||
| 159 | app.Handlers.Delete(rootpath, f) | ||
| 160 | return app | ||
| 161 | } | ||
| 162 | |||
| 163 | // add router for Options method | ||
| 164 | func (app *App) Options(rootpath string, f FilterFunc) *App { | ||
| 165 | app.Handlers.Options(rootpath, f) | ||
| 166 | return app | ||
| 167 | } | ||
| 168 | |||
| 169 | // add router for Head method | ||
| 170 | func (app *App) Head(rootpath string, f FilterFunc) *App { | ||
| 171 | app.Handlers.Head(rootpath, f) | ||
| 172 | return app | ||
| 173 | } | ||
| 174 | |||
| 175 | // add router for Patch method | ||
| 176 | func (app *App) Patch(rootpath string, f FilterFunc) *App { | ||
| 177 | app.Handlers.Patch(rootpath, f) | ||
| 178 | return app | ||
| 179 | } | ||
| 180 | |||
| 181 | // add router for Patch method | ||
| 182 | func (app *App) Any(rootpath string, f FilterFunc) *App { | ||
| 183 | app.Handlers.Any(rootpath, f) | ||
| 184 | return app | ||
| 185 | } | ||
| 186 | |||
| 187 | // add router for http.Handler | ||
| 188 | func (app *App) Handler(rootpath string, h http.Handler) *App { | ||
| 189 | app.Handlers.Handler(rootpath, h) | ||
| 190 | return app | ||
| 191 | } | ||
| 192 | |||
| 139 | // UrlFor creates a url with another registered controller handler with params. | 193 | // UrlFor creates a url with another registered controller handler with params. |
| 140 | // The endpoint is formed as path.controller.name to defined the controller method which will run. | 194 | // The endpoint is formed as path.controller.name to defined the controller method which will run. |
| 141 | // The values need key-pair data to assign into controller method. | 195 | // The values need key-pair data to assign into controller method. | ... | ... |
| ... | @@ -121,6 +121,60 @@ func AutoPrefix(prefix string, c ControllerInterface) *App { | ... | @@ -121,6 +121,60 @@ func AutoPrefix(prefix string, c ControllerInterface) *App { |
| 121 | return BeeApp | 121 | return BeeApp |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | // register router for Get method | ||
| 125 | func Get(rootpath string, f FilterFunc) *App { | ||
| 126 | BeeApp.Get(rootpath, f) | ||
| 127 | return BeeApp | ||
| 128 | } | ||
| 129 | |||
| 130 | // register router for Post method | ||
| 131 | func Post(rootpath string, f FilterFunc) *App { | ||
| 132 | BeeApp.Post(rootpath, f) | ||
| 133 | return BeeApp | ||
| 134 | } | ||
| 135 | |||
| 136 | // register router for Delete method | ||
| 137 | func Delete(rootpath string, f FilterFunc) *App { | ||
| 138 | BeeApp.Delete(rootpath, f) | ||
| 139 | return BeeApp | ||
| 140 | } | ||
| 141 | |||
| 142 | // register router for Put method | ||
| 143 | func Put(rootpath string, f FilterFunc) *App { | ||
| 144 | BeeApp.Put(rootpath, f) | ||
| 145 | return BeeApp | ||
| 146 | } | ||
| 147 | |||
| 148 | // register router for Head method | ||
| 149 | func Head(rootpath string, f FilterFunc) *App { | ||
| 150 | BeeApp.Head(rootpath, f) | ||
| 151 | return BeeApp | ||
| 152 | } | ||
| 153 | |||
| 154 | // register router for Options method | ||
| 155 | func Options(rootpath string, f FilterFunc) *App { | ||
| 156 | BeeApp.Options(rootpath, f) | ||
| 157 | return BeeApp | ||
| 158 | } | ||
| 159 | |||
| 160 | // register router for Patch method | ||
| 161 | func Patch(rootpath string, f FilterFunc) *App { | ||
| 162 | BeeApp.Patch(rootpath, f) | ||
| 163 | return BeeApp | ||
| 164 | } | ||
| 165 | |||
| 166 | // register router for all method | ||
| 167 | func Any(rootpath string, f FilterFunc) *App { | ||
| 168 | BeeApp.Any(rootpath, f) | ||
| 169 | return BeeApp | ||
| 170 | } | ||
| 171 | |||
| 172 | // register router for own Handler | ||
| 173 | func Handler(rootpath string, h http.Handler) *App { | ||
| 174 | BeeApp.Handler(rootpath, h) | ||
| 175 | return BeeApp | ||
| 176 | } | ||
| 177 | |||
| 124 | // ErrorHandler registers http.HandlerFunc to each http err code string. | 178 | // ErrorHandler registers http.HandlerFunc to each http err code string. |
| 125 | // usage: | 179 | // usage: |
| 126 | // beego.ErrorHandler("404",NotFound) | 180 | // beego.ErrorHandler("404",NotFound) | ... | ... |
| ... | @@ -35,6 +35,12 @@ const ( | ... | @@ -35,6 +35,12 @@ const ( |
| 35 | FinishRouter | 35 | FinishRouter |
| 36 | ) | 36 | ) |
| 37 | 37 | ||
| 38 | const ( | ||
| 39 | routerTypeBeego = iota | ||
| 40 | routerTypeRESTFul | ||
| 41 | routerTypeHandler | ||
| 42 | ) | ||
| 43 | |||
| 38 | var ( | 44 | var ( |
| 39 | // supported http methods. | 45 | // supported http methods. |
| 40 | HTTPMETHOD = []string{"get", "post", "put", "delete", "patch", "options", "head", "trace", "connect"} | 46 | HTTPMETHOD = []string{"get", "post", "put", "delete", "patch", "options", "head", "trace", "connect"} |
| ... | @@ -60,6 +66,9 @@ type controllerInfo struct { | ... | @@ -60,6 +66,9 @@ type controllerInfo struct { |
| 60 | controllerType reflect.Type | 66 | controllerType reflect.Type |
| 61 | methods map[string]string | 67 | methods map[string]string |
| 62 | hasMethod bool | 68 | hasMethod bool |
| 69 | handler http.Handler | ||
| 70 | runfunction FilterFunc | ||
| 71 | routerType int | ||
| 63 | } | 72 | } |
| 64 | 73 | ||
| 65 | // ControllerRegistor containers registered router rules, controller handlers and filters. | 74 | // ControllerRegistor containers registered router rules, controller handlers and filters. |
| ... | @@ -92,10 +101,211 @@ func NewControllerRegistor() *ControllerRegistor { | ... | @@ -92,10 +101,211 @@ func NewControllerRegistor() *ControllerRegistor { |
| 92 | // Add("/api",&RestController{},"get,post:ApiFunc") | 101 | // Add("/api",&RestController{},"get,post:ApiFunc") |
| 93 | // Add("/simple",&SimpleController{},"get:GetFunc;post:PostFunc") | 102 | // Add("/simple",&SimpleController{},"get:GetFunc;post:PostFunc") |
| 94 | func (p *ControllerRegistor) Add(pattern string, c ControllerInterface, mappingMethods ...string) { | 103 | func (p *ControllerRegistor) Add(pattern string, c ControllerInterface, mappingMethods ...string) { |
| 95 | parts := strings.Split(pattern, "/") | 104 | j, params, parts := p.splitRoute(pattern) |
| 105 | reflectVal := reflect.ValueOf(c) | ||
| 106 | t := reflect.Indirect(reflectVal).Type() | ||
| 107 | methods := make(map[string]string) | ||
| 108 | if len(mappingMethods) > 0 { | ||
| 109 | semi := strings.Split(mappingMethods[0], ";") | ||
| 110 | for _, v := range semi { | ||
| 111 | colon := strings.Split(v, ":") | ||
| 112 | if len(colon) != 2 { | ||
| 113 | panic("method mapping format is invalid") | ||
| 114 | } | ||
| 115 | comma := strings.Split(colon[0], ",") | ||
| 116 | for _, m := range comma { | ||
| 117 | if m == "*" || utils.InSlice(strings.ToLower(m), HTTPMETHOD) { | ||
| 118 | if val := reflectVal.MethodByName(colon[1]); val.IsValid() { | ||
| 119 | methods[strings.ToLower(m)] = colon[1] | ||
| 120 | } else { | ||
| 121 | panic(colon[1] + " method doesn't exist in the controller " + t.Name()) | ||
| 122 | } | ||
| 123 | } else { | ||
| 124 | panic(v + " is an invalid method mapping. Method doesn't exist " + m) | ||
| 125 | } | ||
| 126 | } | ||
| 127 | } | ||
| 128 | } | ||
| 129 | if j == 0 { | ||
| 130 | //now create the Route | ||
| 131 | route := &controllerInfo{} | ||
| 132 | route.pattern = pattern | ||
| 133 | route.controllerType = t | ||
| 134 | route.methods = methods | ||
| 135 | route.routerType = routerTypeBeego | ||
| 136 | if len(methods) > 0 { | ||
| 137 | route.hasMethod = true | ||
| 138 | } | ||
| 139 | p.fixrouters = append(p.fixrouters, route) | ||
| 140 | } else { // add regexp routers | ||
| 141 | //recreate the url pattern, with parameters replaced | ||
| 142 | //by regular expressions. then compile the regex | ||
| 143 | pattern = strings.Join(parts, "/") | ||
| 144 | regex, regexErr := regexp.Compile(pattern) | ||
| 145 | if regexErr != nil { | ||
| 146 | //TODO add error handling here to avoid panic | ||
| 147 | panic(regexErr) | ||
| 148 | } | ||
| 149 | |||
| 150 | //now create the Route | ||
| 151 | |||
| 152 | route := &controllerInfo{} | ||
| 153 | route.regex = regex | ||
| 154 | route.params = params | ||
| 155 | route.pattern = pattern | ||
| 156 | route.methods = methods | ||
| 157 | route.routerType = routerTypeBeego | ||
| 158 | if len(methods) > 0 { | ||
| 159 | route.hasMethod = true | ||
| 160 | } | ||
| 161 | route.controllerType = t | ||
| 162 | p.routers = append(p.routers, route) | ||
| 163 | } | ||
| 164 | } | ||
| 165 | |||
| 166 | // add get method | ||
| 167 | // usage: | ||
| 168 | // Get("/", func(ctx *context.Context){ | ||
| 169 | // ctx.Output.Body("hello world") | ||
| 170 | // }) | ||
| 171 | func (p *ControllerRegistor) Get(pattern string, f FilterFunc) { | ||
| 172 | p.AddMethod("get", pattern, f) | ||
| 173 | } | ||
| 174 | |||
| 175 | // add post method | ||
| 176 | // usage: | ||
| 177 | // Post("/api", func(ctx *context.Context){ | ||
| 178 | // ctx.Output.Body("hello world") | ||
| 179 | // }) | ||
| 180 | func (p *ControllerRegistor) Post(pattern string, f FilterFunc) { | ||
| 181 | p.AddMethod("post", pattern, f) | ||
| 182 | } | ||
| 183 | |||
| 184 | // add put method | ||
| 185 | // usage: | ||
| 186 | // Put("/api/:id", func(ctx *context.Context){ | ||
| 187 | // ctx.Output.Body("hello world") | ||
| 188 | // }) | ||
| 189 | func (p *ControllerRegistor) Put(pattern string, f FilterFunc) { | ||
| 190 | p.AddMethod("put", pattern, f) | ||
| 191 | } | ||
| 192 | |||
| 193 | // add delete method | ||
| 194 | // usage: | ||
| 195 | // Delete("/api/:id", func(ctx *context.Context){ | ||
| 196 | // ctx.Output.Body("hello world") | ||
| 197 | // }) | ||
| 198 | func (p *ControllerRegistor) Delete(pattern string, f FilterFunc) { | ||
| 199 | p.AddMethod("delete", pattern, f) | ||
| 200 | } | ||
| 201 | |||
| 202 | // add head method | ||
| 203 | // usage: | ||
| 204 | // Head("/api/:id", func(ctx *context.Context){ | ||
| 205 | // ctx.Output.Body("hello world") | ||
| 206 | // }) | ||
| 207 | func (p *ControllerRegistor) Head(pattern string, f FilterFunc) { | ||
| 208 | p.AddMethod("head", pattern, f) | ||
| 209 | } | ||
| 210 | |||
| 211 | // add patch method | ||
| 212 | // usage: | ||
| 213 | // Patch("/api/:id", func(ctx *context.Context){ | ||
| 214 | // ctx.Output.Body("hello world") | ||
| 215 | // }) | ||
| 216 | func (p *ControllerRegistor) Patch(pattern string, f FilterFunc) { | ||
| 217 | p.AddMethod("patch", pattern, f) | ||
| 218 | } | ||
| 219 | |||
| 220 | // add options method | ||
| 221 | // usage: | ||
| 222 | // Options("/api/:id", func(ctx *context.Context){ | ||
| 223 | // ctx.Output.Body("hello world") | ||
| 224 | // }) | ||
| 225 | func (p *ControllerRegistor) Options(pattern string, f FilterFunc) { | ||
| 226 | p.AddMethod("options", pattern, f) | ||
| 227 | } | ||
| 228 | |||
| 229 | // add all method | ||
| 230 | // usage: | ||
| 231 | // Any("/api/:id", func(ctx *context.Context){ | ||
| 232 | // ctx.Output.Body("hello world") | ||
| 233 | // }) | ||
| 234 | func (p *ControllerRegistor) Any(pattern string, f FilterFunc) { | ||
| 235 | p.AddMethod("*", pattern, f) | ||
| 236 | } | ||
| 237 | |||
| 238 | // add http method router | ||
| 239 | // usage: | ||
| 240 | // AddMethod("get","/api/:id", func(ctx *context.Context){ | ||
| 241 | // ctx.Output.Body("hello world") | ||
| 242 | // }) | ||
| 243 | func (p *ControllerRegistor) AddMethod(method, pattern string, f FilterFunc) { | ||
| 244 | if method != "*" && !utils.InSlice(strings.ToLower(method), HTTPMETHOD) { | ||
| 245 | panic("not support http method: " + method) | ||
| 246 | } | ||
| 247 | route := &controllerInfo{} | ||
| 248 | route.routerType = routerTypeRESTFul | ||
| 249 | route.runfunction = f | ||
| 250 | methods := make(map[string]string) | ||
| 251 | if method == "*" { | ||
| 252 | for _, val := range HTTPMETHOD { | ||
| 253 | methods[val] = val | ||
| 254 | } | ||
| 255 | } else { | ||
| 256 | methods[method] = method | ||
| 257 | } | ||
| 258 | route.methods = methods | ||
| 259 | paramnums, params, parts := p.splitRoute(pattern) | ||
| 260 | if paramnums == 0 { | ||
| 261 | //now create the Route | ||
| 262 | route.pattern = pattern | ||
| 263 | p.fixrouters = append(p.fixrouters, route) | ||
| 264 | } else { | ||
| 265 | //recreate the url pattern, with parameters replaced | ||
| 266 | //by regular expressions. then compile the regex | ||
| 267 | pattern = strings.Join(parts, "/") | ||
| 268 | regex, regexErr := regexp.Compile(pattern) | ||
| 269 | if regexErr != nil { | ||
| 270 | panic(regexErr) | ||
| 271 | } | ||
| 272 | //now create the Route | ||
| 273 | route.regex = regex | ||
| 274 | route.params = params | ||
| 275 | route.pattern = pattern | ||
| 276 | p.routers = append(p.routers, route) | ||
| 277 | } | ||
| 278 | } | ||
| 96 | 279 | ||
| 280 | func (p *ControllerRegistor) Handler(pattern string, h http.Handler) { | ||
| 281 | paramnums, params, parts := p.splitRoute(pattern) | ||
| 282 | route := &controllerInfo{} | ||
| 283 | route.routerType = routerTypeHandler | ||
| 284 | route.handler = h | ||
| 285 | if paramnums == 0 { | ||
| 286 | route.pattern = pattern | ||
| 287 | p.fixrouters = append(p.fixrouters, route) | ||
| 288 | } else { | ||
| 289 | //recreate the url pattern, with parameters replaced | ||
| 290 | //by regular expressions. then compile the regex | ||
| 291 | pattern = strings.Join(parts, "/") | ||
| 292 | regex, regexErr := regexp.Compile(pattern) | ||
| 293 | if regexErr != nil { | ||
| 294 | panic(regexErr) | ||
| 295 | } | ||
| 296 | //now create the Route | ||
| 297 | route.regex = regex | ||
| 298 | route.params = params | ||
| 299 | route.pattern = pattern | ||
| 300 | p.routers = append(p.routers, route) | ||
| 301 | } | ||
| 302 | } | ||
| 303 | |||
| 304 | // analisys the patter to params & parts | ||
| 305 | func (p *ControllerRegistor) splitRoute(pattern string) (paramnums int, params map[int]string, parts []string) { | ||
| 306 | parts = strings.Split(pattern, "/") | ||
| 97 | j := 0 | 307 | j := 0 |
| 98 | params := make(map[int]string) | 308 | params = make(map[int]string) |
| 99 | for i, part := range parts { | 309 | for i, part := range parts { |
| 100 | if strings.HasPrefix(part, ":") { | 310 | if strings.HasPrefix(part, ":") { |
| 101 | expr := "(.*)" | 311 | expr := "(.*)" |
| ... | @@ -180,63 +390,7 @@ func (p *ControllerRegistor) Add(pattern string, c ControllerInterface, mappingM | ... | @@ -180,63 +390,7 @@ func (p *ControllerRegistor) Add(pattern string, c ControllerInterface, mappingM |
| 180 | parts[i] = string(out) | 390 | parts[i] = string(out) |
| 181 | } | 391 | } |
| 182 | } | 392 | } |
| 183 | reflectVal := reflect.ValueOf(c) | 393 | return j, params, parts |
| 184 | t := reflect.Indirect(reflectVal).Type() | ||
| 185 | methods := make(map[string]string) | ||
| 186 | if len(mappingMethods) > 0 { | ||
| 187 | semi := strings.Split(mappingMethods[0], ";") | ||
| 188 | for _, v := range semi { | ||
| 189 | colon := strings.Split(v, ":") | ||
| 190 | if len(colon) != 2 { | ||
| 191 | panic("method mapping format is invalid") | ||
| 192 | } | ||
| 193 | comma := strings.Split(colon[0], ",") | ||
| 194 | for _, m := range comma { | ||
| 195 | if m == "*" || utils.InSlice(strings.ToLower(m), HTTPMETHOD) { | ||
| 196 | if val := reflectVal.MethodByName(colon[1]); val.IsValid() { | ||
| 197 | methods[strings.ToLower(m)] = colon[1] | ||
| 198 | } else { | ||
| 199 | panic(colon[1] + " method doesn't exist in the controller " + t.Name()) | ||
| 200 | } | ||
| 201 | } else { | ||
| 202 | panic(v + " is an invalid method mapping. Method doesn't exist " + m) | ||
| 203 | } | ||
| 204 | } | ||
| 205 | } | ||
| 206 | } | ||
| 207 | if j == 0 { | ||
| 208 | //now create the Route | ||
| 209 | route := &controllerInfo{} | ||
| 210 | route.pattern = pattern | ||
| 211 | route.controllerType = t | ||
| 212 | route.methods = methods | ||
| 213 | if len(methods) > 0 { | ||
| 214 | route.hasMethod = true | ||
| 215 | } | ||
| 216 | p.fixrouters = append(p.fixrouters, route) | ||
| 217 | } else { // add regexp routers | ||
| 218 | //recreate the url pattern, with parameters replaced | ||
| 219 | //by regular expressions. then compile the regex | ||
| 220 | pattern = strings.Join(parts, "/") | ||
| 221 | regex, regexErr := regexp.Compile(pattern) | ||
| 222 | if regexErr != nil { | ||
| 223 | //TODO add error handling here to avoid panic | ||
| 224 | panic(regexErr) | ||
| 225 | } | ||
| 226 | |||
| 227 | //now create the Route | ||
| 228 | |||
| 229 | route := &controllerInfo{} | ||
| 230 | route.regex = regex | ||
| 231 | route.params = params | ||
| 232 | route.pattern = pattern | ||
| 233 | route.methods = methods | ||
| 234 | if len(methods) > 0 { | ||
| 235 | route.hasMethod = true | ||
| 236 | } | ||
| 237 | route.controllerType = t | ||
| 238 | p.routers = append(p.routers, route) | ||
| 239 | } | ||
| 240 | } | 394 | } |
| 241 | 395 | ||
| 242 | // Add auto router to ControllerRegistor. | 396 | // Add auto router to ControllerRegistor. |
| ... | @@ -501,6 +655,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) | ... | @@ -501,6 +655,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) |
| 501 | var runrouter reflect.Type | 655 | var runrouter reflect.Type |
| 502 | var findrouter bool | 656 | var findrouter bool |
| 503 | var runMethod string | 657 | var runMethod string |
| 658 | var routerInfo *controllerInfo | ||
| 504 | params := make(map[string]string) | 659 | params := make(map[string]string) |
| 505 | 660 | ||
| 506 | w := &responseWriter{writer: rw} | 661 | w := &responseWriter{writer: rw} |
| ... | @@ -584,6 +739,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) | ... | @@ -584,6 +739,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) |
| 584 | if requestPath == route.pattern { | 739 | if requestPath == route.pattern { |
| 585 | runMethod = p.getRunMethod(r.Method, context, route) | 740 | runMethod = p.getRunMethod(r.Method, context, route) |
| 586 | if runMethod != "" { | 741 | if runMethod != "" { |
| 742 | routerInfo = route | ||
| 587 | runrouter = route.controllerType | 743 | runrouter = route.controllerType |
| 588 | findrouter = true | 744 | findrouter = true |
| 589 | break | 745 | break |
| ... | @@ -598,6 +754,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) | ... | @@ -598,6 +754,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) |
| 598 | if requestPath[n-1] == '/' && route.pattern+"/" == requestPath { | 754 | if requestPath[n-1] == '/' && route.pattern+"/" == requestPath { |
| 599 | runMethod = p.getRunMethod(r.Method, context, route) | 755 | runMethod = p.getRunMethod(r.Method, context, route) |
| 600 | if runMethod != "" { | 756 | if runMethod != "" { |
| 757 | routerInfo = route | ||
| 601 | runrouter = route.controllerType | 758 | runrouter = route.controllerType |
| 602 | findrouter = true | 759 | findrouter = true |
| 603 | break | 760 | break |
| ... | @@ -636,6 +793,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) | ... | @@ -636,6 +793,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) |
| 636 | } | 793 | } |
| 637 | runMethod = p.getRunMethod(r.Method, context, route) | 794 | runMethod = p.getRunMethod(r.Method, context, route) |
| 638 | if runMethod != "" { | 795 | if runMethod != "" { |
| 796 | routerInfo = route | ||
| 639 | runrouter = route.controllerType | 797 | runrouter = route.controllerType |
| 640 | context.Input.Params = params | 798 | context.Input.Params = params |
| 641 | findrouter = true | 799 | findrouter = true |
| ... | @@ -706,7 +864,23 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) | ... | @@ -706,7 +864,23 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) |
| 706 | if do_filter(BeforeExec) { | 864 | if do_filter(BeforeExec) { |
| 707 | goto Admin | 865 | goto Admin |
| 708 | } | 866 | } |
| 867 | isRunable := false | ||
| 868 | if routerInfo != nil { | ||
| 869 | if routerInfo.routerType == routerTypeRESTFul { | ||
| 870 | if _, ok := routerInfo.methods[strings.ToLower(r.Method)]; ok { | ||
| 871 | isRunable = true | ||
| 872 | routerInfo.runfunction(context) | ||
| 873 | } else { | ||
| 874 | middleware.Exception("405", rw, r, "Method Not Allowed") | ||
| 875 | goto Admin | ||
| 876 | } | ||
| 877 | } else if routerInfo.routerType == routerTypeHandler { | ||
| 878 | isRunable = true | ||
| 879 | routerInfo.handler.ServeHTTP(rw, r) | ||
| 880 | } | ||
| 881 | } | ||
| 709 | 882 | ||
| 883 | if !isRunable { | ||
| 710 | //Invoke the request handler | 884 | //Invoke the request handler |
| 711 | vc := reflect.New(runrouter) | 885 | vc := reflect.New(runrouter) |
| 712 | execController, ok := vc.Interface().(ControllerInterface) | 886 | execController, ok := vc.Interface().(ControllerInterface) |
| ... | @@ -765,6 +939,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) | ... | @@ -765,6 +939,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) |
| 765 | 939 | ||
| 766 | // finish all runrouter. release resource | 940 | // finish all runrouter. release resource |
| 767 | execController.Finish() | 941 | execController.Finish() |
| 942 | } | ||
| 768 | 943 | ||
| 769 | //execute middleware filters | 944 | //execute middleware filters |
| 770 | if do_filter(AfterExec) { | 945 | if do_filter(AfterExec) { | ... | ... |
| ... | @@ -10,6 +10,8 @@ import ( | ... | @@ -10,6 +10,8 @@ import ( |
| 10 | "net/http" | 10 | "net/http" |
| 11 | "net/http/httptest" | 11 | "net/http/httptest" |
| 12 | "testing" | 12 | "testing" |
| 13 | |||
| 14 | "github.com/astaxie/beego/context" | ||
| 13 | ) | 15 | ) |
| 14 | 16 | ||
| 15 | type TestController struct { | 17 | type TestController struct { |
| ... | @@ -232,3 +234,47 @@ func TestAutoPrefix(t *testing.T) { | ... | @@ -232,3 +234,47 @@ func TestAutoPrefix(t *testing.T) { |
| 232 | t.Errorf("TestAutoPrefix can't run") | 234 | t.Errorf("TestAutoPrefix can't run") |
| 233 | } | 235 | } |
| 234 | } | 236 | } |
| 237 | |||
| 238 | func TestRouterGet(t *testing.T) { | ||
| 239 | r, _ := http.NewRequest("GET", "/user", nil) | ||
| 240 | w := httptest.NewRecorder() | ||
| 241 | |||
| 242 | handler := NewControllerRegistor() | ||
| 243 | handler.Get("/user", func(ctx *context.Context) { | ||
| 244 | ctx.Output.Body([]byte("Get userlist")) | ||
| 245 | }) | ||
| 246 | handler.ServeHTTP(w, r) | ||
| 247 | if w.Body.String() != "Get userlist" { | ||
| 248 | t.Errorf("TestRouterGet can't run") | ||
| 249 | } | ||
| 250 | } | ||
| 251 | |||
| 252 | func TestRouterPost(t *testing.T) { | ||
| 253 | r, _ := http.NewRequest("POST", "/user/123", nil) | ||
| 254 | w := httptest.NewRecorder() | ||
| 255 | |||
| 256 | handler := NewControllerRegistor() | ||
| 257 | handler.Post("/user/:id", func(ctx *context.Context) { | ||
| 258 | ctx.Output.Body([]byte(ctx.Input.Param(":id"))) | ||
| 259 | }) | ||
| 260 | handler.ServeHTTP(w, r) | ||
| 261 | if w.Body.String() != "123" { | ||
| 262 | t.Errorf("TestRouterPost can't run") | ||
| 263 | } | ||
| 264 | } | ||
| 265 | |||
| 266 | func sayhello(w http.ResponseWriter, r *http.Request) { | ||
| 267 | w.Write([]byte("sayhello")) | ||
| 268 | } | ||
| 269 | |||
| 270 | func TestRouterHandler(t *testing.T) { | ||
| 271 | r, _ := http.NewRequest("POST", "/sayhi", nil) | ||
| 272 | w := httptest.NewRecorder() | ||
| 273 | |||
| 274 | handler := NewControllerRegistor() | ||
| 275 | handler.Handler("/sayhi", http.HandlerFunc(sayhello)) | ||
| 276 | handler.ServeHTTP(w, r) | ||
| 277 | if w.Body.String() != "sayhello" { | ||
| 278 | t.Errorf("TestRouterHandler can't run") | ||
| 279 | } | ||
| 280 | } | ... | ... |
-
Please register or sign in to post a comment