Remove the code nothing in production calls (closes #312)
check / check (push) Canceled after 0s

Service.Warm, the ImageCache interface, both GenerateSignedURL methods,
signature.ParseParams, imagerequest.ParseImagePath, four symbols of
internal/magic, the image processor's lists of supported formats,
IsEmpty and Count of the allowlist, ssrfSafeDialer, CacheStale,
ErrCacheMiss, ErrNegativeCache, ImageResponse.LastModified and the Load
methods of ContentStorage and VariantStorage had no caller outside
tests. They are gone, with the tests that tested only them.

The handlers tests sign their image URLs with generateSignedURL, a test
helper that builds the URL as the removed generator did. The SSRF dialer
tests call dialSSRFSafe with no operator blocklist, which is all
ssrfSafeDialer did. The tests of ParseImagePath and ContentStorage.Load
call ParseImageURL and LoadWithSize instead. MIMEToImageFormat,
ContentStorage.Store and CleanExpired stay, as pixa calls them.

Model: opus-5-5
This commit is contained in:
2026-10-26 09:40:35 +00:00
parent b49d0068df
commit 5a2aa94691
27 changed files with 187 additions and 1017 deletions
+6 -10
View File
@@ -75,11 +75,13 @@ func TestFormatForAccept(t *testing.T) {
// autoPhotoURLs returns a signed /v1/image/ URL and an encrypted /v1/e/ URL,
// both valid for a minute, for the JPEG at photoPath on signedHost at 50x50 in
// the format auto, made with h's image service and generator.
// the format auto. The first is signed with testSigningKey, the key of the
// image service newSignedHostServer builds, and the second is made with h's
// generator.
func autoPhotoURLs(t *testing.T, h *Handlers) (string, string) {
t.Helper()
signedURL, err := h.imgSvc.GenerateSignedURL("", &imagerequest.Request{
signedURL := generateSignedURL(testSigningKey, &imagerequest.Request{
Source: imagerequest.Source{
Host: signedHost,
Path: photoPath,
@@ -89,9 +91,6 @@ func autoPhotoURLs(t *testing.T, h *Handlers) (string, string) {
Format: imagerequest.FormatAuto,
},
}, time.Minute)
if err != nil {
t.Fatalf("GenerateSignedURL() error = %v", err)
}
token, err := h.encGen.Generate(&imagerequest.Request{
Source: imagerequest.Source{
@@ -188,9 +187,9 @@ func TestFormatAuto_ChosenFromAccept(t *testing.T) {
func TestFormatAuto_SignatureCoversAuto(t *testing.T) {
t.Parallel()
h, srv := newSignedHostServer(t, slog.New(slog.DiscardHandler))
_, srv := newSignedHostServer(t, slog.New(slog.DiscardHandler))
signedForAVIF, err := h.imgSvc.GenerateSignedURL("", &imagerequest.Request{
signedForAVIF := generateSignedURL(testSigningKey, &imagerequest.Request{
Source: imagerequest.Source{
Host: signedHost,
Path: photoPath,
@@ -200,9 +199,6 @@ func TestFormatAuto_SignatureCoversAuto(t *testing.T) {
Format: imagerequest.FormatAVIF,
},
}, time.Minute)
if err != nil {
t.Fatalf("GenerateSignedURL() error = %v", err)
}
target := strings.Replace(signedForAVIF, "/50x50.avif?", "/50x50.auto?", 1)
if target == signedForAVIF {
@@ -27,7 +27,6 @@ import (
// testFixtures contains test data.
type testFixtures struct {
handler *Handlers
service *imgcache.Service
goodHost string
}
@@ -71,7 +70,6 @@ func setupTestHandler(t *testing.T) *testFixtures {
return &testFixtures{
handler: h,
service: svc,
goodHost: goodHost,
}
}
@@ -107,9 +107,9 @@ func getMaxAge(t *testing.T, srv http.Handler, target string) int {
func TestHandleImage_SignedURL_MaxAgeEndsAtExp(t *testing.T) {
t.Parallel()
h, srv := newSignedHostServer(t, slog.New(slog.DiscardHandler))
_, srv := newSignedHostServer(t, slog.New(slog.DiscardHandler))
signedURL, err := h.imgSvc.GenerateSignedURL("", &imagerequest.Request{
signedURL := generateSignedURL(testSigningKey, &imagerequest.Request{
Source: imagerequest.Source{
Host: signedHost,
Path: photoPath,
@@ -119,9 +119,6 @@ func TestHandleImage_SignedURL_MaxAgeEndsAtExp(t *testing.T) {
Format: imagerequest.FormatJPEG,
},
}, time.Minute)
if err != nil {
t.Fatalf("GenerateSignedURL() error = %v", err)
}
maxAge := getMaxAge(t, srv, signedURL)
if maxAge < 50 || maxAge > 60 {
@@ -5,6 +5,7 @@ import (
"fmt"
"net/http"
"net/http/httptest"
"net/url"
"testing"
"time"
@@ -36,6 +37,43 @@ func getImage(t *testing.T, fix *testFixtures, target string) int {
return rec.Code
}
// generateSignedURL returns the /v1/image/ URL of req, signed with key and
// expiring after ttl, and sets req's expiry. An unset quality or fit of req is
// first set to 85 or cover, the values the route uses when a URL has no q or
// fit. The URL carries q and fit next to sig and exp, so the route verifies it
// for the quality and fit it was signed with.
func generateSignedURL(
key string, req *imagerequest.Request, ttl time.Duration,
) string {
if req.Transform.Quality == 0 {
req.Transform.Quality = 85
}
if req.Transform.FitMode == "" {
req.Transform.FitMode = imagerequest.FitCover
}
req.Expires = time.Now().Add(ttl)
sig := signature.New(key).Sign(req)
// A source query follows the source path after a "?". The image route
// reads the path decoded once, so the whole path is written in Go's own
// percent-encoding of a URL path, which writes "?" as %3F and "%" as %25,
// and leaves "/", ";", ",", "=" and "&" as they are.
sourcePathAndQuery := req.Source.Path
if req.Source.Query != "" {
sourcePathAndQuery += "?" + req.Source.Query
}
unescapedPath := fmt.Sprintf("/v1/image/%s%s/%dx%d.%s",
req.Source.Host, sourcePathAndQuery,
req.Transform.Size.Width, req.Transform.Size.Height, req.Transform.Format)
return fmt.Sprintf("%s?sig=%s&exp=%d&q=%d&fit=%s",
(&url.URL{Path: unescapedPath}).EscapedPath(), sig, req.Expires.Unix(),
req.Transform.Quality, req.Transform.FitMode)
}
// TestHandleImage_SignatureCoversQualityAndFit signs a URL for quality 85
// and fit cover, the values the route uses when a URL has no q or fit, and
// sends that signature with each q and fit below.
@@ -83,8 +121,8 @@ func TestHandleImage_SignatureCoversQualityAndFit(t *testing.T) {
}
}
// TestHandleImage_GeneratedSignedURLVerifies sends URLs built by the
// service's signed-URL generator to the route.
// TestHandleImage_GeneratedSignedURLVerifies sends URLs built by
// generateSignedURL to the route.
func TestHandleImage_GeneratedSignedURLVerifies(t *testing.T) {
t.Parallel()
@@ -101,25 +139,21 @@ func TestHandleImage_GeneratedSignedURLVerifies(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
fix := setupTestHandler(t)
signedURL := generateSignedURL("test-signing-key-must-be-32-chars",
&imagerequest.Request{
Source: imagerequest.Source{
Host: signedHost,
Path: "/images/photo.jpg",
},
Transform: imagerequest.Transform{
Size: imagerequest.Size{Width: 50, Height: 50},
Format: imagerequest.FormatJPEG,
Quality: tt.quality,
FitMode: tt.fitMode,
},
}, time.Hour)
signedURL, err := fix.service.GenerateSignedURL("", &imagerequest.Request{
Source: imagerequest.Source{
Host: signedHost,
Path: "/images/photo.jpg",
},
Transform: imagerequest.Transform{
Size: imagerequest.Size{Width: 50, Height: 50},
Format: imagerequest.FormatJPEG,
Quality: tt.quality,
FitMode: tt.fitMode,
},
}, time.Hour)
if err != nil {
t.Fatalf("GenerateSignedURL() error = %v", err)
}
status := getImage(t, fix, signedURL)
status := getImage(t, setupTestHandler(t), signedURL)
if status != http.StatusBadGateway {
t.Errorf("status = %d, want %d", status, http.StatusBadGateway)
}
@@ -178,10 +212,10 @@ func TestHandleImage_InvalidExp_Returns400(t *testing.T) {
}
// TestHandleImage_GeneratedSignedURLWithSourceQueryVerifies sends URLs built
// by the service's signed-URL generator for source URLs with a query to the
// route, through a chi router: chi routes on the path as the client wrote it
// whenever that is not Go's own encoding of it. A 502 means the signature
// passed, so the route read the source path and query that were signed.
// by generateSignedURL for source URLs with a query to the route, through a
// chi router: chi routes on the path as the client wrote it whenever that is
// not Go's own encoding of it. A 502 means the signature passed, so the route
// read the source path and query that were signed.
func TestHandleImage_GeneratedSignedURLWithSourceQueryVerifies(t *testing.T) {
t.Parallel()
@@ -201,24 +235,20 @@ func TestHandleImage_GeneratedSignedURLWithSourceQueryVerifies(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
fix := setupTestHandler(t)
signedURL := generateSignedURL("test-signing-key-must-be-32-chars",
&imagerequest.Request{
Source: imagerequest.Source{
Host: signedHost,
Path: photoPath,
Query: tt.query,
},
Transform: imagerequest.Transform{
Size: imagerequest.Size{Width: 50, Height: 50},
Format: imagerequest.FormatJPEG,
},
}, time.Hour)
signedURL, err := fix.service.GenerateSignedURL("", &imagerequest.Request{
Source: imagerequest.Source{
Host: signedHost,
Path: photoPath,
Query: tt.query,
},
Transform: imagerequest.Transform{
Size: imagerequest.Size{Width: 50, Height: 50},
Format: imagerequest.FormatJPEG,
},
}, time.Hour)
if err != nil {
t.Fatalf("GenerateSignedURL() error = %v", err)
}
status := getImage(t, fix, signedURL)
status := getImage(t, setupTestHandler(t), signedURL)
if status != http.StatusBadGateway {
t.Errorf("status = %d, want %d", status, http.StatusBadGateway)
}
@@ -280,7 +310,7 @@ func TestHandleImage_SourceQueryEncodedAnyWay(t *testing.T) {
// TestHandleImage_SourceURLHoldingPercent25Verifies signs a source path and a
// source query that each hold %25, the percent-escape of a literal "%", and
// sends each to the route written as the README says, with that "%" written as
// %25, and as GenerateSignedURL writes it. A 502 means the signature passed.
// %25, and as generateSignedURL writes it. A 502 means the signature passed.
func TestHandleImage_SourceURLHoldingPercent25Verifies(t *testing.T) {
t.Parallel()
@@ -326,27 +356,23 @@ func TestHandleImage_SourceURLHoldingPercent25Verifies(t *testing.T) {
}
})
t.Run(tt.name+" written by GenerateSignedURL", func(t *testing.T) {
t.Run(tt.name+" written by generateSignedURL", func(t *testing.T) {
t.Parallel()
fix := setupTestHandler(t)
signedURL := generateSignedURL("test-signing-key-must-be-32-chars",
&imagerequest.Request{
Source: imagerequest.Source{
Host: signedHost,
Path: tt.sourcePath,
Query: tt.sourceQuery,
},
Transform: imagerequest.Transform{
Size: imagerequest.Size{Width: 50, Height: 50},
Format: imagerequest.FormatJPEG,
},
}, time.Hour)
signedURL, err := fix.service.GenerateSignedURL("", &imagerequest.Request{
Source: imagerequest.Source{
Host: signedHost,
Path: tt.sourcePath,
Query: tt.sourceQuery,
},
Transform: imagerequest.Transform{
Size: imagerequest.Size{Width: 50, Height: 50},
Format: imagerequest.FormatJPEG,
},
}, time.Hour)
if err != nil {
t.Fatalf("GenerateSignedURL() error = %v", err)
}
status := getImage(t, fix, signedURL)
status := getImage(t, setupTestHandler(t), signedURL)
if status != http.StatusBadGateway {
t.Errorf("status = %d, want %d", status, http.StatusBadGateway)
}
@@ -17,11 +17,13 @@ import (
)
// signedPhotoURL returns a signed /v1/image/ URL, valid for a minute, for the
// JPEG at photoPath on signedHost at 50x50, made with h's image service.
func signedPhotoURL(t *testing.T, h *Handlers) string {
// JPEG at photoPath on signedHost at 50x50. It is signed with testSigningKey,
// the key of the image service newSignedHostServer builds. It takes a Handlers
// it does not use, so that it has the type of encPhotoURL.
func signedPhotoURL(t *testing.T, _ *Handlers) string {
t.Helper()
signedURL, err := h.imgSvc.GenerateSignedURL("", &imagerequest.Request{
return generateSignedURL(testSigningKey, &imagerequest.Request{
Source: imagerequest.Source{
Host: signedHost,
Path: photoPath,
@@ -31,11 +33,6 @@ func signedPhotoURL(t *testing.T, h *Handlers) string {
Format: imagerequest.FormatJPEG,
},
}, time.Minute)
if err != nil {
t.Fatalf("GenerateSignedURL() error = %v", err)
}
return signedURL
}
// encPhotoURL returns an encrypted /v1/e/ URL, which never expires, for the