ZDDC/zddc/internal/apps
ZDDC b20e98b6aa fix(apps): cache key now includes scheme + full host:port (no collisions)
The previous keyForURL stripped default ports (:443 for https, :80
for http) and omitted the scheme, so:

  http://example.com/x.html   ──┐
  https://example.com/x.html  ──┴──→ same cache entry (collision)

  https://example.com/x.html      ──┐
  https://example.com:443/x.html  ──┴──→ same cache entry

This was a defensible HTTP convention but a real correctness issue
on reverse-proxy stacks where http and https legitimately serve
different bytes for the same path, or where two upstreams share a
host but answer on different default ports.

New layout: <scheme>/<host>[:<port>]/<path>. Full origin tuple in
the key, no port stripping, scheme segregation. Examples:

  https/zddc.varasys.io/releases/archive_stable.html
  https/example.com:8443/x.html
  http/example.com/y.html      (distinct from https/example.com/y.html)

Operators retain the "ls _app/ to inspect what's cached" affordance
they relied on; they just see one extra directory layer (scheme
first, then host).

Tests:
  * Updated TestKeyForURL to assert the new layout for every
    previously-covered case
  * New TestKeyForURL_NoCollisions explicitly asserts that the
    dimensions previously collapsed (default-port↔bare, http↔https,
    different non-default ports) now produce distinct keys

Doc references to the cache layout under <ZDDC_ROOT>/_app/ updated
in zddc/README.md (3 mentions).

NOTE: existing _app/ caches under the old layout will be ignored
on first request after upgrade — entries will be re-fetched and
written to the new path. Operators can `rm -rf <ZDDC_ROOT>/_app`
during the upgrade window if they prefer not to have orphans.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 17:57:28 -05:00
..
embedded chore(embedded): cut v0.0.16-beta — refresh SHA off the dangling 8df0def 2026-05-04 07:57:35 -05:00
apps.go feat(zddc-server): apps fetch+cache subsystem with cascade overrides 2026-05-01 15:25:25 -05:00
apps_test.go feat(zddc-server): apps fetch+cache subsystem with cascade overrides 2026-05-01 15:25:25 -05:00
availability.go feat(browse): generic directory listing tool — default at folder URLs 2026-05-03 19:56:51 -05:00
availability_test.go feat(zddc-server): apps fetch+cache subsystem with cascade overrides 2026-05-01 15:25:25 -05:00
cache.go fix(apps): cache key now includes scheme + full host:port (no collisions) 2026-05-04 17:57:28 -05:00
cache_test.go fix(apps): cache key now includes scheme + full host:port (no collisions) 2026-05-04 17:57:28 -05:00
embed.go perf(server): ETag + max-age=0 on embedded HTML responses 2026-05-04 07:49:17 -05:00
fetch.go feat(zddc-server): apps fetch+cache subsystem with cascade overrides 2026-05-01 15:25:25 -05:00
handler.go perf(server): ETag + max-age=0 on embedded HTML responses 2026-05-04 07:49:17 -05:00
handler_test.go perf(server): ETag + max-age=0 on embedded HTML responses 2026-05-04 07:49:17 -05:00
singleflight.go feat(zddc-server): apps fetch+cache subsystem with cascade overrides 2026-05-01 15:25:25 -05:00
singleflight_test.go feat(zddc-server): apps fetch+cache subsystem with cascade overrides 2026-05-01 15:25:25 -05:00
versions.go feat(zddc-server): CLI flags, --version, CWD-default ZDDC_ROOT 2026-05-01 15:43:31 -05:00