TaxBusby
TaxBusby•4w ago

Piping two TCP connections to each other

Hey, I'm messing around trying to create a proxy in deno. I want to take an incoming connection, use some logic to decide how to route it, and then create an outgoing connection to pass it to. I have some code like this right now:
const listener = Deno.listen({
hostname: "127.0.0.1",
port: 8445,
transport: "tcp",
});
for await (const inConn of listener) {
const buf = new Uint8Array(4096);

await inConn.read(buf);
// TODO Routing logic
console.log("Connecting to local server (OUT)...");
const outConn = await Deno.connect({
hostname: "127.0.0.1",
port: 8443,
transport: "tcp",
});
console.log("Flushing buffer to OUT");
await outConn.write(buf);

console.log("Send all other data from IN to OUT");
inConn.readable.pipeTo(outConn.writable);

console.log("Send all other data from OUT to IN");
outConn.readable.pipeTo(inConn.writable);

console.log("Finished establishing connetion");
}
const listener = Deno.listen({
hostname: "127.0.0.1",
port: 8445,
transport: "tcp",
});
for await (const inConn of listener) {
const buf = new Uint8Array(4096);

await inConn.read(buf);
// TODO Routing logic
console.log("Connecting to local server (OUT)...");
const outConn = await Deno.connect({
hostname: "127.0.0.1",
port: 8443,
transport: "tcp",
});
console.log("Flushing buffer to OUT");
await outConn.write(buf);

console.log("Send all other data from IN to OUT");
inConn.readable.pipeTo(outConn.writable);

console.log("Send all other data from OUT to IN");
outConn.readable.pipeTo(inConn.writable);

console.log("Finished establishing connetion");
}
Which seems right to me in theory, but when I run it I get some streaming error after these commands all run:
Connecting to local server (OUT)...
Flushing buffer to OUT
Send all other data from IN to OUT
Send all other data from OUT to IN
Finished establishing connetion
error: Uncaught (in promise) Interrupted: operation canceled
at async Object.pull (ext:deno_web/06_streams.js:991:27)
Connecting to local server (OUT)...
Flushing buffer to OUT
Send all other data from IN to OUT
Send all other data from OUT to IN
Finished establishing connetion
error: Uncaught (in promise) Interrupted: operation canceled
at async Object.pull (ext:deno_web/06_streams.js:991:27)
Any idea if I'm using these APIs wrong, or if this might be a bug? I noticed pipeTo returns a promise, but if I await these it seems to stall the program indefinitely (like it's waiting for the pipe to close)
3 Replies
TaxBusby
TaxBusbyOP•4w ago
I just realized that read and write to buffers does not guarantee that the buffer is fully exhausted. I'll see if that's the issue first Nope, if I remove the initial read/write to buffer, it still fails in the same way
Leokuma
Leokuma•2w ago
@Doctor 🤖 Do you happen to know this?
Doctor 🤖
Doctor 🤖•2w ago
I'm not familiar with Deno.listen, but if you want a proxy why not use nginx?