-
Notifications
You must be signed in to change notification settings - Fork 0
/
route.go
80 lines (67 loc) · 1.48 KB
/
route.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
package gopcp_service
import (
"fmt"
"log"
"net/http"
"regexp"
)
type HTTPHandler func(http.ResponseWriter, *http.Request)
type Route struct {
URLPattern *regexp.Regexp
Handler HTTPHandler
MethodsSupported map[string]bool
}
type Router struct {
Routes []Route
}
func NewRoute(
pattern string,
handler HTTPHandler,
methods map[string]bool,
) Route {
route := Route{}
compiledPattern := regexp.MustCompile(pattern)
route.URLPattern = compiledPattern
route.Handler = handler
route.MethodsSupported = methods
return route
}
func (r Route) Match(req *http.Request) bool {
match := r.URLPattern.FindStringSubmatch(req.URL.Path)
if len(match) > 0 {
for i, name := range r.URLPattern.SubexpNames() {
if i != 0 && name != "" {
req.Form.Add(name, match[i])
}
}
return true
} else {
return false
}
}
func (r Route) Handle(w http.ResponseWriter, req *http.Request) {
if val, ok := r.MethodsSupported[req.Method]; ok && val == true {
r.Handler(w, req)
} else {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("Unsupported method: " + req.Method))
}
}
func (r Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
log.Printf("access %s", req.URL)
defer func() {
if r := recover(); r != nil {
fmt.Printf("Recovered in %s", r)
}
}()
for _, route := range r.Routes {
if route.Match(req) {
route.Handle(w, req)
return
}
}
http.NotFound(w, req)
}
func GetRouter(routes []Route) Router {
return Router{routes}
}