geonix 1.23.2 → 1.23.4
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/.vscode/settings.json +2 -1
- package/package.json +1 -1
- package/src/Gateway.js +4 -4
- package/src/Util.js +37 -21
- package/test/gateway.js +25 -24
- package/test/upload.js +23 -0
- package/test/ws_auth.js +21 -0
package/.vscode/settings.json
CHANGED
package/package.json
CHANGED
package/src/Gateway.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { connection } from "./Connection.js";
|
|
2
2
|
import { registry } from "./Registry.js";
|
|
3
|
-
import { createTCPServer, GeonixVersion, picoid, proxyHttp, sleep } from "./Util.js";
|
|
3
|
+
import { cleanupWebsocketUrl, createTCPServer, GeonixVersion, picoid, proxyHttp, sleep } from "./Util.js";
|
|
4
4
|
import express, { Router } from "express";
|
|
5
5
|
import { Request } from "./Request.js";
|
|
6
6
|
import { HEALTH_CHECK_ENDPOINT } from "./WebServer.js";
|
|
@@ -401,10 +401,10 @@ export class Gateway {
|
|
|
401
401
|
|
|
402
402
|
if (verb === "ws") {
|
|
403
403
|
router.ws(uri, (ws, req) => {
|
|
404
|
-
|
|
404
|
+
let target = cleanupWebsocketUrl(`ws://${backend}${req.originalUrl}`);
|
|
405
405
|
|
|
406
|
-
logger.debug("proxy.web.ws.to:",
|
|
407
|
-
this.#proxyWebsocketOverNats(
|
|
406
|
+
logger.debug("proxy.web.ws.to:", target);
|
|
407
|
+
this.#proxyWebsocketOverNats(target, ws, req);
|
|
408
408
|
});
|
|
409
409
|
} else {
|
|
410
410
|
router[verb](uri, async (req, res, _next) => {
|
package/src/Util.js
CHANGED
|
@@ -280,6 +280,25 @@ export async function parseMultipart(req, _options) {
|
|
|
280
280
|
let activePart;
|
|
281
281
|
let done = false;
|
|
282
282
|
|
|
283
|
+
const write = (chunk) => {
|
|
284
|
+
if (options.useMemory) {
|
|
285
|
+
activePart.body.push(chunk);
|
|
286
|
+
} else {
|
|
287
|
+
activePart.body.write(chunk);
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
const newPart = () => {
|
|
292
|
+
// create new part
|
|
293
|
+
const bodyFile = tempFilename();
|
|
294
|
+
activePart = {
|
|
295
|
+
headers: {},
|
|
296
|
+
bodyFile: options.useMemory ? undefined : bodyFile,
|
|
297
|
+
body: options.useMemory ? [] : createWriteStream(bodyFile, { flags: "wx" })
|
|
298
|
+
};
|
|
299
|
+
parts.push(activePart);
|
|
300
|
+
};
|
|
301
|
+
|
|
283
302
|
while (stream.readable) {
|
|
284
303
|
// next next chunk
|
|
285
304
|
let chunk = stream.read(BUFFER_SIZE);
|
|
@@ -296,35 +315,26 @@ export async function parseMultipart(req, _options) {
|
|
|
296
315
|
const isLastBoundary = combined[boundaryIndex + boundary.length] === 45 && combined[boundaryIndex + boundary.length + 1] === 45;
|
|
297
316
|
|
|
298
317
|
if (boundaryIndex === -1) {
|
|
318
|
+
lastChunk = combined;
|
|
299
319
|
break;
|
|
300
320
|
}
|
|
301
321
|
|
|
302
322
|
if (boundaryIndex > 0) {
|
|
303
|
-
|
|
304
|
-
activePart.body.push(combined.slice(0, boundaryIndex));
|
|
305
|
-
} else {
|
|
306
|
-
activePart.body.write(combined.slice(0, boundaryIndex));
|
|
307
|
-
}
|
|
323
|
+
write(combined.subarray(0, boundaryIndex));
|
|
308
324
|
}
|
|
309
325
|
|
|
310
326
|
if (isLastBoundary) {
|
|
311
|
-
combined = combined.
|
|
327
|
+
combined = combined.subarray(boundaryIndex + boundary.length + 2);
|
|
312
328
|
done = true;
|
|
313
329
|
break;
|
|
314
330
|
}
|
|
315
331
|
|
|
316
|
-
|
|
317
|
-
const bodyFile = tempFilename();
|
|
318
|
-
activePart = {
|
|
319
|
-
headers: {},
|
|
320
|
-
bodyFile: options.useMemory ? undefined : bodyFile,
|
|
321
|
-
body: options.useMemory ? [] : createWriteStream(bodyFile, { flags: "wx" })
|
|
322
|
-
};
|
|
323
|
-
parts.push(activePart);
|
|
332
|
+
newPart();
|
|
324
333
|
|
|
325
334
|
const endOfHeaders = combined.indexOf(END_OF_HEADERS, boundaryIndex);
|
|
335
|
+
|
|
326
336
|
activePart.headers = combined
|
|
327
|
-
.
|
|
337
|
+
.subarray(boundaryIndex + boundary.length + 2, endOfHeaders).toString()
|
|
328
338
|
.split("\r\n")
|
|
329
339
|
.reduce((acc, val) => {
|
|
330
340
|
const [header, value] = val.split(": ");
|
|
@@ -332,18 +342,14 @@ export async function parseMultipart(req, _options) {
|
|
|
332
342
|
return acc;
|
|
333
343
|
}, {});
|
|
334
344
|
|
|
335
|
-
combined = combined.
|
|
345
|
+
combined = combined.subarray(endOfHeaders + END_OF_HEADERS.length);
|
|
336
346
|
|
|
337
347
|
lastChunk = combined;
|
|
338
348
|
}
|
|
339
349
|
|
|
340
350
|
// there's no boundary in the chunk, add it to active part
|
|
341
351
|
if (activePart && lastChunk.length > 0 && !done) {
|
|
342
|
-
|
|
343
|
-
activePart.body.push(lastChunk);
|
|
344
|
-
} else {
|
|
345
|
-
activePart.body.write(lastChunk);
|
|
346
|
-
}
|
|
352
|
+
write(lastChunk);
|
|
347
353
|
lastChunk = Buffer.alloc(0);
|
|
348
354
|
}
|
|
349
355
|
}
|
|
@@ -407,4 +413,14 @@ export function deepMerge(target, ...source) {
|
|
|
407
413
|
}
|
|
408
414
|
|
|
409
415
|
return target;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
export function cleanupWebsocketUrl(url) {
|
|
419
|
+
try {
|
|
420
|
+
const parsed = new URL(url);
|
|
421
|
+
parsed.pathname = parsed.pathname.replace(/\/\.websocket$/, "");
|
|
422
|
+
return parsed.toString();
|
|
423
|
+
} catch {
|
|
424
|
+
return url;
|
|
425
|
+
}
|
|
410
426
|
}
|
package/test/gateway.js
CHANGED
|
@@ -1,33 +1,34 @@
|
|
|
1
1
|
import { Gateway, Service, streamToBuffer } from "../exports.js";
|
|
2
2
|
import { parseMultipart } from "../src/Util.js";
|
|
3
3
|
|
|
4
|
-
class TestService extends Service {
|
|
4
|
+
// class TestService extends Service {
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
// "GET /"(req, res) {
|
|
7
|
+
// res.send("Hello World");
|
|
8
|
+
// }
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
// async "POST /upload"(req, res) {
|
|
11
|
+
// const parts = await parseMultipart(req, { useMemory: false });
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
// for (const part of parts) {
|
|
14
|
+
// console.log(part.body);
|
|
15
|
+
// }
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
// res.send("OK");
|
|
18
|
+
// }
|
|
19
19
|
|
|
20
|
-
}
|
|
20
|
+
// }
|
|
21
21
|
|
|
22
|
-
TestService.start({
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
});
|
|
29
|
-
Gateway.start({
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
});
|
|
22
|
+
// TestService.start({
|
|
23
|
+
// middleware: {
|
|
24
|
+
// raw: true,
|
|
25
|
+
// json: false,
|
|
26
|
+
// cookies: false,
|
|
27
|
+
// }
|
|
28
|
+
// });
|
|
29
|
+
// Gateway.start({
|
|
30
|
+
// beforeRequest: (req, res) => {
|
|
31
|
+
// res.set("X-Test", "Test");
|
|
32
|
+
// }
|
|
33
|
+
// });
|
|
34
|
+
Gateway.start();
|
package/test/upload.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { write } from "fs";
|
|
2
|
+
import { Service, streamToBuffer } from "../exports.js";
|
|
3
|
+
import { parseMultipart } from "../src/Util.js";
|
|
4
|
+
import { writeFile } from "fs/promises";
|
|
5
|
+
|
|
6
|
+
class UploadService extends Service {
|
|
7
|
+
|
|
8
|
+
async "POST /upload"(req, res) {
|
|
9
|
+
const files = await parseMultipart(req, { useMemory: false });
|
|
10
|
+
|
|
11
|
+
for (const file of files) {
|
|
12
|
+
file.body = await streamToBuffer(file.body);
|
|
13
|
+
console.log(`${file.filename} ${file.headers["content-type"]} size=${file.body.length}`);
|
|
14
|
+
|
|
15
|
+
await writeFile("/tmp/temp.pdf", file.body);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
res.send("ok");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
UploadService.start({ middleware: { raw: false } });
|
package/test/ws_auth.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Gateway, ServeStatic, Service } from "../exports.js";
|
|
2
|
+
|
|
3
|
+
class ServiceFirst extends Service {
|
|
4
|
+
"WS /ws/first" = (ws) => {
|
|
5
|
+
ws.on("message", (message) => {
|
|
6
|
+
ws.send("first:" + message);
|
|
7
|
+
});
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
class ServiceSecond extends Service {
|
|
12
|
+
"WS /ws/second" = (ws) => {
|
|
13
|
+
ws.on("message", (message) => {
|
|
14
|
+
ws.send("second:" + message);
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
Gateway.start();
|
|
20
|
+
ServiceFirst.start();
|
|
21
|
+
ServiceSecond.start();
|