Skip to content

Fix the /api proxy: auth header, query string, all methods, gzip - #5

Merged
coderback merged 1 commit into
mainfrom
fix/vercel-proxy
Oct 10, 2026
Merged

coderback merged 1 commit into
mainfrom
fix/vercel-proxy

Conversation

@coderback

Copy link
Copy Markdown
Owner

Fixes the Next.js /api/* proxy (frontend/src/app/api/[...path]/route.ts). It is only used when nginx is not in front of the frontend, e.g. on Vercel; docker compose is unaffected.

What was broken

Problem Effect
Authorization header not forwarded every logged-in call rejected
Only GET and POST exported profile save (PUT) and status change (PATCH) returned 405
Query string dropped job filters, paging and the applications status filter never reached the API
Upstream content-encoding passed through after fetch had decoded the body gzip responses arrived corrupted
Path rebuilt from decoded segments %2F in an id became an extra path segment
No abort propagation closing the tab left the upstream request (and a live apply session) running

What changed

  • Forwards an allowlist of request headers: authorization, content-type, accept, accept-language, last-event-id. Cookies and host are not passed on.
  • Exports GET, HEAD, POST, PUT, PATCH and DELETE.
  • Builds the target from the raw URL, so the query string and percent-encoding survive.
  • Strips content-encoding, content-length, transfer-encoding, connection and keep-alive from the response.
  • Passes request.signal upstream and sets cache: "no-store".
  • Returns JSON {"detail": ...} with 502 when the API is unreachable and 503 when API_URL is unset.

Testing

Ran the production build (.next/standalone/server.js) against a local fake backend that echoes what it receives. 21 checks: headers, each method with a body, bodiless POST, a 3 MB multipart upload, query string, encoded path, gzip, 404 pass-through, Content-Disposition, SSE arriving incrementally, and upstream cancellation on client disconnect.

  • Old code: 11/21
  • New code: 21/21

Not tested against the real API or on Vercel.

Notes

  • No function maxDuration is set, so Vercel's plan default applies. An apply session with review can run past five minutes and may need it raised.
  • API_URL (the backend's address) is required by this route and is not yet documented in the README or .env.example.

The Next.js proxy used when nginx is not in front (e.g. on Vercel) only
passed content-type and only handled GET and POST.

- Forward Authorization (every logged-in call was rejected)
- Handle PUT, PATCH, DELETE and HEAD (profile save and status changes
  returned 405)
- Keep the query string and percent-encoding of the path
- Drop content-encoding/content-length from the response: fetch has
  already decoded the body, so gzip responses arrived corrupted
- Cancel the upstream request when the client disconnects
- Do not pass cookies to the API; never cache; return JSON 502/503 when
  the API is unreachable or API_URL is unset
@coderback
coderback merged commit 8391442 into main Oct 10, 2026
3 checks passed
@coderback
coderback deleted the fix/vercel-proxy branch October 10, 2026 22:21
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.

1 participant