Skip to content
Merged
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
19 changes: 14 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,12 @@ extension=zstd.so

### Output handler option

Name | Default | Changeable
------------------------------- | ------- | ----------
zstd.output\_compression | 0 | PHP\_INI\_ALL
zstd.output\_compression\_level | 3 | PHP\_INI\_ALL
zstd.output\_compression\_dict | "" | PHP\_INI\_ALL
Name | Default | Changeable
--------------------------------------- | ------- | ----------
zstd.output\_compression | 0 | PHP\_INI\_ALL
zstd.output\_compression\_level | 3 | PHP\_INI\_ALL
zstd.output\_compression\_exclude\_types | "" | PHP\_INI\_ALL
zstd.output\_compression\_dict | "" | PHP\_INI\_ALL

* zstd.output\_compression _boolean_/_integer_

Expand All @@ -85,6 +86,14 @@ zstd.output\_compression\_dict | "" | PHP\_INI\_ALL
Specify a value between 1 to 22.
The default value of `ZSTD_COMPRESS_LEVEL_DEFAULT` (3).

* 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.

* zstd.output\_compression\_dict _string_

Specifies the path to the compressed dictionary file to be
Expand Down
1 change: 1 addition & 0 deletions php_zstd.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ ZEND_BEGIN_MODULE_GLOBALS(zstd)
zend_long output_compression;
zend_long output_compression_default;
zend_long output_compression_level;
char *output_compression_exclude_types;
char *output_compression_dict;
php_zstd_context *ob_handler;
bool handler_registered;
Expand Down
20 changes: 20 additions & 0 deletions tests/ob_exclude_001.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
--TEST--
zstd.output_compression_exclude_types exact match
--SKIPIF--
<?php
include (dirname(__FILE__) . '/ob_skipif.inc');
?>
--INI--
zstd.output_compression=1
zstd.output_compression_exclude_types=application/pdf
--ENV--
HTTP_ACCEPT_ENCODING=zstd
--GET--
ob=020
--FILE--
<?php
header('Content-Type: application/pdf');
echo "hi\n";
?>
--EXPECT--
hi
20 changes: 20 additions & 0 deletions tests/ob_exclude_002.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
--TEST--
zstd.output_compression_exclude_types wildcard match
--SKIPIF--
<?php
include (dirname(__FILE__) . '/ob_skipif.inc');
?>
--INI--
zstd.output_compression=1
zstd.output_compression_exclude_types=image/*
--ENV--
HTTP_ACCEPT_ENCODING=zstd
--GET--
ob=021
--FILE--
<?php
header('Content-Type: image/png');
echo "hi\n";
?>
--EXPECT--
hi
20 changes: 20 additions & 0 deletions tests/ob_exclude_003.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
--TEST--
zstd.output_compression_exclude_types match with charset parameter
--SKIPIF--
<?php
include (dirname(__FILE__) . '/ob_skipif.inc');
?>
--INI--
zstd.output_compression=1
zstd.output_compression_exclude_types=text/html
--ENV--
HTTP_ACCEPT_ENCODING=zstd
--GET--
ob=022
--FILE--
<?php
header('Content-Type: text/html; charset=UTF-8');
echo "hi\n";
?>
--EXPECT--
hi
23 changes: 23 additions & 0 deletions tests/ob_exclude_004.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
--TEST--
zstd.output_compression_exclude_types no match still compresses
--SKIPIF--
<?php
include (dirname(__FILE__) . '/ob_skipif.inc');
?>
--INI--
zstd.output_compression=1
zstd.output_compression_exclude_types=image/*,application/pdf
--ENV--
HTTP_ACCEPT_ENCODING=zstd
--GET--
ob=023
--FILE--
<?php
header('Content-Type: text/html');
echo "hi\n";
?>
--EXPECT_EXTERNAL--
files/ob_001.zstd
--EXPECTHEADERS--
Content-Encoding: zstd
Vary: Accept-Encoding
67 changes: 67 additions & 0 deletions zstd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1295,6 +1295,64 @@ static int php_zstd_output_encoding(void)
return PHP_ZSTD_G(compression_coding);
}

static int php_zstd_output_mimetype_excluded(void)
{
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;

if (!mimetype || !*mimetype || !exclude || !*exclude) {
return 0;
}

end = mimetype;
while (*end && *end != ';' && *end != ' ' && *end != '\t'
&& *end != '\r' && *end != '\n') {
end++;
}
mimetype_len = end - mimetype;
p = exclude;

while (*p) {
size_t token_len;

while (*p == ',' || *p == ' ' || *p == '\t' || *p == '\r'
|| *p == '\n') {
p++;
}

end = p;
while (*end && *end != ',' && *end != ' ' && *end != '\t'
&& *end != '\r' && *end != '\n') {
end++;
}

token_len = end - p;

if (token_len > 0) {
if (token_len >= 2 && p[token_len - 2] == '/'
&& p[token_len - 1] == '*') {
size_t prefix_len = token_len - 1;

if (mimetype_len >= prefix_len
&& !strncasecmp(mimetype, p, prefix_len)) {
return 1;
}
}

if (mimetype_len == token_len
&& !strncasecmp(mimetype, p, token_len)) {
return 1;
}
}

p = end;
}

return 0;
}

static zend_string*
php_zstd_output_handler_load_dict(php_zstd_context *ctx)
{
Expand Down Expand Up @@ -1499,6 +1557,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()) {
return FAILURE;
}

if (!php_zstd_output_encoding()) {
if ((output_context->op & PHP_OUTPUT_HANDLER_START)
&& (output_context->op != (PHP_OUTPUT_HANDLER_START
Expand Down Expand Up @@ -1736,6 +1799,10 @@ PHP_INI_BEGIN()
TOSTRING(ZSTD_CLEVEL_DEFAULT),
PHP_INI_ALL, OnUpdateLong, output_compression_level,
zend_zstd_globals, zstd_globals)
STD_PHP_INI_ENTRY("zstd.output_compression_exclude_types", "",
PHP_INI_ALL, OnUpdateString,
output_compression_exclude_types,
zend_zstd_globals, zstd_globals)
STD_PHP_INI_ENTRY("zstd.output_compression_dict", "",
PHP_INI_ALL, OnUpdateString, output_compression_dict,
zend_zstd_globals, zstd_globals)
Expand Down
Loading