-
Notifications
You must be signed in to change notification settings - Fork 1
/
router.go
109 lines (86 loc) · 1.93 KB
/
router.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
102
103
104
105
106
107
108
109
package wenex
import (
"net/http"
"net/url"
"strings"
)
func newRouter() *Router {
return &Router{
method: make(map[string][]*Chain),
}
}
// Router struct
type Router struct {
method map[string][]*Chain
}
// StrictRoute routing binds expression to the end of line
func (r *Router) StrictRoute(pattern string, methods ...string) *Chain {
return r.route(true, pattern, methods)
}
// WeakRoute routing don't binds expression to the end of line
func (r *Router) WeakRoute(pattern string, methods ...string) *Chain {
return r.route(false, pattern, methods)
}
func (r *Router) route(strict bool, pattern string, methods []string) *Chain {
c := &Chain{
strict: strict,
pattern: r.parse(pattern),
}
c.lenPattern = len(c.pattern)
for _, method := range methods {
r.method[method] = append(r.method[method], c)
}
return c
}
func (r *Router) parse(pattern string) []string {
if pattern == "" || pattern[0] != '/' {
pattern = "/" + pattern
}
return strings.Split(pattern, "/")
}
func (r *Router) match(re *http.Request) []http.Handler {
path := strings.Split(re.URL.EscapedPath(), "/")
lenPath := len(path)
for _, chain := range r.method[re.Method] {
if chain.lenPattern > lenPath {
continue
}
if chain.strict && chain.lenPattern < lenPath {
continue
}
query := url.Values{}
var i int
var pattern string
for i, pattern = range chain.pattern {
if pattern == path[i] {
continue
}
if path[i] != "" {
if pattern == "*" {
continue
}
if pattern == "" {
if !chain.strict {
continue
}
} else if pattern[0] == ':' {
query.Add(pattern[1:], path[i])
continue
}
}
i--
break
}
if i == chain.lenPattern-1 {
if len(query) != 0 {
if re.URL.RawQuery == "" {
re.URL.RawQuery = query.Encode()
} else {
re.URL.RawQuery += "&" + query.Encode()
}
}
return chain.handler
}
}
return []http.Handler{http.NotFoundHandler()}
}