Document how a source query goes into an image URL, and accept it (closes #255)
check / check (push) Canceled after 0s
check / check (push) Canceled after 0s
The query follows the source path after %3F. The image route now parses the request's path decoded once instead of chi's wildcard, which holds the path as the client wrote it whenever that is not Go's own encoding of it, so a / ; or , written as %2F, %3B or %2C, as GenerateSignedURL wrote them, hid the %3F and the request failed with 401. Now the ? and every % in the source path or query must be percent-encoded and any other character may be. GenerateSignedURL writes Go's own encoding of the path. The README states the rule, with an example and its signature. Model: opus-5-5
This commit is contained in:
1 parent
4634d2dc2f
commit
f9c878161a
7 files changed
+74
-48
No files matched your search
@@ -198,7 +198,7 @@ func TestHandleImage_GeneratedSignedURLWithSourceQueryVerifies(t *testing.T) {
|
||||
|
||||
signedURL, err := fix.service.GenerateSignedURL("", &imgcache.ImageRequest{
|
||||
SourceHost: signedHost,
|
||||
SourcePath: "/images/photo.jpg",
|
||||
SourcePath: photoPath,
|
||||
SourceQuery: tt.query,
|
||||
Size: imgcache.Size{Width: 50, Height: 50},
|
||||
Format: imgcache.FormatJPEG,
|
||||
@@ -226,7 +226,7 @@ func TestHandleImage_SourceQueryEncodedAnyWay(t *testing.T) {
|
||||
signer := signature.New("test-signing-key-must-be-32-chars")
|
||||
sig := signer.Sign(&signature.Request{
|
||||
SourceHost: signedHost,
|
||||
SourcePath: "/images/photo.jpg",
|
||||
SourcePath: photoPath,
|
||||
SourceQuery: "url=https://origin.example.com/my%20cat.jpg",
|
||||
Width: 50,
|
||||
Height: 50,
|
||||
@@ -237,23 +237,23 @@ func TestHandleImage_SourceQueryEncodedAnyWay(t *testing.T) {
|
||||
})
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
writtenSource string
|
||||
name string
|
||||
writtenQuery string
|
||||
}{
|
||||
{"only ? and % encoded",
|
||||
"/images/photo.jpg%3Furl=https://origin.example.com/my%2520cat.jpg"},
|
||||
"%3Furl=https://origin.example.com/my%2520cat.jpg"},
|
||||
{"every reserved character encoded",
|
||||
"/images/photo.jpg%3Furl%3Dhttps%3A%2F%2Forigin.example.com%2Fmy%2520cat.jpg"},
|
||||
"%3Furl%3Dhttps%3A%2F%2Forigin.example.com%2Fmy%2520cat.jpg"},
|
||||
{"lower-case hex digits",
|
||||
"/images/photo.jpg%3furl=https://origin.example.com/my%2520cat.jpg"},
|
||||
"%3furl=https://origin.example.com/my%2520cat.jpg"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
target := fmt.Sprintf("/v1/image/%s%s/50x50.jpeg?sig=%s&exp=%d",
|
||||
signedHost, tt.writtenSource, sig, expires.Unix())
|
||||
target := fmt.Sprintf("/v1/image/%s%s%s/50x50.jpeg?sig=%s&exp=%d",
|
||||
signedHost, photoPath, tt.writtenQuery, sig, expires.Unix())
|
||||
|
||||
status := getImage(t, setupTestHandler(t), target)
|
||||
if status != http.StatusBadGateway {
|
||||
|
||||
Reference in new issue
Block a user