Featureful (#31)
* Fix loading within the CLI * Remove app * Remove promise handle * Add initial travis file * Add libxkbfile dependency * Add libxkbfile-dev * Add build script * Fix malformed bash statement * Remove yarn from script * Improve build script * Extract upx before usage * Only run upx if on linux * Ensure resource directory exists * Pack runnable binary * Export binary with platform * Improve build process * Install upx before running install script * Update typescript version before running nexe * Add os.release() function for multi-platform support * Update travis.yml to improve deployment * Add on CI * Update to v1.31.0 * Add libsecret * Update build target * Skip cleanup * Fix built-in extensions * Add basics for apps * Create custom DNS server * Fix forking within CLI. Fixes TS language features * Fix filename resolve * Fix default extensions path * Add custom dialog * Store workspace path * Remove outfiles * Cleanup * Always authed outside of CLI * Use location.host for client * Remove useless app interface * Remove debug file for building wordlist * Use chromes tcp host * Update patch * Build browser app before packaging * Replace all css containing file:// URLs, fix webviews * Fix save * Fix mkdir
This commit is contained in:
4
packages/tunnel/package.json
Normal file
4
packages/tunnel/package.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "@coder/tunnel",
|
||||
"main": "src/tunnel.ts"
|
||||
}
|
48
packages/tunnel/src/client.ts
Normal file
48
packages/tunnel/src/client.ts
Normal file
@ -0,0 +1,48 @@
|
||||
import { Event, Emitter } from "@coder/events";
|
||||
import { TunnelCloseCode } from "./common";
|
||||
|
||||
export interface TunnelCloseEvent {
|
||||
readonly code: TunnelCloseCode;
|
||||
readonly reason: string;
|
||||
}
|
||||
|
||||
export interface ClientConnection {
|
||||
readonly onData: Event<ArrayBuffer>;
|
||||
readonly onClose: Event<TunnelCloseEvent>;
|
||||
send(data: ArrayBuffer): void;
|
||||
}
|
||||
|
||||
export const forward = (connectionUrl: string): Promise<ClientConnection> => {
|
||||
return new Promise((resolve, reject): void => {
|
||||
const socket = new WebSocket(connectionUrl);
|
||||
const closeEmitter = new Emitter<TunnelCloseEvent>();
|
||||
const dataEmitter = new Emitter<ArrayBuffer>();
|
||||
const connection: ClientConnection = {
|
||||
get onClose(): Event<TunnelCloseEvent> {
|
||||
return closeEmitter.event;
|
||||
},
|
||||
get onData(): Event<ArrayBuffer> {
|
||||
return dataEmitter.event;
|
||||
},
|
||||
send(data: ArrayBuffer): void {
|
||||
socket.send(data);
|
||||
},
|
||||
};
|
||||
socket.binaryType = "arraybuffer";
|
||||
socket.addEventListener("message", (event) => {
|
||||
dataEmitter.emit(event.data);
|
||||
});
|
||||
socket.addEventListener("error", (event) => {
|
||||
reject("uncertain");
|
||||
});
|
||||
socket.addEventListener("open", () => {
|
||||
resolve(connection);
|
||||
});
|
||||
socket.addEventListener("close", (event) => {
|
||||
closeEmitter.emit({
|
||||
code: event.code,
|
||||
reason: event.reason,
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
5
packages/tunnel/src/common.ts
Normal file
5
packages/tunnel/src/common.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export enum TunnelCloseCode {
|
||||
Normal = 1000,
|
||||
Error = 4000,
|
||||
ConnectionRefused = 4001,
|
||||
}
|
53
packages/tunnel/src/server.ts
Normal file
53
packages/tunnel/src/server.ts
Normal file
@ -0,0 +1,53 @@
|
||||
import * as net from "net";
|
||||
import { TunnelCloseCode } from "./common";
|
||||
|
||||
export interface WS {
|
||||
addEventListener(event: "message", cb: (event: {
|
||||
// tslint:disable-next-line:no-any
|
||||
readonly data: any;
|
||||
}) => void): void;
|
||||
addEventListener(event: "close", cb: () => void): void;
|
||||
binaryType: string;
|
||||
close(code: number, reason?: string): void;
|
||||
// tslint:disable-next-line:no-any
|
||||
send(data: any): void;
|
||||
}
|
||||
|
||||
export const handle = async (socket: WS, port: number): Promise<void> => {
|
||||
const hosts = [
|
||||
"127.0.0.1",
|
||||
"::", // localhost
|
||||
];
|
||||
|
||||
let localSocket: net.Socket | undefined;
|
||||
for (let i = 0; i < hosts.length; i++) {
|
||||
if (localSocket) {
|
||||
break;
|
||||
}
|
||||
localSocket = await new Promise((resolve, reject): void => {
|
||||
const socket = net.connect({
|
||||
host: hosts[i],
|
||||
port,
|
||||
}, () => {
|
||||
// Connected
|
||||
resolve(socket);
|
||||
});
|
||||
socket.on("error", (err: Error & { readonly code: string }) => {
|
||||
if (err.code === "ECONNREFUSED") {
|
||||
resolve(undefined);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
if (!localSocket) {
|
||||
socket.close(TunnelCloseCode.ConnectionRefused);
|
||||
|
||||
return;
|
||||
}
|
||||
socket.binaryType = "arraybuffer";
|
||||
socket.addEventListener("message", (event) => localSocket!.write(Buffer.from(event.data)));
|
||||
socket.addEventListener("close", () => localSocket!.end());
|
||||
localSocket.on("data", (data) => socket.send(data));
|
||||
localSocket.on("error", (err) => socket.close(TunnelCloseCode.Error, err.toString()));
|
||||
localSocket.on("close", () => socket.close(TunnelCloseCode.Normal));
|
||||
};
|
Reference in New Issue
Block a user