diff --git a/internal/imgcache/imgcache.go b/internal/imgcache/imgcache.go index f44df71..f6b0ef4 100644 --- a/internal/imgcache/imgcache.go +++ b/internal/imgcache/imgcache.go @@ -79,11 +79,18 @@ type ImageRequest struct { Signature string // Expires is the signature expiration timestamp Expires time.Time + // AllowHTTP indicates whether HTTP (non-TLS) is allowed for this request + AllowHTTP bool } -// SourceURL returns the full upstream URL to fetch +// SourceURL returns the full upstream URL to fetch. +// Uses http:// scheme when AllowHTTP is true, otherwise https://. func (r *ImageRequest) SourceURL() string { - url := "https://" + r.SourceHost + r.SourcePath + scheme := "https" + if r.AllowHTTP { + scheme = "http" + } + url := scheme + "://" + r.SourceHost + r.SourcePath if r.SourceQuery != "" { url += "?" + r.SourceQuery } diff --git a/internal/imgcache/service.go b/internal/imgcache/service.go index 5c90256..519f6c1 100644 --- a/internal/imgcache/service.go +++ b/internal/imgcache/service.go @@ -21,6 +21,7 @@ type Service struct { signer *Signer whitelist *HostWhitelist log *slog.Logger + allowHTTP bool } // ServiceConfig holds configuration for the image service. @@ -68,6 +69,11 @@ func NewService(cfg *ServiceConfig) (*Service, error) { log = slog.Default() } + allowHTTP := false + if cfg.FetcherConfig != nil { + allowHTTP = cfg.FetcherConfig.AllowHTTP + } + return &Service{ cache: cfg.Cache, fetcher: fetcher, @@ -75,6 +81,7 @@ func NewService(cfg *ServiceConfig) (*Service, error) { signer: signer, whitelist: NewHostWhitelist(cfg.Whitelist), log: log, + allowHTTP: allowHTTP, }, nil } @@ -83,6 +90,9 @@ var ErrNegativeCached = errors.New("request is in negative cache (recently faile // Get retrieves a processed image, fetching and processing if necessary. func (s *Service) Get(ctx context.Context, req *ImageRequest) (*ImageResponse, error) { + // Propagate AllowHTTP setting to the request + req.AllowHTTP = s.allowHTTP + // Check negative cache first - skip fetching for recently-failed URLs negHit, err := s.cache.checkNegativeCache(ctx, req) if err != nil { diff --git a/internal/imgcache/sourceurl_test.go b/internal/imgcache/sourceurl_test.go new file mode 100644 index 0000000..7119fa1 --- /dev/null +++ b/internal/imgcache/sourceurl_test.go @@ -0,0 +1,44 @@ +package imgcache + +import "testing" + +func TestImageRequest_SourceURL_DefaultHTTPS(t *testing.T) { + req := &ImageRequest{ + SourceHost: "cdn.example.com", + SourcePath: "/photos/cat.jpg", + SourceQuery: "v=2", + } + + got := req.SourceURL() + want := "https://cdn.example.com/photos/cat.jpg?v=2" + if got != want { + t.Errorf("SourceURL() = %q, want %q", got, want) + } +} + +func TestImageRequest_SourceURL_AllowHTTP(t *testing.T) { + req := &ImageRequest{ + SourceHost: "localhost:8080", + SourcePath: "/photos/cat.jpg", + AllowHTTP: true, + } + + got := req.SourceURL() + want := "http://localhost:8080/photos/cat.jpg" + if got != want { + t.Errorf("SourceURL() = %q, want %q", got, want) + } +} + +func TestImageRequest_SourceURL_AllowHTTPFalse(t *testing.T) { + req := &ImageRequest{ + SourceHost: "cdn.example.com", + SourcePath: "/img.jpg", + AllowHTTP: false, + } + + got := req.SourceURL() + if got != "https://cdn.example.com/img.jpg" { + t.Errorf("SourceURL() = %q, want https scheme", got) + } +}