Skip to content

fix(edge): drain refused request bodies so the refusal reaches the client - #118

Merged
Programcode merged 1 commit into
mainfrom
fix/edge-request-body-drain
Oct 7, 2026
Merged

Programcode merged 1 commit into
mainfrom
fix/edge-request-body-drain

Conversation

@Programcode

@Programcode Programcode commented Oct 7, 2026 •

Copy link
Copy Markdown
Owner

Follow-up to #116, found while verifying it on staging before the production deploy.

Problem

The hosted Edge runtime doesn't send a function's response until the request body has been read. #116 made share and import-source refuse oversized requests before reading them, so on staging a 600 KB share got its 413 only when the gateway gave up, after about 150 s (a 503). A rejected token sent with a large body had the same problem. This didn't show locally under plain Deno.

Fix

  • readBoundedBody reads an oversized request to the end, discards it (spending at most 10 s), and then refuses it. Oversized upstream responses are still cancelled, not read.
  • share and import-source drain the body the same way when requireUser rejects the token.

Verification

  • New test "readBoundedBody reads an oversized request to the end before refusing it" fails on main and passes here. The existing test that cancels an oversized upstream response still passes.
  • Local: npm run test:edge 335/335, lint and typecheck pass. GitHub Actions is still refused for billing, so there is no CI run.
  • Staging, with this branch's functions deployed by hand (supabase functions deploy --project-ref brifeyypjauyusmkptkx):
    • Signed-in shares of 600 KB and 2 MB got a 413 in 0.25–0.7 s; before this fix they hung until a 503 at 160 s.
    • A 600 KB body with a rejected token got a 401 in 0.9 s from share and 0.4 s from import-source; before, it got no answer within 30 s.
    • The staging sync later put main's share back. That's expected, and this PR makes the two match.
  • Also checked on staging for fix(edge): bound import-source and share requests #116 (unchanged by this PR): a source dripping slowly through a public tunnel got a 504 at 10.8 s, and the source server saw the disconnect at 9.9 s. Hostnames resolving to 198.18.0.1 and 224.0.0.1 got a 400. A real Wikipedia import worked. A normal share got a 30-day expiry and reads back anonymously. expiresInDays: 91 got a 400.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved handling of oversized uploads: rejected requests are drained before the size error is returned, with a timeout and abort support.
    • Requests rejected during authentication now have their bodies discarded, helping prevent unfinished uploads from lingering.
    • Oversized upstream responses are stopped without reading the entire response.
  • Tests
    • Added coverage for oversized request and response streams, including body draining and cancellation behavior.

…ient

The hosted Edge runtime holds a function's response until the request
body has been read. After #116, an oversized share or import request got
its 413 only when the gateway gave up about 150 s later, and the same held
for a rejected token sent with a large body.

readBoundedBody now reads an oversized request to the end and discards it,
for at most 10 s, before refusing it. Upstream responses are still
cancelled. share and import-source drain the body the same way when they
reject a token.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 7, 2026 16:03
@vercel

vercel Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
debate-navigator Ready Ready Preview Oct 7, 2026 4:04pm UTC
debatelab-staging Ready Ready Preview Oct 7, 2026 4:04pm UTC

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository YAML (base), Organization UI (inherited)
  • Review profile: CHILL
  • Plan: Free
  • Run ID: 3ce77879-ba93-41e0-82d0-18b6eb3f1da2
📥 Commits

Reviewing files that changed from the base of the PR and between 41e374a and c01815b.

📒 Files selected for processing (4)
  • supabase/functions/_shared/bounded-body.test.ts
  • supabase/functions/_shared/bounded-body.ts
  • supabase/functions/import-source/index.ts
  • supabase/functions/share/index.ts

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The shared bounded-body helper now drains oversized request bodies and can discard unused request bodies with a time limit and optional abort signal. The import-source and share handlers call it after authentication errors. Tests cover request draining and response cancellation.

Changes

Request Body Draining

Layer / File(s) Summary
Bounded body handling
supabase/functions/_shared/bounded-body.ts, supabase/functions/_shared/bounded-body.test.ts
readBoundedBody drains oversized request bodies before raising BodyTooLargeError; oversized responses are cancelled. The new discardRequestBody helper drains unused request bodies with a time limit and optional abort signal. Tests cover both behaviors.
Authentication error cleanup
supabase/functions/import-source/index.ts, supabase/functions/share/index.ts
Both handlers call discardRequestBody after an authentication failure with an HttpError and before returning the error response.

Estimated code review effort: 3 (Moderate) | ~20 minutes

  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Note

🎁 Summarized by CodeRabbit Free

Your organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Essentials by visiting https://app.coderabbit.ai/settings/billing.

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

@Programcode

Copy link
Copy Markdown
Owner Author

Codex review (gpt-6.1-sol, high) of c01815b: no findings. It noted that the wrong-method, banned-user and import-quota rejections still answer before reading the body. Those predate this PR, and real clients send small bodies there, so they stay as they are.

@Programcode
Programcode merged commit 6ec1a65 into main Oct 7, 2026
8 of 18 checks passed
@Programcode
Programcode deleted the fix/edge-request-body-drain branch October 7, 2026 16:08

This branch was successfully deployed

2 active deployments
Preview – debate-navigator — c01815ba Deployed Oct 7, 2026 by vercel[bot]
Preview – debatelab-staging — c01815ba Deployed Oct 7, 2026 by vercel[bot]
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.

2 participants