本站源代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

107 lines
2.7KB

  1. package denco
  2. import (
  3. "net/http"
  4. )
  5. // Mux represents a multiplexer for HTTP request.
  6. type Mux struct{}
  7. // NewMux returns a new Mux.
  8. func NewMux() *Mux {
  9. return &Mux{}
  10. }
  11. // GET is shorthand of Mux.Handler("GET", path, handler).
  12. func (m *Mux) GET(path string, handler HandlerFunc) Handler {
  13. return m.Handler("GET", path, handler)
  14. }
  15. // POST is shorthand of Mux.Handler("POST", path, handler).
  16. func (m *Mux) POST(path string, handler HandlerFunc) Handler {
  17. return m.Handler("POST", path, handler)
  18. }
  19. // PUT is shorthand of Mux.Handler("PUT", path, handler).
  20. func (m *Mux) PUT(path string, handler HandlerFunc) Handler {
  21. return m.Handler("PUT", path, handler)
  22. }
  23. // HEAD is shorthand of Mux.Handler("HEAD", path, handler).
  24. func (m *Mux) HEAD(path string, handler HandlerFunc) Handler {
  25. return m.Handler("HEAD", path, handler)
  26. }
  27. // Handler returns a handler for HTTP method.
  28. func (m *Mux) Handler(method, path string, handler HandlerFunc) Handler {
  29. return Handler{
  30. Method: method,
  31. Path: path,
  32. Func: handler,
  33. }
  34. }
  35. // Build builds a http.Handler.
  36. func (m *Mux) Build(handlers []Handler) (http.Handler, error) {
  37. recordMap := make(map[string][]Record)
  38. for _, h := range handlers {
  39. recordMap[h.Method] = append(recordMap[h.Method], NewRecord(h.Path, h.Func))
  40. }
  41. mux := newServeMux()
  42. for m, records := range recordMap {
  43. router := New()
  44. if err := router.Build(records); err != nil {
  45. return nil, err
  46. }
  47. mux.routers[m] = router
  48. }
  49. return mux, nil
  50. }
  51. // Handler represents a handler of HTTP request.
  52. type Handler struct {
  53. // Method is an HTTP method.
  54. Method string
  55. // Path is a routing path for handler.
  56. Path string
  57. // Func is a function of handler of HTTP request.
  58. Func HandlerFunc
  59. }
  60. // The HandlerFunc type is aliased to type of handler function.
  61. type HandlerFunc func(w http.ResponseWriter, r *http.Request, params Params)
  62. type serveMux struct {
  63. routers map[string]*Router
  64. }
  65. func newServeMux() *serveMux {
  66. return &serveMux{
  67. routers: make(map[string]*Router),
  68. }
  69. }
  70. // ServeHTTP implements http.Handler interface.
  71. func (mux *serveMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  72. handler, params := mux.handler(r.Method, r.URL.Path)
  73. handler(w, r, params)
  74. }
  75. func (mux *serveMux) handler(method, path string) (HandlerFunc, []Param) {
  76. if router, found := mux.routers[method]; found {
  77. if handler, params, found := router.Lookup(path); found {
  78. return handler.(HandlerFunc), params
  79. }
  80. }
  81. return NotFound, nil
  82. }
  83. // NotFound replies to the request with an HTTP 404 not found error.
  84. // NotFound is called when unknown HTTP method or a handler not found.
  85. // If you want to use the your own NotFound handler, please overwrite this variable.
  86. var NotFound = func(w http.ResponseWriter, r *http.Request, _ Params) {
  87. http.NotFound(w, r)
  88. }
上海开阖软件有限公司 沪ICP备12045867号-1