b6f789c4 by Bill Davis

Changes to handle multi filters on execution pt

1 parent aae89576
...@@ -318,9 +318,10 @@ func DelStaticPath(url string) *App { ...@@ -318,9 +318,10 @@ func DelStaticPath(url string) *App {
318 318
319 // InsertFilter adds a FilterFunc with pattern condition and action constant. 319 // InsertFilter adds a FilterFunc with pattern condition and action constant.
320 // The pos means action constant including 320 // The pos means action constant including
321 // beego.BeforeRouter, beego.AfterStatic, beego.BeforeExec, beego.AfterExec and beego.FinishRouter. 321 // beego.BeforeStatic, beego.BeforeRouter, beego.BeforeExec, beego.AfterExec and beego.FinishRouter.
322 func InsertFilter(pattern string, pos int, filter FilterFunc) *App { 322 // The bool params is for setting the returnOnOutput value (false allows multiple filters to execute)
323 BeeApp.Handlers.InsertFilter(pattern, pos, filter) 323 func InsertFilter(pattern string, pos int, filter FilterFunc, params ...bool) *App {
324 BeeApp.Handlers.InsertFilter(pattern, pos, filter, params...)
324 return BeeApp 325 return BeeApp
325 } 326 }
326 327
......
...@@ -17,9 +17,10 @@ package beego ...@@ -17,9 +17,10 @@ package beego
17 // FilterRouter defines filter operation before controller handler execution. 17 // FilterRouter defines filter operation before controller handler execution.
18 // it can match patterned url and do filter function when action arrives. 18 // it can match patterned url and do filter function when action arrives.
19 type FilterRouter struct { 19 type FilterRouter struct {
20 filterFunc FilterFunc 20 filterFunc FilterFunc
21 tree *Tree 21 tree *Tree
22 pattern string 22 pattern string
23 returnOnOutput bool
23 } 24 }
24 25
25 // ValidRouter check current request is valid for this filter. 26 // ValidRouter check current request is valid for this filter.
......
...@@ -381,7 +381,9 @@ func (p *ControllerRegistor) AddAutoPrefix(prefix string, c ControllerInterface) ...@@ -381,7 +381,9 @@ func (p *ControllerRegistor) AddAutoPrefix(prefix string, c ControllerInterface)
381 } 381 }
382 382
383 // Add a FilterFunc with pattern rule and action constant. 383 // Add a FilterFunc with pattern rule and action constant.
384 func (p *ControllerRegistor) InsertFilter(pattern string, pos int, filter FilterFunc) error { 384 // The bool params is for setting the returnOnOutput value (false allows multiple filters to execute)
385 func (p *ControllerRegistor) InsertFilter(pattern string, pos int, filter FilterFunc, params ...bool) error {
386
385 mr := new(FilterRouter) 387 mr := new(FilterRouter)
386 mr.tree = NewTree() 388 mr.tree = NewTree()
387 mr.pattern = pattern 389 mr.pattern = pattern
...@@ -389,6 +391,11 @@ func (p *ControllerRegistor) InsertFilter(pattern string, pos int, filter Filter ...@@ -389,6 +391,11 @@ func (p *ControllerRegistor) InsertFilter(pattern string, pos int, filter Filter
389 if !RouterCaseSensitive { 391 if !RouterCaseSensitive {
390 pattern = strings.ToLower(pattern) 392 pattern = strings.ToLower(pattern)
391 } 393 }
394 if params == nil {
395 mr.returnOnOutput = true
396 } else {
397 mr.returnOnOutput = params[0]
398 }
392 mr.tree.AddRouter(pattern, true) 399 mr.tree.AddRouter(pattern, true)
393 return p.insertFilterRouter(pos, mr) 400 return p.insertFilterRouter(pos, mr)
394 } 401 }
...@@ -587,7 +594,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) ...@@ -587,7 +594,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
587 if ok, p := filterR.ValidRouter(urlPath); ok { 594 if ok, p := filterR.ValidRouter(urlPath); ok {
588 context.Input.Params = p 595 context.Input.Params = p
589 filterR.filterFunc(context) 596 filterR.filterFunc(context)
590 if w.started { 597 if filterR.returnOnOutput && w.started {
591 return true 598 return true
592 } 599 }
593 } 600 }
......
...@@ -17,6 +17,7 @@ package beego ...@@ -17,6 +17,7 @@ package beego
17 import ( 17 import (
18 "net/http" 18 "net/http"
19 "net/http/httptest" 19 "net/http/httptest"
20 "strings"
20 "testing" 21 "testing"
21 22
22 "github.com/astaxie/beego/context" 23 "github.com/astaxie/beego/context"
...@@ -385,3 +386,196 @@ func testRequest(method, path string) (*httptest.ResponseRecorder, *http.Request ...@@ -385,3 +386,196 @@ func testRequest(method, path string) (*httptest.ResponseRecorder, *http.Request
385 386
386 return recorder, request 387 return recorder, request
387 } 388 }
389
390 // Execution point: BeforeRouter
391 // expectation: only BeforeRouter function is executed, notmatch output as router doesn't handle
392 func TestFilterBeforeRouter(t *testing.T) {
393 testName := "TestFilterBeforeRouter"
394 url := "/beforeRouter"
395
396 mux := NewControllerRegister()
397 mux.InsertFilter(url, BeforeRouter, beegoBeforeRouter1)
398
399 mux.Get(url, beegoFilterFunc)
400
401 rw, r := testRequest("GET", url)
402 mux.ServeHTTP(rw, r)
403
404 if strings.Contains(rw.Body.String(), "BeforeRouter1") == false {
405 t.Errorf(testName + " BeforeRouter did not run")
406 }
407 if strings.Contains(rw.Body.String(), "hello") == true {
408 t.Errorf(testName + " BeforeRouter did not return properly")
409 }
410 }
411
412 // Execution point: BeforeExec
413 // expectation: only BeforeExec function is executed, match as router determines route only
414 func TestFilterBeforeExec(t *testing.T) {
415 testName := "TestFilterBeforeExec"
416 url := "/beforeExec"
417
418 mux := NewControllerRegister()
419 mux.InsertFilter(url, BeforeRouter, beegoFilterNoOutput)
420 mux.InsertFilter(url, BeforeExec, beegoBeforeExec1)
421
422 mux.Get(url, beegoFilterFunc)
423
424 rw, r := testRequest("GET", url)
425 mux.ServeHTTP(rw, r)
426
427 if strings.Contains(rw.Body.String(), "BeforeExec1") == false {
428 t.Errorf(testName + " BeforeExec did not run")
429 }
430 if strings.Contains(rw.Body.String(), "hello") == true {
431 t.Errorf(testName + " BeforeExec did not return properly")
432 }
433 if strings.Contains(rw.Body.String(), "BeforeRouter") == true {
434 t.Errorf(testName + " BeforeRouter ran in error")
435 }
436 }
437
438 // Execution point: AfterExec
439 // expectation: only AfterExec function is executed, match as router handles
440 func TestFilterAfterExec(t *testing.T) {
441 testName := "TestFilterAfterExec"
442 url := "/afterExec"
443
444 mux := NewControllerRegister()
445 mux.InsertFilter(url, BeforeRouter, beegoFilterNoOutput)
446 mux.InsertFilter(url, BeforeExec, beegoFilterNoOutput)
447 mux.InsertFilter(url, AfterExec, beegoAfterExec1)
448
449 mux.Get(url, beegoFilterFunc)
450
451 rw, r := testRequest("GET", url)
452 mux.ServeHTTP(rw, r)
453
454 if strings.Contains(rw.Body.String(), "AfterExec1") == false {
455 t.Errorf(testName + " AfterExec did not run")
456 }
457 if strings.Contains(rw.Body.String(), "hello") == false {
458 t.Errorf(testName + " handler did not run properly")
459 }
460 if strings.Contains(rw.Body.String(), "BeforeRouter") == true {
461 t.Errorf(testName + " BeforeRouter ran in error")
462 }
463 if strings.Contains(rw.Body.String(), "BeforeExec") == true {
464 t.Errorf(testName + " BeforeExec ran in error")
465 }
466 }
467
468 // Execution point: FinishRouter
469 // expectation: only FinishRouter function is executed, match as router handles
470 func TestFilterFinishRouter(t *testing.T) {
471 testName := "TestFilterFinishRouter"
472 url := "/finishRouter"
473
474 mux := NewControllerRegister()
475 mux.InsertFilter(url, BeforeRouter, beegoFilterNoOutput)
476 mux.InsertFilter(url, BeforeExec, beegoFilterNoOutput)
477 mux.InsertFilter(url, AfterExec, beegoFilterNoOutput)
478 mux.InsertFilter(url, FinishRouter, beegoFinishRouter1)
479
480 mux.Get(url, beegoFilterFunc)
481
482 rw, r := testRequest("GET", url)
483 mux.ServeHTTP(rw, r)
484
485 if strings.Contains(rw.Body.String(), "FinishRouter1") == true {
486 t.Errorf(testName + " FinishRouter did not run")
487 }
488 if strings.Contains(rw.Body.String(), "hello") == false {
489 t.Errorf(testName + " handler did not run properly")
490 }
491 if strings.Contains(rw.Body.String(), "AfterExec1") == true {
492 t.Errorf(testName + " AfterExec ran in error")
493 }
494 if strings.Contains(rw.Body.String(), "BeforeRouter") == true {
495 t.Errorf(testName + " BeforeRouter ran in error")
496 }
497 if strings.Contains(rw.Body.String(), "BeforeExec") == true {
498 t.Errorf(testName + " BeforeExec ran in error")
499 }
500 }
501
502 // Execution point: FinishRouter
503 // expectation: only first FinishRouter function is executed, match as router handles
504 func TestFilterFinishRouterMultiFirstOnly(t *testing.T) {
505 testName := "TestFilterFinishRouterMultiFirstOnly"
506 url := "/finishRouterMultiFirstOnly"
507
508 mux := NewControllerRegister()
509 mux.InsertFilter(url, FinishRouter, beegoFinishRouter1)
510 mux.InsertFilter(url, FinishRouter, beegoFinishRouter2)
511
512 mux.Get(url, beegoFilterFunc)
513
514 rw, r := testRequest("GET", url)
515 mux.ServeHTTP(rw, r)
516
517 if strings.Contains(rw.Body.String(), "FinishRouter1") == false {
518 t.Errorf(testName + " FinishRouter1 did not run")
519 }
520 if strings.Contains(rw.Body.String(), "hello") == false {
521 t.Errorf(testName + " handler did not run properly")
522 }
523 // not expected in body
524 if strings.Contains(rw.Body.String(), "FinishRouter2") == true {
525 t.Errorf(testName + " FinishRouter2 did run")
526 }
527 }
528
529 // Execution point: FinishRouter
530 // expectation: both FinishRouter functions execute, match as router handles
531 func TestFilterFinishRouterMulti(t *testing.T) {
532 testName := "TestFilterFinishRouterMulti"
533 url := "/finishRouterMulti"
534
535 mux := NewControllerRegister()
536 mux.InsertFilter(url, FinishRouter, beegoFinishRouter1, false)
537 mux.InsertFilter(url, FinishRouter, beegoFinishRouter2)
538
539 mux.Get(url, beegoFilterFunc)
540
541 rw, r := testRequest("GET", url)
542 mux.ServeHTTP(rw, r)
543
544 if strings.Contains(rw.Body.String(), "FinishRouter1") == false {
545 t.Errorf(testName + " FinishRouter1 did not run")
546 }
547 if strings.Contains(rw.Body.String(), "hello") == false {
548 t.Errorf(testName + " handler did not run properly")
549 }
550 if strings.Contains(rw.Body.String(), "FinishRouter2") == false {
551 t.Errorf(testName + " FinishRouter2 did not run properly")
552 }
553 }
554
555 func beegoFilterNoOutput(ctx *context.Context) {
556 return
557 }
558 func beegoBeforeRouter1(ctx *context.Context) {
559 ctx.WriteString("|BeforeRouter1")
560 }
561 func beegoBeforeRouter2(ctx *context.Context) {
562 ctx.WriteString("|BeforeRouter2")
563 }
564 func beegoBeforeExec1(ctx *context.Context) {
565 ctx.WriteString("|BeforeExec1")
566 }
567 func beegoBeforeExec2(ctx *context.Context) {
568 ctx.WriteString("|BeforeExec2")
569 }
570 func beegoAfterExec1(ctx *context.Context) {
571 ctx.WriteString("|AfterExec1")
572 }
573 func beegoAfterExec2(ctx *context.Context) {
574 ctx.WriteString("|AfterExec2")
575 }
576 func beegoFinishRouter1(ctx *context.Context) {
577 ctx.WriteString("|FinishRouter1")
578 }
579 func beegoFinishRouter2(ctx *context.Context) {
580 ctx.WriteString("|FinishRouter2")
581 }
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!