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]