Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit dd18dc7

Browse files
committed
feat: integration with FrameworkBundle
1 parent a287042 commit dd18dc7

File tree

4 files changed

+58
-1
lines changed

4 files changed

+58
-1
lines changed

src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
6.3
5+
---
6+
7+
* Add `AbstractController::sendEarlyHints()` to send HTTP Early Hints
8+
49
6.2
510
---
611

src/Symfony/Bundle/FrameworkBundle/Controller/AbstractController.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Bundle\FrameworkBundle\Controller;
1313

1414
use Psr\Container\ContainerInterface;
15+
use Psr\Link\EvolvableLinkInterface;
1516
use Psr\Link\LinkInterface;
1617
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
1718
use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface;
@@ -42,6 +43,7 @@
4243
use Symfony\Component\Serializer\SerializerInterface;
4344
use Symfony\Component\WebLink\EventListener\AddLinkHeaderListener;
4445
use Symfony\Component\WebLink\GenericLinkProvider;
46+
use Symfony\Component\WebLink\HttpHeaderSerializer;
4547
use Symfony\Contracts\Service\Attribute\Required;
4648
use Symfony\Contracts\Service\ServiceSubscriberInterface;
4749
use Twig\Environment;
@@ -58,6 +60,8 @@ abstract class AbstractController implements ServiceSubscriberInterface
5860
*/
5961
protected $container;
6062

63+
private ?HttpHeaderSerializer $httpHeaderSerializer = null;
64+
6165
/**
6266
* @required
6367
*/
@@ -405,4 +409,41 @@ protected function addLink(Request $request, LinkInterface $link): void
405409

406410
$request->attributes->set('_links', $linkProvider->withLink($link));
407411
}
412+
413+
/**
414+
* @param LinkInterface[] $links
415+
*/
416+
protected function sendEarlyHints(iterable $links, ?Response $response = null): Response
417+
{
418+
if (!class_exists(HttpHeaderSerializer::class)) {
419+
throw new \LogicException('You cannot use the "sendEarlyHints" method if the WebLink component is not available. Try running "composer require symfony/web-link".');
420+
}
421+
422+
if (null === $response) {
423+
$response = new Response();
424+
}
425+
426+
if (null === $this->httpHeaderSerializer) {
427+
$this->httpHeaderSerializer = new HttpHeaderSerializer();
428+
}
429+
430+
$response->headers->set('Link', $this->httpHeaderSerializer->serialize($this->populateEarlyHints($links)), false);
431+
$response->sendHeaders(103);
432+
433+
return $response;
434+
}
435+
436+
/**
437+
* @internal
438+
*/
439+
private function populateEarlyHints(iterable $links): \Generator
440+
{
441+
foreach ($links as $link) {
442+
if ($link instanceof EvolvableLinkInterface && !$link->getRels()) {
443+
$link = $link->withRel('preload');
444+
}
445+
446+
yield $link;
447+
}
448+
}
408449
}

src/Symfony/Bundle/FrameworkBundle/Tests/Controller/AbstractControllerTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,4 +645,15 @@ public function testAddLink()
645645
$this->assertContains($link1, $links);
646646
$this->assertContains($link2, $links);
647647
}
648+
649+
public function testSendEarlyHints()
650+
{
651+
$controller = $this->createController();
652+
$response = $controller->sendEarlyHints([
653+
(new Link(href: '/style.css'))->withAttribute('as', 'stylesheet'),
654+
(new Link(href: '/script.js'))->withAttribute('as', 'script'),
655+
]);
656+
657+
$this->assertSame('</style.css>; rel="preload"; as="stylesheet",</script.js>; rel="preload"; as="script"', $response->headers->get('Link'));
658+
}
648659
}

src/Symfony/Bundle/FrameworkBundle/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
"symfony/deprecation-contracts": "^2.1|^3",
2626
"symfony/error-handler": "^6.1",
2727
"symfony/event-dispatcher": "^5.4|^6.0",
28-
"symfony/http-foundation": "^6.2",
28+
"symfony/http-foundation": "^6.3",
2929
"symfony/http-kernel": "^6.2",
3030
"symfony/polyfill-mbstring": "~1.0",
3131
"symfony/filesystem": "^5.4|^6.0",

0 commit comments

Comments
 (0)