querysub 0.82.0 → 0.83.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "querysub",
3
- "version": "0.82.0",
3
+ "version": "0.83.0",
4
4
  "main": "index.js",
5
5
  "license": "MIT",
6
6
  "note1": "note on node-forge fork, see https://github.com/digitalbazaar/forge/issues/744 for details",
@@ -1,11 +1,15 @@
1
1
  import debugbreak from "debugbreak";
2
2
  import * as net from "net";
3
3
  import ws from "ws";
4
+ import child_process from "child_process";
4
5
 
5
6
  // Expose the internal port, via a tcp connection that we forward to internal port, for the first time
6
7
  // externalIP connects to us.
7
8
  // - console.warn if any other ips try to connect
8
9
  // - console.error if externalIP tries to connects multiple times
10
+ // - If any connection is closed, we terminate the forward, making this fairly safe (after a developer
11
+ // is finished debugging the connection can't be reused, and if it used while they are debugging
12
+ // they will likely notice).
9
13
  export async function hackDevtoolsWebsocketForward(config: {
10
14
  internalPort: number;
11
15
  externalIP: string;
@@ -13,78 +17,120 @@ export async function hackDevtoolsWebsocketForward(config: {
13
17
  externalPort: number;
14
18
  cancel: () => void;
15
19
  }> {
16
- const server = net.createServer();
20
+ const forwardCode = (() => {
21
+ const net = require("net");
22
+ const config = JSON.parse(process.argv[2]);
23
+ const server = net.createServer();
17
24
 
18
- // Start listening on a random available port, binding to all interfaces (0.0.0.0)
19
- server.listen(0, "0.0.0.0");
25
+ // Start listening on a random available port, binding to all interfaces (0.0.0.0)
26
+ server.listen(0, "0.0.0.0");
20
27
 
21
- server.on("connection", (socket) => {
22
- const clientIP = socket.remoteAddress;
28
+ server.on("connection", (socket: net.Socket) => {
29
+ const clientIP = socket.remoteAddress;
23
30
 
24
- if (clientIP !== config.externalIP) {
25
- console.error(`Rejected connection attempt from unauthorized IP: ${clientIP}`);
26
- socket.destroy();
27
- return;
28
- }
31
+ if (clientIP !== config.externalIP) {
32
+ console.error(`Rejected connection attempt from unauthorized IP: ${clientIP}`);
33
+ socket.destroy();
34
+ return;
35
+ }
29
36
 
30
- console.log(`Forwarding connection from ${config.externalIP}:${(address as any).port} to 127.0.0.1:${config.internalPort}`);
37
+ const address = server.address();
38
+ if (!address || typeof address === "string") {
39
+ throw new Error("Failed to get server address");
40
+ }
31
41
 
32
- // Forward the connection to the internal port
33
- const internalConnection = net.createConnection({
34
- host: "127.0.0.1",
35
- port: config.internalPort,
36
- });
37
- internalConnection.on("data", (data) => {
38
- socket.write(data);
42
+ console.log(`Forwarding connection from ${config.externalIP}:${address.port} to 127.0.0.1:${config.internalPort}`);
43
+
44
+ // Forward the connection to the internal port
45
+ const internalConnection = net.createConnection({
46
+ host: "127.0.0.1",
47
+ port: config.internalPort,
48
+ });
49
+ internalConnection.on("data", (data: Buffer) => {
50
+ socket.write(data);
51
+ });
52
+ let first = true;
53
+ socket.on("data", (data: Buffer) => {
54
+ // UGH... fix the host, otherwise devtools rejects the request.
55
+ if (first) {
56
+ first = false;
57
+ let lines = data.toString().split("\r\n");
58
+ lines[1] = `Host: 127.0.0.1:${config.internalPort}`;
59
+ data = Buffer.from(lines.join("\r\n"));
60
+ }
61
+ internalConnection.write(data);
62
+ });
63
+
64
+ // Handle socket closure
65
+ socket.on("close", () => {
66
+ internalConnection.destroy();
67
+ // IMPORTANT! We terminate when the connection is closed, which is what makes this safe.
68
+ process.exit();
69
+ });
70
+ socket.on("error", (err: Error) => {
71
+ internalConnection.destroy();
72
+ });
73
+
74
+ internalConnection.on("close", () => {
75
+ socket.destroy();
76
+ });
77
+ internalConnection.on("error", (err: Error) => {
78
+ socket.destroy();
79
+ });
39
80
  });
40
- let first = true;
41
- socket.on("data", (data) => {
42
- // UGH... fix the host, otherwise devtools rejects the request.
43
- if (first) {
44
- first = false;
45
- let lines = data.toString().split("\r\n");
46
- lines[1] = `Host: 127.0.0.1:${config.internalPort}`;
47
- data = Buffer.from(lines.join("\r\n"));
81
+
82
+ // Wait to we start listening
83
+ server.on("listening", () => {
84
+ const address = server.address();
85
+ if (!address || typeof address === "string") {
86
+ throw new Error("Failed to get server address");
48
87
  }
49
- internalConnection.write(data);
50
- });
51
88
 
52
- // // Handle socket closure
53
- socket.on("close", () => {
54
- internalConnection.destroy();
55
- // TESTING:
56
- // - For now, we don't close the server, so... we can reconnect. I think this might be required...
57
- //server.close();
58
- });
59
- socket.on("error", (err) => {
60
- internalConnection.destroy();
89
+ console.log(`EXTERNAL_PORT:${address.port}`);
61
90
  });
91
+ }).toString();
62
92
 
63
- internalConnection.on("close", () => {
64
- socket.destroy();
65
- });
66
- internalConnection.on("error", (err) => {
67
- socket.destroy();
68
- });
93
+ const child = child_process.spawn("node", [
94
+ "-e",
95
+ `(${forwardCode})()`,
96
+ JSON.stringify(config)
97
+ ]);
98
+
99
+ let externalPort: number | undefined;
100
+ let portPromiseResolve: ((port: number) => void) | undefined;
101
+ const portPromise = new Promise<number>((resolve) => {
102
+ portPromiseResolve = resolve;
69
103
  });
70
104
 
71
- // Wait to we start listening
72
- await new Promise((resolve) => {
73
- server.on("listening", resolve);
105
+ let curData = "";
106
+ child.stdout.on("data", (data) => {
107
+ console.log(data.toString());
108
+ curData += data.toString();
109
+ const match = curData.match(/EXTERNAL_PORT:(\d+)/);
110
+ if (match) {
111
+ externalPort = parseInt(match[1], 10);
112
+ if (portPromiseResolve) {
113
+ portPromiseResolve(externalPort);
114
+ }
115
+ }
116
+ });
117
+
118
+ child.stderr.on("data", (data) => {
119
+ console.error(data.toString());
74
120
  });
75
121
 
76
- // Get the randomly assigned port number
77
- const address = server.address();
78
- if (!address || typeof address === "string") {
79
- throw new Error("Failed to get server address");
80
- }
122
+ child.on("error", (err) => {
123
+ console.error("Failed to start child process:", err);
124
+ throw err;
125
+ });
81
126
 
82
- console.log(`Exposing external port ${address.port} to internal port ${config.internalPort} (for ${config.externalIP})`);
127
+ // Wait for the port to be available
128
+ externalPort = await portPromise;
83
129
 
84
130
  return {
85
- externalPort: address.port,
131
+ externalPort,
86
132
  cancel: () => {
87
- server.close();
133
+ child.kill();
88
134
  }
89
135
  };
90
136
  }
@@ -265,10 +265,11 @@ export class NodeViewer extends qreact.Component {
265
265
  <button onClick={async () => {
266
266
  const controller = NodeViewerController.nodes[getBrowserUrlNode()];
267
267
  let url = await controller.getExternalInspectURL(str);
268
+ console.log(url);
268
269
  console.log(url.replace("https://notdevtools.com/devtools", "devtools://devtools/bundled"));
269
270
  // devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&wss=99-250-124-91.querysub.com:2058/cc5b76b2-549f-4a66-8026-021811e9edd3
270
271
 
271
- //window.open(url, "_blank");
272
+ window.open(url, "_blank");
272
273
  }}>
273
274
  Inspect
274
275
  </button>