Separate completed transfers and retain original file extensions
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { execFileSync } from 'node:child_process';
|
||||
import { randomBytes, randomInt, randomUUID } from 'node:crypto';
|
||||
import assert from 'node:assert/strict';
|
||||
import { mkdtempSync, readFileSync, readdirSync, rmSync, unlinkSync } from 'node:fs';
|
||||
import { existsSync, mkdtempSync, readFileSync, readdirSync, rmSync, unlinkSync } from 'node:fs';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { resolve } from 'node:path';
|
||||
const suffix = randomUUID().slice(0, 8),
|
||||
@@ -151,6 +151,15 @@ try {
|
||||
`import {createHash} from 'node:crypto';const state=${JSON.stringify(fileState.pending)},base='http://127.0.0.1:${port}',path='/api/uploads/resumable/'+state.uploadId;const headers={Origin:'https://hop.test',Cookie:state.cookie,'X-CSRF-Token':state.csrf};const r=await fetch(base+path,{headers});const progress=await r.json();if(!r.ok||progress.offset!==8*1024*1024)throw Error('partial offset not preserved');const last=await fetch(base+path,{method:'PUT',headers:{...headers,'Content-Type':'application/octet-stream','Upload-Offset':String(progress.offset)},body:Buffer.alloc(7,120)});if(!last.ok)throw Error(await last.text());const complete=await fetch(base+path+'/complete',{method:'POST',headers:{...headers,'Content-Type':'application/json'},body:'{}'});if(!complete.ok)throw Error(await complete.text());const list=await fetch(base+'/api/device/items',{headers:{Cookie:${JSON.stringify(fileState.cookie)}}});const item=(await list.json()).items.find(i=>i.file?.name==='resume.bin');const downloaded=await fetch(base+'/api/access/'+item.accessId+'/download',{headers:{Cookie:${JSON.stringify(fileState.cookie)}}});const content=Buffer.from(await downloaded.arrayBuffer());if(!downloaded.ok||content.length!==8*1024*1024+7||!content.equals(Buffer.alloc(content.length,120)))throw Error('resumed content mismatch');console.log('resumed');`,
|
||||
);
|
||||
assert.equal(resumed, 'resumed');
|
||||
// Completed physical paths and the original download URL survive another restart.
|
||||
docker('restart', name);
|
||||
wait();
|
||||
assert.equal(
|
||||
node(
|
||||
`const r=await fetch('http://127.0.0.1:${port}/api/access/${fileState.accessId}/download',{headers:{Cookie:${JSON.stringify(fileState.cookie)}}});if(!r.ok)throw Error('completed download failed after restart');console.log(await r.text());`,
|
||||
),
|
||||
'Docker file persistence',
|
||||
);
|
||||
const integrity = node(
|
||||
`import Database from 'better-sqlite3';const db=new Database('/data/database/hop.sqlite');console.log(db.pragma('integrity_check',{simple:true}));db.close();`,
|
||||
);
|
||||
@@ -163,12 +172,14 @@ try {
|
||||
),
|
||||
);
|
||||
assert.deepEqual(mode, { uid: 12001, gid: 12001, mode: 0o700 });
|
||||
const originals = resolve(folder, 'originals');
|
||||
const stored = readdirSync(originals).find(
|
||||
(key) => readFileSync(resolve(originals, key)).toString() === 'Docker file persistence',
|
||||
const completed = resolve(folder, 'completed');
|
||||
const stored = readdirSync(completed).find(
|
||||
(key) => readFileSync(resolve(completed, key)).toString() === 'Docker file persistence',
|
||||
);
|
||||
assert(stored, 'uploaded file is visible in the host project directory');
|
||||
unlinkSync(resolve(originals, stored));
|
||||
assert(stored, 'downloaded anonymous file is visible in the host completed directory');
|
||||
assert.match(stored, /^[a-f0-9-]{36}\.txt$/);
|
||||
assert.equal(existsSync(resolve(folder, 'originals', stored)), false);
|
||||
unlinkSync(resolve(completed, stored));
|
||||
const missing = JSON.parse(
|
||||
node(
|
||||
`const r=await fetch('http://127.0.0.1:${port}/api/access/${fileState.accessId}/download',{headers:{Cookie:${JSON.stringify(fileState.cookie)}}});console.log(JSON.stringify({status:r.status,body:await r.json()}));`,
|
||||
|
||||
Reference in New Issue
Block a user