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.
@@ -6,5 +6,6 @@
6
6
  "javascript"
7
7
  ],
8
8
  "editor.tabSize": 4,
9
- "editor.detectIndentation": false
9
+ "editor.detectIndentation": false,
10
+ "editor.formatOnSave": true
10
11
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "geonix",
3
- "version": "1.23.2",
3
+ "version": "1.23.4",
4
4
  "type": "module",
5
5
  "description": "",
6
6
  "bin": {
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
- const url = req.originalUrl.replace(/\/\.websocket$/, "");
404
+ let target = cleanupWebsocketUrl(`ws://${backend}${req.originalUrl}`);
405
405
 
406
- logger.debug("proxy.web.ws.to:", backend + req.originalUrl);
407
- this.#proxyWebsocketOverNats(`ws://${backend}${url}`, ws, req);
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
- if (options.useMemory) {
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.slice(boundaryIndex + boundary.length + 2);
327
+ combined = combined.subarray(boundaryIndex + boundary.length + 2);
312
328
  done = true;
313
329
  break;
314
330
  }
315
331
 
316
- // create new part
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
- .slice(boundaryIndex + boundary.length + 2, endOfHeaders).toString()
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.slice(endOfHeaders + END_OF_HEADERS.length);
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
- if (options.useMemory) {
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
- "GET /"(req, res) {
7
- res.send("Hello World");
8
- }
6
+ // "GET /"(req, res) {
7
+ // res.send("Hello World");
8
+ // }
9
9
 
10
- async "POST /upload"(req, res) {
11
- const parts = await parseMultipart(req, { useMemory: false });
10
+ // async "POST /upload"(req, res) {
11
+ // const parts = await parseMultipart(req, { useMemory: false });
12
12
 
13
- for (const part of parts) {
14
- console.log(part.body);
15
- }
13
+ // for (const part of parts) {
14
+ // console.log(part.body);
15
+ // }
16
16
 
17
- res.send("OK");
18
- }
17
+ // res.send("OK");
18
+ // }
19
19
 
20
- }
20
+ // }
21
21
 
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
- });
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 } });
@@ -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();