zeev            Tue Mar  6 12:43:55 2001 EDT

  Modified files:              
    /php4/ext/zlib      zlib.c php_zlib.h 
  Log:
  Implement internal output compression0:wq
  
  
Index: php4/ext/zlib/zlib.c
diff -u php4/ext/zlib/zlib.c:1.74 php4/ext/zlib/zlib.c:1.75
--- php4/ext/zlib/zlib.c:1.74   Sun Mar  4 07:12:38 2001
+++ php4/ext/zlib/zlib.c        Tue Mar  6 12:43:54 2001
@@ -16,11 +16,12 @@
    |          Stefan Röhrich <[EMAIL PROTECTED]>                                |
    +----------------------------------------------------------------------+
  */
-/* $Id: zlib.c,v 1.74 2001/03/04 15:12:38 zeev Exp $ */
+/* $Id: zlib.c,v 1.75 2001/03/06 20:43:54 zeev Exp $ */
 #define IS_EXT_MODULE
 
 #include "php.h"
 #include "SAPI.h"
+#include "php_ini.h"
 
 #include <stdlib.h>
 #include <errno.h>
@@ -106,6 +107,12 @@
        {NULL, NULL, NULL}
 };
 
+
+PHP_INI_BEGIN()
+    STD_PHP_INI_BOOLEAN("zlib.output_compression",   "0",    PHP_INI_ALL,     
+OnUpdateInt,        output_compression,   php_zlib_globals,     zlib_globals)
+PHP_INI_END()
+
+
 zend_module_entry php_zlib_module_entry = {
        "zlib",
        php_zlib_functions,
@@ -155,6 +162,8 @@
        REGISTER_LONG_CONSTANT("FORCE_GZIP", CODING_GZIP, CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("FORCE_DEFLATE", CODING_DEFLATE, CONST_CS | 
CONST_PERSISTENT);
 
+       REGISTER_INI_ENTRIES();
+
        return SUCCESS;
 }
 
@@ -163,6 +172,15 @@
        ZLIBLS_FETCH();
 
        ZLIBG(ob_gzhandler_status) = 0;
+       switch (ZLIBG(output_compression)) {
+               case 0:
+                       break;
+               case 1:
+                       php_enable_output_compression(4096);
+                       break;
+               default:
+                       php_enable_output_compression(ZLIBG(output_compression));
+       }
        return SUCCESS;
 }
 
@@ -177,6 +195,8 @@
     }
 #endif
        
+       UNREGISTER_INI_ENTRIES();
+
        return SUCCESS;
 }
 
@@ -939,7 +959,7 @@
 
 
 
-static int php_do_deflate(uint str_length, Bytef **p_buffer, uint *p_buf_used, 
zend_bool do_start, zend_bool do_end ZLIBLS_DC)
+static int php_do_deflate(uint str_length, Bytef **p_buffer, uint *p_buffer_len, 
+zend_bool do_start, zend_bool do_end ZLIBLS_DC)
 {
        Bytef *buffer;
        uInt prev_outlen, outlen;
@@ -948,16 +968,23 @@
        int end_offset = (do_end?8:0);
 
        outlen = sizeof(char) * (str_length * 1.001 + 12);
-       buffer = (Bytef *) emalloc(outlen+start_offset+end_offset);
+       if ((outlen+start_offset+end_offset) > *p_buffer_len) {
+               buffer = (Bytef *) emalloc(outlen+start_offset+end_offset);
+       } else {
+               buffer = *p_buffer;
+       }
        
        ZLIBG(stream).next_out = buffer+start_offset;
        ZLIBG(stream).avail_out = outlen;
 
+
        err = deflate(&ZLIBG(stream), Z_SYNC_FLUSH);
        while (err == Z_OK && !ZLIBG(stream).avail_out) {
                prev_outlen = outlen;
                outlen *= 3;
-               buffer = realloc(buffer, outlen+start_offset+end_offset);
+               if ((outlen+start_offset+end_offset) > *p_buffer_len) {
+                       buffer = realloc(buffer, outlen+start_offset+end_offset);
+               }
                
                ZLIBG(stream).next_out = buffer+start_offset + prev_outlen;
                ZLIBG(stream).avail_out = prev_outlen * 2;
@@ -969,19 +996,17 @@
                err = deflate(&ZLIBG(stream), Z_FINISH);
        }
 
+
        *p_buffer = buffer;
-       *p_buf_used = outlen - ZLIBG(stream).avail_out;
+       *p_buffer_len = outlen - ZLIBG(stream).avail_out;
+
        return err;
 }
 
 
 int php_deflate_string(const char *str, uint str_length, char **newstr, uint 
*new_length, int coding, zend_bool do_start, zend_bool do_end)
 {
-       Bytef *buffer;
-       uInt buf_used;
        int err;
-       Bytef header_buffer[11];
-       Bytef trailer_buffer[9];
        ZLIBLS_FETCH();
 
        ZLIBG(compression_coding) = coding;
@@ -1000,10 +1025,6 @@
                                        return FAILURE;
                                }
                
-                               /* Write a very simple .gz header: */
-                               sprintf(header_buffer, "%c%c%c%c%c%c%c%c%c%c", 
gz_magic[0],
-                                                       gz_magic[1], Z_DEFLATED, 0 
/*flags*/,
-                                                       0,0,0,0 /*time*/, 0 
/*xflags*/, OS_CODE);
                                ZLIBG(crc) = crc32(0L, Z_NULL, 0);
                                break;
                        case CODING_DEFLATE:
@@ -1023,34 +1044,33 @@
                ZLIBG(crc) = crc32(ZLIBG(crc), (const Bytef *) str, str_length);
        }
 
-       err = php_do_deflate(str_length, &buffer, &buf_used, do_start, do_end 
ZLIBLS_CC);
+       err = php_do_deflate(str_length, (Bytef **) newstr, new_length, do_start, 
+do_end ZLIBLS_CC);
        /* TODO: error handling (err may be Z_STREAM_ERROR, Z_BUF_ERROR, ?) */
 
-       if (do_end) {
-               if (ZLIBG(compression_coding) == 1) {
-                       /* write crc & stream.total_in in LSB order */
-                       sprintf(trailer_buffer, "%c%c%c%c%c%c%c%c",
-                                               (char) ZLIBG(crc) & 0xFF,
-                                               (char) (ZLIBG(crc) >> 8) & 0xFF,
-                                               (char) (ZLIBG(crc) >> 16) & 0xFF,
-                                               (char) (ZLIBG(crc) >> 24) & 0xFF,
-                                               (char) ZLIBG(stream).total_in & 0xFF,
-                                               (char) (ZLIBG(stream).total_in >> 8) & 
0xFF,
-                                               (char) (ZLIBG(stream).total_in >> 16) 
& 0xFF,
-                                               (char) (ZLIBG(stream).total_in >> 24) 
& 0xFF);
-               }
-       }
-       
-       *newstr = buffer;
-       *new_length = buf_used;
-
        if (do_start) {
-               memcpy(buffer, header_buffer, 10);
+               /* Write a very simple .gz header: */
+               (*newstr)[0] = gz_magic[0];
+               (*newstr)[1] = gz_magic[1];
+               (*newstr)[2] = Z_DEFLATED;
+               (*newstr)[3] = (*newstr)[4] = (*newstr)[5] = (*newstr)[6] = 
+(*newstr)[7] = (*newstr)[8] = 0;
+               (*newstr)[9] = OS_CODE;
                *new_length += 10;
        }
        if (do_end) {
-               memcpy(buffer+buf_used+(do_start?10:0), trailer_buffer, 8);
-               *new_length += 8;
+               if (ZLIBG(compression_coding) == 1) {
+                       char *trailer = (*newstr)+(*new_length);
+
+                       /* write crc & stream.total_in in LSB order */
+                       trailer[0] = (char) ZLIBG(crc) & 0xFF;
+                       trailer[1] = (char) (ZLIBG(crc) >> 8) & 0xFF;
+                       trailer[2] = (char) (ZLIBG(crc) >> 16) & 0xFF;
+                       trailer[3] = (char) (ZLIBG(crc) >> 24) & 0xFF;
+                       trailer[4] = (char) ZLIBG(stream).total_in & 0xFF;
+                       trailer[5] = (char) (ZLIBG(stream).total_in >> 8) & 0xFF;
+                       trailer[6] = (char) (ZLIBG(stream).total_in >> 16) & 0xFF;
+                       trailer[7] = (char) (ZLIBG(stream).total_in >> 24) & 0xFF;
+                       *new_length += 8;
+               }
                deflateEnd(&ZLIBG(stream));
        }
 
@@ -1125,6 +1145,8 @@
        convert_to_long_ex(zv_mode);
        do_start = ((Z_LVAL_PP(zv_mode) & PHP_OUTPUT_HANDLER_START) ? 1 : 0);
        do_end = ((Z_LVAL_PP(zv_mode) & PHP_OUTPUT_HANDLER_END) ? 1 : 0);
+       Z_STRVAL_P(return_value) = NULL;
+       Z_STRLEN_P(return_value) = 0;
        if (php_deflate_string(Z_STRVAL_PP(zv_string), Z_STRLEN_PP(zv_string), 
&Z_STRVAL_P(return_value), &Z_STRLEN_P(return_value), coding, do_start, 
do_end)==SUCCESS) {
                Z_TYPE_P(return_value) = IS_STRING;
                if (do_start) {
@@ -1164,4 +1186,48 @@
                *return_value = **zv_string;
                zval_copy_ctor(return_value);
        }
+}
+
+
+
+static void php_gzip_output_handler(char *output, uint output_len, char 
+**handled_output, uint *handled_output_len, int mode)
+{
+       zend_bool do_start, do_end;
+       ZLIBLS_FETCH();
+
+       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)!=SUCCESS) {
+               zend_error(E_ERROR, "Compression failed");
+       }
+}
+
+
+int php_enable_output_compression(int buffer_size)
+{
+       zval **a_encoding, **data;
+
+       if (zend_hash_find(&EG(symbol_table), "HTTP_SERVER_VARS", 
+sizeof("HTTP_SERVER_VARS"), (void **) &data)==FAILURE
+               || Z_TYPE_PP(data)!=IS_ARRAY
+               || zend_hash_find(Z_ARRVAL_PP(data), "HTTP_ACCEPT_ENCODING", 
+sizeof("HTTP_ACCEPT_ENCODING"), (void **) &a_encoding)==FAILURE) {
+               return FAILURE;
+       }
+       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;
+               }
+               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;
+               }
+               ZLIBG(ob_gzip_coding) = CODING_DEFLATE;
+       } else {
+               return FAILURE;
+       }
+       
+       php_start_ob_buffer(NULL, buffer_size);
+       php_ob_set_internal_handler(php_gzip_output_handler, buffer_size*1.5);
+       return SUCCESS;
 }
Index: php4/ext/zlib/php_zlib.h
diff -u php4/ext/zlib/php_zlib.h:1.14 php4/ext/zlib/php_zlib.h:1.15
--- php4/ext/zlib/php_zlib.h:1.14       Sun Mar  4 07:12:38 2001
+++ php4/ext/zlib/php_zlib.h    Tue Mar  6 12:43:54 2001
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: php_zlib.h,v 1.14 2001/03/04 15:12:38 zeev Exp $ */
+/* $Id: php_zlib.h,v 1.15 2001/03/06 20:43:54 zeev Exp $ */
 
 #ifndef PHP_ZLIB_H
 #define PHP_ZLIB_H
@@ -33,6 +33,8 @@
     z_stream stream;
     uLong crc;
        int ob_gzhandler_status;
+       int ob_gzip_coding;
+       int output_compression;
 } php_zlib_globals;
 
 extern zend_module_entry php_zlib_module_entry;
@@ -64,6 +66,7 @@
 PHP_FUNCTION(ob_gzhandler);
 
 FILE *zlib_fopen_wrapper(char *path, char *mode, int options, int *issock, int 
*socketd, char **opened_path);
+int php_enable_output_compression(int buffer_size);
 
 
 #ifdef ZTS

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to