Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 14, 01:30 UTC
httpcaddyfile: Preserve IPv6 addresses through normalization (fix #4381)
Remove unnecessary Key() method and improve related tests
Matthew Holt committed
Oct 20, 2021 at 10:27 UTC
0ffb2229b00c3e6b484fb7fac6d5ff8d652c2cc8
2 files changed
+105
-55
caddyconfig/httpcaddyfile/addresses.go
+3
-23
@@ -337,7 +337,9 @@ func (a Address) Normalize() Address {
337
// ensure host is normalized if it's an IP address
338
host := strings.TrimSpace(a.Host)
339
if ip := net.ParseIP(host); ip != nil {
340
- host = ip.String()
340
+ if ipv6 := ip.To16(); ipv6 != nil && ipv6.DefaultMask() == nil {
341
+ host = ipv6.String()
342
+ }
343
}
344
345
return Address{
@@ -349,28 +351,6 @@ func (a Address) Normalize() Address {
351
}
352
}
353
352
-// Key returns a string form of a, much like String() does, but this
353
-// method doesn't add anything default that wasn't in the original.
354
-func (a Address) Key() string {
355
- res := ""
356
- if a.Scheme != "" {
357
- res += a.Scheme + "://"
358
- }
359
- if a.Host != "" {
360
- res += a.Host
361
- }
362
- // insert port only if the original has its own explicit port
363
- if a.Port != "" &&
364
- len(a.Original) >= len(res) &&
365
- strings.HasPrefix(a.Original[len(res):], ":"+a.Port) {
366
- res += ":" + a.Port
367
- }
368
- if a.Path != "" {
369
- res += a.Path
370
- }
371
- return res
372
-}
373
-
354
// lowerExceptPlaceholders lowercases s except within
355
// placeholders (substrings in non-escaped '{ }' spans).
356
// See https://github.com/caddyserver/caddy/issues/3264
caddyconfig/httpcaddyfile/addresses_test.go
+102
-32
@@ -106,67 +106,128 @@ func TestAddressString(t *testing.T) {
106
func TestKeyNormalization(t *testing.T) {
107
testCases := []struct {
108
input string
109
- expect string
109
+ expect Address
110
}{
111
{
112
- input: "example.com",
113
- expect: "example.com",
112
+ input: "example.com",
113
+ expect: Address{
114
+ Host: "example.com",
115
+ },
116
},
117
{
116
- input: "http://host:1234/path",
117
- expect: "http://host:1234/path",
118
+ input: "http://host:1234/path",
119
+ expect: Address{
120
+ Scheme: "http",
121
+ Host: "host",
122
+ Port: "1234",
123
+ Path: "/path",
124
+ },
125
},
126
{
120
- input: "HTTP://A/ABCDEF",
121
- expect: "http://a/ABCDEF",
127
+ input: "HTTP://A/ABCDEF",
128
+ expect: Address{
129
+ Scheme: "http",
130
+ Host: "a",
131
+ Path: "/ABCDEF",
132
+ },
133
},
134
{
124
- input: "A/ABCDEF",
125
- expect: "a/ABCDEF",
135
+ input: "A/ABCDEF",
136
+ expect: Address{
137
+ Host: "a",
138
+ Path: "/ABCDEF",
139
+ },
140
},
141
{
128
- input: "A:2015/Path",
129
- expect: "a:2015/Path",
142
+ input: "A:2015/Path",
143
+ expect: Address{
144
+ Host: "a",
145
+ Port: "2015",
146
+ Path: "/Path",
147
+ },
148
},
149
{
132
- input: "sub.{env.MY_DOMAIN}",
133
- expect: "sub.{env.MY_DOMAIN}",
150
+ input: "sub.{env.MY_DOMAIN}",
151
+ expect: Address{
152
+ Host: "sub.{env.MY_DOMAIN}",
153
+ },
154
},
155
{
136
- input: "sub.ExAmPle",
137
- expect: "sub.example",
156
+ input: "sub.ExAmPle",
157
+ expect: Address{
158
+ Host: "sub.example",
159
+ },
160
},
161
{
140
- input: "sub.\\{env.MY_DOMAIN\\}",
141
- expect: "sub.\\{env.my_domain\\}",
162
+ input: "sub.\\{env.MY_DOMAIN\\}",
163
+ expect: Address{
164
+ Host: "sub.\\{env.my_domain\\}",
165
+ },
166
},
167
{
144
- input: "sub.{env.MY_DOMAIN}.com",
145
- expect: "sub.{env.MY_DOMAIN}.com",
168
+ input: "sub.{env.MY_DOMAIN}.com",
169
+ expect: Address{
170
+ Host: "sub.{env.MY_DOMAIN}.com",
171
+ },
172
},
173
{
148
- input: ":80",
149
- expect: ":80",
174
+ input: ":80",
175
+ expect: Address{
176
+ Port: "80",
177
+ },
178
},
179
{
152
- input: ":443",
153
- expect: ":443",
180
+ input: ":443",
181
+ expect: Address{
182
+ Port: "443",
183
+ },
184
},
185
{
156
- input: ":1234",
157
- expect: ":1234",
186
+ input: ":1234",
187
+ expect: Address{
188
+ Port: "1234",
189
+ },
190
},
191
{
192
input: "",
161
- expect: "",
193
+ expect: Address{},
194
},
195
{
196
input: ":",
165
- expect: "",
197
+ expect: Address{},
198
},
199
{
168
- input: "[::]",
169
- expect: "::",
200
+ input: "[::]",
201
+ expect: Address{
202
+ Host: "::",
203
+ },
204
+ },
205
+ {
206
+ input: "127.0.0.1",
207
+ expect: Address{
208
+ Host: "127.0.0.1",
209
+ },
210
+ },
211
+ {
212
+ input: "[2001:db8:85a3:8d3:1319:8a2e:370:7348]:1234",
213
+ expect: Address{
214
+ Host: "2001:db8:85a3:8d3:1319:8a2e:370:7348",
215
+ Port: "1234",
216
+ },
217
+ },
218
+ {
219
+ // IPv4 address in IPv6 form (#4381)
220
+ input: "[::ffff:cff4:e77d]:1234",
221
+ expect: Address{
222
+ Host: "::ffff:cff4:e77d",
223
+ Port: "1234",
224
+ },
225
+ },
226
+ {
227
+ input: "::ffff:cff4:e77d",
228
+ expect: Address{
229
+ Host: "::ffff:cff4:e77d",
230
+ },
231
},
232
}
233
for i, tc := range testCases {
@@ -175,9 +236,18 @@ func TestKeyNormalization(t *testing.T) {
236
t.Errorf("Test %d: Parsing address '%s': %v", i, tc.input, err)
237
continue
238
}
178
- if actual := addr.Normalize().Key(); actual != tc.expect {
179
- t.Errorf("Test %d: Input '%s': Expected '%s' but got '%s'", i, tc.input, tc.expect, actual)
239
+ actual := addr.Normalize()
240
+ if actual.Scheme != tc.expect.Scheme {
241
+ t.Errorf("Test %d: Input '%s': Expected Scheme='%s' but got Scheme='%s'", i, tc.input, tc.expect.Scheme, actual.Scheme)
242
+ }
243
+ if actual.Host != tc.expect.Host {
244
+ t.Errorf("Test %d: Input '%s': Expected Host='%s' but got Host='%s'", i, tc.input, tc.expect.Host, actual.Host)
245
+ }
246
+ if actual.Port != tc.expect.Port {
247
+ t.Errorf("Test %d: Input '%s': Expected Port='%s' but got Port='%s'", i, tc.input, tc.expect.Port, actual.Port)
248
+ }
249
+ if actual.Path != tc.expect.Path {
250
+ t.Errorf("Test %d: Input '%s': Expected Path='%s' but got Path='%s'", i, tc.input, tc.expect.Path, actual.Path)
251
}
181
-
252
}
253
}