Skip to content

fix: eliminate dead uid scale URLs under volatile ThumborScaleStorage - #18

Merged
jensens merged 10 commits into
mainfrom
fix/svg-uid-scale-urls
Aug 3, 2026
Merged

jensens merged 10 commits into
mainfrom
fix/svg-uid-scale-urls

Conversation

@jensens

@jensens jensens commented Aug 3, 2026 •

Copy link
Copy Markdown
Member

Closes #17.

Root cause (see the correction comment on the issue): the volatile
ThumborScaleStorage makes every uid-based scale URL unresolvable —
get_or_generate reads a fresh empty per-instance dict on traversal.
purge_scales was a red herring.

Two-pronged fix:

  1. Never emit uid URLs. Skip-Thumbor types (SVG) get the original
    field URL + ?v=<modified-millis> cache buster, wired into both
    plone.namedfile code paths (legacy __init__ for 7.x — the pinned
    version, where _scale_url is never called — and _scale_url for

    = 8.0.0a2). The HiDPI srcset attribute and the srcset() method
    now emit Thumbor URLs. picture() needs no change — it consumes
    scale().url. srcset() mirrors the parent's edge-case guards, and
    the HiDPI srcset path threads crop info through for scale infos
    that carry a scale name.

  2. Heal uid URLs already in the wild (cached HTML, stale
    image_scales catalog metadata): get_or_generate parses the
    deterministic {fieldname}-{width}-{md5} uid and regenerates the
    info on the fly. Raster heals to a 302 → Thumbor, SVG serves the
    original field bytes. Only widths registered in plone.allowed_sizes
    are accepted (width 0 = original), so arbitrary dimensions cannot be
    signed on demand.

Ops note: no reindex strictly required thanks to (2), but a one-off
image_scales reindex after deploy stops stale uid URLs from being
served in fresh catalog-driven listings.

🤖 Generated with Claude Code

jensens and others added 10 commits August 3, 2026 23:08
#17)

- Add _skip_type_fallback_url() helper to generate field URLs with optional cache busters
- SVG images fall back to field URL (browsers scale vectors themselves)
- Cache buster uses data.modified (field) or context._p_mtime (content)
- Wire fallback in ThumborImageScale.__init__ (legacy path), ThumborImageScale._scale_url, and ThumborImageScaling._scale_url
- Add four new tests covering field URL behavior and cache busters

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ocs drift)

Also mark up zope2.Public as inline code in a security-doc heading so
vale (pre-commit, changed-files-only) passes again.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@jensens
jensens merged commit 9dd033e into main Aug 3, 2026
4 checks passed
@jensens
jensens deleted the fix/svg-uid-scale-urls branch August 3, 2026 22:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SVG images: permanent 404 scale URLs — volatile ThumborScaleStorage makes every uid-based scale URL unresolvable

1 participant