Add SHA-256 checksums to the uploaded data
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / action / FileUploadPreflightAction.class.php
CommitLineData
b0bcc3d6
AE
1<?php
2
3namespace wcf\action;
4
5use Laminas\Diactoros\Response\JsonResponse;
6use Psr\Http\Message\ResponseInterface;
7use Psr\Http\Message\ServerRequestInterface;
8use Psr\Http\Server\RequestHandlerInterface;
9use wcf\http\Helper;
10use wcf\system\request\LinkHandler;
11use wcf\system\WCF;
12
13final class FileUploadPreflightAction implements RequestHandlerInterface
14{
15 public function handle(ServerRequestInterface $request): ResponseInterface
16 {
17 // TODO: For now we only require the filename and size to be provided.
18 $parameters = Helper::mapQueryParameters(
19 $request->getParsedBody(),
20 <<<'EOT'
21 array {
22 filename: non-empty-string,
05718033
AE
23 fileSize: positive-int,
24 fileHash: non-empty-string,
b0bcc3d6
AE
25 }
26 EOT,
27 );
28
29 // TODO: The chunk calculation shouldn’t be based on a fixed number.
30 $chunkSize = 2_000_000;
05718033 31 $chunks = (int)\ceil($parameters['fileSize'] / $chunkSize);
b0bcc3d6
AE
32
33 $identifier = $this->createTemporaryFile($parameters);
34
35 $endpoints = [];
36 for ($i = 0; $i < $chunks; $i++) {
37 $endpoints[] = LinkHandler::getInstance()->getControllerLink(
38 FileUploadAction::class,
39 [
40 'identifier' => $identifier,
41 'sequenceNo' => $i,
42 ]
43 );
44 }
45
46 return new JsonResponse([
47 'endpoints' => $endpoints,
48 ]);
49 }
50
51 private function createTemporaryFile(array $parameters): string
52 {
53 $identifier = \bin2hex(\random_bytes(20));
54
55 $sql = "INSERT INTO wcf1_file_temporary
05718033
AE
56 (identifier, time, filename, fileSize, fileHash)
57 VALUES (?, ?, ?, ?, ?)";
b0bcc3d6
AE
58 $statement = WCF::getDB()->prepare($sql);
59 $statement->execute([
60 $identifier,
61 \TIME_NOW,
62 $parameters['filename'],
05718033
AE
63 $parameters['fileSize'],
64 $parameters['fileHash'],
b0bcc3d6
AE
65 ]);
66
67 return $identifier;
68 }
69}