Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 15d0ad5

Browse files
Merge branch '5.4' into 6.4
* 5.4: [HttpClient] Fix option "resolve" with IPv6 addresses Fix twig deprecations in web profiler twig files [HttpClient] Fix option "bindto" with IPv6 addresses fixes symfony#58904 [Validator] review latvian translations
2 parents 160acd2 + aea227a commit 15d0ad5

File tree

12 files changed

+122
-46
lines changed

12 files changed

+122
-46
lines changed

src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/notifier.html.twig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@
138138
{{- 'Content: ' ~ notification.getContent() }}<br/>
139139
{{- 'Importance: ' ~ notification.getImportance() }}<br/>
140140
{{- 'Emoji: ' ~ (notification.getEmoji() is empty ? '(empty)' : notification.getEmoji()) }}<br/>
141-
{{- 'Exception: ' ~ notification.getException() ?? '(empty)' }}<br/>
141+
{{- 'Exception: ' ~ (notification.getException() ?? '(empty)') }}<br/>
142142
{{- 'ExceptionAsString: ' ~ (notification.getExceptionAsString() is empty ? '(empty)' : notification.getExceptionAsString()) }}
143143
</pre>
144144
</div>

src/Symfony/Component/HttpClient/CurlHttpClient.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ public function request(string $method, string $url, array $options = []): Respo
278278
if (file_exists($options['bindto'])) {
279279
$curlopts[\CURLOPT_UNIX_SOCKET_PATH] = $options['bindto'];
280280
} elseif (!str_starts_with($options['bindto'], 'if!') && preg_match('/^(.*):(\d+)$/', $options['bindto'], $matches)) {
281-
$curlopts[\CURLOPT_INTERFACE] = $matches[1];
281+
$curlopts[\CURLOPT_INTERFACE] = trim($matches[1], '[]');
282282
$curlopts[\CURLOPT_LOCALPORT] = $matches[2];
283283
} else {
284284
$curlopts[\CURLOPT_INTERFACE] = $options['bindto'];

src/Symfony/Component/HttpClient/HttpClientTrait.php

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,14 @@ private static function mergeDefaultOptions(array $options, array $defaultOption
207207
if ($resolve = $options['resolve'] ?? false) {
208208
$options['resolve'] = [];
209209
foreach ($resolve as $k => $v) {
210-
$options['resolve'][substr(self::parseUrl('http://'.$k)['authority'], 2)] = (string) $v;
210+
if ('' === $v = (string) $v) {
211+
throw new InvalidArgumentException(sprintf('Option "resolve" for host "%s" cannot be empty.', $k));
212+
}
213+
if ('[' === $v[0] && ']' === substr($v, -1) && str_contains($v, ':')) {
214+
$v = substr($v, 1, -1);
215+
}
216+
217+
$options['resolve'][substr(self::parseUrl('http://'.$k)['authority'], 2)] = $v;
211218
}
212219
}
213220

@@ -230,7 +237,14 @@ private static function mergeDefaultOptions(array $options, array $defaultOption
230237

231238
if ($resolve = $defaultOptions['resolve'] ?? false) {
232239
foreach ($resolve as $k => $v) {
233-
$options['resolve'] += [substr(self::parseUrl('http://'.$k)['authority'], 2) => (string) $v];
240+
if ('' === $v = (string) $v) {
241+
throw new InvalidArgumentException(sprintf('Option "resolve" for host "%s" cannot be empty.', $k));
242+
}
243+
if ('[' === $v[0] && ']' === substr($v, -1) && str_contains($v, ':')) {
244+
$v = substr($v, 1, -1);
245+
}
246+
247+
$options['resolve'] += [substr(self::parseUrl('http://'.$k)['authority'], 2) => $v];
234248
}
235249
}
236250

src/Symfony/Component/HttpClient/Internal/AmpListener.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,12 @@ public function startTlsNegotiation(Request $request): Promise
8181
public function startSendingRequest(Request $request, Stream $stream): Promise
8282
{
8383
$host = $stream->getRemoteAddress()->getHost();
84+
$this->info['primary_ip'] = $host;
8485

8586
if (str_contains($host, ':')) {
8687
$host = '['.$host.']';
8788
}
8889

89-
$this->info['primary_ip'] = $host;
9090
$this->info['primary_port'] = $stream->getRemoteAddress()->getPort();
9191
$this->info['pretransfer_time'] = microtime(true) - $this->info['start_time'];
9292
$this->info['debug'] .= sprintf("* Connected to %s (%s) port %d\n", $request->getUri()->getHost(), $host, $this->info['primary_port']);

src/Symfony/Component/HttpClient/Internal/AmpResolver.php

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,31 @@ public function __construct(array &$dnsMap)
3434

3535
public function resolve(string $name, ?int $typeRestriction = null): Promise
3636
{
37-
if (!isset($this->dnsMap[$name]) || !\in_array($typeRestriction, [Record::A, null], true)) {
37+
$recordType = Record::A;
38+
$ip = $this->dnsMap[$name] ?? null;
39+
40+
if (null !== $ip && str_contains($ip, ':')) {
41+
$recordType = Record::AAAA;
42+
}
43+
if (null === $ip || $recordType !== ($typeRestriction ?? $recordType)) {
3844
return Dns\resolver()->resolve($name, $typeRestriction);
3945
}
4046

41-
return new Success([new Record($this->dnsMap[$name], Record::A, null)]);
47+
return new Success([new Record($ip, $recordType, null)]);
4248
}
4349

4450
public function query(string $name, int $type): Promise
4551
{
46-
if (!isset($this->dnsMap[$name]) || Record::A !== $type) {
52+
$recordType = Record::A;
53+
$ip = $this->dnsMap[$name] ?? null;
54+
55+
if (null !== $ip && str_contains($ip, ':')) {
56+
$recordType = Record::AAAA;
57+
}
58+
if (null === $ip || $recordType !== $type) {
4759
return Dns\resolver()->query($name, $type);
4860
}
4961

50-
return new Success([new Record($this->dnsMap[$name], Record::A, null)]);
62+
return new Success([new Record($ip, $recordType, null)]);
5163
}
5264
}

src/Symfony/Component/HttpClient/NativeHttpClient.php

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ public function request(string $method, string $url, array $options = []): Respo
8080
if (str_starts_with($options['bindto'], 'host!')) {
8181
$options['bindto'] = substr($options['bindto'], 5);
8282
}
83+
if ((\PHP_VERSION_ID < 80223 || 80300 <= \PHP_VERSION_ID && 80311 < \PHP_VERSION_ID) && '\\' === \DIRECTORY_SEPARATOR && '[' === $options['bindto'][0]) {
84+
$options['bindto'] = preg_replace('{^\[[^\]]++\]}', '[$0]', $options['bindto']);
85+
}
8386
}
8487

8588
$hasContentLength = isset($options['normalized_headers']['content-length']);
@@ -334,29 +337,35 @@ private static function parseHostPort(array $url, array &$info): array
334337
*/
335338
private static function dnsResolve(string $host, NativeClientState $multi, array &$info, ?\Closure $onProgress): string
336339
{
337-
if (null === $ip = $multi->dnsCache[$host] ?? null) {
340+
$flag = '' !== $host && '[' === $host[0] && ']' === $host[-1] && str_contains($host, ':') ? \FILTER_FLAG_IPV6 : \FILTER_FLAG_IPV4;
341+
$ip = \FILTER_FLAG_IPV6 === $flag ? substr($host, 1, -1) : $host;
342+
343+
if (filter_var($ip, \FILTER_VALIDATE_IP, $flag)) {
344+
// The host is already an IP address
345+
} elseif (null === $ip = $multi->dnsCache[$host] ?? null) {
338346
$info['debug'] .= "* Hostname was NOT found in DNS cache\n";
339347
$now = microtime(true);
340348

341349
if (!$ip = gethostbynamel($host)) {
342350
throw new TransportException(sprintf('Could not resolve host "%s".', $host));
343351
}
344352

345-
$info['namelookup_time'] = microtime(true) - ($info['start_time'] ?: $now);
346353
$multi->dnsCache[$host] = $ip = $ip[0];
347354
$info['debug'] .= "* Added {$host}:0:{$ip} to DNS cache\n";
348355
} else {
349356
$info['debug'] .= "* Hostname was found in DNS cache\n";
357+
$host = str_contains($ip, ':') ? "[$ip]" : $ip;
350358
}
351359

360+
$info['namelookup_time'] = microtime(true) - ($info['start_time'] ?: $now);
352361
$info['primary_ip'] = $ip;
353362

354363
if ($onProgress) {
355364
// Notify DNS resolution
356365
$onProgress();
357366
}
358367

359-
return $ip;
368+
return $host;
360369
}
361370

362371
/**

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

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,6 @@ protected function getHttpClient(string $testCase): HttpClientInterface
3333
return new CurlHttpClient(['verify_peer' => false, 'verify_host' => false], 6, 50);
3434
}
3535

36-
public function testBindToPort()
37-
{
38-
$client = $this->getHttpClient(__FUNCTION__);
39-
$response = $client->request('GET', 'http://localhost:8057', ['bindto' => '127.0.0.1:9876']);
40-
$response->getStatusCode();
41-
42-
$r = new \ReflectionProperty($response, 'handle');
43-
44-
$curlInfo = curl_getinfo($r->getValue($response));
45-
46-
self::assertSame('127.0.0.1', $curlInfo['local_ip']);
47-
self::assertSame(9876, $curlInfo['local_port']);
48-
}
49-
5036
public function testTimeoutIsNotAFatalError()
5137
{
5238
if ('\\' === \DIRECTORY_SEPARATOR) {

src/Symfony/Component/Security/Core/Resources/translations/security.lv.xlf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
</trans-unit>
7777
<trans-unit id="20">
7878
<source>Too many failed login attempts, please try again in %minutes% minutes.</source>
79-
<target>Pārāk daudz neveiksmīgu autentifikācijas mēģinājumu, lūdzu, mēģiniet vēlreiz pēc %minutes% minūtes.|Pārāk daudz neveiksmīgu autentifikācijas mēģinājumu, lūdzu, mēģiniet vēlreiz pēc %minutes% minūtēm.</target>
79+
<target>Pārāk daudz neveiksmīgu autentifikācijas mēģinājumu, lūdzu, mēģiniet vēlreiz pēc %minutes% minūtēm.</target>
8080
</trans-unit>
8181
</body>
8282
</file>

src/Symfony/Component/Validator/Resources/translations/validators.lv.xlf

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -452,19 +452,19 @@
452452
</trans-unit>
453453
<trans-unit id="116">
454454
<source>This value does not represent a valid week in the ISO 8601 format.</source>
455-
<target state="needs-translation">This value does not represent a valid week in the ISO 8601 format.</target>
455+
<target>Šī vērtība neatspoguļo nedēļu ISO 8601 formatā.</target>
456456
</trans-unit>
457457
<trans-unit id="117">
458458
<source>This value is not a valid week.</source>
459-
<target state="needs-translation">This value is not a valid week.</target>
459+
<target>Šī vērtība nav derīga nedēļa.</target>
460460
</trans-unit>
461461
<trans-unit id="118">
462462
<source>This value should not be before week "{{ min }}".</source>
463-
<target state="needs-translation">This value should not be before week "{{ min }}".</target>
463+
<target>Šai vērtībai nevajadzētu būt pirms "{{ min }}" nedēļas.</target>
464464
</trans-unit>
465465
<trans-unit id="119">
466466
<source>This value should not be after week "{{ max }}".</source>
467-
<target state="needs-translation">This value should not be after week "{{ max }}".</target>
467+
<target>Šai vērtībai nevajadzētu būt pēc "{{ max }}" nedēļas.</target>
468468
</trans-unit>
469469
</body>
470470
</file>

src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,26 @@
1212
$_POST['content-type'] = $_SERVER['HTTP_CONTENT_TYPE'] ?? '?';
1313
}
1414

15+
$headers = [
16+
'SERVER_PROTOCOL',
17+
'SERVER_NAME',
18+
'REQUEST_URI',
19+
'REQUEST_METHOD',
20+
'PHP_AUTH_USER',
21+
'PHP_AUTH_PW',
22+
'REMOTE_ADDR',
23+
'REMOTE_PORT',
24+
];
25+
26+
foreach ($headers as $k) {
27+
if (isset($_SERVER[$k])) {
28+
$vars[$k] = $_SERVER[$k];
29+
}
30+
}
31+
1532
foreach ($_SERVER as $k => $v) {
16-
switch ($k) {
17-
default:
18-
if (!str_starts_with($k, 'HTTP_')) {
19-
continue 2;
20-
}
21-
// no break
22-
case 'SERVER_NAME':
23-
case 'SERVER_PROTOCOL':
24-
case 'REQUEST_URI':
25-
case 'REQUEST_METHOD':
26-
case 'PHP_AUTH_USER':
27-
case 'PHP_AUTH_PW':
28-
$vars[$k] = $v;
33+
if (str_starts_with($k, 'HTTP_')) {
34+
$vars[$k] = $v;
2935
}
3036
}
3137

src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public static function tearDownAfterClass(): void
3636
{
3737
TestHttpServer::stop(8067);
3838
TestHttpServer::stop(8077);
39+
TestHttpServer::stop(8087);
3940
}
4041

4142
abstract protected function getHttpClient(string $testCase): HttpClientInterface;
@@ -734,6 +735,18 @@ public function testIdnResolve()
734735
$this->assertSame(200, $response->getStatusCode());
735736
}
736737

738+
public function testIPv6Resolve()
739+
{
740+
TestHttpServer::start(-8087, '[::1]');
741+
742+
$client = $this->getHttpClient(__FUNCTION__);
743+
$response = $client->request('GET', 'http://symfony.com:8087/', [
744+
'resolve' => ['symfony.com' => '::1'],
745+
]);
746+
747+
$this->assertSame(200, $response->getStatusCode());
748+
}
749+
737750
public function testNotATimeout()
738751
{
739752
$client = $this->getHttpClient(__FUNCTION__);
@@ -1148,4 +1161,33 @@ public function testWithOptions()
11481161
$response = $client2->request('GET', '/');
11491162
$this->assertSame(200, $response->getStatusCode());
11501163
}
1164+
1165+
public function testBindToPort()
1166+
{
1167+
$client = $this->getHttpClient(__FUNCTION__);
1168+
$response = $client->request('GET', 'http://localhost:8057', ['bindto' => '127.0.0.1:9876']);
1169+
$response->getStatusCode();
1170+
1171+
$vars = $response->toArray();
1172+
1173+
self::assertSame('127.0.0.1', $vars['REMOTE_ADDR']);
1174+
self::assertSame('9876', $vars['REMOTE_PORT']);
1175+
}
1176+
1177+
public function testBindToPortV6()
1178+
{
1179+
TestHttpServer::start(-8087);
1180+
1181+
$client = $this->getHttpClient(__FUNCTION__);
1182+
$response = $client->request('GET', 'http://[::1]:8087', ['bindto' => '[::1]:9876']);
1183+
$response->getStatusCode();
1184+
1185+
$vars = $response->toArray();
1186+
1187+
self::assertSame('::1', $vars['REMOTE_ADDR']);
1188+
1189+
if ('\\' !== \DIRECTORY_SEPARATOR) {
1190+
self::assertSame('9876', $vars['REMOTE_PORT']);
1191+
}
1192+
}
11511193
}

src/Symfony/Contracts/HttpClient/Test/TestHttpServer.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ public static function start(int $port = 8057/* , string $workingDirectory = nul
2525
{
2626
$workingDirectory = \func_get_args()[1] ?? __DIR__.'/Fixtures/web';
2727

28+
if (0 > $port) {
29+
$port = -$port;
30+
$ip = '[::1]';
31+
} else {
32+
$ip = '127.0.0.1';
33+
}
34+
2835
if (isset(self::$process[$port])) {
2936
self::$process[$port]->stop();
3037
} else {
@@ -34,14 +41,14 @@ public static function start(int $port = 8057/* , string $workingDirectory = nul
3441
}
3542

3643
$finder = new PhpExecutableFinder();
37-
$process = new Process(array_merge([$finder->find(false)], $finder->findArguments(), ['-dopcache.enable=0', '-dvariables_order=EGPCS', '-S', '127.0.0.1:'.$port]));
44+
$process = new Process(array_merge([$finder->find(false)], $finder->findArguments(), ['-dopcache.enable=0', '-dvariables_order=EGPCS', '-S', $ip.':'.$port]));
3845
$process->setWorkingDirectory($workingDirectory);
3946
$process->start();
4047
self::$process[$port] = $process;
4148

4249
do {
4350
usleep(50000);
44-
} while (!@fopen('http://127.0.0.1:'.$port, 'r'));
51+
} while (!@fopen('http://'.$ip.':'.$port, 'r'));
4552

4653
return $process;
4754
}

0 commit comments

Comments
 (0)