Files
Evan JarrettandClaude Opus 5.5 7c36fb76f2 deploy: add the Bunny middleware that tells the appview a HEAD was a HEAD
Bunny forwards HEAD to the origin as GET, and edge rules run after the
rewrite, so the X-Original-Method header the appview reads (a2d3428) can
only come from an Edge Script's onClientRequest hook. Without it a blob
existence check on a hold with no download CDN gets a GET-signed URL and
S3 answers the client's HEAD with a 403, aborting the push.

The README records the pull zone requirements (dashboard link, before-cache
phase, no conflicting edge rule), the bundled build, and the rollback.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nLGZF8xmdYZrLwpuP2CJT
2026-10-28 09:16:27 -05:00
..

method-middleware

Bunny Edge Script (middleware) on the registry-cr pull zone (id 6562831), which fronts bouy.cr, buoy.cr and seamark.cr. Script id 99492, named seamark-method-mw.

Bunny always forwards HEAD to the origin as GET, and edge rules run after that rewrite, so neither a "method is HEAD" trigger nor %{Request.Method} can recover the original verb. Without it the appview presigns a blob existence check (HEAD) for GET, the client follows the redirect with HEAD, and S3 rejects the signature with a 403. Every client aborts the push when that happens, for any blob that already exists on a hold without a download CDN (pull_zone).

This script runs in onClientRequest, before the rewrite, and sets X-Original-Method: HEAD for a client HEAD. It strips any client-sent copy first, so the header cannot be spoofed through the CDN. The appview reads it in ExtractAuthMethod (pkg/appview/middleware/registry.go).

Requirements on the pull zone

  • Script linked as the zone's middleware. Link it in the dashboard: setting MiddlewareScriptId through the API left the script unlinked and every request failed with an empty 400.
  • "Run script before cache" on (EdgeScriptExecutionPhase: 2). onClientRequest silently does not run otherwise.
  • No edge rule that sets X-Original-Method. Edge rules run after the script and would overwrite its value with the rewritten GET.

Build and deploy

The SDK must be bundled in. Importing it from esm.sh at runtime made cold starts fail with "script startup time exceeded".

npm install --no-save @bunny.net/edgescript-sdk@0.13.0
npx esbuild main.ts --bundle --format=esm --platform=neutral --target=es2022 --outfile=dist/index.js
bunny scripts deploy dist/index.js 99492

Rollback

Set EdgeScriptExecutionPhase back to 0 (or unlink the script). Blob HEADs then fail again on holds without a download CDN, as before.

bunny api POST /pullzone/6562831 --body '{"EdgeScriptExecutionPhase":0}'