forked from goadesign/goa
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mux.go
101 lines (88 loc) · 3.5 KB
/
mux.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package goa
import (
"net/http"
"net/url"
"github.com/dimfeld/httptreemux"
)
type (
// MuxHandler provides the low level implementation for an API endpoint.
// The values argument includes both the querystring and path parameter values.
MuxHandler func(http.ResponseWriter, *http.Request, url.Values)
// MethodNotAllowedHandler provides the implementation for an MethodNotAllowed
// handler. The values argument includes both the querystring and path parameter
// values. The methods argument includes both the allowed method identifier
// and the registered handler.
MethodNotAllowedHandler func(http.ResponseWriter, *http.Request, url.Values, map[string]httptreemux.HandlerFunc)
// ServeMux is the interface implemented by the service request muxes.
// It implements http.Handler and makes it possible to register request handlers for
// specific HTTP methods and request path via the Handle method.
ServeMux interface {
http.Handler
// Handle sets the MuxHandler for a given HTTP method and path.
Handle(method, path string, handle MuxHandler)
// HandleNotFound sets the MuxHandler invoked for requests that don't match any
// handler registered with Handle. The values argument given to the handler is
// always nil.
HandleNotFound(handle MuxHandler)
// HandleMethodNotAllowed sets the MethodNotAllowedHandler invoked for requests
// that match the path of a handler but not its HTTP method. The values argument
// given to the Handler is always nil.
HandleMethodNotAllowed(handle MethodNotAllowedHandler)
// Lookup returns the MuxHandler associated with the given HTTP method and path.
Lookup(method, path string) MuxHandler
}
// Muxer implements an adapter that given a request handler can produce a mux handler.
Muxer interface {
MuxHandler(string, Handler, Unmarshaler) MuxHandler
}
// mux is the default ServeMux implementation.
mux struct {
router *httptreemux.TreeMux
handles map[string]MuxHandler
}
)
// NewMux returns a Mux.
func NewMux() ServeMux {
r := httptreemux.New()
r.EscapeAddedRoutes = true
return &mux{
router: r,
handles: make(map[string]MuxHandler),
}
}
// Handle sets the handler for the given verb and path.
func (m *mux) Handle(method, path string, handle MuxHandler) {
hthandle := func(rw http.ResponseWriter, req *http.Request, htparams map[string]string) {
params := req.URL.Query()
for n, p := range htparams {
params.Set(n, p)
}
handle(rw, req, params)
}
m.handles[method+path] = handle
m.router.Handle(method, path, hthandle)
}
// HandleNotFound sets the MuxHandler invoked for requests that don't match any
// handler registered with Handle.
func (m *mux) HandleNotFound(handle MuxHandler) {
nfh := func(rw http.ResponseWriter, req *http.Request) {
handle(rw, req, nil)
}
m.router.NotFoundHandler = nfh
}
// HandleMethodNotAllowed sets the MuxHandler invoked for requests that match
// the path of a handler but not its HTTP method.
func (m *mux) HandleMethodNotAllowed(handle MethodNotAllowedHandler) {
mna := func(rw http.ResponseWriter, req *http.Request, methods map[string]httptreemux.HandlerFunc) {
handle(rw, req, nil, methods)
}
m.router.MethodNotAllowedHandler = mna
}
// Lookup returns the MuxHandler associated with the given method and path.
func (m *mux) Lookup(method, path string) MuxHandler {
return m.handles[method+path]
}
// ServeHTTP is the function called back by the underlying HTTP server to handle incoming requests.
func (m *mux) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
m.router.ServeHTTP(rw, req)
}