]> granicus.if.org Git - php/commitdiff
Commit patch as discussed on LinuxTag and posted to php-dev in June.
authorStefan Roehrich <sr@php.net>
Sun, 28 Jul 2002 14:08:08 +0000 (14:08 +0000)
committerStefan Roehrich <sr@php.net>
Sun, 28 Jul 2002 14:08:08 +0000 (14:08 +0000)
Disables zlib.output_compression for scripts with image/ content-type
header (fixes bug #16109) and makes it possible to switch
zlib.output_compression during script execution before the headers are
sent.
@- zlib.output_compression is disabled for "image/" content-type
@  headers and can be changed during script execution. (Stefan)

ext/zlib/php_zlib.h
ext/zlib/zlib.c
main/SAPI.c

index 333eb1224b7b37842303428c503d06731ff9fd9b..ce57652a469779522c0661b445d5c9a77bdadf60 100644 (file)
@@ -66,6 +66,9 @@ extern php_stream_wrapper php_stream_gzip_wrapper;
 
 #define phpext_zlib_ptr zlib_module_ptr
 
+#define CODING_GZIP            1
+#define CODING_DEFLATE 2
+
 #endif /* PHP_ZLIB_H */
 
 /*
index edf031e2426de37f64b78501040131ac7ca4e606..3848b25186c0b1a2e4b334add2cd6ac5b6ed0b5d 100644 (file)
@@ -74,8 +74,6 @@
 #endif
 
 #define OS_CODE                        0x03 /* FIXME */
-#define CODING_GZIP            1
-#define CODING_DEFLATE 2
 #define GZIP_HEADER_LENGTH             10
 #define GZIP_FOOTER_LENGTH             8
 
@@ -144,6 +142,26 @@ static PHP_INI_MH(OnUpdate_zlib_output_compression)
                return FAILURE;
        }
 
+       if(new_value == NULL)
+               return FAILURE;
+
+       if(!strncasecmp(new_value, "off", sizeof("off"))) {
+               new_value = "0";
+               new_value_length = sizeof("0");
+       } else if(!strncasecmp(new_value, "on", sizeof("on"))) {
+               new_value = "4096";
+               new_value_length = sizeof("4096");
+       } else if(stage == PHP_INI_STAGE_RUNTIME &&
+                         strncmp(new_value, "0", sizeof("0")) && strncmp(new_value, "1", sizeof("1"))) {
+               php_error(E_WARNING, "Cannot change zlib.output_compression buffer size during script execution");
+               return FAILURE;
+       }
+
+       if (stage == PHP_INI_STAGE_RUNTIME && SG(headers_sent) && !SG(request_info).no_headers) {
+               php_error(E_WARNING, "Cannot change zlib.output_compression - headers already sent");
+               return FAILURE;
+       }
+
        OnUpdateInt(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
 
        return SUCCESS;
@@ -161,7 +179,7 @@ static PHP_INI_MH(OnUpdate_zlib_output_compression_level)
 
 
 PHP_INI_BEGIN()
-    STD_PHP_INI_BOOLEAN("zlib.output_compression", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdate_zlib_output_compression, output_compression, zend_zlib_globals, zlib_globals)
+    STD_PHP_INI_BOOLEAN("zlib.output_compression", "0", PHP_INI_ALL, OnUpdate_zlib_output_compression, output_compression, zend_zlib_globals, zlib_globals)
        STD_PHP_INI_ENTRY("zlib.output_compression_level", "-1", PHP_INI_ALL, OnUpdate_zlib_output_compression_level, output_compression_level, zend_zlib_globals, zlib_globals)
 PHP_INI_END()
 
@@ -197,6 +215,7 @@ PHP_MINIT_FUNCTION(zlib)
 PHP_RINIT_FUNCTION(zlib)
 {
        ZLIBG(ob_gzhandler_status) = 0;
+       ZLIBG(ob_gzip_coding) = 0;
        switch (ZLIBG(output_compression)) {
                case 0:
                        break;
@@ -947,11 +966,15 @@ static void php_gzip_output_handler(char *output, uint output_len, char **handle
 {
        zend_bool do_start, do_end;
 
-       do_start = (mode & PHP_OUTPUT_HANDLER_START ? 1 : 0);
-       do_end = (mode & PHP_OUTPUT_HANDLER_END ? 1 : 0);
-       if (php_deflate_string(output, output_len, handled_output, handled_output_len, ZLIBG(ob_gzip_coding), do_start, do_end, ZLIBG(output_compression_level) TSRMLS_CC)!=SUCCESS) {
-               zend_error(E_ERROR, "Compression failed");
-       } 
+       if (!ZLIBG(output_compression)) {
+               *handled_output = NULL;
+       } else {
+               do_start = (mode & PHP_OUTPUT_HANDLER_START ? 1 : 0);
+               do_end = (mode & PHP_OUTPUT_HANDLER_END ? 1 : 0);
+               if (php_deflate_string(output, output_len, handled_output, handled_output_len, ZLIBG(ob_gzip_coding), do_start, do_end, ZLIBG(output_compression_level) TSRMLS_CC)!=SUCCESS) {
+                       zend_error(E_ERROR, "Compression failed");
+               }
+       }
 }
 /* }}} */
 
@@ -968,20 +991,8 @@ int php_enable_output_compression(int buffer_size TSRMLS_DC)
        }
        convert_to_string_ex(a_encoding);
        if (php_memnstr(Z_STRVAL_PP(a_encoding), "gzip", 4, Z_STRVAL_PP(a_encoding) + Z_STRLEN_PP(a_encoding))) {
-               if (sapi_add_header("Content-Encoding: gzip", sizeof("Content-Encoding: gzip") - 1, 1)==FAILURE) {
-                       return FAILURE;
-               }
-               if (sapi_add_header("Vary: Accept-Encoding", sizeof("Vary: Accept-Encoding") - 1, 1)==FAILURE) {
-                       return FAILURE;                 
-               }
                ZLIBG(ob_gzip_coding) = CODING_GZIP;
        } else if(php_memnstr(Z_STRVAL_PP(a_encoding), "deflate", 7, Z_STRVAL_PP(a_encoding) + Z_STRLEN_PP(a_encoding))) {
-               if (sapi_add_header("Content-Encoding: deflate", sizeof("Content-Encoding: deflate") - 1, 1)==FAILURE) {
-                       return FAILURE;
-               }
-               if (sapi_add_header("Vary: Accept-Encoding", sizeof("Vary: Accept-Encoding") - 1, 1)==FAILURE) {
-                       return FAILURE;                 
-               }
                ZLIBG(ob_gzip_coding) = CODING_DEFLATE;
        } else {
                return FAILURE;
index 8f53ff85396e42f533e2ba14ae062e912abe73ee..af39e3bbdcaa756bdf7f2760b184c1ceac8b9dbb 100644 (file)
 #if (HAVE_PCRE || HAVE_BUNDLED_PCRE) && !defined(COMPILE_DL_PCRE)
 #include "ext/pcre/php_pcre.h"
 #endif
+#if HAVE_ZLIB
+#include "ext/zlib/php_zlib.h"
+ZEND_EXTERN_MODULE_GLOBALS(zlib)
+#endif
 #ifdef ZTS
 #include "TSRM.h"
 #endif
@@ -485,6 +489,11 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC)
                        if (!STRCASECMP(header_line, "Content-Type")) {
                                char *ptr = colon_offset+1, *mimetype = NULL, *newheader;
                                size_t len = header_line_len - (ptr - header_line), newlen;
+#if HAVE_ZLIB
+                               if(strncmp(ptr, "image/", sizeof("image/"))) {
+                                       ZLIBG(output_compression) = 0;
+                               }
+#endif
                                while (*ptr == ' ' && *ptr != '\0') {
                                        ptr++;
                                }
@@ -633,6 +642,31 @@ SAPI_API int sapi_send_headers(TSRMLS_D)
                return SUCCESS;
        }
 
+#if HAVE_ZLIB
+       /* Add output compression headers at this late stage in order to make
+          it possible to switch it off inside the script. */
+       if (ZLIBG(output_compression)) {
+               switch (ZLIBG(ob_gzip_coding)) {
+                       case CODING_GZIP:
+                               if (sapi_add_header("Content-Encoding: gzip", sizeof("Content-Encoding: gzip") - 1, 1)==FAILURE) {
+                                       return FAILURE;
+                               }
+                               if (sapi_add_header("Vary: Accept-Encoding", sizeof("Vary: Accept-Encoding") - 1, 1)==FAILURE) {
+                                       return FAILURE;                 
+                               }
+                               break;
+                       case CODING_DEFLATE:
+                               if (sapi_add_header("Content-Encoding: deflate", sizeof("Content-Encoding: deflate") - 1, 1)==FAILURE) {
+                                       return FAILURE;
+                               }
+                               if (sapi_add_header("Vary: Accept-Encoding", sizeof("Vary: Accept-Encoding") - 1, 1)==FAILURE) {
+                                       return FAILURE;                 
+                               }
+                               break;
+               }
+       }
+#endif
+
        /* Success-oriented.  We set headers_sent to 1 here to avoid an infinite loop
         * in case of an error situation.
         */