Skip to content

Commit

Permalink
Merge branch '6.4' into 7.0
Browse files Browse the repository at this point in the history
* 6.4:
  [Validator] Missing translations for Estonian (et)
  [HttpFoundation] Prevent duplicated headers when using Early Hints
  [VarDumper] Fix configuring CliDumper with SYMFONY_IDE env var
  [Cache] improve BC with 5.4 pools
  [PhpUnitBridge][VarDumper] fix color detection
  [CI] Make sure we preserve file->header when we run sync-translations.php
  [Cache] Fix BC layer with pre-6.1 cache items
  Review validators.sl.xlf
  [Mailer][Postmark][Webhook] Don't require tag and metadata
  [Scheduler] Fix messenger receiver with no alias
  • Loading branch information
xabbuh committed Feb 8, 2024
2 parents ebe0c11 + ebc713b commit 439fdfd
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 14 deletions.
24 changes: 11 additions & 13 deletions Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -330,23 +330,21 @@ public function sendHeaders(?int $statusCode = null): static
$replace = false;

// As recommended by RFC 8297, PHP automatically copies headers from previous 103 responses, we need to deal with that if headers changed
if (103 === $statusCode) {
$previousValues = $this->sentHeaders[$name] ?? null;
if ($previousValues === $values) {
// Header already sent in a previous response, it will be automatically copied in this response by PHP
continue;
}
$previousValues = $this->sentHeaders[$name] ?? null;
if ($previousValues === $values) {
// Header already sent in a previous response, it will be automatically copied in this response by PHP
continue;
}

$replace = 0 === strcasecmp($name, 'Content-Type');
$replace = 0 === strcasecmp($name, 'Content-Type');

if (null !== $previousValues && array_diff($previousValues, $values)) {
header_remove($name);
$previousValues = null;
}

$newValues = null === $previousValues ? $values : array_diff($values, $previousValues);
if (null !== $previousValues && array_diff($previousValues, $values)) {
header_remove($name);
$previousValues = null;
}

$newValues = null === $previousValues ? $values : array_diff($values, $previousValues);

foreach ($newValues as $value) {
header($name.': '.$value, $replace, $this->statusCode);
}
Expand Down
31 changes: 31 additions & 0 deletions Tests/Fixtures/response-functional/early_hints.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

// Requires FrankenPHP

use Symfony\Component\HttpFoundation\Response;

$parent = __DIR__;
while (!@file_exists($parent.'/vendor/autoload.php')) {
if (!@file_exists($parent)) {
// open_basedir restriction in effect
break;
}
if ($parent === dirname($parent)) {
echo "vendor/autoload.php not found\n";
exit(1);
}

$parent = dirname($parent);
}

require $parent.'/vendor/autoload.php';

$r = new Response();
$r->headers->set('Link', '</css/style.css>; rel="preload"; as="style"');
$r->sendHeaders(103);

$r->headers->set('Link', '</js/app.js>; rel="preload"; as="script"', false);
$r->sendHeaders(103);

$r->setContent('Hello, Early Hints');
$r->send();
28 changes: 27 additions & 1 deletion Tests/ResponseFunctionalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
namespace Symfony\Component\HttpFoundation\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Process\ExecutableFinder;
use Symfony\Component\Process\Process;

class ResponseFunctionalTest extends TestCase
{
Expand Down Expand Up @@ -51,7 +53,31 @@ public function testCookie($fixture)
public static function provideCookie()
{
foreach (glob(__DIR__.'/Fixtures/response-functional/*.php') as $file) {
yield [pathinfo($file, \PATHINFO_FILENAME)];
if (str_contains($file, 'cookie')) {
yield [pathinfo($file, \PATHINFO_FILENAME)];
}
}
}

/**
* @group integration
*/
public function testInformationalResponse()
{
if (!(new ExecutableFinder())->find('curl')) {
$this->markTestSkipped('curl is not installed');
}

if (!($fp = @fsockopen('localhost', 80, $errorCode, $errorMessage, 2))) {
$this->markTestSkipped('FrankenPHP is not running');
}
fclose($fp);

$p = new Process(['curl', '-v', 'http://localhost/early_hints.php']);
$p->run();
$output = $p->getErrorOutput();

$this->assertSame(3, preg_match_all('#Link: </css/style\.css>; rel="preload"; as="style"#', $output));
$this->assertSame(2, preg_match_all('#Link: </js/app\.js>; rel="preload"; as="script"#', $output));
}
}

0 comments on commit 439fdfd

Please sign in to comment.