Both image routes: the plain IPv4 source host 203.0.113.5 must not be
refused when blocked_networks lists ::/0. It fails on this branch: Go
keeps a plain IPv4 address in the mapped form, and isBlockedIP matches
that form as written. The case that expected [::ffff:203.0.113.5]
refused with ::ffff:0:0/96 listed, added earlier on this branch, is
dropped: the mapped form is matched only as the IPv4 address it holds.
Model: opus-5-5
Both image routes: [::203.0.113.5] must answer 403 when blocked_networks
lists ::/96, and [::ffff:203.0.113.5] when it lists ::ffff:0:0/96 or
203.0.113.0/24. The ::/96 and ::ffff:0:0/96 cases fail on this branch:
isBlockedIP matches such an address only by the IPv4 address it holds.
Model: opus-5-5
Both image routes, with the fetcher pixad builds from the config:
[64:ff9b:1::a00:1] must answer 403, and [::203.0.113.5] must answer 403
when blocked_networks lists 203.0.113.0/24 and must not be refused when
the list is empty. The first two fail on next: both addresses are
fetched.
Model: opus-5-5
The check that keeps pixa from fetching internal addresses read an
IPv6 address as IPv4 only in the mapped form (::ffff:a.b.c.d), so the
IPv4-compatible form, such as ::127.0.0.1, was judged as IPv6 and
passed. An address in ::/96 is now judged by the IPv4 address it holds,
so one holding a private, loopback or link-local address is refused on
both image routes before any upstream request. The NAT64 range
64:ff9b::/96 stays blocked whole, as it was on next.
Model: opus-5-5
The fetcher took the host from the source URL and stripped a port with
net.SplitHostPort, which fails when there is no port, so a bracketed
IPv6 host such as [2001:db8::a] kept its brackets, its name lookup
failed, and the request answered 500. validateURL now takes the host
with url.URL.Hostname(), which drops the brackets and any port, so such
a host is fetched like one with a port, through /v1/image/ and through
an encrypted URL, and a private IPv6 address is still refused.
Model: opus-5-5
The generator page passed the source host and path into the encrypted
URL as entered, so a host spelled in another letter case, or a source
with no path against the same source with /, made separate cache keys
and fetched one upstream image twice. The page now lower-cases the
source host, as /v1/image/ does, and writes an empty source path as /,
before it builds the encrypted URL. The checks the page gained for
#288 still hold.
Model: opus-5-5
The source URL was built by joining the decoded path and query as
text, so a space in the query reached the upstream raw and failed with
502, 100%25.png made a URL Go could not parse and answered 401, and
%20 and %2520 fetched the same path under different cache keys. The
source URL is now built with net/url, so each decoded path and query is
one upstream request matching its signature and cache key; the query
encodes the characters a browser encodes, ' included. The generator page
compares what pixa would fetch with the URL as entered, and answers 400
with the URL to use when they differ, or for a user name and password
or a .. segment.
Model: opus-5-5