Commit 06aab9ee authored by Benni Mack's avatar Benni Mack
Browse files

[!!!][TASK] Use ".gz" instead of ".gzip" for compressed resources

When using compressed files such as JS / CSS files,
the files are now put in a ".gz" file extension instead
of ".gzip" as this is more wide-spread and possible by default.

Also see
https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types

Resolves: #93182
Releases: main
Change-Id: I27aa2dbf5d36809eb85c77701b47e03cf5618692
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/67272

Tested-by: core-ci's avatarcore-ci <typo3@b13.com>
Tested-by: Markus Klein's avatarMarkus Klein <markus.klein@typo3.org>
Tested-by: Mathias Bolt Lesniak's avatarMathias Bolt Lesniak <mathias@pixelant.no>
Tested-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
Reviewed-by: Markus Klein's avatarMarkus Klein <markus.klein@typo3.org>
Reviewed-by: Mathias Bolt Lesniak's avatarMathias Bolt Lesniak <mathias@pixelant.no>
Reviewed-by: crell's avatarcrell <larry@garfieldtech.com>
Reviewed-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
parent bd79e7bb
...@@ -47,6 +47,8 @@ class ResourceCompressor ...@@ -47,6 +47,8 @@ class ResourceCompressor
*/ */
protected $createGzipped = false; protected $createGzipped = false;
protected string $gzipFileExtension = '.gz';
/** /**
* @var int * @var int
*/ */
...@@ -55,7 +57,7 @@ class ResourceCompressor ...@@ -55,7 +57,7 @@ class ResourceCompressor
/** /**
* @var string * @var string
*/ */
protected $htaccessTemplate = '<FilesMatch "\\.(js|css)(\\.gzip)?$"> protected $htaccessTemplate = '<FilesMatch "\\.(js|css)(\\.gz)?$">
<IfModule mod_expires.c> <IfModule mod_expires.c>
ExpiresActive on ExpiresActive on
ExpiresDefault "access plus 7 days" ExpiresDefault "access plus 7 days"
...@@ -368,7 +370,7 @@ class ResourceCompressor ...@@ -368,7 +370,7 @@ class ResourceCompressor
$pathinfo = PathUtility::pathinfo($filenameAbsolute); $pathinfo = PathUtility::pathinfo($filenameAbsolute);
$targetFile = $this->targetDirectory . $pathinfo['filename'] . '-' . md5($unique) . '.css'; $targetFile = $this->targetDirectory . $pathinfo['filename'] . '-' . md5($unique) . '.css';
// only create it, if it doesn't exist, yet // only create it, if it doesn't exist, yet
if (!file_exists(Environment::getPublicPath() . '/' . $targetFile) || $this->createGzipped && !file_exists(Environment::getPublicPath() . '/' . $targetFile . '.gzip')) { if (!file_exists(Environment::getPublicPath() . '/' . $targetFile) || $this->createGzipped && !file_exists(Environment::getPublicPath() . '/' . $targetFile . $this->gzipFileExtension)) {
$contents = $this->compressCssString((string)file_get_contents($filenameAbsolute)); $contents = $this->compressCssString((string)file_get_contents($filenameAbsolute));
if (!str_contains($filename, $this->targetDirectory)) { if (!str_contains($filename, $this->targetDirectory)) {
$contents = $this->cssFixRelativeUrlPaths($contents, $filename); $contents = $this->cssFixRelativeUrlPaths($contents, $filename);
...@@ -422,7 +424,7 @@ class ResourceCompressor ...@@ -422,7 +424,7 @@ class ResourceCompressor
$pathinfo = PathUtility::pathinfo($filename); $pathinfo = PathUtility::pathinfo($filename);
$targetFile = $this->targetDirectory . $pathinfo['filename'] . '-' . md5($unique) . '.js'; $targetFile = $this->targetDirectory . $pathinfo['filename'] . '-' . md5($unique) . '.js';
// only create it, if it doesn't exist, yet // only create it, if it doesn't exist, yet
if (!file_exists(Environment::getPublicPath() . '/' . $targetFile) || $this->createGzipped && !file_exists(Environment::getPublicPath() . '/' . $targetFile . '.gzip')) { if (!file_exists(Environment::getPublicPath() . '/' . $targetFile) || $this->createGzipped && !file_exists(Environment::getPublicPath() . '/' . $targetFile . $this->gzipFileExtension)) {
$contents = (string)file_get_contents($filenameAbsolute); $contents = (string)file_get_contents($filenameAbsolute);
$this->writeFileAndCompressed($targetFile, $contents); $this->writeFileAndCompressed($targetFile, $contents);
} }
...@@ -577,7 +579,7 @@ class ResourceCompressor ...@@ -577,7 +579,7 @@ class ResourceCompressor
} }
/** /**
* Writes $contents into file $filename together with a gzipped version into $filename.gz * Writes $contents into file $filename together with a gzipped version into $filename.gz (gzipFileExtension)
* *
* @param string $filename Target filename * @param string $filename Target filename
* @param string $contents File contents * @param string $contents File contents
...@@ -588,7 +590,7 @@ class ResourceCompressor ...@@ -588,7 +590,7 @@ class ResourceCompressor
GeneralUtility::writeFile(Environment::getPublicPath() . '/' . $filename, $contents); GeneralUtility::writeFile(Environment::getPublicPath() . '/' . $filename, $contents);
if ($this->createGzipped) { if ($this->createGzipped) {
// create compressed version // create compressed version
GeneralUtility::writeFile(Environment::getPublicPath() . '/' . $filename . '.gzip', (string)gzencode($contents, $this->gzipCompressionLevel)); GeneralUtility::writeFile(Environment::getPublicPath() . '/' . $filename . $this->gzipFileExtension, (string)gzencode($contents, $this->gzipCompressionLevel));
} }
} }
...@@ -597,13 +599,13 @@ class ResourceCompressor ...@@ -597,13 +599,13 @@ class ResourceCompressor
* based on HTTP_ACCEPT_ENCODING * based on HTTP_ACCEPT_ENCODING
* *
* @param string $filename File name * @param string $filename File name
* @return string $filename suffixed with '.gzip' or not - dependent on HTTP_ACCEPT_ENCODING * @return string $filename suffixed with '.gz' or not - dependent on HTTP_ACCEPT_ENCODING
*/ */
protected function returnFileReference($filename) protected function returnFileReference($filename)
{ {
// if the client accepts gzip and we can create gzipped files, we give him compressed versions // if the client accepts gzip and we can create gzipped files, we give him compressed versions
if ($this->createGzipped && str_contains(GeneralUtility::getIndpEnv('HTTP_ACCEPT_ENCODING'), 'gzip')) { if ($this->createGzipped && str_contains(GeneralUtility::getIndpEnv('HTTP_ACCEPT_ENCODING'), 'gzip')) {
$filename .= '.gzip'; $filename .= $this->gzipFileExtension;
} }
return PathUtility::getRelativePath($this->rootPath, Environment::getPublicPath() . '/') . $filename; return PathUtility::getRelativePath($this->rootPath, Environment::getPublicPath() . '/') . $filename;
} }
......
...@@ -344,7 +344,7 @@ BE: ...@@ -344,7 +344,7 @@ BE:
description: 'Don''t use exec() function (except for ImageMagick which is disabled by <a href="#GFX-im">[GFX][im]</a>=0). If set, all file operations are done by the default PHP-functions. This is necessary under Windows! On Unix the system commands by exec() can be used, unless this is disabled.' description: 'Don''t use exec() function (except for ImageMagick which is disabled by <a href="#GFX-im">[GFX][im]</a>=0). If set, all file operations are done by the default PHP-functions. This is necessary under Windows! On Unix the system commands by exec() can be used, unless this is disabled.'
compressionLevel: compressionLevel:
type: text type: text
description: 'Determines output compression of BE output. Makes output smaller but slows down the page generation depending on the compression level. Requires a) zlib in your PHP installation and b) special rewrite rules for .css.gzip and .js.gzip (please see <code>_.htaccess</code> for an example). Range 1-9, where 1 is least compression and 9 is greatest compression. ''true'' as value will set the compression based on the PHP default settings (usually 5). Suggested and most optimal value is 5.' description: 'Determines output compression of BE output. Makes output smaller but slows down the page generation depending on the compression level. Requires a) zlib in your PHP installation and b) special rewrite rules for .css.gz and .js.gz (please see <code>_.htaccess</code> for an example). Range 1-9, where 1 is least compression and 9 is greatest compression. ''true'' as value will set the compression based on the PHP default settings (usually 5). Suggested and most optimal value is 5.'
checkStoredRecords: checkStoredRecords:
type: bool type: bool
description: 'If set, values of the record are validated after saving in DataHandler. Disable only if using a database in strict mode.' description: 'If set, values of the record are validated after saving in DataHandler. Disable only if using a database in strict mode.'
......
.. include:: /Includes.rst.txt
.. _breaking-93182-1651654104
===================================================================
Breaking: #93182 - Changed file extension for gzip compressed files
===================================================================
See :issue:`93182`
Description
===========
When using file compression for resources such as JavaScript or
StyleSheets via :php:`$GLOBALS[TYPO3_CONF_VARS][FE][compressionLevel]` or
:php:`$GLOBALS[TYPO3_CONF_VARS][BE][compressionLevel]` the generated files are
now written via the file extension ".gz" instead of ".gzip" in previous versions.
TYPO3 follows the de-facto standard for compressed assets,
as ".gz" is much more widespread than ".gzip" file extensions
(see https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types).
Impact
======
Compressed resources are now generated and served via ".gz".
Affected installations
======================
TYPO3 installations setting the global configuration option.
Migration
=========
Adapt possible .htaccess files by replacing ".gzip" with ".gz" if this feature
is activated.
.. index:: Backend, Frontend, NotScanned, ext:core
...@@ -105,7 +105,7 @@ class ResourceCompressorTest extends BaseTestCase ...@@ -105,7 +105,7 @@ class ResourceCompressorTest extends BaseTestCase
public function compressedCssFileIsFlaggedToNotCompressAgain(): void public function compressedCssFileIsFlaggedToNotCompressAgain(): void
{ {
$fileName = 'fooFile.css'; $fileName = 'fooFile.css';
$compressedFileName = $fileName . '.gzip'; $compressedFileName = $fileName . '.gz';
$testFileFixture = [ $testFileFixture = [
$fileName => [ $fileName => [
'file' => $fileName, 'file' => $fileName,
...@@ -130,7 +130,7 @@ class ResourceCompressorTest extends BaseTestCase ...@@ -130,7 +130,7 @@ class ResourceCompressorTest extends BaseTestCase
public function compressedJsFileIsFlaggedToNotCompressAgain(): void public function compressedJsFileIsFlaggedToNotCompressAgain(): void
{ {
$fileName = 'fooFile.js'; $fileName = 'fooFile.js';
$compressedFileName = $fileName . '.gzip'; $compressedFileName = $fileName . '.gz';
$testFileFixture = [ $testFileFixture = [
$fileName => [ $fileName => [
'file' => $fileName, 'file' => $fileName,
......
...@@ -33,13 +33,13 @@ ...@@ -33,13 +33,13 @@
# *) Set $GLOBALS['TYPO3_CONF_VARS']['FE']['compressionLevel'] = 9 together with the TypoScript properties # *) Set $GLOBALS['TYPO3_CONF_VARS']['FE']['compressionLevel'] = 9 together with the TypoScript properties
# config.compressJs and config.compressCss for GZIP compression of Frontend JS and CSS files. # config.compressJs and config.compressCss for GZIP compression of Frontend JS and CSS files.
#<FilesMatch "\.js\.gzip$"> #<FilesMatch "\.js\.gz">
# AddType "text/javascript" .gzip # AddType "text/javascript" .gz
#</FilesMatch> #</FilesMatch>
#<FilesMatch "\.css\.gzip$"> #<FilesMatch "\.css\.gz">
# AddType "text/css" .gzip # AddType "text/css" .gz
#</FilesMatch> #</FilesMatch>
#AddEncoding gzip .gzip #AddEncoding x-gzip .gz
<IfModule mod_deflate.c> <IfModule mod_deflate.c>
# Force compression for mangled `Accept-Encoding` request headers # Force compression for mangled `Accept-Encoding` request headers
...@@ -303,7 +303,7 @@ AddDefaultCharset utf-8 ...@@ -303,7 +303,7 @@ AddDefaultCharset utf-8
# IMPORTANT: This rule has to be the very first RewriteCond in order to work! # IMPORTANT: This rule has to be the very first RewriteCond in order to work!
RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)\.(\d+)\.(php|js|css|png|jpg|gif|gzip)$ %{ENV:CWD}$1.$3 [L] RewriteRule ^(.+)\.(\d+)\.(php|js|css|png|jpg|gif|gz)$ %{ENV:CWD}$1.$3 [L]
# Access block for folders # Access block for folders
RewriteRule _(?:recycler|temp)_/ - [F] RewriteRule _(?:recycler|temp)_/ - [F]
......
...@@ -61,7 +61,7 @@ ...@@ -61,7 +61,7 @@
<action type="Rewrite" url="typo3/index.php" appendQueryString="true" /> <action type="Rewrite" url="typo3/index.php" appendQueryString="true" />
</rule> </rule>
<rule name="TYPO3 - Version Number in File Name (if set)" stopProcessing="true"> <rule name="TYPO3 - Version Number in File Name (if set)" stopProcessing="true">
<match url="^(.+)\.(\d+)\.(php|js|css|png|jpg|gif|gzip)$" ignoreCase="false" /> <match url="^(.+)\.(\d+)\.(php|js|css|png|jpg|gif|gz)$" ignoreCase="false" />
<conditions logicalGrouping="MatchAll"> <conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" /> <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" /> <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment