[PR #513] [MERGED] fix: image optimizer fallback stream reuse #635

Closed
opened 2026-05-06 13:09:13 +02:00 by BreizhHardware · 0 comments

📋 Pull Request Information

Original PR: https://github.com/cloudflare/vinext/pull/513
Author: @JaredStowell
Created: 3/13/2026
Status: Merged
Merged: 3/13/2026
Merged by: @james-elicx

Base: mainHead: jstowell/fix-image-optimizer-fallback


📝 Commits (2)

📊 Changes

4 files changed (+291 additions, -15 deletions)

View changed files

📝 packages/vinext/src/index.ts (+2 -1)
📝 packages/vinext/src/server/image-optimization.ts (+25 -11)
tests/image-optimization-parity.test.ts (+151 -0)
📝 tests/shims.test.ts (+113 -3)

📄 Description

Fix /_vinext/image fallback behavior when image transformation fails after consuming the source stream.

This also fixes a Pages Router dev-mode parity bug where local image redirects did not percent-encode unicode paths in the Location header.

Root cause

The image optimization path on Workers streams the source image into the transform handler. If the transform implementation starts consuming the source stream and then throws, the original response body can no longer be reused safely for fallback.

Fix

  1. tries the transform normally
  2. tries to serve the original source response directly if transform fails
  3. re-fetches the source image only if the fallback path cannot reuse the original body because it was already disturbed/locked

This keeps the normal success path streaming and avoids tee-based buffering, while still recovering correctly from consumed-stream failures.

Changes

  • replace clone-based fallback in the shared image optimizer with refetch-on-failure fallback
  • preserve cache/security headers on passthrough responses via a shared helper
  • fix Pages Router dev image redirects to emit percent-encoded Location headers for unicode paths
  • add regression tests for:
    • transform failure before body consumption
    • transform failure after body consumption
    • refetch fallback header behavior
    • refetch fallback 404 behavior
    • refetch fallback unsafe-content behavior
  • add integration tests for local unicode and space-containing image URLs in both App Router and Pages Router

Testing

  • pnpm test tests/shims.test.ts -t "handleImageOptimization"
  • pnpm test tests/image-optimization-parity.test.ts
  • pnpm run fmt
  • pnpm run typecheck

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/cloudflare/vinext/pull/513 **Author:** [@JaredStowell](https://github.com/JaredStowell) **Created:** 3/13/2026 **Status:** ✅ Merged **Merged:** 3/13/2026 **Merged by:** [@james-elicx](https://github.com/james-elicx) **Base:** `main` ← **Head:** `jstowell/fix-image-optimizer-fallback` --- ### 📝 Commits (2) - [`855211d`](https://github.com/cloudflare/vinext/commit/855211d229be5077f67383cffa0fd5621dbdc1cb) fix image optimizer fallback - [`906b47a`](https://github.com/cloudflare/vinext/commit/906b47a3a441e0831bf98be3d1ca51b0176b047c) refetch on failure ### 📊 Changes **4 files changed** (+291 additions, -15 deletions) <details> <summary>View changed files</summary> 📝 `packages/vinext/src/index.ts` (+2 -1) 📝 `packages/vinext/src/server/image-optimization.ts` (+25 -11) ➕ `tests/image-optimization-parity.test.ts` (+151 -0) 📝 `tests/shims.test.ts` (+113 -3) </details> ### 📄 Description Fix `/_vinext/image` fallback behavior when image transformation fails after consuming the source stream. This also fixes a Pages Router dev-mode parity bug where local image redirects did not percent-encode unicode paths in the `Location` header. ## Root cause The image optimization path on Workers streams the source image into the transform handler. If the transform implementation starts consuming the source stream and then throws, the original response body can no longer be reused safely for fallback. ## Fix 1. tries the transform normally 2. tries to serve the original source response directly if transform fails 3. re-fetches the source image only if the fallback path cannot reuse the original body because it was already disturbed/locked This keeps the normal success path streaming and avoids tee-based buffering, while still recovering correctly from consumed-stream failures. ## Changes - replace clone-based fallback in the shared image optimizer with refetch-on-failure fallback - preserve cache/security headers on passthrough responses via a shared helper - fix Pages Router dev image redirects to emit percent-encoded `Location` headers for unicode paths - add regression tests for: - transform failure before body consumption - transform failure after body consumption - refetch fallback header behavior - refetch fallback 404 behavior - refetch fallback unsafe-content behavior - add integration tests for local unicode and space-containing image URLs in both App Router and Pages Router ## Testing - `pnpm test tests/shims.test.ts -t "handleImageOptimization"` - `pnpm test tests/image-optimization-parity.test.ts` - `pnpm run fmt` - `pnpm run typecheck` --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
BreizhHardware 2026-05-06 13:09:13 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/vinext#635
No description provided.