-
Notifications
You must be signed in to change notification settings - Fork 102
/
bone.go
91 lines (80 loc) · 2.4 KB
/
bone.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
/********************************
*** Multiplexer for Go ***
*** Bone is under MIT license ***
*** Code by CodingFerret ***
*** github.com/go-zoo ***
*********************************/
package bone
import (
"net/http"
"strings"
)
// Mux have routes and a notFound handler
// Route: all the registred route
// notFound: 404 handler, default http.NotFound if not provided
type Mux struct {
Routes map[string][]*Route
prefix string
notFound http.Handler
Validators map[string]Validator
Serve func(rw http.ResponseWriter, req *http.Request)
CaseSensitive bool
}
var (
static = "static"
method = []string{"GET", "POST", "PUT", "DELETE", "HEAD", "PATCH", "OPTIONS"}
)
type adapter func(*Mux) *Mux
// New create a pointer to a Mux instance
func New(adapters ...adapter) *Mux {
m := &Mux{Routes: make(map[string][]*Route), Serve: nil, CaseSensitive: true}
for _, adap := range adapters {
adap(m)
}
if m.Serve == nil {
m.Serve = m.DefaultServe
}
return m
}
// RegisterValidatorFunc makes the provided function available to the routes register on that mux as a validator
func (m *Mux) RegisterValidatorFunc(name string, validator func(string) bool) {
if m.Validators == nil {
m.Validators = make(map[string]Validator)
}
m.Validators[name] = newValidatorFunc(validator)
}
// RegisterValidator makes the provided validator available to the routes register on that mux
func (m *Mux) RegisterValidator(name string, validator Validator) {
if m.Validators == nil {
m.Validators = make(map[string]Validator)
}
m.Validators[name] = validator
}
// Prefix set a default prefix for all routes registred on the router
func (m *Mux) Prefix(p string) *Mux {
m.prefix = strings.TrimSuffix(p, "/")
return m
}
// DefaultServe is the default http request handler
func (m *Mux) DefaultServe(rw http.ResponseWriter, req *http.Request) {
// Check if a route match
if !m.parse(rw, req) {
// Check if it's a static ressource
if !m.staticRoute(rw, req) {
// Check if the request path doesn't end with /
if !m.validate(rw, req) {
// Check if same route exists for another HTTP method
if !m.otherMethods(rw, req) {
m.HandleNotFound(rw, req)
}
}
}
}
}
// ServeHTTP pass the request to the serve method of Mux
func (m *Mux) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
if !m.CaseSensitive {
req.URL.Path = strings.ToLower(req.URL.Path)
}
m.Serve(rw, req)
}