validateURL in internal/httpfetcher cut a port off the source host with net.SplitHostPort. For an IPv6 address in brackets with no port, as in https://[2001:db8::a]/a.png, that call fails, so the brackets stayed on, the name lookup failed, and the request answered 500 through /v1/image/ and through an encrypted URL. The check now parses the source URL with net/url and takes the host from Hostname(), which drops the brackets whether or not a port follows. The address is then looked up, and a private one is refused with 403, as it already was with a port.
The fetcher's other uses of the host stay as they are: the dialer is always handed an address with a port, and the connection limit per host only uses the host text to tell hosts apart, which works with the brackets on.
The router test is the first commit, the fix the second. It sends both image routes an IPv6 source host with and without a port: a public address must be fetched, a private one refused with 403 without reaching the upstream.
Disclosure: the doc comment of TestGeneratorMakesOneImageURLForTwoSpellingsOfASourceURL still says the fetcher refuses an IPv6 address written without a port. It is left as it is, because an existing test may not change without approval.
Model: opus-5-5
Fixes https://git.eeqj.de/sneak/pixa/issues/295.
`validateURL` in `internal/httpfetcher` cut a port off the source host with `net.SplitHostPort`. For an IPv6 address in brackets with no port, as in `https://[2001:db8::a]/a.png`, that call fails, so the brackets stayed on, the name lookup failed, and the request answered 500 through `/v1/image/` and through an encrypted URL. The check now parses the source URL with `net/url` and takes the host from `Hostname()`, which drops the brackets whether or not a port follows. The address is then looked up, and a private one is refused with 403, as it already was with a port.
The fetcher's other uses of the host stay as they are: the dialer is always handed an address with a port, and the connection limit per host only uses the host text to tell hosts apart, which works with the brackets on.
The router test is the first commit, the fix the second. It sends both image routes an IPv6 source host with and without a port: a public address must be fetched, a private one refused with 403 without reaching the upstream.
Disclosure: the doc comment of `TestGeneratorMakesOneImageURLForTwoSpellingsOfASourceURL` still says the fetcher refuses an IPv6 address written without a port. It is left as it is, because an existing test may not change without approval.
Model: opus-5-5
A router test against a test upstream that records each request: an
IPv6 source host written with and without a port, through a /v1/image/
URL with a signature and through an encrypted URL. A public address must
be fetched, a private one refused with 403 without reaching the
upstream. The cases without a port fail: each answers 500.
Model: opus-5-5
The fetcher's check of a source URL cut a port off the host with
net.SplitHostPort, which fails when an IPv6 address in brackets has no
port, so the brackets stayed on, the name lookup failed and the request
answered 500. The check now parses the URL and takes the host from
Hostname(), which drops the brackets with or without a port, so the
address is looked up and a private one is refused with 403.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Fixes #295.
validateURLininternal/httpfetchercut a port off the source host withnet.SplitHostPort. For an IPv6 address in brackets with no port, as inhttps://[2001:db8::a]/a.png, that call fails, so the brackets stayed on, the name lookup failed, and the request answered 500 through/v1/image/and through an encrypted URL. The check now parses the source URL withnet/urland takes the host fromHostname(), which drops the brackets whether or not a port follows. The address is then looked up, and a private one is refused with 403, as it already was with a port.The fetcher's other uses of the host stay as they are: the dialer is always handed an address with a port, and the connection limit per host only uses the host text to tell hosts apart, which works with the brackets on.
The router test is the first commit, the fix the second. It sends both image routes an IPv6 source host with and without a port: a public address must be fetched, a private one refused with 403 without reaching the upstream.
Disclosure: the doc comment of
TestGeneratorMakesOneImageURLForTwoSpellingsOfASourceURLstill says the fetcher refuses an IPv6 address written without a port. It is left as it is, because an existing test may not change without approval.Model: opus-5-5
Review passed.
Model: opus-5-5
3689685680to6f50eb20dfRebased onto
next; no file conflicted, and onlyTODO.mdneeded its entry moved back to the top of Completed Steps.Model: opus-5-5