Move ImageProcessor, Params, New(), DefaultMaxInputBytes, ErrInputDataTooLarge,
and related types from internal/imgcache/ into a new standalone package
internal/imageprocessor/.
The imageprocessor package defines its own Format, FitMode, Size, Request, and
Result types, making it fully independent with no imports from imgcache. The
imgcache service converts between its own types and imageprocessor types at the
boundary.
Changes:
- New package: internal/imageprocessor/ with imageprocessor.go and tests
- Removed: processor.go and processor_test.go from internal/imgcache/
- Removed: Processor interface and ProcessResult from imgcache.go (now unused)
- Updated: service.go uses *imageprocessor.ImageProcessor directly
- Copied: testdata/red.avif for AVIF decode test
Addresses review feedback on PR #37: image processing is a distinct concern
from the HTTP service layer and belongs in its own package.
SourceURL() previously hardcoded https:// regardless of the AllowHTTP
config setting. This made testing with HTTP-only test servers impossible.
Add AllowHTTP field to ImageRequest and use it to determine the URL
scheme. The Service propagates the config setting to each request.
Fixes#1
- Capture TLS version, cipher suite, HTTP version, and remote addr
- Add download bitrate using go-humanize SI formatting
- Use consistent WxH format for dimensions (not struct notation)
- Rename input/output to src/dst for consistency
- Add separate "upstream fetched" log with connection details
FetchResult now includes:
- StatusCode: HTTP status from upstream
- FetchDurationMs: time to fetch from upstream
- RemoteAddr: upstream server address
SourceMetadata now stores:
- ContentLength: size from upstream
- FetchDurationMs: fetch timing
- RemoteAddr: for debugging
Image conversion log now includes:
- host: source hostname (was missing)
- path: source path (renamed from file)
- convert_ms: image processing time
- quality: requested quality setting
- fit: requested fit mode
- Return ErrUnsupportedOutputFormat for WebP/AVIF encoding
- Return ErrInvalidFitMode for unknown fit mode values
- Add ValidateFitMode() for input validation
- Validate fit mode at handler level before processing
Silent fallbacks violate the principle of least surprise and mask bugs.
When a user explicitly specifies a value, we should either honor it or
return an error - never silently substitute a different value.