sneak
51a1ae4a13
Add failing test for hot cache ContentType
...
Hot cache lookups must return ContentType to serve correct
Content-Type headers. Currently returns empty string.
2026-01-08 12:25:01 -08:00
sneak
10b5cc7063
Fix proportional scaling when single dimension is 0
...
When only width or height is specified (the other being 0), scale the
image proportionally to maintain aspect ratio. Previously, 0 was passed
directly to the resize function which produced a 0x0 image.
2026-01-08 12:20:58 -08:00
sneak
817d760b4d
Add failing tests for proportional scaling
...
When only one dimension is provided (e.g., width=400, height=0),
the image should scale proportionally. Currently returns 0x0.
2026-01-08 12:20:19 -08:00
sneak
70d55977c0
Add WebP encoding support
...
Uses github.com/gen2brain/webp - a CGO-free library that uses WASM via
wazero runtime for encoding. WebP decoding was already supported.
- Add gen2brain/webp dependency for encoding
- Implement WebP encoding in processor.go
- Add FormatWebP to SupportedOutputFormats
- Re-enable WebP option in generator form dropdown
- Mark WebP encoding as complete in TODO.md
2026-01-08 11:55:45 -08:00
sneak
0c9eb35bd2
Add failing test for WebP encoding support
...
TDD: This test expects WebP encoding to succeed. It currently fails
because WebP encoding is not implemented (returns ErrUnsupportedOutputFormat).
The test will pass once we add the gen2brain/webp library.
2026-01-08 11:54:03 -08:00
sneak
aab43db44a
Add WebP and AVIF encoding support to P0 TODO
2026-01-08 11:12:59 -08:00
sneak
064ab10607
Add no-silent-fallback rule to CLAUDE.md
...
Never silently fall back to a different setting when a user's parameter
explicitly specifies a value. Return an error for invalid explicit values;
only apply defaults for omitted parameters.
2026-01-08 11:08:33 -08:00
sneak
37af10cc2b
Update generator form for supported formats and Never expiry
...
- Remove WebP and AVIF options (encoding not supported)
- Add GIF option (encoding is supported)
- Add 'Never' TTL option as default
2026-01-08 11:08:28 -08:00
sneak
b55b75cbe7
Fix silent fallbacks for unsupported formats and fit modes
...
- 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.
2026-01-08 11:08:22 -08:00
sneak
df6d347e68
Add tests for unsupported output format errors
...
Tests verify that WebP and AVIF encoding requests return
ErrUnsupportedOutputFormat instead of silently falling back
to a different format.
2026-01-08 11:08:16 -08:00
sneak
014c144d73
Add 'Never' expiry option for encrypted URLs
...
- Make ExpiresAt optional in CBOR (omitempty) for smaller tokens
- Treat ExpiresAt=0 as 'never expires' in parser
- URL-encode token with url.PathEscape() for safety
- Add 'Never' as default TTL option in generator form
2026-01-08 11:08:11 -08:00
sneak
d9f4e2038e
Add manual test script for auth and encrypted URLs
...
scripts/manual-test.sh tests:
1. Healthcheck endpoint
2. Login page displays
3. Wrong password shows error
4. Correct password shows generator
5. Generate encrypted URL
6. Fetch image via encrypted URL
7. Fetch image via direct proxy (whitelisted)
8. Logout redirects to login
9. Expired URL returns 410
2026-01-08 10:53:02 -08:00
sneak
b233871241
Add detailed logging for image conversions on cache miss
...
Log includes:
- file path
- input/output format
- input/output size in bytes
- input/output dimensions
- size ratio (percentage)
Also adds InputWidth, InputHeight, InputFormat to ProcessResult
2026-01-08 10:44:34 -08:00
sneak
02de534cc2
Reorganize TODO.md: remove completed, prioritize for 1.0
...
P0 Critical: Manual testing, cache eviction, config validation
P1 Production: Blocked networks, rate limiting, EXIF stripping
P2 Nice to have: Everything else
2026-01-08 10:41:00 -08:00
sneak
d8bb374f73
Merge feature/http-response-handling: ETag, HEAD, conditional requests
2026-01-08 10:09:14 -08:00
sneak
774ee97ba1
Update TODO.md: mark HTTP response handling items complete
...
Completed:
- ETag generation and validation
- Conditional requests (If-None-Match)
- HEAD request support
- Metrics endpoint with auth (already implemented)
2026-01-08 10:09:10 -08:00
sneak
1f809a6fc9
Implement ETag, HEAD requests, and conditional requests
...
- Add ETag generation based on output content hash (first 16 chars)
- Add ContentLength to ImageResponse from cache
- Add LoadWithSize method to ContentStorage
- Add GetOutputWithSize method to Cache
- Handle HEAD requests returning headers only
- Handle If-None-Match conditional requests returning 304
- Register HEAD route for image proxy endpoint
2026-01-08 10:08:38 -08:00
sneak
4df3e44eff
Add failing tests for ETag, HEAD requests, and conditional requests
...
TDD: Write tests first before implementation for:
- ETag generation and consistency in service layer
- HEAD request support (headers only, no body)
- Conditional requests with If-None-Match header (304 responses)
2026-01-08 10:06:18 -08:00
sneak
aed9dd6e8d
Merge feature/graceful-shutdown-and-sanitization: Add security headers middleware
2026-01-08 10:02:34 -08:00
sneak
6f423af65d
Update TODO.md: mark graceful shutdown and sanitization as complete
2026-01-08 10:02:29 -08:00
sneak
2e349a8b83
Implement security headers middleware
...
Adds X-Content-Type-Options, X-Frame-Options, Referrer-Policy,
and X-XSS-Protection headers to all responses.
2026-01-08 10:02:17 -08:00
sneak
5de7a26735
Add failing tests for security headers middleware
...
Tests for X-Content-Type-Options, X-Frame-Options, Referrer-Policy,
X-XSS-Protection headers on responses.
2026-01-08 10:01:36 -08:00
sneak
9592175238
Merge feature/security-validations: Add input dimension and path traversal validation
2026-01-08 08:50:43 -08:00
sneak
90be4e7763
Update TODO.md: mark security validations as complete
2026-01-08 08:50:37 -08:00
sneak
95408e68d4
Implement max input dimensions and path traversal validation
...
- Reject input images exceeding MaxInputDimension (8192px) to prevent DoS
- Detect path traversal: ../, encoded variants, backslashes, null bytes
2026-01-08 08:50:18 -08:00
sneak
c964feac7e
Add failing tests for input dimension and path traversal validation
...
Tests for:
- ErrInputTooLarge when input image exceeds MaxInputDimension
- ErrPathTraversal for ../, encoded traversal, backslashes, null bytes
2026-01-08 08:48:11 -08:00
sneak
857be30e82
Update TODO.md: mark auth/encrypted URLs feature as complete
2026-01-08 08:43:23 -08:00
sneak
06c99b6f4e
Merge feature/auth-and-encrypted-urls: Add login, sessions, and encrypted URLs
2026-01-08 07:41:28 -08:00
sneak
f601e17812
Add implementation plan for auth and encrypted URLs feature
2026-01-08 07:39:31 -08:00
sneak
6355886dba
Add vendoring and repo size guidelines to CLAUDE.md
2026-01-08 07:39:27 -08:00
sneak
2cbafe374c
Add mock fetcher and service tests for imgcache
...
Introduces Fetcher interface, mock implementation for testing,
and ApplyMigrations helper for test database setup.
2026-01-08 07:39:18 -08:00
sneak
1f0ec59eb5
Wire up auth routes and encrypted URL endpoint
...
Add session manager and encurl generator to handlers.
Register /, /logout, /generate, /v1/e/{token}, /static/* routes.
2026-01-08 07:38:44 -08:00
sneak
08d6e264ed
Add auth and encrypted image handlers
...
Login page, logout, URL generator form, and /v1/e/{token}
endpoint for serving images from encrypted URLs.
2026-01-08 07:38:15 -08:00
sneak
aad5e59d23
Add static files and HTML templates for web UI
...
Embedded Tailwind CSS and login/generator templates.
Self-contained with no external dependencies.
2026-01-08 07:38:09 -08:00
sneak
c033e918f0
Add encurl package for encrypted URL tokens
...
CBOR-encoded payloads with NaCl secretbox encryption.
Supports expiration, image parameters with omitempty defaults.
2026-01-08 07:38:05 -08:00
sneak
041b18f651
Add session package for encrypted cookie management
...
Uses gorilla/securecookie with keys derived via HKDF.
30-day TTL, HttpOnly, Secure, SameSiteStrict cookies.
2026-01-08 07:37:58 -08:00
sneak
3f4f345d1c
Add seal package for authenticated encryption
...
Provides HKDF-SHA256 key derivation and NaCl secretbox
(XSalsa20-Poly1305) encryption/decryption utilities.
2026-01-08 07:37:53 -08:00
sneak
1e890ffbcc
Fix spelling, punctuation, and capitalization in CLAUDE.md
2026-01-08 05:29:08 -08:00
sneak
f244d9c7e0
Add per-host connection limits for upstream fetching
...
- Add upstream_connections_per_host config option (default: 20)
- Implement per-host semaphores to limit concurrent connections
- Semaphore released when response body is closed
- Prevents overwhelming origin servers with parallel requests
2026-01-08 05:19:20 -08:00
sneak
49ff72dfa8
Add bin/ to gitignore
2026-01-08 05:14:11 -08:00
sneak
6304556837
Refactor to serve all responses from cached files on disk
...
- StoreOutput now returns output hash for immediate retrieval
- Cache misses now serve from disk file after storing (same as hits)
- Log served_bytes from actual io.Copy result (avoids stat calls)
- Remove ContentLength field usage for cache hits (stream from file)
- Fix tests to properly check all return values
2026-01-08 05:11:55 -08:00
sneak
1a97f42cd8
Add detailed logging for image requests with cache status and timing
2026-01-08 05:04:08 -08:00
sneak
6a20406b0f
Add -config flag using cobra to specify config file path
2026-01-08 04:58:05 -08:00
sneak
271527679e
Add example config file with whitelisted hosts
2026-01-08 04:09:06 -08:00
sneak
9647829ac9
Support YAML list format for whitelist_hosts config
2026-01-08 04:08:51 -08:00
sneak
3fcf9d9146
Add failing test for YAML list format in whitelist_hosts config
2026-01-08 04:08:11 -08:00
sneak
cc0fd29954
Update TODO.md with completed image processing items
2026-01-08 04:02:53 -08:00
sneak
fd2d108f9c
Wire up image handler endpoint with service orchestration
...
- Add image proxy config options (signing_key, whitelist_hosts, allow_http)
- Create Service to orchestrate cache, fetcher, and processor
- Initialize image service in handlers OnStart hook
- Implement HandleImage with URL parsing, signature validation, cache
- Implement HandleRobotsTxt for search engine prevention
- Parse query params for signature, quality, and fit mode
2026-01-08 04:01:53 -08:00
sneak
5462c9222c
Add pure Go image processor with resize and format conversion
...
Implements the Processor interface using disintegration/imaging library.
Supports JPEG, PNG, GIF, WebP decoding and JPEG, PNG, GIF encoding.
Includes all fit modes: cover, contain, fill, inside, outside.
2026-01-08 03:54:50 -08:00
sneak
9629139989
Add tests for cache service
...
Tests cover: lookup miss/hit, store source/output, negative caching,
negative cache expiry, hot cache, output retrieval, stats, and cleanup.
2026-01-08 03:39:23 -08:00
sneak
11295db68a
Exclude vendor directory from format checks
2026-01-08 03:37:58 -08:00
sneak
d9e57de108
Add TDD and commit workflow rules to CLAUDE.md
2026-01-08 03:36:22 -08:00
sneak
b14c897408
Update TODO.md with completed caching layer items
2026-01-08 03:36:05 -08:00
sneak
6d32b7ee23
Fix formatting in fetcher and signature tests
2026-01-08 03:36:00 -08:00
sneak
30c5c077e5
Add cache service with hot cache and negative caching
...
Implements cache lookup with in-memory hot path, source/output storage,
negative caching for failed fetches, TTL expiration, and statistics tracking.
2026-01-08 03:35:55 -08:00
sneak
2f20c71da0
Add content-addressable storage and cache key generation
...
ContentStorage stores blobs at <dir>/<ab>/<cd>/<sha256> paths.
MetadataStorage stores JSON at <dir>/<host>/<path_hash>.json.
CacheKey generates unique keys from request parameters.
2026-01-08 03:35:50 -08:00
sneak
4595929275
Add embedded SQL migrations system
...
Migrations are stored in schema/*.sql and embedded via go:embed.
Applied migrations are tracked in schema_migrations table.
Initial schema includes source_content, source_metadata, output_content,
request_cache, negative_cache, and cache_stats tables.
2026-01-08 03:35:43 -08:00
sneak
27eb9fb513
Add HMAC signature specification to README
...
Documents the signature scheme: HMAC-SHA256 over host:path:query:width:height:format:expiration
with base64url encoding and Unix timestamp expiration.
2026-01-08 03:35:36 -08:00
sneak
30d63e80dc
Add magic byte detection for image format validation
...
Implements format detection by checking file magic bytes for JPEG, PNG,
GIF, WebP, AVIF, and SVG. Includes validation against declared Content-Type.
2026-01-08 03:35:29 -08:00
sneak
9ff44b7e65
Update TODO.md with completed core features
2026-01-08 03:02:24 -08:00
sneak
cc2c40bfbf
Implement HMAC-SHA256 signature generation and verification
2026-01-08 03:02:09 -08:00
sneak
2b0ccd6052
Implement host whitelist for source domains
2026-01-08 03:00:53 -08:00
sneak
018c280267
Add ParseImagePath for chi wildcard and upstream fetcher with SSRF protection
2026-01-08 02:59:48 -08:00
sneak
c69ddf6f61
Implement URL parser for image proxy routes
2026-01-08 02:55:05 -08:00
sneak
a9573a4b10
Mark project setup tasks complete in TODO.md
2026-01-08 02:53:49 -08:00
sneak
09a0e6f039
Fix formatting alignment in server constants
2026-01-08 02:31:01 -08:00
sneak
1ac16bcfb4
Remove unused respondError function
2026-01-08 02:30:13 -08:00
sneak
837c91e0dd
Rename unused ctx parameters in server hooks
2026-01-08 02:29:48 -08:00
sneak
827f9743b8
Add package and const block comments to imgcache
2026-01-08 02:29:25 -08:00
sneak
453fd22ce2
Add doc comment to HandleHealthCheck method
2026-01-08 02:28:30 -08:00
sneak
eb2ba92745
Add comment to SQLite blank import
2026-01-08 02:28:05 -08:00
sneak
29adb6ee47
Rename unused parameters to _ to satisfy linter
2026-01-08 02:27:45 -08:00
sneak
146eeee070
Use bit shift for HTTPMaxHeaderBytes constant
2026-01-08 02:26:47 -08:00
sneak
31df1a4a03
Rename LoggerParams to Params to avoid stuttering
2026-01-08 02:26:15 -08:00
sneak
1824d99f55
Rename ServerParams to Params to avoid stuttering
2026-01-08 02:25:56 -08:00
sneak
3f6328766c
Rename MiddlewareParams to Params to avoid stuttering
2026-01-08 02:25:42 -08:00
sneak
ad89bd9232
Rename HealthcheckParams and HealthcheckResponse to avoid stuttering
2026-01-08 02:25:28 -08:00
sneak
43e4172fb3
Rename HandlersParams to Params to avoid stuttering
2026-01-08 02:25:00 -08:00
sneak
c68c8909f7
Rename DatabaseParams to Params to avoid stuttering
2026-01-08 02:24:40 -08:00
sneak
d95d31df25
Rename ConfigParams to Params to avoid stuttering
2026-01-08 02:24:20 -08:00
sneak
34fb126e6c
Add package comment and fix var-declaration in main
2026-01-08 02:23:56 -08:00
sneak
ef6e67e786
Add blank line before return in SourceURL
2026-01-08 02:23:23 -08:00
sneak
751e557884
Define ShutdownTimeout and SentryFlushTimeout constants
2026-01-08 02:22:58 -08:00
sneak
0eb6193431
Use HTTPWriteTimeout constant for request timeout
2026-01-08 02:22:25 -08:00
sneak
bf24a310bc
Define HTTP server timeout and header size constants
2026-01-08 02:21:54 -08:00
sneak
115f92660d
Define CORSMaxAgeSeconds constant
2026-01-08 02:21:30 -08:00
sneak
ce25ea8f6f
Define DefaultPort and DefaultStateDir constants
2026-01-08 02:21:00 -08:00
sneak
516853626d
Add basic webserver skeleton with healthcheck
2026-01-08 02:20:23 -08:00
sneak
38faf56be0
Add .gitignore
2026-01-08 02:20:18 -08:00
sneak
c491bc7af3
Add Go module definition
2026-01-08 02:18:49 -08:00
sneak
6071fd5bb7
Add project documentation and linter config
2026-01-08 02:18:45 -08:00
sneak
4ef9141960
Add Makefile with check, lint, test, fmt targets
...
- check: default target, runs fmt-check, lint, and test
- fmt-check: verifies code is properly formatted
- fmt: formats code with gofmt
- lint: runs golangci-lint
- test: runs go test
- build: builds pixad binary with version info
- clean: removes build artifacts
2026-01-08 01:51:46 -08:00
sneak
12f6f6fe75
Add TODO.md with implementation checklist
...
Complete linear checklist of tasks to implement the pixa caching
image reverse proxy server, covering project setup, core features,
caching, image processing, security, and operational concerns.
2026-01-08 01:51:15 -08:00