Skip to content

Commit e381471

Browse files
committed
Deletion of uploaded files moved out to the kernel.terminate listener. Added tests to ensure that files have been deleted
1 parent 47938c6 commit e381471

File tree

6 files changed

+50
-22
lines changed

6 files changed

+50
-22
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Luzrain\PHPStreamServerBundle\Http;
6+
7+
use Symfony\Component\HttpFoundation\File\UploadedFile;
8+
use Symfony\Component\HttpKernel\Event\TerminateEvent;
9+
10+
final class DeleteUploadedFilesListener
11+
{
12+
public function onKernelTerminate(TerminateEvent $event): void
13+
{
14+
if (!$event->isMainRequest()) {
15+
return;
16+
}
17+
18+
$files = $event->getRequest()->files->all();
19+
20+
\array_walk_recursive($files, static function (UploadedFile $file) {
21+
if (\file_exists($file->getRealPath())) {
22+
\unlink($file->getRealPath());
23+
}
24+
});
25+
}
26+
}

src/Http/HttpRequestHandler.php

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,8 @@
1111
use Psr\Http\Message\StreamFactoryInterface;
1212
use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory;
1313
use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory;
14-
use Symfony\Bridge\PsrHttpMessage\Factory\UploadedFile;
1514
use Symfony\Bridge\PsrHttpMessage\HttpFoundationFactoryInterface;
1615
use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface;
17-
use Symfony\Component\HttpFoundation\Request;
18-
use Symfony\Component\HttpFoundation\Response;
1916
use Symfony\Component\HttpKernel\KernelInterface;
2017
use Symfony\Component\HttpKernel\TerminableInterface;
2118

@@ -70,24 +67,13 @@ private function handle(ServerRequestInterface $request): ResponseInterface
7067
/** @var WorkerProcess $worker */
7168
$worker = $this->kernel->getContainer()->get('phpstreamserver.worker');
7269

73-
$worker->getEventLoop()->defer(fn() => $this->terminate($symfonyRequest, $symfonyResponse));
74-
75-
return $this->psrHttpFactory->createResponse($symfonyResponse);
76-
}
77-
78-
private function terminate(Request $symfonyRequest, Response $symfonyResponse): void
79-
{
80-
if ($this->kernel instanceof TerminableInterface) {
81-
$this->kernel->terminate($symfonyRequest, $symfonyResponse);
82-
}
83-
84-
// Delete all uploaded files
85-
$files = $symfonyRequest->files->all();
86-
\array_walk_recursive($files, static function (UploadedFile $file) {
87-
if (\file_exists($file->getRealPath())) {
88-
\unlink($file->getRealPath());
70+
$worker->getEventLoop()->defer(function () use ($symfonyRequest, $symfonyResponse): void {
71+
if ($this->kernel instanceof TerminableInterface) {
72+
$this->kernel->terminate($symfonyRequest, $symfonyResponse);
8973
}
9074
});
75+
76+
return $this->psrHttpFactory->createResponse($symfonyResponse);
9177
}
9278

9379
private function findFileInPublicDirectory(string $requestPath): string|null

src/Internal/Functions.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@ public static function cpuCount(): int
2222
if (\PHP_VERSION_ID >= 80300) {
2323
return \posix_sysconf(\POSIX_SC_NPROCESSORS_ONLN);
2424
} elseif (\DIRECTORY_SEPARATOR === '/' && \function_exists('shell_exec')) {
25-
return \strtolower(\PHP_OS) === 'darwin'
26-
? (int) \shell_exec('sysctl -n machdep.cpu.core_count')
27-
: (int) \shell_exec('nproc');
25+
return \strtolower(\PHP_OS) === 'darwin' ? (int) \shell_exec('sysctl -n machdep.cpu.core_count') : (int) \shell_exec('nproc');
2826
} else {
2927
return 1;
3028
}

src/config/services.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Luzrain\PHPStreamServerBundle\ConfigLoader;
66
use Luzrain\PHPStreamServerBundle\Event\HttpServerStartEvent;
7+
use Luzrain\PHPStreamServerBundle\Http\DeleteUploadedFilesListener;
78
use Luzrain\PHPStreamServerBundle\Http\HttpRequestHandler;
89
use Luzrain\PHPStreamServerBundle\Internal\WorkerConfigurator;
910
use Luzrain\PHPStreamServerBundle\ReloadStrategy\OnEachRequest;
@@ -15,6 +16,7 @@
1516
use Symfony\Component\DependencyInjection\ContainerBuilder;
1617
use Symfony\Component\DependencyInjection\Reference;
1718
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
19+
use Symfony\Component\HttpKernel\Event\TerminateEvent;
1820

1921
return static function (array $config, ContainerBuilder $container) {
2022
$container
@@ -48,6 +50,14 @@
4850
->setPublic(true)
4951
;
5052

53+
$container
54+
->register('phpstreamserver.delete_uploaded_files_listener', DeleteUploadedFilesListener::class)
55+
->addTag('kernel.event_listener', [
56+
'event' => TerminateEvent::class,
57+
'priority' => -1024,
58+
])
59+
;
60+
5161
if ($config['reload_strategy']['on_exception']['active']) {
5262
$container
5363
->register('phpstreamserver.on_exception_reload_strategy', OnException::class)

tests/App/RequestTestController.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ private function normalizeFiles(UploadedFile &$file): void
3535
'filename' => $file->getClientOriginalName(),
3636
'extension' => $file->getClientOriginalExtension(),
3737
'sha1' => \hash_file('sha1', $file->getRealPath()),
38+
'realpath' => $file->getRealPath(),
3839
'size' => $file->getSize(),
3940
];
4041
}

tests/RequestTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ public function testMultipartRequest(): void
150150
]),
151151
]);
152152

153+
\usleep(500000);
154+
153155
// Assert request
154156
$this->assertCount(2, $response['post']);
155157
$this->assertSame('test-1-data', $response['post']['test-1']);
@@ -161,30 +163,35 @@ public function testMultipartRequest(): void
161163
$this->assertSame('txt', $file['extension']);
162164
$this->assertSame(75, $file['size']);
163165
$this->assertSame('781eaba2e9a92ddf42748bd8f56a9990459ea413', $file['sha1']);
166+
$this->assertFileDoesNotExist($file['realpath']);
164167

165168
$file = $response['files']['file_one'][1];
166169
$this->assertSame('test2.txt', $file['filename']);
167170
$this->assertSame('txt', $file['extension']);
168171
$this->assertSame(47, $file['size']);
169172
$this->assertSame('f69850b7b6dddf24c14581956f5b6aa3ae9cd54e', $file['sha1']);
173+
$this->assertFileDoesNotExist($file['realpath']);
170174

171175
$file = $response['files']['file_three'];
172176
$this->assertSame('test3.txt', $file['filename']);
173177
$this->assertSame('txt', $file['extension']);
174178
$this->assertSame(27, $file['size']);
175179
$this->assertSame('4c129254b51981cba03e4c8aac82bb329880971a', $file['sha1']);
180+
$this->assertFileDoesNotExist($file['realpath']);
176181

177182
$file = $response['files']['image'];
178183
$this->assertSame('dot.png', $file['filename']);
179184
$this->assertSame('png', $file['extension']);
180185
$this->assertSame(70, $file['size']);
181186
$this->assertSame('4a5eb7171b58e08a6881721e3b43d5a44419a2be', $file['sha1']);
187+
$this->assertFileDoesNotExist($file['realpath']);
182188

183189
$file = $response['files']['big_file'];
184190
$this->assertSame('t.bin', $file['filename']);
185191
$this->assertSame('bin', $file['extension']);
186192
$this->assertSame(5000000, $file['size']);
187193
$this->assertSame('1310fa4a837135d0a5d13388a21e49474eea00ac', $file['sha1']);
194+
$this->assertFileDoesNotExist($file['realpath']);
188195
}
189196

190197
public function testRawRequest(): void

0 commit comments

Comments
 (0)