8000 Merge branch '5.1' · symfony/symfony@73ca97c · GitHub
[go: up one dir, main page]

Skip to content

Commit 73ca97c

Browse files
Merge branch '5.1'
* 5.1: [HttpClient] fix using proxies with NativeHttpClient [4.4] Ignore more deprecations for Mockery mocks [Routing] fix using !important and defaults/reqs in inline route definitions [ErrorHandler][DebugClassLoader] Do not check Mockery mocks classes [HttpClient] Fix using https with proxies [TwigBundle] Only remove kernel exception listener if twig is used [DI] Fix changelog Remove CHANGELOG files for 4.x Adjust expired range check Fix redis connection error message [DI] fix dumping non-shared lazy services
2 parents d0ded92 + d825513 commit 73ca97c

File tree

16 files changed

+117
-3981
lines changed

16 files changed

+117
-3981
lines changed

CHANGELOG-4.0.md

Lines changed: 0 additions & 919 deletions
This file was deleted.

CHANGELOG-4.1.md

Lines changed: 0 additions & 586 deletions
This file was deleted.

CHANGELOG-4.2.md

Lines changed: 0 additions & 668 deletions
This file was deleted.

CHANGELOG-4.3.md

Lines changed: 0 additions & 848 deletions
This file was deleted.

CHANGELOG-4.4.md

Lines changed: 0 additions & 922 deletions
This file was deleted.

src/Symfony/Component/BrowserKit/Cookie.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ public function isHttpOnly()
306306
*/
307307
public function isExpired()
308308
{
309-
return null !== $this->expires && 0 != $this->expires && $this->expires < time();
309+
return null !== $this->expires && 0 != $this->expires && $this->expires <= time();
310310
}
311311

312312
/**

src/Symfony/Component/DependencyInjection/CHANGELOG.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ CHANGELOG
2727
* allowed loading and dumping tags with an attribute named "name"
2828
* deprecated `Definition::getDeprecationMessage()`, use `Definition::getDeprecation()` instead
2929
* deprecated `Alias::getDeprecationMessage()`, use `Alias::getDeprecation()` instead
30-
* deprecated PHP-DSL's `inline()` function, use `service()` instead
3130
* added support of PHP8 static return type for withers
3231
* added `AliasDeprecatedPublicServicesPass` to deprecate public services to private
3332

src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -863,18 +863,45 @@ protected function {$methodName}($lazyInitialization)
863863
}
864864
}
865865

866-
if ($this->getProxyDumper()->isProxyCandidate($definition)) {
867-
$factoryCode = $definition->isShared() ? ($asFile ? "\$this->load('%s', false)" : '$this->%s(false)') : '$this->factories[%2$s](false)';
868-
$factoryCode = $this->getProxyDumper()->getProxyFactoryCode($definition, $id, sprintf($factoryCode, $methodName, $this->doExport($id)));
866+
if (!$definition->isShared()) {
867+
$factory = sprintf('$this->factories%s[%s]', $definition->isPublic() ? '' : "['service_container']", $this->doExport($id));
868+
}
869+
870+
if ($isProxyCandidate = $this->getProxyDumper()->isProxyCandidate($definition)) {
871+
if (!$definition->isShared()) {
872+
$code .= sprintf(' %s = %1$s ?? ', $factory);
873+
874+
if ($asFile) {
875+
$code .= "function () {\n";
876+
$code .= " return self::do(\$container);\n";
877+
$code .= " };\n\n";
878+
} else {
879+
$code .= sprintf("\\Closure::fromCallable([\$this, '%s']);\n\n", $methodName);
880+
}
881+
}
882+
883+
$factoryCode = $asFile ? 'self::do($container, false)' : sprintf('$this->%s(false)', $methodName);
884+
$factoryCode = $this->getProxyDumper()->getProxyFactoryCode($definition, $id, $factoryCode);
869885
$code .= $asFile ? preg_replace('/function \(([^)]*+)\) {/', 'function (\1) use ($container) {', $factoryCode) : $factoryCode;
870886
}
871887

872-
$code .= $this->addServiceInclude($id, $definition);
888+
$c = $this->addServiceInclude($id, $definition);
889+
890+
if ('' !== $c && $isProxyCandidate && !$definition->isShared()) {
891+
$c = implode("\n", array_map(function ($line) { return $line ? ' '.$line : $line; }, explode("\n", $c)));
892+
$code .= " static \$include = true;\n\n";
893+
$code .= " if (\$include) {\n";
894+
$code .= $c;
895+
$code .= " \$include = false;\n";
896+
$code .= " }\n\n";
897+
} else {
898+
$code .= $c;
899+
}
900+
873901
$c = $this->addInlineService($id, $definition);
874902

875-
if (!$definition->isShared()) {
903+
if (!$isProxyCandidate && !$definition->isShared()) {
876904
$c = implode("\n", array_map(function ($line) { return $line ? ' '.$line : $line; }, explode("\n", $c)));
877-
$factory = sprintf('$this->factories%s[%s]', $definition->isPublic() ? '' : "['service_container']", $this->doExport($id));
878905
$lazyloadInitialization = $definition->isLazy() ? '$lazyLoad = true' : '';
879906

880907
$c = sprintf(" %s = function (%s) {\n%s };\n\n return %1\$s();\n", $factory, $lazyloadInitialization, $c);

src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ public function testNonSharedLazyDumpAsFiles()
307307
->setLazy(true);
308308
$container->compile();
309309
$dumper = new PhpDumper($container);
310+
$dumper->setProxyDumper(new \DummyProxyDumper());
310311
$dump = print_r($dumper->dump(['as_files' => true, 'file' => __DIR__, 'inline_factories_parameter' => false, 'inline_class_loader_parameter' => false]), true);
311312

312313
if ('\\' === \DIRECTORY_SEPARATOR) {

src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_non_shared_lazy.php

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,11 @@ protected function getBarService()
6767
*/
6868
protected function getFooService($lazyLoad = true)
6969
{
70-
// lazy factory for stdClass
70+
$this->factories['service_container']['foo'] = $this->factories['service_container']['foo'] ?? \Closure::fromCallable([$this, 'getFooService']);
7171

72-
$this->factories['service_container']['foo'] = function ($lazyLoad = true) {
73-
return new \stdClass();
74-
};
72+
// lazy factory for stdClass
7573

76-
return $this->factories['service_container']['foo']();
74+
return new \stdClass();
7775
}
7876
}
7977

src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_non_shared_lazy_as_files.txt

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,34 @@ class getNonSharedFooService extends ProjectServiceContainer
2828
*/
2929
public static function do($container, $lazyLoad = true)
3030
{
31-
include_once $container->targetDir.''.'/Fixtures/includes/foo_lazy.php';
32-
33-
$container->factories['non_shared_foo'] = function ($lazyLoad = true) use ($container) {
34-
return new \Bar\FooLazyClass();
31+
$container->factories['non_shared_foo'] = $container->factories['non_shared_foo'] ?? function () use ($container) {
32+
return self::do($container);
3533
};
3634

37-
return $container->factories['non_shared_foo']();
35+
// lazy factory for Bar\FooLazyClass
36+
37+
static $include = true;
38+
39+
if ($include) {
40+
include_once $container->targetDir.''.'/Fixtures/includes/foo_lazy.php';
41+
42+
$include = false;
43+
}
44+
45+
return new \Bar\FooLazyClass();
3846
}
3947
}
4048

49+
[Container%s/proxy.php] => <?php
50+
51+
namespace Container%s;
52+
53+
// proxy code for Bar\FooLazyClass
54+
55+
if (!\class_exists('proxy', false)) {
56+
\class_alias(__NAMESPACE__.'\\proxy', 'proxy', false);
57+
}
58+
4159
[Container%s/ProjectServiceContainer.php] => <?php
4260

4361
namespace Container%s;
@@ -105,6 +123,13 @@ class ProjectServiceContainer extends Container
105123

106124
return class_exists($class, false) ? $class::do($this, $lazyLoad) : $service;
107125
}
126+
127+
protected function createProxy($class, \Closure $factory)
128+
{
129+
class_exists($class, false) || require __DIR__.'/'.$class.'.php';
130+
131+
return $factory();
132+
}
108133
}
109134

110135
[ProjectServiceContainer.preload.php] => <?php
@@ -120,6 +145,7 @@ if (in_array(PHP_SAPI, ['cli', 'phpdbg'], true)) {
120145

121146
require dirname(__DIR__, %d).'%svendor/autoload.php';
122147
require __DIR__.'/Container%s/ProjectServiceContainer.php';
148+
require __DIR__.'/Container%s/proxy.php';
123149
require __DIR__.'/Container%s/getNonSharedFooService.php';
124150

125151
$classes = [];

src/Symfony/Component/ErrorHandler/DebugClassLoader.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Doctrine\Common\Persistence\Proxy as LegacyProxy;
1515
use Doctrine\Persistence\Proxy;
16+
use Mockery\MockInterface;
1617
use PHPUnit\Framework\MockObject\Matcher\StatelessInvocation;
1718
use PHPUnit\Framework\MockObject\MockObject;
1819
use Prophecy\Prophecy\ProphecySubjectInterface;
@@ -306,6 +307,7 @@ public static function checkClasses(): bool
306307
&& !is_subclass_of($symbols[$i], Proxy::class)
307308
&& !is_subclass_of($symbols[$i], ProxyInterface::class)
308309
&& !is_subclass_of($symbols[$i], LegacyProxy::class)
310+
&& !is_subclass_of($symbols[$i], MockInterface::class)
309311
) {
310312
$loader->checkClass($symbols[$i]);
311313
}

src/Symfony/Component/HttpClient/NativeHttpClient.php

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -215,15 +215,18 @@ public function request(string $method, string $url, array $options = []): Respo
215215
$context = stream_context_create($context, ['notification' => $notification]);
216216

217217
$resolver = static function ($multi) use ($context, $options, $url, &$info, $onProgress) {
218-
[$host, $port, $url['authority']] = self::dnsResolve($url, $multi, $info, $onProgress);
218+
[$host, $port] = self::parseHostPort($url, $info);
219219

220220
if (!isset($options['normalized_headers']['host'])) {
221221
$options['headers'][] = 'Host: '.$host.$port;
222222
}
223223

224-
stream_context_set_option($context, 'ssl', 'peer_name', $host);
225224
$proxy = self::getProxy($options['proxy'], $url, $options['no_proxy']);
226-
self::configureHeadersAndProxy($context, $host, $options['headers'], $proxy);
225+
226+
if (!self::configureHeadersAndProxy($context, $host, $options['headers'], $proxy, 'https:' === $url['scheme'])) {
227+
$ip = self::dnsResolve($host, $multi, $info, $onProgress);
228+
$url['authority'] = substr_replace($url['authority'], $ip, -\strlen($host) - \strlen($port), \strlen($host));
229+
}
227230

228231
return [self::createRedirectResolver($options, $host, $proxy, $info, $onProgress), implode('', $url)];
229232
};
@@ -269,9 +272,9 @@ private static function getBodyAsString($body): string
269272
}
270273

271274
/**
272-
* Resolves the IP of the host using the local DNS cache if possible.
275+
* Extracts the host and the port from the URL.
273276
*/
274-
private static function dnsResolve(array $url, NativeClientState $multi, array &$info, ?\Closure $onProgress): array
277+
private static function parseHostPort(array $url, array &$info): array
275278
{
276279
if ($port = parse_url($url['authority'], \PHP_URL_PORT) ?: '') {
277280
$info['primary_port'] = $port;
@@ -280,8 +283,14 @@ private static function dnsResolve(array $url, NativeClientState $multi, array &
280283
$info['primary_port'] = 'http:' === $url['scheme'] ? 80 : 443;
281284
}
282285

283-
$host = parse_url($url['authority'], \PHP_URL_HOST);
286+
return [parse_url($url['authority'], \PHP_URL_HOST), $port];
287+
}
284288

289+
/**
290+
* Resolves the IP of the host using the local DNS cache if possible.
291+
*/
292+
private static function dnsResolve($host, NativeClientState $multi, array &$info, ?\Closure $onProgress): string
293+
{
285294
if (null === $ip = $multi->dnsCache[$host] ?? null) {
286295
$info['debug'] .= "* Hostname was NOT found in DNS cache\n";
287296
$now = microtime(true);
@@ -304,7 +313,7 @@ private static function dnsResolve(array $url, NativeClientState $multi, array &
304313
$onProgress();
305314
}
306315

307-
return [$host, $port, substr_replace($url['authority'], $ip, -\strlen($host) - \strlen($port), \strlen($host))];
316+
return $ip;
308317
}
309318

310319
/**
@@ -367,24 +376,33 @@ private static function createRedirectResolver(array $options, string $host, ?ar
367376
}
368377
}
369378

370-
[$host, $port, $url['authority']] = self::dnsResolve($url, $multi, $info, $onProgress);
371-
stream_context_set_option($context, 'ssl', 'peer_name', $host);
379+
[$host, $port] = self::parseHostPort($url, $info);
372380

373381
if (false !== (parse_url($location, \PHP_URL_HOST) ?? false)) {
374382
// Authorization and Cookie headers MUST NOT follow except for the initial host name
375383
$requestHeaders = $redirectHeaders['host'] === $host ? $redirectHeaders['with_auth'] : $redirectHeaders['no_auth'];
376384
$requestHeaders[] = 'Host: '.$host.$port;
377-
self::configureHeadersAndProxy($context, $host, $requestHeaders, $proxy);
385+
$dnsResolve = !self::configureHeadersAndProxy($context, $host, $requestHeaders, $proxy, 'https:' === $url['scheme']);
386+
} else {
387+
$dnsResolve = isset(stream_context_get_options($context)['ssl']['peer_name']);
388+
}
389+
390+
if ($dnsResolve) {
391+
$ip = self::dnsResolve($host, $multi, $info, $onProgress);
392+
$url['authority'] = substr_replace($url['authority'], $ip, -\strlen($host) - \strlen($port), \strlen($host));
378393
}
379394

380395
return implode('', $url);
381396
};
382397
}
383398

384-
private static function configureHeadersAndProxy($context, string $host, array $requestHeaders, ?array $proxy): bool
399+
private static function configureHeadersAndProxy($context, string $host, array $requestHeaders, ?array $proxy, bool $isSsl): bool
385400
{
386401
if (null === $proxy) {
387-
return stream_context_set_option($context, 'http', 'header', $requestHeaders);
402+
stream_context_set_option($context, 'http', 'header', $requestHeaders);
403+
stream_context_set_option($context, 'ssl', 'peer_name', $host);
404+
405+
return false;
388406
}
389407

390408
// Matching "no_proxy" should follow the behavior of curl
@@ -393,17 +411,24 @@ private static function configureHeadersAndProxy($context, string $host, array $
393411
$dotRule = '.'.ltrim($rule, '.');
394412

395413
if ('*' === $rule || $host === $rule || substr($host, -\strlen($dotRule)) === $dotRule) {
396-
return stream_context_set_option($context, 'http', 'header', $requestHeaders);
414+
stream_context_set_option($context, 'http', 'proxy', null);
415+
stream_context_set_option($context, 'http', 'request_fulluri', false);
416+
stream_context_set_option($context, 'http', 'header', $requestHeaders);
417+
stream_context_set_option($context, 'ssl', 'peer_name', $host);
418+
419+
return false;
397420
}
398421
}
399422

400-
stream_context_set_option($context, 'http', 'proxy', $proxy['url']);
401-
stream_context_set_option($context, 'http', 'request_fulluri', true);
402-
403423
if (null !== $proxy['auth']) {
404424
$requestHeaders[] = 'Proxy-Authorization: '.$proxy['auth'];
405425
}
406426

407-
return stream_context_set_option($context, 'http', 'header', $requestHeaders);
427+
stream_context_set_option($context, 'http', 'proxy', $proxy['url']);
428+
stream_context_set_option($context, 'http', 'request_fulluri', !$isSsl);
429+
stream_context_set_option($context, 'http', 'header', $requestHeaders);
430+
stream_context_set_option($context, 'ssl', 'peer_name', null);
431+
432+
return true;
408433
}
409434
}

src/Symfony/Component/Messenger/Bridge/Redis/Transport/Connection.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,11 @@ public function __construct(array $configuration, array $connectionCredentials =
7171
}
7272

7373
if (null !== $auth && !$this->connection->auth($auth)) {
74-
throw new InvalidArgumentException('Redis connection failed: '.$redis->getLastError());
74+
throw new InvalidArgumentException('Redis connection failed: '.$this->connection->getLastError());
7575
}
7676

7777
if (($dbIndex = $configuration['dbindex'] ?? self::DEFAULT_OPTIONS['dbindex']) && !$this->connection->select($dbIndex)) {
78-
throw new InvalidArgumentException('Redis connection failed: '.$redis->getLastError());
78+
throw new InvalidArgumentException('Redis connection failed: '.$this->connection->getLastError());
7979
}
8080

8181
foreach (['stream', 'group', 'consumer'] as $key) {

src/Symfony/Component/Routing/Route.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,7 @@ private function extractInlineDefaultsAndRequirements(string $pattern): string
539539
return $pattern;
540540
}
541541

542-
return preg_replace_callback('#\{(\w++)(<.*?>)?(\?[^\}]*+)?\}#', function ($m) {
542+
return preg_replace_callback('#\{(!?\w++)(<.*?>)?(\?[^\}]*+)?\}#', function ($m) {
543543
if (isset($m[3][0])) {
544544
$this->setDefault($m[1], '?' !== $m[3] ? substr($m[3], 1) : null);
545545
}

src/Symfony/Component/Routing/Tests/RouteTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ public function testInlineDefaultAndRequirement()
218218
$this->assertEquals((new Route('/foo/{bar}'))->setDefault('bar', null), new Route('/foo/{bar?}'));
219219
$this->assertEquals((new Route('/foo/{bar}'))->setDefault('bar', 'baz'), new Route('/foo/{bar?baz}'));
220220
$this->assertEquals((new Route('/foo/{bar}'))->setDefault('bar', 'baz<buz>'), new Route('/foo/{bar?baz<buz>}'));
221+
$this->assertEquals((new Route('/foo/{!bar}'))->setDefault('!bar', 'baz<buz>'), new Route('/foo/{!bar?baz<buz>}'));
221222
$this->assertEquals((new Route('/foo/{bar}'))->setDefault('bar', 'baz'), new Route('/foo/{bar?}', ['bar' => 'baz']));
222223

223224
$this->assertEquals((new Route('/foo/{bar}'))->setRequirement('bar', '.*'), new Route('/foo/{bar<.*>}'));

0 commit comments

Comments
 (0)
0