osborn 0.9.13 → 0.9.15
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/dist/index.js +38 -16
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -15,6 +15,8 @@ import { dirname, join } from 'node:path';
|
|
|
15
15
|
import { fileURLToPath } from 'node:url';
|
|
16
16
|
import { spawn } from 'node:child_process';
|
|
17
17
|
import { homedir, tmpdir } from 'node:os';
|
|
18
|
+
import { PassThrough } from 'node:stream';
|
|
19
|
+
import { createGunzip } from 'node:zlib';
|
|
18
20
|
// Resolve __dirname for this ESM module so we can find sibling files (e.g.
|
|
19
21
|
// meeting-output.html) relative to the compiled JS location, NOT process.cwd().
|
|
20
22
|
// In production cwd is the user's workspace; the static file lives next to dist/index.js.
|
|
@@ -376,8 +378,26 @@ function startApiServer(workingDir, port) {
|
|
|
376
378
|
const targetWorkDir = url.searchParams.get('targetWorkDir');
|
|
377
379
|
const tmpDir = mkdtempSync(join(tmpdir(), 'osborn-import-'));
|
|
378
380
|
const tarProc = spawn('tar', ['-xf', '-', '-C', tmpDir]);
|
|
379
|
-
//
|
|
380
|
-
|
|
381
|
+
// Stream-sniff the first chunk to detect gzip magic bytes (0x1f 0x8b).
|
|
382
|
+
// Then route through createGunzip() if gzip, otherwise pipe raw to tar.
|
|
383
|
+
// This avoids any reliance on Content-Type or Content-Encoding headers.
|
|
384
|
+
const passthrough = new PassThrough();
|
|
385
|
+
let sniffDone = false;
|
|
386
|
+
req.once('data', (firstChunk) => {
|
|
387
|
+
sniffDone = true;
|
|
388
|
+
const isGzip = firstChunk[0] === 0x1f && firstChunk[1] === 0x8b;
|
|
389
|
+
passthrough.write(firstChunk);
|
|
390
|
+
req.pipe(passthrough);
|
|
391
|
+
const source = isGzip ? passthrough.pipe(createGunzip()) : passthrough;
|
|
392
|
+
source.pipe(tarProc.stdin);
|
|
393
|
+
});
|
|
394
|
+
req.once('end', () => {
|
|
395
|
+
if (!sniffDone) {
|
|
396
|
+
// Empty body — just end tar stdin
|
|
397
|
+
passthrough.end();
|
|
398
|
+
tarProc.stdin.end();
|
|
399
|
+
}
|
|
400
|
+
});
|
|
381
401
|
tarProc.stdin.on('error', (err) => {
|
|
382
402
|
console.error('[import] tar stdin error', err);
|
|
383
403
|
tarProc.kill('SIGTERM');
|
|
@@ -522,22 +542,24 @@ function startApiServer(workingDir, port) {
|
|
|
522
542
|
}
|
|
523
543
|
const tmpExtractDir = mkdtempSync(join(tmpdir(), 'osborn-import-'));
|
|
524
544
|
try {
|
|
525
|
-
// Reassemble chunks into a
|
|
545
|
+
// Reassemble all chunks into a combined buffer, then sniff first 2 bytes
|
|
546
|
+
// to detect gzip magic (0x1f 0x8b). Route through createGunzip() if gzip,
|
|
547
|
+
// otherwise pass raw bytes — always using tar -xf (no -z flag).
|
|
548
|
+
const chunkBuffers = [];
|
|
549
|
+
for (const chunkFile of expectedChunks) {
|
|
550
|
+
chunkBuffers.push(readFileSync(join(uploadDir, chunkFile)));
|
|
551
|
+
}
|
|
552
|
+
const combined = Buffer.concat(chunkBuffers);
|
|
553
|
+
const isGzip = combined[0] === 0x1f && combined[1] === 0x8b;
|
|
526
554
|
const tarProc = spawn('tar', ['-xf', '-', '-C', tmpExtractDir]);
|
|
527
|
-
//
|
|
555
|
+
// Feed combined buffer through gunzip (if needed) then into tar stdin
|
|
556
|
+
const feedStream = new PassThrough();
|
|
557
|
+
const tarInput = isGzip ? feedStream.pipe(createGunzip()) : feedStream;
|
|
558
|
+
tarInput.pipe(tarProc.stdin);
|
|
559
|
+
feedStream.end(combined);
|
|
528
560
|
const streamChunks = async () => {
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
await new Promise((resolve, reject) => {
|
|
532
|
-
tarProc.stdin.write(chunkData, (err) => {
|
|
533
|
-
if (err)
|
|
534
|
-
reject(err);
|
|
535
|
-
else
|
|
536
|
-
resolve();
|
|
537
|
-
});
|
|
538
|
-
});
|
|
539
|
-
}
|
|
540
|
-
tarProc.stdin.end();
|
|
561
|
+
// feeding is already initiated above; just return a resolved promise
|
|
562
|
+
await Promise.resolve();
|
|
541
563
|
};
|
|
542
564
|
streamChunks().catch(err => {
|
|
543
565
|
console.error('[import-finalize] chunk stream error', err);
|