From 94b0eb4dad48b13ae7ec97702223305a071553d5 Mon Sep 17 00:00:00 2001 From: Chris Wanstrath Date: Mon, 29 Sep 2025 20:53:07 -0700 Subject: [PATCH] tunnel binary files --- app/src/sneaker.ts | 50 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/app/src/sneaker.ts b/app/src/sneaker.ts index 4b7557c..ef57af9 100644 --- a/app/src/sneaker.ts +++ b/app/src/sneaker.ts @@ -84,6 +84,8 @@ export async function connectSneaker(app: string, subdomain = ""): Promise void let promise = new Promise(res => resolve = res) @@ -115,25 +117,57 @@ export async function connectSneaker(app: string, subdomain = ""): Promise = {} res.headers.forEach((v, k) => (headers[k] = v)) - ws.send(JSON.stringify({ - id: msg.id, - status: res.status, - headers, - body, - })) + const contentType = res.headers.get('content-type') || '' + const isBinary = isBinaryContentType(contentType) + + let body: string | ArrayBuffer + let responseData: any + + if (isBinary) { + const arrayBuffer = await res.arrayBuffer() + const base64 = Buffer.from(arrayBuffer).toString('base64') + + responseData = { + id: msg.id, + status: res.status, + headers, + body: base64, + isBinary: true + } + } else { + body = await res.text() + + responseData = { + id: msg.id, + status: res.status, + headers, + body, + isBinary: false + } + } + + ws.send(JSON.stringify(responseData)) } catch (err: any) { ws.send(JSON.stringify({ id: msg.id, status: 500, headers: { "content-type": "text/plain" }, body: "error: " + err.message, + isBinary: false })) } } return promise -} \ No newline at end of file +} + +function isBinaryContentType(contentType: string): boolean { + const binaryTypes = [ + 'image/', 'audio/', 'video/', 'application/octet-stream', + 'application/pdf', 'application/zip', 'font/' + ] + return binaryTypes.some(type => contentType.startsWith(type)) +}