path.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. package ss
  2. import (
  3. "strings"
  4. //"fmt"
  5. //"path"
  6. )
  7. // The type implements path routing for requests.
  8. type PathRouter struct {
  9. pathMap map[string] Handler
  10. def Handler
  11. }
  12. // Returns new empty PathRouter with the def
  13. // specified as the default fallback.
  14. func Path(def Handler) *PathRouter {
  15. ret := &PathRouter{}
  16. ret.pathMap = map[string] Handler{}
  17. ret.def = def
  18. return ret
  19. }
  20. // Define new handler for the specified path.
  21. // The defined path must not contain slashes and will panic otherwise.
  22. func (router *PathRouter) Case(pth string, handler Handler) *PathRouter {
  23. _, dup := router.pathMap[pth]
  24. if dup {
  25. panic(DupDefErr)
  26. }
  27. router.pathMap[pth] = handler
  28. return router
  29. }
  30. // Implementing the Handler.
  31. func (router *PathRouter) Handle(c *Context) {
  32. pth := c.Path()
  33. var splits []string
  34. var name, rest string
  35. if len(pth)>0 && pth[0] == '/' { // Handling the root path.
  36. splits = strings.SplitN(pth, "/", 3)
  37. if len(splits) > 1 {
  38. name = splits[1]
  39. }
  40. if len(splits) > 2 {
  41. rest = splits[2]
  42. }
  43. } else { // Handling the relative path. (second or n-th call)
  44. splits = strings.SplitN(pth, "/", 2)
  45. if len(splits) > 0 {
  46. name = splits[0]
  47. }
  48. if len(splits) > 1 {
  49. rest = splits[1]
  50. }
  51. }
  52. handler, ok := router.pathMap[name]
  53. if !ok {
  54. if router.def == nil {
  55. c.NotFound()
  56. } else {
  57. router.def.Handle(c)
  58. }
  59. return
  60. }
  61. c.RelUrl.Path = rest
  62. handler.Handle(c)
  63. }