8000 Merge branch '4.4' into 5.0 · symfony/symfony@c048ea5 · GitHub
[go: up one dir, main page]

Skip to content

Commit c048ea5

Browse files
Merge branch '4.4' into 5.0
* 4.4: [Config] improve perf of glob discovery when GLOB_BRACE is not available use utf8mb4_bin to align code with documentation [HttpClient] make pushed responses retry-able [VarDumper] ignore failing __debugInfo()
2 parents c253ffd + d7a0679 commit c048ea5

File tree

6 files changed

+111
-25
lines changed

6 files changed

+111
-25
lines changed

src/Symfony/Component/Config/Resource/GlobResource.php

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class GlobResource implements \IteratorAggregate, SelfCheckingResourceInterface
3131
private $hash;
3232
private $forExclusion;
3333
private $excludedPrefixes;
34+
private $globBrace;
3435

3536
/**
3637
* @param string $prefix A directory prefix
@@ -47,6 +48,7 @@ public function __construct(string $prefix, string $pattern, bool $recursive, bo
4748
$this->recursive = $recursive;
4849
$this->forExclusion = $forExclusion;
4950
$this->excludedPrefixes = $excludedPrefixes;
51+
$this->globBrace = \defined('GLOB_BRACE') ? GLOB_BRACE : 0;
5052

5153
if (false === $this->prefix) {
5254
throw new \InvalidArgumentException(sprintf('The path "%s" does not exist.', $prefix));
@@ -98,9 +100,20 @@ public function getIterator(): \Traversable
98100
return;
99101
}
100102
$prefix = str_replace('\\', '/', $this->prefix);
103+
$paths = null;
104+
105+
if (0 !== strpos($this->prefix, 'phar://') && false === strpos($this->pattern, '/**/')) {
106+
if ($this->globBrace || false === strpos($this->pattern, '{')) {
107+
$paths = glob($this->prefix.$this->pattern, GLOB_NOSORT | $this->globBrace);
108+
} elseif (false === strpos($this->pattern, '\\') || !preg_match('/\\\\[,{}]/', $this->pattern)) {
109+
foreach ($this->expandGlob($this->pattern) as $p) {
110+
$paths[] = glob($this->prefix.$p, GLOB_NOSORT);
111+
}
112+
$paths = array_merge(...$paths);
113+
}
114+
}
101115

102-
if (0 !== strpos($this->prefix, 'phar://') && false === strpos($this->pattern, '/**/') && (\defined('GLOB_BRACE') || false === strpos($this->pattern, '{'))) {
103-
$paths = glob($this->prefix.$this->pattern, GLOB_NOSORT | (\defined('GLOB_BRACE') ? GLOB_BRACE : 0));
116+
if (null !== $paths) {
104117
sort($paths);
105118
foreach ($paths as $path) {
106119
if ($this->excludedPrefixes) {
@@ -184,4 +197,34 @@ private function computeHash(): string
184197

185198
return hash_final($hash);
186199
}
200+
201+
private function expandGlob(string $pattern): array
202+
{
203+
$segments = preg_split('/\{([^{}]*+)\}/', $pattern, -1, PREG_SPLIT_DELIM_CAPTURE);
204+
$paths = [$segments[0]];
205+
$patterns = [];
206+
207+
for ($i = 1; $i < \count($segments); $i += 2) {
208+
$patterns = [];
209+
210+
foreach (explode(',', $segments[$i]) as $s) {
211+
foreach ($paths as $p) {
212+
$patterns[] = $p.$s.$segments[1 + $i];
213+
}
214+
}
215+
216+
$paths = $patterns;
217+
}
218+
219+
$j = 0;
220+
foreach ($patterns as $i => $p) {
221+
if (false !== strpos($p, '{')) {
222+
$p = $this->expandGlob($p);
223+
array_splice($paths, $i + $j, 1, $p);
224+
$j += \count($p) - 1;
225+
}
226+
}
227+
228+
return $paths;
229+
}
187230
}

src/Symfony/Component/Config/Tests/Resource/GlobResourceTest.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,4 +165,33 @@ public function testIsFreshRecursiveDetectsNewFile()
165165
touch($dir.'/Resource/TmpGlob');
166166
$this->assertFalse($resource->isFresh(0));
167167
}
168+
169+
public function testBraceFallback()
170+
{
171+
$dir = \dirname(__DIR__).\DIRECTORY_SEPARATOR.'Fixtures';
172+
$resource = new GlobResource($dir, '/*{/*/*.txt,.x{m,n}l}', true);
173+
174+
$p = new \ReflectionProperty($resource, 'globBrace');
175+
$p->setAccessible(true);
176+
$p->setValue($resource, 0);
177+
178+
$expected = [
179+
$dir.'/Exclude/ExcludeToo/AnotheExcludedFile.txt',
180+
$dir.'/foo.xml',
181+
];
182+
183+
$this->assertSame($expected, array_keys(iterator_to_array($resource)));
184+
}
185+
186+
public function testUnbalancedBraceFallback()
187+
{
188+
$dir = \dirname(__DIR__).\DIRECTORY_SEPARATOR.'Fixtures';
189+
$resource = new GlobResource($dir, '/*{/*/*.txt,.x{m,nl}', true);
190+
191+
$p = new \ReflectionProperty($resource, 'globBrace');
192+
$p->setAccessible(true);
193+
$p->setValue($resource, 0);
194+
195+
$this->assertSame([], array_keys(iterator_to_array($resource)));
196+
}
168197
}

src/Symfony/Component/HttpClient/CurlHttpClient.php

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -119,23 +119,6 @@ public function request(string $method, string $url, array $options = []): Respo
119119
$options['normalized_headers']['user-agent'][] = $options['headers'][] = 'User-Agent: Symfony HttpClient/Curl';
120120
}
121121

122-
if ($pushedResponse = $this->multi->pushedResponses[$url] ?? null) {
123-
unset($this->multi->pushedResponses[$url]);
124-
125-
if (self::acceptPushForRequest($method, $options, $pushedResponse)) {
126-
$this->logger && $this->logger->debug(sprintf('Accepting pushed response: "%s %s"', $method, $url));
127-
128-
// Reinitialize the pushed response with request's options
129-
$pushedResponse->response->__construct($this->multi, $url, $options, $this->logger);
130-
131-
return $pushedResponse->response;
132-
}
133-
134-
$this->logger && $this->logger->debug(sprintf('Rejecting pushed response: "%s".', $url));
135-
}
136-
137-
$this->logger && $this->logger->info(sprintf('Request: "%s %s"', $method, $url));
138-
139122
$curlopts = [
140123
CURLOPT_URL => $url,
141124
CURLOPT_TCP_NODELAY => true,
@@ -294,7 +277,26 @@ public function request(string $method, string $url, array $options = []): Respo
294277
$curlopts[CURLOPT_TIMEOUT_MS] = 1000 * $options['max_duration'];
295278
}
296279

297-
$ch = curl_init();
280+
if ($pushedResponse = $this->multi->pushedResponses[$url] ?? null) {
281+
unset($this->multi->pushedResponses[$url]);
282+
283+
if (self::acceptPushForRequest($method, $options, $pushedResponse)) {
284+
$this->logger && $this->logger->debug(sprintf('Accepting pushed response: "%s %s"', $method, $url));
285+
286+
// Reinitialize the pushed response with request's options
287+
$ch = $pushedResponse->handle;
288+
$pushedResponse = $pushedResponse->response;
289+
$pushedResponse->__construct($this->multi, $url, $options, $this->logger);
290+
} else {
291+
$this->logger && $this->logger->debug(sprintf('Rejecting pushed response: "%s".', $url));
292+
$pushedResponse = null;
293+
}
294+
}
295+
296+
if (!$pushedResponse) {
297+
$ch = curl_init();
298+
$this->logger && $this->logger->info(sprintf('Request: "%s %s"', $method, $url));
299+
}
298300

299301
foreach ($curlopts as $opt => $value) {
300302
if (null !== $value && !curl_setopt($ch, $opt, $value) && CURLOPT_CERTINFO !== $opt) {
@@ -306,7 +308,7 @@ public function request(string $method, string $url, array $options = []): Respo
306308
}
307309
}
308310

309-
return new CurlResponse($this->multi, $ch, $options, $this->logger, $method, self::createRedirectResolver($options, $host));
311+
return $pushedResponse ?? new CurlResponse($this->multi, $ch, $options, $this->logger, $method, self::createRedirectResolver($options, $host));
310312
}
311313

312314
/**
@@ -396,7 +398,7 @@ private static function handlePush($parent, $pushed, array $requestHeaders, Curl
396398
$url .= $headers[':path'][0];
397399
$logger && $logger->debug(sprintf('Queueing pushed response: "%s"', $url));
398400

399-
$multi->pushedResponses[$url] = new PushedResponse(new CurlResponse($multi, $pushed), $headers, $multi->openHandles[(int) $parent][1] ?? []);
401+
$multi->pushedResponses[$url] = new PushedResponse(new CurlResponse($multi, $pushed), $headers, $multi->openHandles[(int) $parent][1] ?? [], $pushed);
400402

401403
return CURL_PUSH_OK;
402404
}

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,13 @@ final class PushedResponse
2929

3030
public $parentOptions = [];
3131

32-
public function __construct(CurlResponse $response, array $requestHeaders, array $parentOptions)
32+
public $handle;
33+
34+
public function __construct(CurlResponse $response, array $requestHeaders, array $parentOptions, $handle)
3335
{
3436
$this->response = $response;
3537
$this->requestHeaders = $requestHeaders;
3638
$this->parentOptions = $parentOptions;
39+
$this->handle = $handle;
3740
}
3841
}

src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ public function createTable()
219219
// - trailing space removal
220220
// - case-insensitivity
221221
// - language processing like é == e
222-
$sql = "CREATE TABLE $this->table ($this->idCol VARBINARY(128) NOT NULL PRIMARY KEY, $this->dataCol BLOB NOT NULL, $this->lifetimeCol INTEGER UNSIGNED NOT NULL, $this->timeCol INTEGER UNSIGNED NOT NULL) COLLATE utf8_bin, ENGINE = InnoDB";
222+
$sql = "CREATE TABLE $this->table ($this->idCol VARBINARY(128) NOT NULL PRIMARY KEY, $this->dataCol BLOB NOT NULL, $this->lifetimeCol INTEGER UNSIGNED NOT NULL, $this->timeCol INTEGER UNSIGNED NOT NULL) COLLATE utf8mb4_bin, ENGINE = InnoDB";
223223
break;
224224
case 'sqlite':
225225
$sql = "CREATE TABLE $this->table ($this->idCol TEXT NOT NULL PRIMARY KEY, $this->dataCol BLOB NOT NULL, $this->lifetimeCol INTEGER NOT NULL, $this->timeCol INTEGER NOT NULL)";

src/Symfony/Component/VarDumper/Caster/Caster.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@ class Caster
4646
*/
4747
public static function castObject(object $obj, string $class, bool $hasDebugInfo = false): array
4848
{
49+
if ($hasDebugInfo) {
50+
try {
51+
$debugInfo = $obj->__debugInfo();
52+
} catch (\Exception $e) {
53+
// ignore failing __debugInfo()
54+
$hasDebugInfo = false;
55+
}
56+
}
57+
4958
$a = $obj instanceof \Closure ? [] : (array) $obj;
5059

5160
if ($obj instanceof \__PHP_Incomplete_Class) {
@@ -81,7 +90,7 @@ public static function castObject(object $obj, string $class, bool $hasDebugInfo
8190
}
8291
}
8392

84-
if ($hasDebugInfo && \is_array($debugInfo = $obj->__debugInfo())) {
93+
if ($hasDebugInfo && \is_array($debugInfo)) {
8594
foreach ($debugInfo as $k => $v) {
8695
if (!isset($k[0]) || "\0" !== $k[0]) {
8796
$k = self::PREFIX_VIRTUAL.$k;

0 commit comments

Comments
 (0)
0