...
1 package middleware
2
3 import (
4 "net/http"
5 "strings"
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 func RouteHeaders() HeaderRouter {
48 return HeaderRouter{}
49 }
50
51 type HeaderRouter map[string][]HeaderRoute
52
53 func (hr HeaderRouter) Route(header string, match string, middlewareHandler func(next http.Handler) http.Handler) HeaderRouter {
54 header = strings.ToLower(header)
55 k := hr[header]
56 if k == nil {
57 hr[header] = []HeaderRoute{}
58 }
59 hr[header] = append(hr[header], HeaderRoute{MatchOne: NewPattern(match), Middleware: middlewareHandler})
60 return hr
61 }
62
63 func (hr HeaderRouter) RouteAny(header string, match []string, middlewareHandler func(next http.Handler) http.Handler) HeaderRouter {
64 header = strings.ToLower(header)
65 k := hr[header]
66 if k == nil {
67 hr[header] = []HeaderRoute{}
68 }
69 patterns := []Pattern{}
70 for _, m := range match {
71 patterns = append(patterns, NewPattern(m))
72 }
73 hr[header] = append(hr[header], HeaderRoute{MatchAny: patterns, Middleware: middlewareHandler})
74 return hr
75 }
76
77 func (hr HeaderRouter) RouteDefault(handler func(next http.Handler) http.Handler) HeaderRouter {
78 hr["*"] = []HeaderRoute{{Middleware: handler}}
79 return hr
80 }
81
82 func (hr HeaderRouter) Handler(next http.Handler) http.Handler {
83 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
84 if len(hr) == 0 {
85
86 next.ServeHTTP(w, r)
87 }
88
89
90 for header, matchers := range hr {
91 headerValue := r.Header.Get(header)
92 if headerValue == "" {
93 continue
94 }
95 headerValue = strings.ToLower(headerValue)
96 for _, matcher := range matchers {
97 if matcher.IsMatch(headerValue) {
98 matcher.Middleware(next).ServeHTTP(w, r)
99 return
100 }
101 }
102 }
103
104
105 matcher, ok := hr["*"]
106 if !ok || matcher[0].Middleware == nil {
107 next.ServeHTTP(w, r)
108 return
109 }
110 matcher[0].Middleware(next).ServeHTTP(w, r)
111 })
112 }
113
114 type HeaderRoute struct {
115 MatchAny []Pattern
116 MatchOne Pattern
117 Middleware func(next http.Handler) http.Handler
118 }
119
120 func (r HeaderRoute) IsMatch(value string) bool {
121 if len(r.MatchAny) > 0 {
122 for _, m := range r.MatchAny {
123 if m.Match(value) {
124 return true
125 }
126 }
127 } else if r.MatchOne.Match(value) {
128 return true
129 }
130 return false
131 }
132
133 type Pattern struct {
134 prefix string
135 suffix string
136 wildcard bool
137 }
138
139 func NewPattern(value string) Pattern {
140 p := Pattern{}
141 if i := strings.IndexByte(value, '*'); i >= 0 {
142 p.wildcard = true
143 p.prefix = value[0:i]
144 p.suffix = value[i+1:]
145 } else {
146 p.prefix = value
147 }
148 return p
149 }
150
151 func (p Pattern) Match(v string) bool {
152 if !p.wildcard {
153 if p.prefix == v {
154 return true
155 } else {
156 return false
157 }
158 }
159 return len(v) >= len(p.prefix+p.suffix) && strings.HasPrefix(v, p.prefix) && strings.HasSuffix(v, p.suffix)
160 }
161
View as plain text