Test Core::getNoCacheHeaders() with a frozen clock
This avoids the tests randomly failing when current time differs. Also changes the format from RFC 1123 to RFC 7231. Signed-off-by: Maurício Meneghini Fauth <mauricio@mfauth.net>
This commit is contained in:
parent
0ae02437ae
commit
d152e71161
39
src/Core.php
39
src/Core.php
@ -4,6 +4,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use DateTimeInterface;
|
||||
use DateTimeZone;
|
||||
use PhpMyAdmin\Error\ErrorHandler;
|
||||
use PhpMyAdmin\Exceptions\MissingExtensionException;
|
||||
use PhpMyAdmin\Http\ServerRequest;
|
||||
@ -18,7 +21,6 @@ use function explode;
|
||||
use function filter_var;
|
||||
use function function_exists;
|
||||
use function getenv;
|
||||
use function gmdate;
|
||||
use function hash_equals;
|
||||
use function hash_hmac;
|
||||
use function header;
|
||||
@ -45,7 +47,6 @@ use function substr;
|
||||
use function unserialize;
|
||||
use function urldecode;
|
||||
|
||||
use const DATE_RFC1123;
|
||||
use const FILTER_VALIDATE_IP;
|
||||
|
||||
/**
|
||||
@ -209,10 +210,10 @@ class Core
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public static function headerJSON(): array
|
||||
public static function headerJSON(string $currentDateTime = 'now'): array
|
||||
{
|
||||
// No caching
|
||||
$headers = self::getNoCacheHeaders();
|
||||
$headers = self::getNoCacheHeaders($currentDateTime);
|
||||
|
||||
// Media type
|
||||
$headers['Content-Type'] = 'application/json; charset=UTF-8';
|
||||
@ -227,13 +228,15 @@ class Core
|
||||
}
|
||||
|
||||
/** @return array<string, string> */
|
||||
public static function getNoCacheHeaders(): array
|
||||
public static function getNoCacheHeaders(string $currentDateTime = 'now'): array
|
||||
{
|
||||
$headers = [];
|
||||
$date = gmdate(DATE_RFC1123);
|
||||
$formattedDateTime = (new DateTimeImmutable($currentDateTime))
|
||||
->setTimezone(new DateTimeZone('UTC'))
|
||||
->format(DateTimeInterface::RFC7231);
|
||||
|
||||
// rfc2616 - Section 14.21
|
||||
$headers['Expires'] = $date;
|
||||
$headers['Expires'] = $formattedDateTime;
|
||||
|
||||
// HTTP/1.1
|
||||
$headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0';
|
||||
@ -244,7 +247,7 @@ class Core
|
||||
// test case: exporting a database into a .gz file with Safari
|
||||
// would produce files not having the current time
|
||||
// (added this header for Safari but should not harm other browsers)
|
||||
$headers['Last-Modified'] = $date;
|
||||
$headers['Last-Modified'] = $formattedDateTime;
|
||||
|
||||
return $headers;
|
||||
}
|
||||
@ -253,7 +256,6 @@ class Core
|
||||
* @param string $filename Filename to include in headers if empty, none Content-Disposition header will be sent.
|
||||
* @param string $mimetype MIME type to include in headers.
|
||||
* @param int $length Length of content (optional)
|
||||
* @param bool $noCache Whether to include no-caching headers.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
@ -261,13 +263,9 @@ class Core
|
||||
string $filename,
|
||||
string $mimetype,
|
||||
int $length = 0,
|
||||
bool $noCache = true,
|
||||
string $currentDateTime = 'now',
|
||||
): array {
|
||||
$headers = [];
|
||||
|
||||
if ($noCache) {
|
||||
$headers = self::getNoCacheHeaders();
|
||||
}
|
||||
$headers = self::getNoCacheHeaders($currentDateTime);
|
||||
|
||||
/* Replace all possibly dangerous chars in filename */
|
||||
$filename = Sanitize::sanitizeFilename($filename);
|
||||
@ -293,15 +291,10 @@ class Core
|
||||
* @param string $filename Filename to include in headers if empty, none Content-Disposition header will be sent.
|
||||
* @param string $mimetype MIME type to include in headers.
|
||||
* @param int $length Length of content (optional)
|
||||
* @param bool $noCache Whether to include no-caching headers.
|
||||
*/
|
||||
public static function downloadHeader(
|
||||
string $filename,
|
||||
string $mimetype,
|
||||
int $length = 0,
|
||||
bool $noCache = true,
|
||||
): void {
|
||||
$headers = self::getDownloadHeaders($filename, $mimetype, $length, $noCache);
|
||||
public static function downloadHeader(string $filename, string $mimetype, int $length = 0): void
|
||||
{
|
||||
$headers = self::getDownloadHeaders($filename, $mimetype, $length);
|
||||
|
||||
// The default output in PMA uses gzip,
|
||||
// so if we want to output uncompressed file, we should reset the encoding.
|
||||
|
||||
@ -335,7 +335,7 @@ class Header
|
||||
}
|
||||
|
||||
/** @return array<string, string> */
|
||||
public function getHttpHeaders(): array
|
||||
public function getHttpHeaders(string $currentDateTime = 'now'): array
|
||||
{
|
||||
$headers = [];
|
||||
|
||||
@ -388,7 +388,7 @@ class Header
|
||||
*/
|
||||
$headers['Permissions-Policy'] = 'fullscreen=(self), interest-cohort=()';
|
||||
|
||||
$headers = array_merge($headers, Core::getNoCacheHeaders());
|
||||
$headers = array_merge($headers, Core::getNoCacheHeaders($currentDateTime));
|
||||
|
||||
/**
|
||||
* A different Content-Type is set in {@see \PhpMyAdmin\Controllers\Transformation\WrapperController}.
|
||||
|
||||
@ -658,9 +658,13 @@ class CoreTest extends AbstractTestCase
|
||||
|
||||
public function testGetDownloadHeaders(): void
|
||||
{
|
||||
$headersList = Core::getDownloadHeaders('test.sql', 'text/x-sql', 100, false);
|
||||
$headersList = Core::getDownloadHeaders('test.sql', 'text/x-sql', 100, '2015-10-21T05:28:00-02:00');
|
||||
|
||||
$expected = [
|
||||
'Expires' => 'Wed, 21 Oct 2015 07:28:00 GMT',
|
||||
'Cache-Control' => 'no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0',
|
||||
'Pragma' => 'no-cache',
|
||||
'Last-Modified' => 'Wed, 21 Oct 2015 07:28:00 GMT',
|
||||
'Content-Description' => 'File Transfer',
|
||||
'Content-Disposition' => 'attachment; filename="test.sql"',
|
||||
'Content-Type' => 'text/x-sql',
|
||||
@ -672,9 +676,13 @@ class CoreTest extends AbstractTestCase
|
||||
|
||||
public function testGetDownloadHeaders2(): void
|
||||
{
|
||||
$headersList = Core::getDownloadHeaders('test.sql.gz', 'application/x-gzip', 0, false);
|
||||
$headersList = Core::getDownloadHeaders('test.sql.gz', 'application/x-gzip', 0, '2015-10-21T05:28:00-02:00');
|
||||
|
||||
$expected = [
|
||||
'Expires' => 'Wed, 21 Oct 2015 07:28:00 GMT',
|
||||
'Cache-Control' => 'no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0',
|
||||
'Pragma' => 'no-cache',
|
||||
'Last-Modified' => 'Wed, 21 Oct 2015 07:28:00 GMT',
|
||||
'Content-Description' => 'File Transfer',
|
||||
'Content-Disposition' => 'attachment; filename="test.sql.gz"',
|
||||
'Content-Type' => 'application/x-gzip',
|
||||
@ -702,4 +710,28 @@ class CoreTest extends AbstractTestCase
|
||||
|
||||
self::assertSame('', Core::getEnv('PHPMYADMIN_GET_ENV_TEST'));
|
||||
}
|
||||
|
||||
public function testGetNoCacheHeaders(): void
|
||||
{
|
||||
$expected = [
|
||||
'Expires' => 'Wed, 21 Oct 2015 07:28:00 GMT',
|
||||
'Cache-Control' => 'no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0',
|
||||
'Pragma' => 'no-cache',
|
||||
'Last-Modified' => 'Wed, 21 Oct 2015 07:28:00 GMT',
|
||||
];
|
||||
self::assertSame($expected, Core::getNoCacheHeaders('2015-10-21T05:28:00-02:00'));
|
||||
}
|
||||
|
||||
public function testHeaderJSON(): void
|
||||
{
|
||||
$expected = [
|
||||
'Expires' => 'Wed, 21 Oct 2015 07:28:00 GMT',
|
||||
'Cache-Control' => 'no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0',
|
||||
'Pragma' => 'no-cache',
|
||||
'Last-Modified' => 'Wed, 21 Oct 2015 07:28:00 GMT',
|
||||
'Content-Type' => 'application/json; charset=UTF-8',
|
||||
'X-Content-Type-Options' => 'nosniff',
|
||||
];
|
||||
self::assertSame($expected, Core::headerJSON('2015-10-21T05:28:00-02:00'));
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,10 +23,6 @@ use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use PHPUnit\Framework\Attributes\Medium;
|
||||
use ReflectionProperty;
|
||||
|
||||
use function gmdate;
|
||||
|
||||
use const DATE_RFC1123;
|
||||
|
||||
#[CoversClass(Header::class)]
|
||||
#[Medium]
|
||||
class HeaderTest extends AbstractTestCase
|
||||
@ -193,7 +189,6 @@ class HeaderTest extends AbstractTestCase
|
||||
string $expectedWebKitCsp,
|
||||
): void {
|
||||
$header = $this->getNewHeaderInstance();
|
||||
$date = gmdate(DATE_RFC1123);
|
||||
|
||||
$config = Config::getInstance();
|
||||
$config->set('AllowThirdPartyFraming', $frameOptions);
|
||||
@ -203,7 +198,7 @@ class HeaderTest extends AbstractTestCase
|
||||
$config->set('CaptchaCsp', $captchaCsp);
|
||||
|
||||
$expected = [
|
||||
'X-Frame-Options' => $expectedFrameOptions,
|
||||
'X-Frame-Options' => $expectedFrameOptions ?? '',
|
||||
'Referrer-Policy' => 'same-origin',
|
||||
'Content-Security-Policy' => $expectedCsp,
|
||||
'X-Content-Security-Policy' => $expectedXCsp,
|
||||
@ -213,18 +208,17 @@ class HeaderTest extends AbstractTestCase
|
||||
'X-Permitted-Cross-Domain-Policies' => 'none',
|
||||
'X-Robots-Tag' => 'noindex, nofollow',
|
||||
'Permissions-Policy' => 'fullscreen=(self), interest-cohort=()',
|
||||
'Expires' => $date,
|
||||
'Expires' => 'Wed, 21 Oct 2015 07:28:00 GMT',
|
||||
'Cache-Control' => 'no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0',
|
||||
'Pragma' => 'no-cache',
|
||||
'Last-Modified' => $date,
|
||||
'Last-Modified' => 'Wed, 21 Oct 2015 07:28:00 GMT',
|
||||
'Content-Type' => 'text/html; charset=utf-8',
|
||||
];
|
||||
if ($expectedFrameOptions === null) {
|
||||
unset($expected['X-Frame-Options']);
|
||||
}
|
||||
|
||||
$headers = $this->callFunction($header, Header::class, 'getHttpHeaders', []);
|
||||
self::assertSame($expected, $headers);
|
||||
self::assertSame($expected, $header->getHttpHeaders('2015-10-21T05:28:00-02:00'));
|
||||
}
|
||||
|
||||
/** @return mixed[][] */
|
||||
|
||||
Loading…
Reference in New Issue
Block a user