Fetch the source path and query URL-encoded, not joined as text (closes #288)
The source path, decoded, is fetched percent-encoded again by net/url, so 100%25.png fetches /100%25.png, and my%20cat.png and my%2520cat.png fetch different paths. The source query stays as the source URL writes it; the characters a browser percent-encodes in a query, such as a space, are percent-encoded when the image URL is read, so the query is signed and cached as it is sent. The generator page answers 400 for a source URL its image URL would fetch written another way, such as with %2F in the path, and shows the URL pixa would fetch. README.md says how the source path and query are fetched. Model: opus-5-5
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -86,9 +87,11 @@ func ValidateImageRequest(req *ImageRequest) error {
|
||||
type ImageRequest struct {
|
||||
// SourceHost is the origin host (e.g., "cdn.example.com")
|
||||
SourceHost string
|
||||
// SourcePath is the path on the origin (e.g., "/photos/cat.jpg")
|
||||
// SourcePath is the path on the origin with its percent-escapes decoded,
|
||||
// as url.URL's Path holds it (e.g., "/photos/my cat.jpg")
|
||||
SourcePath string
|
||||
// SourceQuery is the optional query string for the origin URL
|
||||
// SourceQuery is the optional query string for the origin URL as the URL
|
||||
// writes it, percent-escapes included, as url.URL's RawQuery holds it
|
||||
SourceQuery string
|
||||
// Size is the requested output dimensions
|
||||
Size Size
|
||||
@@ -107,20 +110,25 @@ type ImageRequest struct {
|
||||
AllowHTTP bool
|
||||
}
|
||||
|
||||
// SourceURL returns the full upstream URL to fetch.
|
||||
// Uses http:// scheme when AllowHTTP is true, otherwise https://.
|
||||
// SourceURL returns the full upstream URL to fetch: the source path
|
||||
// percent-encoded again, as net/url writes a path, so each source path is one
|
||||
// upstream path, and the source query as it is, with the characters
|
||||
// escapeQuery encodes percent-encoded. Uses http:// scheme when AllowHTTP is
|
||||
// true, otherwise https://.
|
||||
func (r *ImageRequest) SourceURL() string {
|
||||
scheme := "https"
|
||||
if r.AllowHTTP {
|
||||
scheme = "http"
|
||||
}
|
||||
|
||||
url := scheme + "://" + r.SourceHost + r.SourcePath
|
||||
if r.SourceQuery != "" {
|
||||
url += "?" + r.SourceQuery
|
||||
sourceURL := url.URL{
|
||||
Scheme: scheme,
|
||||
Host: r.SourceHost,
|
||||
Path: r.SourcePath,
|
||||
RawQuery: escapeQuery(r.SourceQuery),
|
||||
}
|
||||
|
||||
return url
|
||||
return sourceURL.String()
|
||||
}
|
||||
|
||||
// ImageResponse represents a processed image ready to serve
|
||||
|
||||
Reference in New Issue
Block a user