-
Notifications
You must be signed in to change notification settings - Fork 103
/
servmux.go
94 lines (81 loc) · 2.06 KB
/
servmux.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
package coap
import (
"net"
)
// ServeMux provides mappings from a common endpoint to handlers by
// request path.
type ServeMux struct {
m map[string]muxEntry
}
type muxEntry struct {
h Handler
pattern string
}
// NewServeMux creates a new ServeMux.
func NewServeMux() *ServeMux { return &ServeMux{m: make(map[string]muxEntry)} }
// Does path match pattern?
func pathMatch(pattern, path string) bool {
if len(pattern) == 0 {
// should not happen
return false
}
n := len(pattern)
if pattern[n-1] != '/' {
return pattern == path
}
return len(path) >= n && path[0:n] == pattern
}
// Find a handler on a handler map given a path string
// Most-specific (longest) pattern wins
func (mux *ServeMux) match(path string) (h Handler, pattern string) {
var n = 0
for k, v := range mux.m {
if !pathMatch(k, path) {
continue
}
if h == nil || len(k) > n {
n = len(k)
h = v.h
pattern = v.pattern
}
}
return
}
func notFoundHandler(l *net.UDPConn, a *net.UDPAddr, m *Message) *Message {
if m.IsConfirmable() {
return &Message{
Type: Acknowledgement,
Code: NotFound,
}
}
return nil
}
var _ = Handler(&ServeMux{})
// ServeCOAP handles a single COAP message. The message arrives from
// the given listener having originated from the given UDPAddr.
func (mux *ServeMux) ServeCOAP(l *net.UDPConn, a *net.UDPAddr, m *Message) *Message {
h, _ := mux.match(m.PathString())
if h == nil {
h, _ = funcHandler(notFoundHandler), ""
}
// TODO: Rewrite path?
return h.ServeCOAP(l, a, m)
}
// Handle configures a handler for the given path.
func (mux *ServeMux) Handle(pattern string, handler Handler) {
for pattern != "" && pattern[0] == '/' {
pattern = pattern[1:]
}
if pattern == "" {
panic("http: invalid pattern " + pattern)
}
if handler == nil {
panic("http: nil handler")
}
mux.m[pattern] = muxEntry{h: handler, pattern: pattern}
}
// HandleFunc configures a handler for the given path.
func (mux *ServeMux) HandleFunc(pattern string,
f func(l *net.UDPConn, a *net.UDPAddr, m *Message) *Message) {
mux.Handle(pattern, FuncHandler(f))
}