Skip to content

Promote the Edge Proxy Cache Lifetimes - #494

Merged
ptr727 merged 2 commits into
mainfrom
develop
Oct 24, 2026
Merged

ptr727 merged 2 commits into
mainfrom
develop

Conversation

@ptr727

@ptr727 ptr727 commented Oct 24, 2026

Copy link
Copy Markdown
Owner

Summary

Promotes the Blog half of the Cloudflare proxy preparation that ptr727/HomeAutomation-Config#580 tracks.

  • #492 gives every blog response its own Cache-Control. Pages, feeds, the sitemap, index.json, robots.txt, the redirects, and both error pages answer no-cache. The fingerprinted /assets/ are immutable for a year, and /media/ and the root icons get an hour. checks/log-review.jq reads the last element of ClientHost, which is the address the edge saw. OPERATIONS.md and deploy/README.md describe the edge tier and the lifetime classes.

The Dependabot action bumps on develop already match main, so the tree diff is this one change. It adds comment lines to deploy/Caddyfile and checks/log-review.jq, so this PR carries the comments label, as #492 did.

The HomeAutomation-Config session reviewed #492 against Traefik, Caddy, and Cloudflare behavior and found it correct and safe to release. Its follow-ups, which must land before a release runs its gate against a proxied hostname, go in their own feature PR into develop.

Release

#492 changes deploy/Caddyfile, so a release and deploy follow the merge. That covers the GitHub release, the VPS production deploy, and the local production mirror. The change passed the full live check on the local staging mirror (1294 URLs) three times, and three local strict review passes, the last clean.

🤖 Generated with Claude Code

* Name a Cache Lifetime on Every Response Ahead of an Edge Proxy

A proxy that caches by file extension sits in front of neither site today,
and nothing in the bundle says how long a copy may live, so a browser guesses
from Last-Modified and an edge would apply its own defaults. Every blog
response now carries a Cache-Control: pages and feeds revalidate on every
use, the fingerprinted assets are immutable, and media is bounded to an hour
so a replaced image propagates without a purge. Both error pages answer
no-cache whatever path they stand in for, and the family pages state the same.

The log review keeps the last element of ClientHost, since a proxied request
carries the forwarded chain there and a client may prepend any value. The
operations doc names the edge as a tier above Traefik and what it hides.

Verified on the local staging mirror: the live check passes, and each class
serves the header the deploy README's table states.

* Scope the Lifetime Claims and Name Cloudflare Where the Edge Is Meant

The first strict review pass found the deploy README claiming a lifetime on every blog response while the redirects carry none, the operations doc and the jq comment using the edge for Cloudflare where that section means Traefik, the forwarded-chain claim missing the trust condition it depends on, and null guards on a field Traefik always writes.

* Shorten Two Cache Lifetime Sentences and Name the Family Matcher

The second strict review pass found two sentences over the length rule and a claim that the family block has a default header where the catch-all matcher is what reaches its redirects.

* Run the Baseline Cache Header Ahead of the Redirects

Copilot found that the redirect handlers end the route before the baseline no-cache header ran, so a 301 carried no lifetime and a changed map target could outlive a deploy in a cache. The baseline now runs first and the file classes override it. Verified on the local staging mirror: the live check passes, a legacy media redirect and a feed redirect answer no-cache, and the media and error classes keep their headers.

* Place the Media Lifetime Comment Above the Rule It Explains
@ptr727 ptr727 added the comments Permits the comment lines the pull request adds or edits, which the prose gate otherwise refuses label Oct 24, 2026
Copilot AI lite review requested due to automatic review settings October 24, 2026 01:36
@coderabbitai

coderabbitai Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 5c01a56f-7221-4fbf-9f40-73998a4aaba6
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 49.70%. Comparing base (1861c43) to head (f35ec08).
⚠️ Report is 139 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #494   +/-   ##
=======================================
  Coverage   49.70%   49.70%           
=======================================
  Files          10       10           
  Lines        3058     3058           
=======================================
  Hits         1520     1520           
  Misses       1538     1538           
Flag Coverage Δ
python-3.13 49.70% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The Caddy image matcher may cache unintended paths, and the documentation contains two style nits.

No open issues 🎉

What changed in this PR

Promotes explicit cache lifetimes for Blog and family-site responses ahead of Cloudflare proxying, while making log analysis proxy-aware.

Changes:

  • Adds cache-control policies for pages, assets, media, icons, redirects, and errors.
  • Documents the Cloudflare edge tier and cache lifetime classes.
  • Extracts the final client address from forwarded ClientHost chains.
File Summary Review findings
OPERATIONS.md Documents the Cloudflare edge tier and client-address handling. No findings.
deploy/​README.md Defines cache lifetime classes and their operational rationale. Two documentation-style nits regarding hard-wrapped paragraphs.
deploy/​Caddyfile Applies cache headers across site, asset, media, redirect, and error responses. One moderate finding: image matchers may apply the one-hour policy to unintended paths.
checks/​log-review.jq Normalizes forwarded client addresses by selecting the final address. No findings.

Review effort: Lite

@ptr727

ptr727 commented Oct 24, 2026

Copy link
Copy Markdown
Owner Author

Answering the review headline on 070b7ab.

"The Caddy image matcher may cache unintended paths": not a finding. @media path /media/* /*.png /*.ico matches root-level files only, since a middle wildcard in a Caddy path matcher does not cross a /. The built site holds four root-level images, apple-touch-icon.png, favicon-16x16.png, favicon-32x32.png, and favicon.ico, which is the "root icons" class deploy/README.md names. Measured on the local staging mirror: /favicon.ico and /apple-touch-icon.png answer public, max-age=3600, and a nested /external/<file>.png answers no-cache, the baseline value.

"Two documentation-style nits regarding hard-wrapped paragraphs": real. The fleet rule is one logical paragraph per line. #496 rewrites the "Cache lifetimes" section that way, and this promotion picks it up once #496 merges. The rest of deploy/README.md predates this change and is not part of it.

…496)

* Defeat the Edge Cache in the Media Check and Name the Zone Settings

The live check asks for each media file with a per-run query, on the
first request and on the legacy hop, so an edge copy cannot answer for
a file a release lost. Page classes gain no-transform, which opts the
bundle out of Cloudflare's content rewrites whatever the zone enables.
deploy/README.md names the Browser Cache TTL and Caching Level the
lifetimes depend on, and OPERATIONS.md corrects the robots.txt default
and says client_ip is client-chosen behind Cloudflare.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Write the Cache Lifetimes Section One Paragraph per Line

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Serve the Blog's Error Page Precompressed and Name the Page Value

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Bust the Media Cache One Way and Qualify client_ip in the README

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Drop no-transform Until Its Effect on Compression Is Measured

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Use Reference Links in the Deploy README and Say no-cache Revalidates

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Unresolved cache-matching and redirect query-handling issues must be addressed before approval.

No open issues 🎉

Review effort: Lite

@ptr727

ptr727 commented Oct 24, 2026

Copy link
Copy Markdown
Owner Author

Answering the review headline on f35ec08, "Unresolved cache-matching and redirect query-handling issues". The round names no file, line, or finding, so this reads it against the head.

  • Cache matching: the @media matcher point from the round on 070b7ab, answered above. /*.png and /*.ico match root-level files only, the four root icons, and a nested /external/<file>.png answers the no-cache baseline, measured on the local staging mirror.
  • Redirect query handling: the one query this head handles is the live check's ?live-check=<id> on media requests. redir @uploads /media/{re.up.1} 301 writes no query into its target, and checks/golden-media-live.txt holds no ?, so both the first request and the hop get exactly one query. The unit test mocks the redirect dropping the query, as Caddy does, and asserts the token on every media path. Every page redirect is unchanged by this promotion.

No change follows from the headline. #496, which this head carries, passed the full live check on the local staging mirror (1294 URLs), and its final content had a recorded local strict review pass with no findings.

@ptr727
ptr727 merged commit 6cda25d into main Oct 24, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comments Permits the comment lines the pull request adds or edits, which the prose gate otherwise refuses

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants