@marcel91200 / caddy Mirror · read-only / commits / 630c62b3
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 12, 10:45 UTC

fixed bug in resolving ip version in dynamic upstreams (#6448)

Aziz Rmadi committed Jul 9, 2024 at 02:06 UTC 630c62b3137abf688aa1a698a614fa28c08e43dd
2 files changed +70 -12
modules/caddyhttp/reverseproxy/upstreams.go
+14 -12
@@ -231,6 +231,19 @@ type IPVersions struct {
231 IPv6 *bool `json:"ipv6,omitempty"`
232 }
233
234 +func resolveIpVersion(versions *IPVersions) string {
235 + resolveIpv4 := versions == nil || (versions.IPv4 == nil && versions.IPv6 == nil) || (versions.IPv4 != nil && *versions.IPv4)
236 + resolveIpv6 := versions == nil || (versions.IPv6 == nil && versions.IPv4 == nil) || (versions.IPv6 != nil && *versions.IPv6)
237 + switch {
238 + case resolveIpv4 && !resolveIpv6:
239 + return "ip4"
240 + case !resolveIpv4 && resolveIpv6:
241 + return "ip6"
242 + default:
243 + return "ip"
244 + }
245 +}
246 +
247 // AUpstreams provides upstreams from A/AAAA lookups.
248 // Results are cached and refreshed at the configured
249 // refresh interval.
@@ -313,9 +326,6 @@ func (au *AUpstreams) Provision(ctx caddy.Context) error {
326 func (au AUpstreams) GetUpstreams(r *http.Request) ([]*Upstream, error) {
327 repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
328
316 - resolveIpv4 := au.Versions == nil || au.Versions.IPv4 == nil || *au.Versions.IPv4
317 - resolveIpv6 := au.Versions == nil || au.Versions.IPv6 == nil || *au.Versions.IPv6
318 -
329 // Map ipVersion early, so we can use it as part of the cache-key.
330 // This should be fairly inexpensive and comes and the upside of
331 // allowing the same dynamic upstream (name + port combination)
@@ -324,15 +334,7 @@ func (au AUpstreams) GetUpstreams(r *http.Request) ([]*Upstream, error) {
334 // It also forced a cache-miss if a previously cached dynamic
335 // upstream changes its ip version, e.g. after a config reload,
336 // while keeping the cache-invalidation as simple as it currently is.
327 - var ipVersion string
328 - switch {
329 - case resolveIpv4 && !resolveIpv6:
330 - ipVersion = "ip4"
331 - case !resolveIpv4 && resolveIpv6:
332 - ipVersion = "ip6"
333 - default:
334 - ipVersion = "ip"
335 - }
337 + ipVersion := resolveIpVersion(au.Versions)
338
339 auStr := repl.ReplaceAll(au.String()+ipVersion, "")
340
modules/caddyhttp/reverseproxy/upstreams_test.go new
+56
@@ -0,0 +1,56 @@
1 +package reverseproxy
2 +
3 +import "testing"
4 +
5 +func TestResolveIpVersion(t *testing.T) {
6 + falseBool := false
7 + trueBool := true
8 + tests := []struct {
9 + Versions *IPVersions
10 + expectedIpVersion string
11 + }{
12 + {
13 + Versions: &IPVersions{IPv4: &trueBool},
14 + expectedIpVersion: "ip4",
15 + },
16 + {
17 + Versions: &IPVersions{IPv4: &falseBool},
18 + expectedIpVersion: "ip",
19 + },
20 + {
21 + Versions: &IPVersions{IPv4: &trueBool, IPv6: &falseBool},
22 + expectedIpVersion: "ip4",
23 + },
24 + {
25 + Versions: &IPVersions{IPv6: &trueBool},
26 + expectedIpVersion: "ip6",
27 + },
28 + {
29 + Versions: &IPVersions{IPv6: &falseBool},
30 + expectedIpVersion: "ip",
31 + },
32 + {
33 + Versions: &IPVersions{IPv6: &trueBool, IPv4: &falseBool},
34 + expectedIpVersion: "ip6",
35 + },
36 + {
37 + Versions: &IPVersions{},
38 + expectedIpVersion: "ip",
39 + },
40 + {
41 + Versions: &IPVersions{IPv4: &trueBool, IPv6: &trueBool},
42 + expectedIpVersion: "ip",
43 + },
44 + {
45 + Versions: &IPVersions{IPv4: &falseBool, IPv6: &falseBool},
46 + expectedIpVersion: "ip",
47 + },
48 + }
49 + for _, test := range tests {
50 + ipVersion := resolveIpVersion(test.Versions)
51 + if ipVersion != test.expectedIpVersion {
52 + t.Errorf("resolveIpVersion(): Expected %s got %s", test.expectedIpVersion, ipVersion)
53 + }
54 + }
55 +
56 +}