Compare commits

...

2 Commits

Author SHA1 Message Date
3ac9a06a9f ok 2026-02-17 07:41:05 -08:00
b967bb9e9a fix POST 2026-02-16 16:21:42 -08:00
2 changed files with 31 additions and 9 deletions

View File

@ -117,6 +117,7 @@ export function connect(options: TunnelOptions): Tunnel {
method: req.method,
headers: req.headers,
body: hasBody ? req.body : undefined,
redirect: "manual",
})
const contentType = response.headers.get("content-type")

View File

@ -25,9 +25,11 @@ type Success = {
export const GIT_SHA = process.env.RENDER_GIT_COMMIT ?? (await Bun.$`git rev-parse HEAD`.text()).trim()
const REQUEST_TIMEOUT = 30_000
type Connection = { app: string, ws: any }
let connections: Record<string, Connection> = {}
const pending = new Map<string, (res: any) => void>
const pending = new Map<string, { resolve: (res: Response) => void, subdomain: string }>
const app = new Hono
@ -65,15 +67,21 @@ app.get("/tunnel", c => {
console.log(`connection opened: ${name} -> ${app}`)
send(ws, { subdomain: name })
},
onClose: (_event, ws) => {
onClose: (_event, _ws) => {
console.log("connection closed:", name)
delete connections[name]
for (const [id, entry] of pending) {
if (entry.subdomain === name) {
entry.resolve({ id, status: 502, headers: {}, body: "Tunnel disconnected" })
pending.delete(id)
}
}
},
async onMessage(event, _ws) {
const msg = JSON.parse(event.data.toString())
const resolve = pending.get(msg.id)
if (resolve) {
resolve(msg)
const entry = pending.get(msg.id)
if (entry) {
entry.resolve(msg)
pending.delete(msg.id)
}
},
@ -95,11 +103,24 @@ app.all("*", async c => {
const id = randomID()
const headers = Object.fromEntries(c.req.raw.headers)
delete headers['host']
delete headers['connection']
delete headers['keep-alive']
delete headers['transfer-encoding']
delete headers['content-length']
const body = await c.req.text()
const app = connection.app
const result = await new Promise<Response>(resolve => {
pending.set(id, resolve)
const result = await new Promise<Response>((resolve, reject) => {
const timer = setTimeout(() => {
pending.delete(id)
reject(new Error("Tunnel request timed out"))
}, REQUEST_TIMEOUT)
pending.set(id, {
resolve: (res) => { clearTimeout(timer); resolve(res) },
subdomain,
})
send(connection.ws, {
id,
app,
@ -108,7 +129,7 @@ app.all("*", async c => {
headers,
body
})
})
}).catch((): Response => ({ id, status: 504, headers: {}, body: "Gateway Timeout" }))
if (result.isBinary) {
const buffer = Buffer.from(result.body, 'base64')
@ -125,7 +146,7 @@ app.all("*", async c => {
})
function send(connection: any, msg: Request | Success) {
console.log("sending", msg)
console.log("sending", 'id' in msg ? `${msg.id} ${msg.method} ${msg.path}` : `connected: ${msg.subdomain}`)
connection.send(JSON.stringify(msg))
}