Hello!

There has been a bug report (#16109) about a bug in Netscape 4.79,
which doesn't display images if Content-Encoding: gzip is used. After
thinking about a browser detection config flag for zlib.output
compression, at LinuxTag we discussed, that a more general solution
would be better, that means switching off output compression for
images and let it be possible to switch it off (or force it on) during
script execution.

So I implemented it this way:

The headers for output compression are sent late, not in the zlib
request init, but in the SAPI send_headers call, I think this is the
latest possible time I can add it, so that it's possible to switch it
off before that time. If you send a header("Content-Type: image/xxx")
output compression is switched off, you can also switch it off via
ini_set('zlib.output_compression', 'Off') (or force it on, if you use
this call with 'On' after the image header was sent, but this only
works, if it was globally enabled, you can't switch it on during
script execution if the default says 'Off' (you need the output
buffering, you also can't change the buffer size)).

If output compression was disabled during the script, the compression
handler simply does noething and no headers are added (so you can
switch the setting only before the headers are sent).

Because I'm no SAPI expert and I don't know, if there are some other
effects, if I add the header in the send_headers call, I haven't
commited it yet, see the attached patch. If nobody objects, I'll
commit it in a few days.

  Stefan

-- 
Stefan Röhrich               [EMAIL PROTECTED], [EMAIL PROTECTED]
                                 http://www.roehri.ch/~sr/
diff -ur /home/sr/cvs/php/php4/ext/zlib/php_zlib.h php4/ext/zlib/php_zlib.h
--- /home/sr/cvs/php/php4/ext/zlib/php_zlib.h   Tue May  7 15:45:48 2002
+++ php4/ext/zlib/php_zlib.h    Sun Jun 23 12:58:39 2002
@@ -66,6 +66,9 @@
 
 #define phpext_zlib_ptr zlib_module_ptr
 
+#define CODING_GZIP            1
+#define CODING_DEFLATE 2
+
 #endif /* PHP_ZLIB_H */
 
 /*
diff -ur /home/sr/cvs/php/php4/ext/zlib/zlib.c php4/ext/zlib/zlib.c
--- /home/sr/cvs/php/php4/ext/zlib/zlib.c       Sun Jun 23 10:35:38 2002
+++ php4/ext/zlib/zlib.c        Mon Jun 24 10:31:52 2002
@@ -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 @@
                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 @@
 
 
 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_RINIT_FUNCTION(zlib)
 {
        ZLIBG(ob_gzhandler_status) = 0;
+       ZLIBG(ob_gzip_coding) = 0;
        switch (ZLIBG(output_compression)) {
                case 0:
                        break;
@@ -947,11 +966,15 @@
 {
        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 @@
        }
        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;
diff -ur /home/sr/cvs/php/php4/main/SAPI.c php4/main/SAPI.c
--- /home/sr/cvs/php/php4/main/SAPI.c   Sun Jun 23 10:35:41 2002
+++ php4/main/SAPI.c    Sun Jun 23 13:15:44 2002
@@ -30,6 +30,10 @@
 #if HAVE_PCRE || HAVE_BUNDLED_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
@@ -443,6 +447,11 @@
                        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++;
                                }
@@ -586,6 +595,31 @@
        if (SG(headers_sent) || SG(request_info).no_headers) {
                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.

-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to