Deploy Ladill Transfer / deploy (push) Successful in 39s
Large files upload in 5 MB chunks (hosting file manager pattern) for the transfer UI and Ladill Mail S2S API, with no app-level file size cap when TRANSFER_MAX_FILE_BYTES=0. Co-authored-by: Cursor <cursoragent@cursor.com>
104 lines
2.9 KiB
PHP
104 lines
2.9 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Transfer;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Services\Upload\ChunkedUploadService;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use RuntimeException;
|
|
|
|
class ChunkedUploadController extends Controller
|
|
{
|
|
public function __construct(
|
|
private ChunkedUploadService $uploads,
|
|
) {}
|
|
|
|
public function init(Request $request): JsonResponse
|
|
{
|
|
$account = ladill_account();
|
|
|
|
$validated = $request->validate([
|
|
'filename' => 'required|string|max:255',
|
|
'filesize' => 'required|integer|min:1',
|
|
]);
|
|
|
|
$uploadId = $this->uploads->init($this->ownerKey($account->id), [
|
|
'filename' => $validated['filename'],
|
|
'filesize' => (int) $validated['filesize'],
|
|
]);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'upload_id' => $uploadId,
|
|
]);
|
|
}
|
|
|
|
public function chunk(Request $request): JsonResponse
|
|
{
|
|
$account = ladill_account();
|
|
$ownerKey = $this->ownerKey($account->id);
|
|
|
|
$validated = $request->validate([
|
|
'upload_id' => 'required|string|uuid',
|
|
'chunk_index' => 'required|integer|min:0',
|
|
'chunk_size' => 'required|integer|min:1',
|
|
'chunk' => 'required|file|max:10240',
|
|
]);
|
|
|
|
$chunk = $request->file('chunk');
|
|
if ($chunk === null) {
|
|
return response()->json(['success' => false, 'error' => 'Chunk missing.'], 422);
|
|
}
|
|
|
|
try {
|
|
$received = $this->uploads->receiveChunk(
|
|
$validated['upload_id'],
|
|
$ownerKey,
|
|
(int) $validated['chunk_index'],
|
|
$chunk,
|
|
(int) $validated['chunk_size'],
|
|
);
|
|
} catch (RuntimeException $e) {
|
|
return response()->json(['success' => false, 'error' => $e->getMessage()], 400);
|
|
}
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'chunk_index' => (int) $validated['chunk_index'],
|
|
'chunks_received' => $received,
|
|
]);
|
|
}
|
|
|
|
public function finalize(Request $request): JsonResponse
|
|
{
|
|
$account = ladill_account();
|
|
$ownerKey = $this->ownerKey($account->id);
|
|
|
|
$validated = $request->validate([
|
|
'upload_id' => 'required|string|uuid',
|
|
'total_chunks' => 'required|integer|min:1',
|
|
]);
|
|
|
|
try {
|
|
$this->uploads->finalize(
|
|
$validated['upload_id'],
|
|
$ownerKey,
|
|
(int) $validated['total_chunks'],
|
|
);
|
|
} catch (RuntimeException $e) {
|
|
return response()->json(['success' => false, 'error' => $e->getMessage()], 400);
|
|
}
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'upload_id' => $validated['upload_id'],
|
|
]);
|
|
}
|
|
|
|
private function ownerKey(int $userId): string
|
|
{
|
|
return 'user:'.$userId;
|
|
}
|
|
}
|