-
Notifications
You must be signed in to change notification settings - Fork 1
/
url_matcher.go
66 lines (56 loc) · 1.27 KB
/
url_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
package mux
import (
"errors"
"net/http"
)
type paramsGetter struct{}
type ParamsMap = map[string]string
func Params(r *http.Request) ParamsMap {
return r.Context().Value(paramsGetter{}).(ParamsMap)
}
func urlMatchesPattern(pattern, url string, paramsMap ParamsMap) (bool, ParamsMap, error) {
if pattern == "" || url == "" {
return false, nil, errors.New("both pattern and url required")
}
patternLen := len(pattern)
urlLen := len(url)
var i, j, paramStart int
// Clear the map without reallocating
for k := range paramsMap {
delete(paramsMap, k)
}
for i < patternLen && j < urlLen {
if pattern[i] == '{' {
paramStart = i + 1
for i < patternLen && pattern[i] != '}' {
i++
}
if i == patternLen {
return false, nil, errors.New("invalid pattern: unclosed '{'")
}
key := pattern[paramStart:i]
valueStart := j
for j < urlLen && url[j] != '/' {
j++
}
paramsMap[key] = url[valueStart:j]
i++ // Skip closing '}'
} else if pattern[i] == '/' {
if url[j] != '/' {
return false, nil, nil
}
i++
j++
} else {
if i == patternLen || j == urlLen || pattern[i] != url[j] {
return false, nil, nil
}
i++
j++
}
}
if i != patternLen || j != urlLen {
return false, nil, nil
}
return true, paramsMap, nil
}