Fetch the source path and query URL-encoded, not joined as text (closes #288)
check / check (push) Canceled after 0s
check / check (push) Canceled after 0s
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
This commit was merged in pull request #289.
This commit is contained in:
@@ -331,6 +331,20 @@ writes one as `%23` is refused with 400. For example,
|
||||
`/v1/image/cdn.example.com/img%3Furl=https://origin.example.com/my%2520cat.jpg/800x600.webp`,
|
||||
signed as shown under Signature Specification.
|
||||
|
||||
The source path is the path with its percent-escapes decoded, and pixa fetches
|
||||
it percent-encoded again: every character other than letters, digits, `-`, `.`,
|
||||
`_`, `~`, `/`, `$`, `&`, `+`, `,`, `:`, `;`, `=` and `@` is sent as a
|
||||
percent-escape. So `my%20cat.jpg` in the image URL is the source path
|
||||
`/my cat.jpg`, fetched as `/my%20cat.jpg`; `my%2520cat.jpg` is the source path
|
||||
`/my%20cat.jpg`, fetched as `/my%2520cat.jpg`; and `100%25.png` is fetched as
|
||||
`/100%25.png`. The source query is the source URL's query as that URL writes it,
|
||||
its percent-escapes included, and is sent as it is, except that the characters a
|
||||
browser percent-encodes in a query (a space, `"`, `'`, `<`, `>`, control
|
||||
characters and characters outside ASCII) and a `%` that does not begin a
|
||||
percent-escape are percent-encoded. pixa signs and caches the query in that
|
||||
form, so `img%3Fname=my%20cat` and `img%3Fname=my%2520cat` in the image URL are
|
||||
the same source query, `name=my%20cat`.
|
||||
|
||||
A size with one side `0` has that side scaled to keep the source's proportions,
|
||||
and is refused with 400 when that side would come out above 8192, the most
|
||||
either side may be; so is a size with `fit=outside`, which scales the image to
|
||||
@@ -445,7 +459,13 @@ nor change what it asks for.
|
||||
sent with an empty format, or none, also makes a JPEG XL URL. Width and
|
||||
height both empty or `0` keep the original size; if only one of them is empty
|
||||
or `0`, that side is scaled to keep the image's proportions. A URL whose
|
||||
scaled side would come out above 8192 answers 400.
|
||||
scaled side would come out above 8192 answers 400, and so does a source URL
|
||||
whose path holds a `..` segment. So does a source URL that the image URL
|
||||
would fetch written another way, and the page then shows the URL pixa would
|
||||
fetch: one with a user name and password, which pixa does not send, or one
|
||||
whose path holds `%2F`, fetched as `/`, or `(`, fetched as `%28`, as pixa
|
||||
keeps the source path decoded and fetches it percent-encoded again (see
|
||||
Routes).
|
||||
3. The page shows the URL, `https://<host>/v1/e/<token>/img.<format>`, and when
|
||||
it expires. `<host>` is the host the page was opened on, and the URL starts
|
||||
with `http` instead while `debug` is on. The name after the token is ignored
|
||||
@@ -507,11 +527,13 @@ Where:
|
||||
- `host` — source host as the URL writes it up to the first `/`, in lower case,
|
||||
keeping an IPv6 address's brackets and any `:` and port after it (e.g.
|
||||
`cdn.example.com`, `cdn.example.com:8443`, `[2001:db8::1]:8443`)
|
||||
- `path` — source path (e.g. `/photos/cat.jpg`), with each `%` written as `%25`
|
||||
and each `:` as `%3A`, so `/photos/a:b.jpg` is signed as `/photos/a%3Ab.jpg`
|
||||
- `query` — source query string, empty string if none, with `%` and `:` written
|
||||
as in `path`; neither then holds a `:`, so path `/a:b` with no query and path
|
||||
`/a` with query `b:` are signed differently
|
||||
- `path` — source path, with its percent-escapes decoded as under Routes (e.g.
|
||||
`/photos/cat.jpg`, or `/photos/my cat.jpg` for `/photos/my%20cat.jpg`), with
|
||||
each `%` written as `%25` and each `:` as `%3A`, so `/photos/a:b.jpg` is
|
||||
signed as `/photos/a%3Ab.jpg`
|
||||
- `query` — source query string as under Routes, empty string if none, with `%`
|
||||
and `:` written as in `path`; neither then holds a `:`, so path `/a:b` with no
|
||||
query and path `/a` with query `b:` are signed differently
|
||||
- `width` — requested width in pixels, `0` for original
|
||||
- `height` — requested height in pixels, `0` for original
|
||||
- `format` — output format, one of those listed under Routes, with `original`
|
||||
|
||||
Reference in New Issue
Block a user