Don't proxy certain headers across the Yalt boundary as it can mess-up proxied local requests
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@trigger.dev/yalt": patch
|
||||
"@trigger.dev/cli": patch
|
||||
---
|
||||
|
||||
Don't proxy certain headers across the Yalt boundary as it can mess-up proxied local requests
|
||||
@@ -9,7 +9,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@cloudflare/workers-types": "~4.20231121.0",
|
||||
"wrangler": "^3.20.0"
|
||||
"wrangler": "^3.21.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@trigger.dev/yalt": "workspace:*"
|
||||
|
||||
@@ -51,8 +51,9 @@ type RouteDecision =
|
||||
| { type: 'not_found' };
|
||||
|
||||
function routeUrl(url: URL, env: Env): RouteDecision {
|
||||
if (url.host.startsWith('localhost:')) {
|
||||
const searchParams = new URLSearchParams(url.search);
|
||||
const searchParams = new URLSearchParams(url.search);
|
||||
|
||||
if (searchParams.has('t')) {
|
||||
const name = searchParams.get('t');
|
||||
|
||||
if (name) {
|
||||
|
||||
@@ -516,11 +516,16 @@ async function createNativeTunnel(
|
||||
// import WS dynamically
|
||||
const WebSocket = await import("ws");
|
||||
|
||||
yaltTunnel = new YaltTunnel(response.url, `${hostname}:${port}`, {
|
||||
WebSocket: WebSocket.default,
|
||||
connectionTimeout: 1000,
|
||||
maxRetries: 10,
|
||||
});
|
||||
yaltTunnel = new YaltTunnel(
|
||||
response.url,
|
||||
`${hostname}:${port}`,
|
||||
{
|
||||
WebSocket: WebSocket.default,
|
||||
connectionTimeout: 1000,
|
||||
maxRetries: 10,
|
||||
},
|
||||
{ verbose: process.env.TUNNEL_VERBOSE === "1" }
|
||||
);
|
||||
|
||||
await yaltTunnel.connect();
|
||||
|
||||
|
||||
@@ -31,18 +31,19 @@
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"zod": "3.22.3",
|
||||
"partysocket": "^0.0.17"
|
||||
"partysocket": "^0.0.17",
|
||||
"zod": "3.22.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@trigger.dev/tsconfig": "workspace:*",
|
||||
"@trigger.dev/tsup": "workspace:*",
|
||||
"@types/debug": "^4.1.7",
|
||||
"@types/jest": "^29.5.3",
|
||||
"@types/node": "18",
|
||||
"jest": "^29.6.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-jest": "^29.1.1",
|
||||
"tsup": "^8.0.1",
|
||||
"@trigger.dev/tsup": "workspace:*",
|
||||
"typescript": "^5.3.0"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
+70
-12
@@ -36,7 +36,7 @@ export async function createRequestMessage(id: string, request: Request): Promis
|
||||
return {
|
||||
type: "request",
|
||||
id,
|
||||
headers: Object.fromEntries(headers),
|
||||
headers: stripHeaders(Object.fromEntries(headers)),
|
||||
method,
|
||||
url,
|
||||
body,
|
||||
@@ -86,26 +86,48 @@ export class YaltApiClient {
|
||||
}
|
||||
}
|
||||
|
||||
export type YaltTunnelOptions = {
|
||||
export type YaltTunnelSocketOptions = {
|
||||
WebSocket?: any;
|
||||
connectionTimeout?: number;
|
||||
maxRetries?: number;
|
||||
};
|
||||
|
||||
export type YaltTunnelOptions = {
|
||||
verbose?: boolean;
|
||||
};
|
||||
|
||||
export class YaltTunnel {
|
||||
socket?: WebSocket;
|
||||
|
||||
constructor(
|
||||
private url: string,
|
||||
private address: string,
|
||||
private socketOptions: YaltTunnelSocketOptions = {},
|
||||
private options: YaltTunnelOptions = {}
|
||||
) {}
|
||||
|
||||
private log(message: string, properties: Record<string, any> = {}) {
|
||||
if (this.options.verbose) {
|
||||
console.log(JSON.stringify({ message, ...properties }));
|
||||
}
|
||||
}
|
||||
|
||||
async connect() {
|
||||
this.socket = new WebSocket(`wss://${this.url}/connect`, [], this.options);
|
||||
this.log("Connecting to tunnel", {
|
||||
url: this.url,
|
||||
address: this.address,
|
||||
socketOptions: this.socketOptions,
|
||||
});
|
||||
|
||||
this.socket.addEventListener("open", () => {});
|
||||
this.socket = new WebSocket(`wss://${this.url}/connect`, [], this.socketOptions);
|
||||
|
||||
this.socket.addEventListener("close", (event) => {});
|
||||
this.socket.addEventListener("open", (args) => {
|
||||
this.log("Connected to tunnel");
|
||||
});
|
||||
|
||||
this.socket.addEventListener("close", (event) => {
|
||||
this.log("Disconnected from tunnel", { event: event.code, reason: event.reason });
|
||||
});
|
||||
|
||||
this.socket.addEventListener("message", async (event) => {
|
||||
const data = JSON.parse(
|
||||
@@ -115,7 +137,7 @@ export class YaltTunnel {
|
||||
const message = ServerMessages.safeParse(data);
|
||||
|
||||
if (!message.success) {
|
||||
console.error(message.error);
|
||||
this.log("Received invalid message", { data });
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -132,7 +154,7 @@ export class YaltTunnel {
|
||||
});
|
||||
|
||||
this.socket.addEventListener("error", (event) => {
|
||||
console.error(event);
|
||||
this.log("Socket error", { error: event.message });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -147,13 +169,31 @@ export class YaltTunnel {
|
||||
|
||||
let response: Response | null = null;
|
||||
|
||||
this.log("Sending local request", {
|
||||
originalUrl: originalUrl.href,
|
||||
requestId: request.id,
|
||||
headers: request.headers,
|
||||
});
|
||||
|
||||
try {
|
||||
response = await fetch(originalUrl.href, {
|
||||
method: request.method,
|
||||
headers: request.headers,
|
||||
headers: stripHeaders(request.headers),
|
||||
body: request.body,
|
||||
});
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
this.log("Error sending local request", {
|
||||
error: error.message,
|
||||
name: error.name,
|
||||
stack: error.stack,
|
||||
requestId: request.id,
|
||||
cause: "cause" in error ? error.cause : undefined,
|
||||
});
|
||||
} else {
|
||||
this.log("Error sending local request", { error, requestId: request.id });
|
||||
}
|
||||
|
||||
// Return a 502 response
|
||||
response = new Response(
|
||||
JSON.stringify({
|
||||
@@ -164,15 +204,33 @@ export class YaltTunnel {
|
||||
}
|
||||
|
||||
try {
|
||||
await sendResponse(request.id, response, this.socket);
|
||||
await this.sendResponse(request.id, response, this.socket);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
private async sendResponse(id: string, response: Response, socket: WebSocket) {
|
||||
const message = await createResponseMessage(id, response);
|
||||
|
||||
this.log("Sending response", { requestId: id, status: response.status });
|
||||
|
||||
return socket.send(JSON.stringify(message));
|
||||
}
|
||||
}
|
||||
|
||||
async function sendResponse(id: string, response: Response, socket: WebSocket) {
|
||||
const message = await createResponseMessage(id, response);
|
||||
// Remove headers that should not be included like connection, host, etc
|
||||
function stripHeaders(headers: Record<string, string>) {
|
||||
const blacklistHeaders = [
|
||||
"connection",
|
||||
"cf-ray",
|
||||
"cf-connecting-ip",
|
||||
"host",
|
||||
"cf-ipcountry",
|
||||
"content-length",
|
||||
];
|
||||
|
||||
return socket.send(JSON.stringify(message));
|
||||
return Object.fromEntries(
|
||||
Object.entries(headers).filter(([key]) => !blacklistHeaders.includes(key.toLowerCase()))
|
||||
);
|
||||
}
|
||||
|
||||
Generated
+7
-5
@@ -399,12 +399,12 @@ importers:
|
||||
specifiers:
|
||||
'@cloudflare/workers-types': ~4.20231121.0
|
||||
'@trigger.dev/yalt': workspace:*
|
||||
wrangler: ^3.20.0
|
||||
wrangler: ^3.21.0
|
||||
dependencies:
|
||||
'@trigger.dev/yalt': link:../../packages/yalt
|
||||
devDependencies:
|
||||
'@cloudflare/workers-types': 4.20231121.0
|
||||
wrangler: 3.20.0
|
||||
wrangler: 3.21.0
|
||||
|
||||
config-packages/eslint-config-custom:
|
||||
specifiers:
|
||||
@@ -1312,6 +1312,7 @@ importers:
|
||||
specifiers:
|
||||
'@trigger.dev/tsconfig': workspace:*
|
||||
'@trigger.dev/tsup': workspace:*
|
||||
'@types/debug': ^4.1.7
|
||||
'@types/jest': ^29.5.3
|
||||
'@types/node': '18'
|
||||
jest: ^29.6.2
|
||||
@@ -1327,6 +1328,7 @@ importers:
|
||||
devDependencies:
|
||||
'@trigger.dev/tsconfig': link:../../config-packages/tsconfig
|
||||
'@trigger.dev/tsup': link:../../config-packages/tsup
|
||||
'@types/debug': 4.1.7
|
||||
'@types/jest': 29.5.3
|
||||
'@types/node': 18.17.1
|
||||
jest: 29.6.2_@types+node@18.17.1
|
||||
@@ -33143,12 +33145,13 @@ packages:
|
||||
- utf-8-validate
|
||||
dev: true
|
||||
|
||||
/wrangler/3.20.0:
|
||||
resolution: {integrity: sha512-7mg25zJByhBmrfG+CbImSid7JNd5lxGovLA167ndtE8Yrqd3TUukrGWL8o0RCQIm0FUcgl2nCzWArJDShlZVKA==}
|
||||
/wrangler/3.21.0:
|
||||
resolution: {integrity: sha512-DLoo4XfjeyuGRAVWZFHmU1jWnZIfyLGDm6Ika9oy/CLCPfJzVJvf2jI70EU5BlEHWDZXMSJKw7FDdgSqwhaQXg==}
|
||||
engines: {node: '>=16.17.0'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
'@cloudflare/kv-asset-handler': 0.2.0
|
||||
'@cspotcode/source-map-support': 0.8.1
|
||||
'@esbuild-plugins/node-globals-polyfill': 0.2.3_esbuild@0.17.19
|
||||
'@esbuild-plugins/node-modules-polyfill': 0.2.2_esbuild@0.17.19
|
||||
blake3-wasm: 2.1.5
|
||||
@@ -33160,7 +33163,6 @@ packages:
|
||||
resolve.exports: 2.0.2
|
||||
selfsigned: 2.4.1
|
||||
source-map: 0.6.1
|
||||
source-map-support: 0.5.21
|
||||
xxhash-wasm: 1.0.2
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.3
|
||||
|
||||
Reference in New Issue
Block a user