Skip to content

Commit 50f21d1

Browse files
authored
Prevent double etl evaluation in buffered response (#1499)
1 parent be1a274 commit 50f21d1

File tree

3 files changed

+70
-1
lines changed

3 files changed

+70
-1
lines changed

src/bridge/symfony/http-foundation/src/Flow/Bridge/Symfony/HttpFoundation/Response/FlowBufferedResponse.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,17 @@ private function evaluate() : void
6060
->write($this->output->memoryLoader($id = \bin2hex(\random_bytes(16)) . '.memory'))
6161
->run();
6262

63-
$this->content = $config->fstab()->for(protocol('memory'))->readFrom(path_memory($id))->content();
63+
$fs = $config->fstab()->for(protocol('memory'));
64+
65+
if ($fs->status(path_memory($id)) === null) {
66+
$this->buffered = true;
67+
$this->content = '';
68+
$this->statusCode = self::HTTP_NO_CONTENT;
69+
70+
return;
71+
}
72+
73+
$this->content = $fs->readFrom(path_memory($id))->content();
74+
$this->buffered = true;
6475
}
6576
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Flow\Bridge\Symfony\HttpFoundation\Tests\Unit\Response;
6+
7+
use function Flow\Bridge\Symfony\HttpFoundation\{http_json_output, http_stream_open};
8+
use function Flow\ETL\DSL\{from_array, int_entry, row, rows};
9+
use Flow\ETL\Extractor;
10+
use Flow\ETL\Tests\FlowTestCase;
11+
12+
final class FlowBufferedResponseTest extends FlowTestCase
13+
{
14+
public function test_response_from_empty_dataset() : void
15+
{
16+
$response = http_stream_open(from_array([]))->response(http_json_output());
17+
18+
self::assertEquals('', $response->getContent());
19+
self::assertEquals(204, $response->getStatusCode());
20+
}
21+
22+
public function test_response_is_buffered_only_once() : void
23+
{
24+
$extractor = $this->createMock(Extractor::class);
25+
26+
$extractor->expects(self::once())->method('extract')->willReturn((function () : \Generator {
27+
yield rows(row(int_entry('id', 1)));
28+
})());
29+
30+
$response = http_stream_open($extractor)->response(http_json_output());
31+
32+
$response->getContent();
33+
$response->getContent();
34+
35+
self::assertEquals('[{"id":1}]', $response->getContent());
36+
self::assertEquals(200, $response->getStatusCode());
37+
}
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Flow\Bridge\Symfony\HttpFoundation\Tests\Unit\Response;
6+
7+
use function Flow\Bridge\Symfony\HttpFoundation\{http_json_output, http_stream_open};
8+
use function Flow\ETL\DSL\from_array;
9+
use PHPUnit\Framework\TestCase;
10+
11+
final class FlowStreamedResponseTest extends TestCase
12+
{
13+
public function test_response_from_empty_dataset() : void
14+
{
15+
$response = http_stream_open(from_array([]))->streamedResponse(http_json_output());
16+
17+
self::assertEquals('', $response->getContent());
18+
self::assertEquals(200, $response->getStatusCode());
19+
}
20+
}

0 commit comments

Comments
 (0)