Skip to content

fix: preserve binary response bodies in curl and HTTP bridge#178

Open
mutewinter wants to merge 1 commit intovercel-labs:mainfrom
mutewinter:fix/preserve-binary-response
Open

fix: preserve binary response bodies in curl and HTTP bridge#178
mutewinter wants to merge 1 commit intovercel-labs:mainfrom
mutewinter:fix/preserve-binary-response

Conversation

@mutewinter
Copy link
Copy Markdown

I wrote this:

I ran into this issue when I noticed some corrupted JPEGs downloaded by an agent using curl, tracked it down to this, it fixes a little larger than I expected, but it does seem like it works fine for me.


Agent wrote this:

FetchResult.body was typed as string and decoded via TextDecoder/response.text(), corrupting any binary response (JPEG, PNG, etc.) — bytes 0xFF became EF BF BD (UTF-8 replacement character) on disk.

Root cause: responseToResult in src/network/fetch.ts always decoded the response as UTF-8 text regardless of content type.

Changes:

  • FetchResult.body is now Uint8Array — raw bytes, never text-decoded
  • responseToResult reads via streaming getReader() or arrayBuffer() instead of TextDecoder/response.text()
  • curl writes Uint8Array directly to the filesystem and renders stdout via fromBuffer(body, "binary") (latin1, one char per byte)
  • Worker HTTP bridge (bridge-handlersync-backend) serialises the body as bodyBase64 over JSON so it survives JSON.stringify across the SharedArrayBuffer boundary; workers decode with atob
  • jb_http in the Python bridge reads bodyBase64, decodes to bytes (content) and UTF-8 text (text) — matching the requests.Response contract

Breaking change for custom fetch option users: SecureFetch implementations must now return body: Uint8Array instead of body: string.

@vercel
Copy link
Copy Markdown

vercel bot commented Apr 3, 2026

@mutewinter is attempting to deploy a commit to the Vercel Labs Team on Vercel.

A member of the Team first needs to authorize it.

};
const body = atob(parsed.bodyBase64 ?? "");
return {
status: parsed.status,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Python HTTP responses have empty content (bytes) because bodyBase64 is stripped by sync-backend before reaching the Python worker.

Fix on Vercel

@cramforce
Copy link
Copy Markdown
Contributor

Thanks. Could you address the one comment?

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