Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 0034e14

Browse filesBrowse files
committed
feature #30325 [HttpKernel] Prevent search engines from indexing dev applications (GaryPEGEOT)
This PR was squashed before being merged into the 4.3-dev branch (closes #30325). Discussion ---------- [HttpKernel] Prevent search engines from indexing dev applications | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #30318 | License | MIT | Doc PR | TODO Add the *X-Robots-Tag: noindex* to dev (and test) applications to prevent search engines to index them. Commits ------- 3dd8671 [HttpKernel] Prevent search engines from indexing dev applications
2 parents 11f1660 + 3dd8671 commit 0034e14
Copy full SHA for 0034e14

File tree

8 files changed

+134
-0
lines changed
Filter options

8 files changed

+134
-0
lines changed

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
+14Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ public function getConfigTreeBuilder()
108108
$this->addWebLinkSection($rootNode);
109109
$this->addLockSection($rootNode);
110110
$this->addMessengerSection($rootNode);
111+
$this->addRobotsIndexSection($rootNode);
111112

112113
return $treeBuilder;
113114
}
@@ -1156,4 +1157,17 @@ function ($a) {
11561157
->end()
11571158
;
11581159
}
1160+
1161+
private function addRobotsIndexSection(ArrayNodeDefinition $rootNode)
1162+
{
1163+
$rootNode
1164+
->children()
1165+
->booleanNode('disallow_search_engine_index')
1166+
->info('Enabled by default when debug is enabled.')
1167+
->defaultValue($this->debug)
1168+
->treatNullLike($this->debug)
1169+
->end()
1170+
->end()
1171+
;
1172+
}
11591173
}

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,10 @@ public function load(array $configs, ContainerBuilder $container)
394394
// remove tagged iterator argument for resource checkers
395395
$container->getDefinition('config_cache_factory')->setArguments([]);
396396
}
397+
398+
if (!$config['disallow_search_engine_index'] ?? false) {
399+
$container->removeDefinition('disallow_search_engine_index_response_listener');
400+
}
397401
}
398402

399403
/**

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,5 +85,8 @@
8585
<argument type="service" id="controller_name_converter" />
8686
<tag name="kernel.event_subscriber" />
8787
</service>
88+
<service id="disallow_search_engine_index_response_listener" class="Symfony\Component\HttpKernel\EventListener\DisallowRobotsIndexingListener">
89+
<tag name="kernel.event_subscriber" />
90+
</service>
8891
</services>
8992
</container>

‎src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,7 @@ class_exists(SemaphoreStore::class) && SemaphoreStore::isSupported() ? 'semaphor
330330
'default_bus' => null,
331331
'buses' => ['messenger.bus.default' => ['default_middleware' => true, 'middleware' => []]],
332332
],
333+
'disallow_search_engine_index' => true,
333334
];
334335
}
335336
}

‎src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
+21Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1327,6 +1327,27 @@ public function testSessionCookieSecureAuto()
13271327
$this->assertEquals($expected, array_keys($container->getDefinition('session_listener')->getArgument(0)->getValues()));
13281328
}
13291329

1330+
public function testRobotsTagListenerIsRegisteredInDebugMode()
1331+
{
1332+
$container = $this->createContainer(['kernel.debug' => true]);
1333+
(new FrameworkExtension())->load([], $container);
1334+
$this->assertTrue($container->has('disallow_search_engine_index_response_listener'), 'DisallowRobotsIndexingListener should be registered');
1335+
1336+
$definition = $container->getDefinition('disallow_search_engine_index_response_listener');
1337+
$this->assertTrue($definition->hasTag('kernel.event_subscriber'), 'DisallowRobotsIndexingListener should have the correct tag');
1338+
1339+
$container = $this->createContainer(['kernel.debug' => true]);
1340+
(new FrameworkExtension())->load([['disallow_search_engine_index' => false]], $container);
1341+
$this->assertFalse(
1342+
$container->has('disallow_search_engine_index_response_listener'),
1343+
'DisallowRobotsIndexingListener should not be registered when explicitly disabled'
1344+
);
1345+
1346+
$container = $this->createContainer(['kernel.debug' => false]);
1347+
(new FrameworkExtension())->load([], $container);
1348+
$this->assertFalse($container->has('disallow_search_engine_index_response_listener'), 'DisallowRobotsIndexingListener should NOT be registered');
1349+
}
1350+
13301351
protected function createContainer(array $data = [])
13311352
{
13321353
return new ContainerBuilder(new ParameterBag(array_merge([

‎src/Symfony/Component/HttpKernel/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpKernel/CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ CHANGELOG
1212
* the base `DataCollector` doesn't implement `Serializable` anymore, you should
1313
store all the serialized state in the data property instead
1414
* `DumpDataCollector` has been marked as `final`
15+
* added an event listener to prevent search engines from indexing applications in debug mode.
1516

1617
4.2.0
1718
-----
+43Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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\Component\HttpKernel\EventListener;
13+
14+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
15+
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
16+
use Symfony\Component\HttpKernel\KernelEvents;
17+
18+
/**
19+
* Ensures that the application is not indexed by search engines.
20+
*
21+
* @author Gary PEGEOT <garypegeot@gmail.com>
22+
*/
23+
class DisallowRobotsIndexingListener implements EventSubscriberInterface
24+
{
25+
private const HEADER_NAME = 'X-Robots-Tag';
26+
27+
public function onResponse(FilterResponseEvent $event): void
28+
{
29+
if (!$event->getResponse()->headers->has(static::HEADER_NAME)) {
30+
$event->getResponse()->headers->set(static::HEADER_NAME, 'noindex');
31+
}
32+
}
33+
34+
/**
35+
* {@inheritdoc}
36+
*/
37+
public static function getSubscribedEvents()
38+
{
39+
return [
40+
KernelEvents::RESPONSE => ['onResponse', -255],
41+
];
42+
}
43+
}
+47Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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\Component\HttpKernel\Tests\EventListener;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\HttpFoundation\Request;
16+
use Symfony\Component\HttpFoundation\Response;
17+
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
18+
use Symfony\Component\HttpKernel\EventListener\DisallowRobotsIndexingListener;
19+
use Symfony\Component\HttpKernel\HttpKernelInterface;
20+
use Symfony\Component\HttpKernel\KernelInterface;
21+
22+
class DisallowRobotsIndexingListenerTest extends TestCase
23+
{
24+
/**
25+
* @dataProvider provideResponses
26+
*/
27+
public function testInvoke(?string $expected, Response $response): void
28+
{
29+
$listener = new DisallowRobotsIndexingListener();
30+
31+
$event = new FilterResponseEvent($this->createMock(HttpKernelInterface::class), $this->createMock(Request::class), KernelInterface::MASTER_REQUEST, $response);
32+
33+
$listener->onResponse($event);
34+
35+
$this->assertSame($expected, $response->headers->get('X-Robots-Tag'), 'Header doesn\'t match expectations');
36+
}
37+
38+
public function provideResponses(): iterable
39+
{
40+
yield 'No header' => ['noindex', new Response()];
41+
42+
yield 'Header already set' => [
43+
'something else',
44+
new Response('', 204, ['X-Robots-Tag' => 'something else']),
45+
];
46+
}
47+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.