This repository has been archived by the owner on Jan 1, 2023. It is now read-only.
/
matcher.go
105 lines (86 loc) · 1.87 KB
/
matcher.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
package gorilla
import (
"strings"
)
type artifact struct {
path string
pathTerminated bool
methodSet map[string]struct{}
isInvalid bool
}
func newArtifact() *artifact {
return &artifact{
path: "/",
pathTerminated: false,
methodSet: nil,
isInvalid: false,
}
}
type matcher interface {
Process(art *artifact)
}
type pathMatcher struct {
path string
}
func newPathMatcher(path string) pathMatcher {
return pathMatcher{
path: path,
}
}
func (matcher pathMatcher) Process(art *artifact) {
if art.isInvalid || art.pathTerminated {
art.isInvalid = true
return
}
art.path = strings.TrimRight(art.path, "/") + strings.TrimRight(matcher.path, "/")
if art.path == "" {
art.path = "/"
}
art.pathTerminated = true
}
type pathPrefixMatcher struct {
pathPrefix string
}
func newPathPrefixMatcher(pathPrefix string) pathPrefixMatcher {
return pathPrefixMatcher{
pathPrefix: pathPrefix,
}
}
func (matcher pathPrefixMatcher) Process(art *artifact) {
if art.isInvalid || art.pathTerminated {
art.isInvalid = true
return
}
art.path = strings.TrimRight(art.path, "/") + strings.TrimRight(matcher.pathPrefix, "/")
if art.path == "" {
art.path = "/"
}
}
type methodsMatcher struct {
methodSet map[string]struct{}
}
func newMethodsMatcher(methodList []string) methodsMatcher {
methodSet := map[string]struct{}{}
for _, method := range methodList {
methodSet[strings.ToUpper(method)] = struct{}{}
}
return methodsMatcher{
methodSet: methodSet,
}
}
func (matcher methodsMatcher) Process(art *artifact) {
if art.isInvalid {
return
}
if art.methodSet == nil {
art.methodSet = matcher.methodSet
art.isInvalid = len(art.methodSet) == 0
return
}
for method := range art.methodSet {
if _, ok := matcher.methodSet[method]; !ok {
delete(art.methodSet, method)
}
}
art.isInvalid = len(art.methodSet) == 0
}