Skip to content

Commit 9b85d1e

Browse files
committed
Merge branch '4.4' into 5.0
* 4.4: Avoid stale-if-error if kernel.debug = true, because it hides errors [Console] Fix SymfonyQuestionHelper tests sometimes failing on AppVeyor [SecurityBundle] Fix collecting traceable listeners info using anonymous: lazy [Filesystem][FilesystemCommonTrait] Use a dedicated directory when there are no namespace [Workflow] Fix configuration node reference for "initial_marking" expand listener in place [DI] deferred exceptions in ResolveParameterPlaceHoldersPass Do not throw exception on valut generate key
2 parents 14e6b2f + ceb3ae4 commit 9b85d1e

File tree

4 files changed

+151
-44
lines changed

4 files changed

+151
-44
lines changed

Debug/TraceableFirewallListener.php

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
namespace Symfony\Bundle\SecurityBundle\Debug;
1313

1414
use Symfony\Bundle\SecurityBundle\EventListener\FirewallListener;
15+
use Symfony\Bundle\SecurityBundle\Security\FirewallContext;
16+
use Symfony\Bundle\SecurityBundle\Security\LazyFirewallContext;
1517
use Symfony\Component\HttpKernel\Event\RequestEvent;
18+
use Symfony\Component\Security\Http\Firewall\AbstractListener;
1619

1720
/**
1821
* Firewall collecting called listeners.
@@ -21,7 +24,7 @@
2124
*/
2225
final class TraceableFirewallListener extends FirewallListener
2326
{
24-
private $wrappedListeners;
27+
private $wrappedListeners = [];
2528

2629
public function getWrappedListeners()
2730
{
@@ -30,14 +33,47 @@ public function getWrappedListeners()
3033

3134
protected function callListeners(RequestEvent $event, iterable $listeners)
3235
{
36+
$wrappedListeners = [];
37+
$wrappedLazyListeners = [];
38+
3339
foreach ($listeners as $listener) {
34-
$wrappedListener = new WrappedListener($listener);
35-
$wrappedListener($event);
36-
$this->wrappedListeners[] = $wrappedListener->getInfo();
40+
if ($listener instanceof LazyFirewallContext) {
41+
\Closure::bind(function () use (&$wrappedLazyListeners, &$wrappedListeners) {
42+
$listeners = [];
43+
foreach ($this->listeners as $listener) {
44+
if ($listener instanceof AbstractListener) {
45+
$listener = new WrappedLazyListener($listener);
46+
$listeners[] = $listener;
47+
$wrappedLazyListeners[] = $listener;
48+
} else {
49+
$listeners[] = function (RequestEvent $event) use ($listener, &$wrappedListeners) {
50+
$wrappedListener = new WrappedListener($listener);
51+
$wrappedListener($event);
52+
$wrappedListeners[] = $wrappedListener->getInfo();
53+
};
54+
}
55+
}
56+
$this->listeners = $listeners;
57+
}, $listener, FirewallContext::class)();
58+
59+
$listener($event);
60+
} else {
61+
$wrappedListener = $listener instanceof AbstractListener ? new WrappedLazyListener($listener) : new WrappedListener($listener);
62+
$wrappedListener($event);
63+
$wrappedListeners[] = $wrappedListener->getInfo();
64+
}
3765

3866
if ($event->hasResponse()) {
3967
break;
4068
}
4169
}
70+
71+
if ($wrappedLazyListeners) {
72+
foreach ($wrappedLazyListeners as $lazyListener) {
73+
$this->wrappedListeners[] = $lazyListener->getInfo();
74+
}
75+
}
76+
77+
$this->wrappedListeners = array_merge($this->wrappedListeners, $wrappedListeners);
4278
}
4379
}

Debug/TraceableListenerTrait.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\SecurityBundle\Debug;
13+
14+
/**
15+
* @author Robin Chalas <[email protected]>
16+
*
17+
* @internal
18+
*/
19+
trait TraceableListenerTrait
20+
{
21+
private $response;
22+
private $listener;
23+
private $time;
24+
private $stub;
25+
26+
/**
27+
* Proxies all method calls to the original listener.
28+
*/
29+
public function __call(string $method, array $arguments)
30+
{
31+
return $this->listener->{$method}(...$arguments);
32+
}
33+
34+
public function getWrappedListener()
35+
{
36+
return $this->listener;
37+
}
38+
}

Debug/WrappedLazyListener.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\SecurityBundle\Debug;
13+
14+
use Symfony\Component\HttpFoundation\Request;
15+
use Symfony\Component\HttpKernel\Event\RequestEvent;
16+
use Symfony\Component\Security\Core\Exception\LazyResponseException;
17+
use Symfony\Component\Security\Http\Firewall\AbstractListener;
18+
use Symfony\Component\VarDumper\Caster\ClassStub;
19+
20+
/**
21+
* Wraps a lazy security listener.
22+
*
23+
* @author Robin Chalas <[email protected]>
24+
*
25+
* @internal
26+
*/
27+
final class WrappedLazyListener extends AbstractListener
28+
{
29+
use TraceableListenerTrait;
30+
31+
public function __construct(AbstractListener $listener)
32+
{
33+
$this->listener = $listener;
34+
}
35+
36+
public function supports(Request $request): ?bool
37+
{
38+
return $this->listener->supports($request);
39+
}
40+
41+
/**
42+
* {@inheritdoc}
43+
*/
44+
public function authenticate(RequestEvent $event)
45+
{
46+
$startTime = microtime(true);
47+
48+
try {
49+
$ret = $this->listener->authenticate($event);
50+
} catch (LazyResponseException $e) {
51+
$this->response = $e->getResponse();
52+
53+
throw $e;
54+
} finally {
55+
$this->time = microtime(true) - $startTime;
56+
}
57+
58+
$this->response = $event->getResponse();
59+
60+
return $ret;
61+
}
62+
63+
public function getInfo(): array
64+
{
65+
return [
66+
'response' => $this->response,
67+
'time' => $this->time,
68+
'stub' => $this->stub ?? $this->stub = ClassStub::wrapCallable($this->listener),
69+
];
70+
}
71+
}

Debug/WrappedListener.php

Lines changed: 2 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,7 @@
2323
*/
2424
final class WrappedListener
2525
{
26-
private $response;
27-
private $listener;
28-
private $time;
29-
private $stub;
30-
private static $hasVarDumper;
26+
use TraceableListenerTrait;
3127

3228
public function __construct(callable $listener)
3329
{
@@ -42,46 +38,12 @@ public function __invoke(RequestEvent $event)
4238
$this->response = $event->getResponse();
4339
}
4440

45-
/**
46-
* Proxies all method calls to the original listener.
47-
*/
48-
public function __call(string $method, array $arguments)
49-
{
50-
return $this->listener->{$method}(...$arguments);
51-
}
52-
53-
public function getWrappedListener(): callable
54-
{
55-
return $this->listener;
56-
}
57-
5841
public function getInfo(): array
5942
{
60-
if (null !== $this->stub) {
61-
// no-op
62-
} elseif (self::$hasVarDumper ?? self::$hasVarDumper = class_exists(ClassStub::class)) {
63-
$this->stub = ClassStub::wrapCallable($this->listener);
64-
} elseif (\is_array($this->listener)) {
65-
$this->stub = (\is_object($this->listener[0]) ? \get_class($this->listener[0]) : $this->listener[0]).'::'.$this->listener[1];
66-
} elseif ($this->listener instanceof \Closure) {
67-
$r = new \ReflectionFunction($this->listener);
68-
if (false !== strpos($r->name, '{closure}')) {
69-
$this->stub = 'closure';
70-
} elseif ($class = $r->getClosureScopeClass()) {
71-
$this->stub = $class->name.'::'.$r->name;
72-
} else {
73-
$this->stub = $r->name;
74-
}
75-
} elseif (\is_string($this->listener)) {
76-
$this->stub = $this->listener;
77-
} else {
78-
$this->stub = \get_class($this->listener).'::__invoke';
79-
}
80-
8143
return [
8244
'response' => $this->response,
8345
'time' => $this->time,
84-
'stub' => $this->stub,
46+
'stub' => $this->stub ?? $this->stub = ClassStub::wrapCallable($this->listener),
8547
];
8648
}
8749
}

0 commit comments

Comments
 (0)