@valentinkolb/filegate 2.3.3 → 2.3.5
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 +1 -1
- package/src/handlers/upload.ts +27 -26
package/package.json
CHANGED
package/src/handlers/upload.ts
CHANGED
|
@@ -113,20 +113,20 @@ const assembleFile = async (meta: UploadMeta): Promise<string | null> => {
|
|
|
113
113
|
|
|
114
114
|
try {
|
|
115
115
|
for (let i = 0; i < meta.totalChunks; i++) {
|
|
116
|
-
|
|
117
|
-
const chunkFile = Bun.file(
|
|
116
|
+
const chunkFilePath = chunkPath(meta.uploadId, i);
|
|
117
|
+
const chunkFile = Bun.file(chunkFilePath);
|
|
118
118
|
|
|
119
|
-
// Verify chunk exists before
|
|
119
|
+
// Verify chunk exists before reading
|
|
120
120
|
if (!(await chunkFile.exists())) {
|
|
121
121
|
writer.end();
|
|
122
122
|
await rm(pathResult.realPath).catch(() => {});
|
|
123
123
|
return `chunk ${i} not found during assembly`;
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
126
|
+
// Read chunk as buffer (more reliable than streaming)
|
|
127
|
+
const data = new Uint8Array(await chunkFile.arrayBuffer());
|
|
128
|
+
hasher.update(data);
|
|
129
|
+
writer.write(data);
|
|
130
130
|
}
|
|
131
131
|
await writer.end();
|
|
132
132
|
} catch (e) {
|
|
@@ -272,32 +272,33 @@ app.post(
|
|
|
272
272
|
return c.json({ error: `chunk index ${chunkIndex} exceeds total ${meta.totalChunks}` }, 400);
|
|
273
273
|
}
|
|
274
274
|
|
|
275
|
-
|
|
276
|
-
|
|
275
|
+
// Read body as ArrayBuffer (more reliable than streaming)
|
|
276
|
+
let bodyBuffer: ArrayBuffer;
|
|
277
|
+
try {
|
|
278
|
+
bodyBuffer = await c.req.arrayBuffer();
|
|
279
|
+
} catch {
|
|
280
|
+
return c.json({ error: "failed to read request body" }, 400);
|
|
281
|
+
}
|
|
277
282
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
283
|
+
if (bodyBuffer.byteLength === 0) {
|
|
284
|
+
return c.json({ error: "missing body" }, 400);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (bodyBuffer.byteLength > config.maxChunkBytes) {
|
|
288
|
+
return c.json({ error: `chunk size exceeds maximum (${config.maxChunkBytes / 1024 / 1024}MB)` }, 413);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
const bodyData = new Uint8Array(bodyBuffer);
|
|
281
292
|
const hasher = new Bun.CryptoHasher("sha256");
|
|
293
|
+
hasher.update(bodyData);
|
|
282
294
|
|
|
295
|
+
// Write chunk to temporary file
|
|
296
|
+
const tempChunkPath = chunkPath(uploadId, chunkIndex) + ".tmp";
|
|
283
297
|
await mkdir(chunksDir(uploadId), { recursive: true });
|
|
284
|
-
const tempFile = Bun.file(tempChunkPath);
|
|
285
|
-
const writer = tempFile.writer();
|
|
286
298
|
|
|
287
299
|
try {
|
|
288
|
-
|
|
289
|
-
chunkSize += chunk.length;
|
|
290
|
-
if (chunkSize > config.maxChunkBytes) {
|
|
291
|
-
writer.end();
|
|
292
|
-
await rm(tempChunkPath).catch(() => {});
|
|
293
|
-
return c.json({ error: `chunk size exceeds maximum (${config.maxChunkBytes / 1024 / 1024}MB)` }, 413);
|
|
294
|
-
}
|
|
295
|
-
hasher.update(chunk);
|
|
296
|
-
writer.write(chunk);
|
|
297
|
-
}
|
|
298
|
-
await writer.end();
|
|
300
|
+
await Bun.write(tempChunkPath, bodyData);
|
|
299
301
|
} catch (e) {
|
|
300
|
-
writer.end();
|
|
301
302
|
await rm(tempChunkPath).catch(() => {});
|
|
302
303
|
throw e;
|
|
303
304
|
}
|