...
1 package rulesfn
2
3 import (
4 "fmt"
5 "net"
6 "net/url"
7 "strings"
8
9 smithyhttp "github.com/aws/smithy-go/transport/http"
10 )
11
12
13
14
15
16
17
18 func IsValidHostLabel(input string, allowSubDomains bool) bool {
19 var labels []string
20 if allowSubDomains {
21 labels = strings.Split(input, ".")
22 } else {
23 labels = []string{input}
24 }
25
26 for _, label := range labels {
27 if !smithyhttp.ValidHostLabel(label) {
28 return false
29 }
30 }
31
32 return true
33 }
34
35
36
37
38
39
40
41
42 func ParseURL(input string) *URL {
43 u, err := url.Parse(input)
44 if err != nil {
45 return nil
46 }
47
48 if u.RawQuery != "" {
49 return nil
50 }
51
52 if u.Scheme != "http" && u.Scheme != "https" {
53 return nil
54 }
55
56 normalizedPath := u.Path
57 if !strings.HasPrefix(normalizedPath, "/") {
58 normalizedPath = "/" + normalizedPath
59 }
60 if !strings.HasSuffix(normalizedPath, "/") {
61 normalizedPath = normalizedPath + "/"
62 }
63
64
65
66
67 authority := strings.ReplaceAll(u.Host, "%", "%25")
68
69 return &URL{
70 Scheme: u.Scheme,
71 Authority: authority,
72 Path: u.Path,
73 NormalizedPath: normalizedPath,
74 IsIp: net.ParseIP(hostnameWithoutZone(u)) != nil,
75 }
76 }
77
78
79
80 type URL struct {
81 Scheme string
82 Authority string
83 Path string
84 NormalizedPath string
85 IsIp bool
86 }
87
88
89
90
91
92 func URIEncode(input string) string {
93 var output strings.Builder
94 for _, c := range []byte(input) {
95 if validPercentEncodedChar(c) {
96 output.WriteByte(c)
97 continue
98 }
99
100 fmt.Fprintf(&output, "%%%X", c)
101 }
102
103 return output.String()
104 }
105
106 func validPercentEncodedChar(c byte) bool {
107 return (c >= 'a' && c <= 'z') ||
108 (c >= 'A' && c <= 'Z') ||
109 (c >= '0' && c <= '9') ||
110 c == '-' || c == '_' || c == '.' || c == '~'
111 }
112
113
114
115
116
117
118
119
120 func hostnameWithoutZone(u *url.URL) string {
121 full := u.Hostname()
122
123
124
125
126 if i := strings.LastIndex(full, "%"); i > -1 {
127 return full[:i]
128 }
129 return full
130 }
131
View as plain text