@marcel91200 / caddy Mirror · read-only / commits / 0ffb2229
Fork 0

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 }