Skip to content

Commit 955e433

Browse files
Merge branch '7.1' into 7.2
* 7.1: [HttpClient] Fix streaming and redirecting with NoPrivateNetworkHttpClient Bump Symfony version to 7.1.10 Update VERSION for 7.1.9 Update CHANGELOG for 7.1.9 Bump Symfony version to 6.4.17 Update VERSION for 6.4.16 Update CHANGELOG for 6.4.16 Bump Symfony version to 5.4.49 Update VERSION for 5.4.48 Update CONTRIBUTORS for 5.4.48 Update CHANGELOG for 5.4.48
2 parents 99ceaed + f4459f8 commit 955e433

7 files changed

+81
-43
lines changed

NoPrivateNetworkHttpClient.php

+14-18
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
use Symfony\Contracts\HttpClient\ChunkInterface;
2121
use Symfony\Contracts\HttpClient\HttpClientInterface;
2222
use Symfony\Contracts\HttpClient\ResponseInterface;
23-
use Symfony\Contracts\HttpClient\ResponseStreamInterface;
2423
use Symfony\Contracts\Service\ResetInterface;
2524

2625
/**
@@ -81,32 +80,34 @@ public function request(string $method, string $url, array $options = []): Respo
8180
$ip = self::dnsResolve($dnsCache, $host, $this->ipFlags, $options);
8281
self::ipCheck($ip, $this->subnets, $this->ipFlags, $host, $url);
8382

84-
if (0 < $maxRedirects = $options['max_redirects']) {
85-
$options['max_redirects'] = 0;
86-
$redirectHeaders['with_auth'] = $redirectHeaders['no_auth'] = $options['headers'];
87-
88-
if (isset($options['normalized_headers']['host']) || isset($options['normalized_headers']['authorization']) || isset($options['normalized_headers']['cookie'])) {
89-
$redirectHeaders['no_auth'] = array_filter($redirectHeaders['no_auth'], static function ($h) {
90-
return 0 !== stripos($h, 'Host:') && 0 !== stripos($h, 'Authorization:') && 0 !== stripos($h, 'Cookie:');
91-
});
92-
}
93-
}
94-
9583
$onProgress = $options['on_progress'] ?? null;
9684
$subnets = $this->subnets;
9785
$ipFlags = $this->ipFlags;
9886

9987
$options['on_progress'] = static function (int $dlNow, int $dlSize, array $info) use ($onProgress, $subnets, $ipFlags): void {
10088
static $lastPrimaryIp = '';
10189

102-
if (($info['primary_ip'] ?? '') !== $lastPrimaryIp) {
90+
if (!\in_array($info['primary_ip'] ?? '', ['', $lastPrimaryIp], true)) {
10391
self::ipCheck($info['primary_ip'], $subnets, $ipFlags, null, $info['url']);
10492
$lastPrimaryIp = $info['primary_ip'];
10593
}
10694

10795
null !== $onProgress && $onProgress($dlNow, $dlSize, $info);
10896
};
10997

98+
if (0 >= $maxRedirects = $options['max_redirects']) {
99+
return new AsyncResponse($this->client, $method, $url, $options);
100+
}
101+
102+
$options['max_redirects'] = 0;
103+
$redirectHeaders['with_auth'] = $redirectHeaders['no_auth'] = $options['headers'];
104+
105+
if (isset($options['normalized_headers']['host']) || isset($options['normalized_headers']['authorization']) || isset($options['normalized_headers']['cookie'])) {
106+
$redirectHeaders['no_auth'] = array_filter($redirectHeaders['no_auth'], static function ($h) {
107+
return 0 !== stripos($h, 'Host:') && 0 !== stripos($h, 'Authorization:') && 0 !== stripos($h, 'Cookie:');
108+
});
109+
}
110+
110111
return new AsyncResponse($this->client, $method, $url, $options, static function (ChunkInterface $chunk, AsyncContext $context) use (&$method, &$options, $maxRedirects, &$redirectHeaders, $subnets, $ipFlags, $dnsCache): \Generator {
111112
if (null !== $chunk->getError() || $chunk->isTimeout() || !$chunk->isFirst()) {
112113
yield $chunk;
@@ -158,11 +159,6 @@ public function request(string $method, string $url, array $options = []): Respo
158159
});
159160
}
160161

161-
public function stream(ResponseInterface|iterable $responses, ?float $timeout = null): ResponseStreamInterface
162-
{
163-
return $this->client->stream($responses, $timeout);
164-
}
165-
166162
/**
167163
* @deprecated since Symfony 7.1, configure the logger on the wrapped HTTP client directly instead
168164
*/

Tests/DataCollector/HttpClientDataCollectorTest.php

-5
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,6 @@ public static function setUpBeforeClass(): void
2424
TestHttpServer::start();
2525
}
2626

27-
public static function tearDownAfterClass(): void
28-
{
29-
TestHttpServer::stop();
30-
}
31-
3227
public function testItCollectsRequestCount()
3328
{
3429
$httpClient1 = $this->httpClientThatHasTracedRequests([

Tests/HttpClientTestCase.php

+67
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,73 @@ public function testNoPrivateNetworkWithResolveAndRedirect()
523523
$client->request('GET', 'http://localhost:8057/302?location=https://symfony.com/');
524524
}
525525

526+
public function testNoPrivateNetwork304()
527+
{
528+
$client = $this->getHttpClient(__FUNCTION__);
529+
$client = new NoPrivateNetworkHttpClient($client, '104.26.14.6/32');
530+
$response = $client->request('GET', 'http://localhost:8057/304', [
531+
'headers' => ['If-Match' => '"abc"'],
532+
'buffer' => false,
533+
]);
534+
535+
$this->assertSame(304, $response->getStatusCode());
536+
$this->assertSame('', $response->getContent(false));
537+
}
538+
539+
public function testNoPrivateNetwork302()
540+
{
541+
$client = $this->getHttpClient(__FUNCTION__);
542+
$client = new NoPrivateNetworkHttpClient($client, '104.26.14.6/32');
543+
$response = $client->request('GET', 'http://localhost:8057/302/relative');
544+
545+
$body = $response->toArray();
546+
547+
$this->assertSame('/', $body['REQUEST_URI']);
548+
$this->assertNull($response->getInfo('redirect_url'));
549+
550+
$response = $client->request('GET', 'http://localhost:8057/302/relative', [
551+
'max_redirects' => 0,
552+
]);
553+
554+
$this->assertSame(302, $response->getStatusCode());
555+
$this->assertSame('http://localhost:8057/', $response->getInfo('redirect_url'));
556+
}
557+
558+
public function testNoPrivateNetworkStream()
559+
{
560+
$client = $this->getHttpClient(__FUNCTION__);
561+
562+
$response = $client->request('GET', 'http://localhost:8057');
563+
$client = new NoPrivateNetworkHttpClient($client, '104.26.14.6/32');
564+
565+
$response = $client->request('GET', 'http://localhost:8057');
566+
$chunks = $client->stream($response);
567+
$result = [];
568+
569+
foreach ($chunks as $r => $chunk) {
570+
if ($chunk->isTimeout()) {
571+
$result[] = 't';
572+
} elseif ($chunk->isLast()) {
573+
$result[] = 'l';
574+
} elseif ($chunk->isFirst()) {
575+
$result[] = 'f';
576+
}
577+
}
578+
579+
$this->assertSame($response, $r);
580+
$this->assertSame(['f', 'l'], $result);
581+
582+
$chunk = null;
583+
$i = 0;
584+
585+
foreach ($client->stream($response) as $chunk) {
586+
++$i;
587+
}
588+
589+
$this->assertSame(1, $i);
590+
$this->assertTrue($chunk->isLast());
591+
}
592+
526593
public function testNoRedirectWithInvalidLocation()
527594
{
528595
$client = $this->getHttpClient(__FUNCTION__);

Tests/HttplugClientTest.php

-5
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,6 @@ public static function setUpBeforeClass(): void
3232
TestHttpServer::start();
3333
}
3434

35-
public static function tearDownAfterClass(): void
36-
{
37-
TestHttpServer::stop();
38-
}
39-
4035
/**
4136
* @requires function ob_gzhandler
4237
*/

Tests/Psr18ClientTest.php

-5
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,6 @@ public static function setUpBeforeClass(): void
2828
TestHttpServer::start();
2929
}
3030

31-
public static function tearDownAfterClass(): void
32-
{
33-
TestHttpServer::stop();
34-
}
35-
3631
/**
3732
* @requires function ob_gzhandler
3833
*/

Tests/RetryableHttpClientTest.php

-5
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,6 @@
2727

2828
class RetryableHttpClientTest extends TestCase
2929
{
30-
public static function tearDownAfterClass(): void
31-
{
32-
TestHttpServer::stop();
33-
}
34-
3530
public function testRetryOnError()
3631
{
3732
$client = new RetryableHttpClient(

Tests/TraceableHttpClientTest.php

-5
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,6 @@ public static function setUpBeforeClass(): void
2929
TestHttpServer::start();
3030
}
3131

32-
public static function tearDownAfterClass(): void
33-
{
34-
TestHttpServer::stop();
35-
}
36-
3732
public function testItTracesRequest()
3833
{
3934
$httpClient = $this->createMock(HttpClientInterface::class);

0 commit comments

Comments
 (0)