-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpattern.go
88 lines (73 loc) · 1.75 KB
/
pattern.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
package gohf
import (
"errors"
"fmt"
"strings"
)
// net/http pattern syntax: [METHOD] [HOST]/[PATH]
// METHOD, HOST and PATH are all optional; that is, the string can be "/".
type pattern struct {
method string
host string
path string
}
func parsePattern(s string) (pattern, error) {
var pat pattern
rest := strings.TrimSpace(s)
if len(rest) == 0 {
return pat, errors.New("empty pattern")
}
var method, host, path string
if i := strings.IndexAny(rest, " \t"); i >= 0 {
method, rest = rest[:i], strings.TrimLeft(rest[i+1:], " \t")
}
if i := strings.IndexByte(rest, '/'); i >= 0 {
host, path = rest[:i], rest[i+1:]
} else {
return pat, fmt.Errorf("invalid pattern: host/path missing \"/\". received: \"%s\"", s)
}
pat.method = method
pat.host = host
pat.path = path
return pat, nil
}
func (pat pattern) String() string {
var s string
if pat.method != "" {
s = pat.method + " "
}
s += pat.host + "/"
s += strings.TrimLeft(pat.path, "/")
return s
}
func mergePattern(p1, p2 pattern) (pattern, error) {
var pat pattern
var method, host, path string
if p1.method != "" && p2.method != "" && p1.method != p2.method {
return pat, fmt.Errorf("method conflict: \"%s\" and \"%s\"", p1.method, p2.method)
}
if p1.host != "" && p2.host != "" && p1.host != p2.host {
return pat, fmt.Errorf("host conflict: \"%s\" and \"%s\"", p1.host, p2.host)
}
if p1.method != "" {
method = p1.method
} else {
method = p2.method
}
if p1.host != "" {
host = p1.host
} else {
host = p2.host
}
if p1.path == "" {
path = p2.path
} else if p2.path == "" {
path = p1.path
} else {
path = strings.TrimRight(p1.path, "/") + "/" + strings.TrimLeft(p2.path, "/")
}
pat.method = method
pat.host = host
pat.path = path
return pat, nil
}