8000 Try to build a reproducer for #58562 · symfony/symfony@45ac25b · GitHub
[go: up one dir, main page]

Skip to content

Commit 45ac25b

Browse files
committed
Try to build a reproducer for #58562
1 parent 96aae60 commit 45ac25b

File tree

3 files changed

+83
-0
lines changed

3 files changed

+83
-0
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
// Test server for https://github.com/symfony/symfony/pull/58562
3+
$context = stream_context_create(
4+
['ssl' => [
5+
'local_cert' => __DIR__.'/tls/server.crt',
6+
'local_pk' => __DIR__.'/tls/server.key',
7+
'disable_compression' => true, // TLS compression attack vulnerability
8+
'verify_peer' => false,
9+
'allow_self_signed' => true,
10+
]]
11+
);
12+
13+
$socket = stream_socket_server('ssl://127.0.0.1:8058', $errno, $errstr, STREAM_SERVER_BIND|STREAM_SERVER_LISTEN, $context);
14+
if (false === $socket) {
15+
die("$errstr ($errno)");
16+
}
17+
$clients = [$socket];
18+
echo "started\n";
19+
while(true) {
20+
$changed = $clients;
21+
stream_select($changed, $write, $except, 10);
22+
if (in_array($socket, $changed)) {
23+
$client = stream_socket_accept($socket);
24+
if (!$client) {
25+
continue;
26+
}
27+
$clients[] = $client;
28+
stream_set_blocking($client, false);
29+
continue;
30+
}
31+
foreach ($changed as $client) {
32+
$buffer = stream_get_contents($client);
33+
if (false === $buffer) {
34+
fclose($client);
35+
$index = array_search($client, $clients);
36+
unset($clients[$index]);
37+
}
38+
if ('' !== $buffer) {
39+
fwrite($client, "HTTP/1.1 401 No ticket\r\n");
40+
fwrite($client, "Cache-Control: max-age=0\r\n");
41+
fwrite($client, "Connection: close\r\n");
42+
fwrite($client, "Server: 127.0.0.1:8058\r\n\r\n");
43+
fclose($client);
44+
$index = array_search($client, $clients);
45+
unset($clients[$index]);
46+
}
47+
}
48+
}

src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Symfony\Component\HttpClient\Internal\ClientState;
1919
use Symfony\Component\HttpClient\Response\StreamWrapper;
2020
use Symfony\Component\Process\Exception\ProcessFailedException;
21+
use Symfony\Component\Process\PhpExecutableFinder;
2122
use Symfony\Component\Process\Process;
2223
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
2324
use Symfony\Contracts\HttpClient\HttpClientInterface;
@@ -311,6 +312,35 @@ public function testDnsFailure()
311312
$response->getStatusCode();
312313
}
313314

315+
/** @see https://github.com/symfony/symfony/pull/58562 */
316+
public function testHandleEmptyResponseOnSslShutDown()
317+
{
318+
$finder = new PhpExecutableFinder();
319+
$process = new Process(array_merge([$finder->find(false)], $finder->findArguments(), ['-dopcache.enable=0', '-f', __DIR__.'/Fixtures/ssl-server58562.php']));
320+
$process->start();
321+
$wait = 0;
322+
do {
323+
$wait += 500;
324+
usleep(500000);
325+
} while ($wait < 10000 && $process->isRunning() && !str_contains($process->getOutput(), "started\n"));
326+
if (!$process->isRunning()) {
327+
self::fail($process->getOutput() . "\n" . $process->getErrorOutput());
328+
}
329+
try {
330+
$client = $this->getHttpClient(__FUNCTION__);
331+
$response = $client->request('GET', 'https://127.0.0.1:8058/');
332+
$headers = $response->getHeaders(false);
333+
$this->assertSame(401, $response->getStatusCode());
334+
$this->assertSame(['max-age=0'], $headers['cache-control']);
335+
$this->assertSame(['close'], $headers['connection']);
336+
$this->assertSame(['127.0.0.1:8058'], $headers['server']);
337+
} catch (\Throwable $exception) {
338+
self::fail($process->getOutput() . "\n" . $process->getErrorOutput() . "\n" . $exception->getMessage());
339+
} finally {
340+
$process->stop();
341+
}
342+
}
343+
314344
private static function startVulcain(HttpClientInterface $client)
315345
{
316346
if (self::$vulcainStarted) {

src/Symfony/Component/HttpClient/Tests/MockHttpClientTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ public function testMocking($factory, array $expectedResponses)
4242
$this->assertSame(2, $client->getRequestsCount());
4343
}
4444

45+
public function testHandleEmptyResponseOnSslShutDown()
46+
{
47+
$this->markTestSkipped('This needs a real network connection.');
48+
}
49+
4550
public static function mockingProvider(): iterable
4651
{
4752
yield 'callable' => [

0 commit comments

Comments
 (0)
0