Skip to content

Commit ad40489

Browse files
Merge branch '7.4' into 8.0
* 7.4: (21 commits) [SecurityBundle] Fix tests with Symfony 7.4 [DependencyInjection] Ensure deprecation detection does not trigger a PHP error [DependencyInjection][FrameworkBundle] fix BC break when dumping container for build/lint commands [Form] Clean up wrong method docblocks in data transformers Fix merge [DependencyInjection] Throw when using `$this` or its internal scope from PHP config files; use the `$loader` variable instead [HttpClient] Fix sharing CurlClientState between clones of CurlHttpClient instances [FrameworkBundle] Don't exclude classes with constraint/serialization attributes from being registered as services Revert "[HttpClient] Lazily initialize CurlClientState" [Yaml] Fix regression handling blank lines in unquoted scalars [Cache] Fix NullAdapter must set taggable [FrameworkBundle] Order alphabetically known tags of `UnusedTagsPass` allow the installation of MercureBundle 0.4 [Console] don't discard existing aliases when constructing Command Import all node definition classes to DefinitionConfigurator Fix the creation of a redis connection with only ext-relay [FrameworkBundle] Dump bundles config reference first [DependencyInjection] Don't add the .container.known_envs parameter when empty [DependencyInjection] Reset resolved state when setting a parameter [HttpKernel] Don't reset services between fragments redering when using in HttpCache ...
2 parents 1449d85 + f065440 commit ad40489

File tree

2 files changed

+84
-2
lines changed

2 files changed

+84
-2
lines changed

Kernel.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
6565
private ?string $warmupDir = null;
6666
private int $requestStackSize = 0;
6767
private bool $resetServices = false;
68+
private bool $handlingHttpCache = false;
6869

6970
/**
7071
* @var array<string, bool>
@@ -96,6 +97,7 @@ public function __clone()
9697
$this->container = null;
9798
$this->requestStackSize = 0;
9899
$this->resetServices = false;
100+
$this->handlingHttpCache = false;
99101
}
100102

101103
public function boot(): void
@@ -168,13 +170,22 @@ public function handle(Request $request, int $type = HttpKernelInterface::MAIN_R
168170
$container = $this->container ?? $this->preBoot();
169171

170172
if ($container->has('http_cache')) {
171-
return $container->get('http_cache')->handle($request, $type, $catch);
173+
$this->handlingHttpCache = true;
174+
175+
try {
176+
return $container->get('http_cache')->handle($request, $type, $catch);
177+
} finally {
178+
$this->handlingHttpCache = false;
179+
$this->resetServices = true;
180+
}
172181
}
173182
}
174183

175184
$this->boot();
176185
++$this->requestStackSize;
177-
$this->resetServices = true;
186+
if (!$this->handlingHttpCache) {
187+
$this->resetServices = true;
188+
}
178189

179190
try {
180191
return $this->getHttpKernel()->handle($request, $type, $catch);

Tests/KernelTest.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
1818
use Symfony\Component\DependencyInjection\ContainerBuilder;
1919
use Symfony\Component\DependencyInjection\ContainerInterface;
20+
use Symfony\Component\DependencyInjection\Reference;
2021
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
2122
use Symfony\Component\Filesystem\Exception\IOException;
2223
use Symfony\Component\Filesystem\Filesystem;
@@ -30,6 +31,7 @@
3031
use Symfony\Component\HttpKernel\HttpKernel;
3132
use Symfony\Component\HttpKernel\HttpKernelInterface;
3233
use Symfony\Component\HttpKernel\Kernel;
34+
use Symfony\Component\HttpKernel\KernelInterface;
3335
use Symfony\Component\HttpKernel\Tests\Fixtures\KernelWithoutBundles;
3436
use Symfony\Component\HttpKernel\Tests\Fixtures\ResettableService;
3537

@@ -492,6 +494,39 @@ public function testServicesResetter()
492494
$this->assertEquals(1, ResettableService::$counter);
493495
}
494496

497+
public function testServicesAreNotResetBetweenHttpCacheFragments()
498+
{
499+
ResettableService::$counter = 0;
500+
$fragmentKernel = new FragmentHandlingKernel();
501+
502+
$kernel = new CustomProjectDirKernel(function (ContainerBuilder $container) {
503+
$container->addCompilerPass(new ResettableServicePass());
504+
$container->register('kernel', CustomProjectDirKernel::class)
505+
->setSynthetic(true)
506+
->setPublic(true);
507+
$container->register('one', ResettableService::class)
508+
->setPublic(true)
509+
->addTag('kernel.reset', ['method' => 'reset']);
510+
$container->register('services_resetter', ServicesResetter::class)->setPublic(true);
511+
$container->register('http_cache', FragmentRenderingHttpCache::class)
512+
->setPublic(true)
513+
->addArgument(new Reference('kernel'));
514+
}, $fragmentKernel, 'http_cache_fragments');
515+
516+
$kernel->handle(new Request());
517+
518+
$this->assertSame([
519+
['/first-fragment', HttpKernelInterface::MAIN_REQUEST],
520+
['/second-fragment', HttpKernelInterface::MAIN_REQUEST],
521+
], $fragmentKernel->handledPaths);
522+
$this->assertSame([0, 0], $fragmentKernel->resetCounters);
523+
$this->assertSame(0, ResettableService::$counter);
524+
525+
$kernel->boot();
526+
527+
$this->assertSame(1, ResettableService::$counter);
528+
}
529+
495530
#[Group('time-sensitive')]
496531
public function testKernelStartTimeIsResetWhileBootingAlreadyBootedKernel()
497532
{
@@ -731,3 +766,39 @@ public function doLoadClassCache(): void
731766
{
732767
}
733768
}
769+
770+
class FragmentHandlingKernel implements HttpKernelInterface
771+
{
772+
public array $handledPaths = [];
773+
public array $resetCounters = [];
774+
775+
public function handle(Request $request, int $type = self::MAIN_REQUEST, bool $catch = true): Response
776+
{
777+
$this->handledPaths[] = [$request->getPathInfo(), $type];
778+
$this->resetCounters[] = ResettableService::$counter;
779+
780+
return new Response($request->getPathInfo());
781+
}
782+
}
783+
784+
class FragmentRenderingHttpCache implements HttpKernelInterface
785+
{
786+
public function __construct(
787+
private KernelInterface $kernel,
788+
private string $trackedServiceId = 'one',
789+
) {
790+
}
791+
792+
public function handle(Request $request, int $type = self::MAIN_REQUEST, bool $catch = true): Response
793+
{
794+
$this->kernel->boot();
795+
$this->kernel->getContainer()->get($this->trackedServiceId);
796+
797+
$responses = [];
798+
foreach (['/first-fragment', '/second-fragment'] as $path) {
799+
$responses[] = $this->kernel->handle(Request::create($path), self::MAIN_REQUEST, $catch);
800+
}
801+
802+
return new Response(implode('', array_map(static fn (Response $response) => $response->getContent(), $responses)));
803+
}
804+
}

0 commit comments

Comments
 (0)