Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,24 @@ zstd.output\_compression\_dict | "" | PHP\_INI\_ALL

* zstd.output\_compression\_exclude\_types _string_

Comma-separated list of MIME types to exclude from transparent output
compression, e.g. `"image/*,application/pdf"`. Both exact types
(`application/pdf`) and wildcard subtypes (`image/*`) are supported.
The comparison ignores any parameters (such as `charset`) present in
the response's `Content-Type` header.
Extension contains a built-in list of non-compressible MIME types.
The list can be found from phpinfo() output. If something is
missing, more MIME types can be added with this ini setting.
Comment thread
coderabbitai[bot] marked this conversation as resolved.

Comma-separated list of MIME types that should not be
compressed by the transparent output handler.

Supports exact MIME type matches and wildcard family matches.
A wildcard entry must use the `type/*` form.

Example (both of these are already in the built-in list):

```ini
zstd.output_compression_exclude_types="video/*,application/pdf"
```

This is useful for already-compressed binary formats where
additional Zstd compression usually provides little benefit.

* zstd.output\_compression\_dict _string_

Expand Down
1 change: 1 addition & 0 deletions package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<file name="config.m4" role="src" />
<file name="config.w32" role="src" />
<file name="php_zstd.h" role="src" />
<file name="php_zstd_mimetype_exclude.h" role="src" />
<file name="zstd.c" role="src" />
<dir name="zstd">
<file name="CHANGELOG" role="doc" />
Expand Down
37 changes: 37 additions & 0 deletions php_zstd_mimetype_exclude.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#ifndef ZSTD_MIMETYPE_EXCLUDE

/**
* Image types listed separately, because svg is quite common
* and compresses well.
*
* Less common types have both, x-prefixed and non-prefixed
* versions because they are somewhat inconsistent with each
* other and perhaps more likely to be misconfigured due to
* those inconsistencies.
**/
#define ZSTD_MIMETYPE_EXCLUDE "\
video/*, \
audio/*, \
image/png, \
image/gif, \
image/jpeg, \
image/jxl, \
image/jp2, \
image/jpm, \
image/webp, \
image/avif, \
image/x-icon, image/vnd.microsoft.icon, \
font/woff, application/font-woff, application/x-font-woff, \
font/woff2, \
application/pdf, application/x-pdf, \
application/zip, application/x-zip, application/zip-compressed, application/x-zip-compressed, \
application/7z-compressed, application/x-7z-compressed, \
application/vnd.rar, application/x-vnd.rar, \
Comment thread
coderabbitai[bot] marked this conversation as resolved.
application/gzip, application/x-gzip, \
application/zstd, application/x-zstd, \
application/br, application/x-br, \
application/lz4, application/x-lz4, \
application/bzip2, application/x-bzip2\
"

#endif
32 changes: 29 additions & 3 deletions tests/info.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,38 @@ if (count($lines) >= 4) {
echo ($lines[3] == 'APCu serializer support => not built') ? "Apcu OK\n" : "Fail: not built\n";
}

/**
* TODO: test built-in header exclusion list
**/
if (PHP_VERSION_ID >= 80000) {
$search = 'Built-in output compression exclusions => ';
$mimeIndex = null;
// could be 4 or 5 depending on apcu
foreach([4, 5] as $index) {
if (isset($lines[$index]) && substr($lines[$index], 0, 42) == $search) {
$mimeIndex = $index;
}
}
if ($mimeIndex) {
$types = explode(', ', substr($lines[$mimeIndex], 42));
$invalidTypes = [];
foreach($types as $type) {
if (!preg_match('/^([a-z]+)\/(([a-z0-9\-\.]+)|\*)$/', $type)) {
$invalidTypes[] = $type;
}
}
if ($invalidTypes) {
echo "Fail: " . implode(", ", $invalidTypes) . "\n";
} else {
echo "MIMEs OK\n";
}
} else {
echo "Fail\n";
}
} else {
echo "MIMEs OK\n";
}
}
--EXPECTF--
Ext version OK
Bundled/external zstd OK
Zstd version OK
Apcu OK
MIMEs OK
1 change: 0 additions & 1 deletion tests/ob_exclude_001.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ include (dirname(__FILE__) . '/ob_skipif.inc');
?>
--INI--
zstd.output_compression=1
zstd.output_compression_exclude_types=application/pdf
--ENV--
HTTP_ACCEPT_ENCODING=zstd
--GET--
Expand Down
2 changes: 1 addition & 1 deletion tests/ob_exclude_002.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ HTTP_ACCEPT_ENCODING=zstd
ob=021
--FILE--
<?php
header('Content-Type: image/png');
header('Content-Type: image/svg+xml');
echo "hi\n";
?>
--EXPECT--
Expand Down
15 changes: 12 additions & 3 deletions zstd.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
#include <Zend/zend_API.h>
#include <Zend/zend_interfaces.h>
#include "php_zstd.h"
#if PHP_VERSION_ID >= 80000
#include "php_zstd_mimetype_exclude.h"
#endif

# pragma GCC diagnostic ignored "-Wunicode"

Expand Down Expand Up @@ -1293,10 +1296,9 @@ static int php_zstd_output_encoding(void)
return PHP_ZSTD_G(compression_coding);
}

static int php_zstd_output_mimetype_excluded(void)
static int php_zstd_output_mimetype_excluded(const char *exclude)
{
const char *mimetype = SG(sapi_headers).mimetype;
const char *exclude = PHP_ZSTD_G(output_compression_exclude_types);
const char *p, *end;
size_t mimetype_len;

Expand Down Expand Up @@ -1556,7 +1558,11 @@ php_zstd_output_handler(void **handler_context,
php_zstd_context *ctx = *(php_zstd_context **) handler_context;

if ((output_context->op & PHP_OUTPUT_HANDLER_START)
&& php_zstd_output_mimetype_excluded()) {
&& (
php_zstd_output_mimetype_excluded(ZSTD_MIMETYPE_EXCLUDE)
||
php_zstd_output_mimetype_excluded(PHP_ZSTD_G(output_compression_exclude_types))
)) {
return FAILURE;
}

Expand Down Expand Up @@ -1964,6 +1970,9 @@ ZEND_MINFO_FUNCTION(zstd)
php_info_print_table_row(2, "APCu serializer interface version", APC_SERIALIZER_ABI);
#else
php_info_print_table_row(2, "APCu serializer support", "not built");
#endif
#if PHP_VERSION_ID >= 80000
php_info_print_table_row(2, "Built-in output compression exclusions", ZSTD_MIMETYPE_EXCLUDE);
#endif
php_info_print_table_end();
DISPLAY_INI_ENTRIES();
Expand Down
Loading