From 9742842975168978fb9baccae05a6a6cca86c9f5 Mon Sep 17 00:00:00 2001 From: clawbot <35+clawbot@noreply.example.org> Date: Tue, 29 Sep 2026 01:26:21 +0000 Subject: [PATCH] Document and test the one-year max-age cap (closes #63) The README said max-age is the seconds left until the URL's expiry, but a URL expiring more than a year away gets one year; it now says at most one year. A new case for an encrypted URL with a two-year TTL expects max-age=31536000. Model: opus-5-5 --- README.md | 7 ++++--- internal/handlers/image_cache_control_internal_test.go | 6 ++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 50f39ef..23fe41b 100644 --- a/README.md +++ b/README.md @@ -102,9 +102,10 @@ than once, is refused with 400. An image is served with `Cache-Control: public, max-age=, immutable`. When the URL has an expiry (an `exp`, or the TTL of an encrypted URL), -`max-age` is the whole seconds left until then, so no browser or proxy cache -keeps the image after pixa would refuse the URL. A URL with no expiry gets one -year. `immutable` only stops a client revalidating while its copy is fresh. +`max-age` is the whole seconds left until then, at most one year, so no browser +or proxy cache keeps the image after pixa would refuse the URL. A URL with no +expiry gets one year. `immutable` only stops a client revalidating while its +copy is fresh. The login form (`POST /`) is limited to 5 attempts per minute per client address, counting an IPv6 client by its /64; an attempt over the limit is diff --git a/internal/handlers/image_cache_control_internal_test.go b/internal/handlers/image_cache_control_internal_test.go index a7522da..bb6a6b9 100644 --- a/internal/handlers/image_cache_control_internal_test.go +++ b/internal/handlers/image_cache_control_internal_test.go @@ -158,8 +158,9 @@ func TestHandleImage_AllowlistedHost_MaxAge(t *testing.T) { } // TestHandleImageEnc_MaxAge verifies that an image served through an encrypted -// URL with a 60 second TTL may be cached for at most those 60 seconds, and that -// one made without a TTL, which never expires, may be cached for a year. +// URL with a 60 second TTL may be cached for at most those 60 seconds, that one +// with a two-year TTL may be cached for a year, and that one made without a +// TTL, which never expires, may be cached for a year. func TestHandleImageEnc_MaxAge(t *testing.T) { t.Parallel() @@ -170,6 +171,7 @@ func TestHandleImageEnc_MaxAge(t *testing.T) { wantAtMost int }{ {"60 second TTL", time.Now().Add(time.Minute).Unix(), 50, 60}, + {"two-year TTL", time.Now().Add(2 * 365 * 24 * time.Hour).Unix(), 31536000, 31536000}, {"no TTL", 0, 31536000, 31536000}, }