Files
pixa/internal/allowlist/allowlist.go
T
sneak 5a2aa94691
check / check (push) Waiting to run
Remove the code nothing in production calls (closes #312)
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
2026-10-26 09:40:35 +00:00

75 lines
1.7 KiB
Go

// Package allowlist provides host-based URL allow-listing for the image proxy.
package allowlist
import (
"net/url"
"strings"
)
// HostAllowList checks whether source hosts are permitted.
type HostAllowList struct {
// exactHosts contains hosts that must match exactly (e.g., "cdn.example.com")
exactHosts map[string]struct{}
// suffixHosts contains domain suffixes to match
// (e.g., ".example.com" matches "cdn.example.com")
suffixHosts []string
}
// New creates a HostAllowList from a list of host patterns.
// Patterns starting with "." are treated as suffix matches.
// Examples:
// - "cdn.example.com" - exact match only
// - ".example.com" - matches cdn.example.com, images.example.com, etc.
func New(patterns []string) *HostAllowList {
w := &HostAllowList{
exactHosts: make(map[string]struct{}),
suffixHosts: make([]string, 0),
}
for _, pattern := range patterns {
pattern = strings.ToLower(strings.TrimSpace(pattern))
if pattern == "" {
continue
}
if strings.HasPrefix(pattern, ".") {
w.suffixHosts = append(w.suffixHosts, pattern)
} else {
w.exactHosts[pattern] = struct{}{}
}
}
return w
}
// IsAllowed checks if a URL's host is in the allow list.
func (w *HostAllowList) IsAllowed(u *url.URL) bool {
if u == nil {
return false
}
host := strings.ToLower(u.Hostname())
if host == "" {
return false
}
// Check exact match
if _, ok := w.exactHosts[host]; ok {
return true
}
// Check suffix match
for _, suffix := range w.suffixHosts {
if strings.HasSuffix(host, suffix) {
return true
}
// Also match if host equals the suffix without the leading dot
// e.g., pattern ".example.com" should match "example.com"
if host == strings.TrimPrefix(suffix, ".") {
return true
}
}
return false
}