]> granicus.if.org Git - php/commitdiff
- Import Jade Nicoletti's transparent gzip encoding support as an output
authorZeev Suraski <zeev@php.net>
Mon, 13 Nov 2000 18:54:37 +0000 (18:54 +0000)
committerZeev Suraski <zeev@php.net>
Mon, 13 Nov 2000 18:54:37 +0000 (18:54 +0000)
  handler.  Works quite nicely!
- Fix buglets in output buffering
- Add output_handler INI directive

12 files changed:
NEWS
ext/zlib/php_zlib.h
ext/zlib/zlib.c
main/SAPI.c
main/SAPI.h
main/main.c
main/php_globals.h
php.ini-dist
php.ini-optimized
php.ini-recommended
sapi/apache/sapi_apache.c
sapi/cgi/cgi_main.c

diff --git a/NEWS b/NEWS
index e14c2e9d87bf94e88fc21d548ae291bdebd3ac0a..038b2d019e91dffc90bb63c8f8c2b3c6db3c2877 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,9 @@ PHP 4.0                                                                    NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 
 ?? ??? 2000, Version 4.0.4
+- Added 'output_handler' INI directive (Zeev)
+- Fixed some buglets in the output buffering mechanism (Zeev)
+- Added transparent gzip compression support (Jade Nicoletti, Zeev)
 - Major overhaul of domxml. Added basic XPath support as well (Uwe)
 - Added 'r' flag to date() which generates an RFC822 formatted date, e.g.
   "Thu,  9 Nov 2000 16:33:01 -0500" (Colin)
index 518ae2543edb227a2e56fbe974a3d1cd382f248f..b856fc9fd0800c3caebb8b238110ccd4f66151b1 100644 (file)
 #ifndef PHP_ZLIB_H
 #define PHP_ZLIB_H
 
-#if HAVE_ZLIB
+#include <zlib.h>
+
 
 typedef struct {
        int gzgetss_state;
+
+       /* variables for transparent gzip encoding */
+    int compression_coding;
+    z_stream stream;
+    uLong crc;
 } php_zlib_globals;
 
 extern zend_module_entry php_zlib_module_entry;
@@ -52,21 +58,25 @@ PHP_FUNCTION(gzcompress);
 PHP_FUNCTION(gzuncompress);
 PHP_FUNCTION(gzdeflate);
 PHP_FUNCTION(gzinflate);
+PHP_FUNCTION(gzencode);
+PHP_FUNCTION(ob_gzhandler);
 
 #ifdef ZTS
 #define ZLIBLS_D php_zlib_globals *zlib_globals
+#define ZLIBLS_DC , ZLIBLS_D
+#define ZLIBLS_C zlib_globals
+#define ZLIBLS_CC , ZLIBLS_C
 #define ZLIBG(v) (zlib_globals->v)
 #define ZLIBLS_FETCH() php_zlib_globals *zlib_globals = ts_resource(zlib_globals_id)
 #else
 #define ZLIBLS_D
+#define ZLIBLS_DC
+#define ZLIBLS_C
+#define ZLIBLS_CC
 #define ZLIBG(v) (zlib_globals.v)
 #define ZLIBLS_FETCH()
 #endif
 
-#else
-#define zlib_module_ptr NULL
-#endif /* HAVE_ZLIB */
-
 #define phpext_zlib_ptr zlib_module_ptr
 
 #endif /* PHP_ZLIB_H */
index 7f4d4ec4103cbaf1cb4bbdf4a17ac981f8e0407a..f70a911624ed57db1598316dedb400f64639e311 100644 (file)
@@ -29,6 +29,7 @@
 #endif 
 
 #include "php.h"
+#include "SAPI.h"
 
 #include <stdlib.h>
 #include <errno.h>
 #include <pwd.h>
 #endif
 #endif
-#if HAVE_ZLIB
 #if defined(HAVE_UNISTD_H) && defined(PHP_WIN32)
 #undef HAVE_UNISTD_H
 #endif
 
-#include <zlib.h>
 
 #ifdef COMPILE_DL_ZLIB
 #ifndef PUTS
@@ -86,8 +85,14 @@ static php_zlib_globals zlib_globals;
 static FILE *zlib_fopen_wrapper(char *path, char *mode, int options, int *issock, int *socketd, char **opened_path);
 #endif 
 
+#define OS_CODE                        0x03 /* FIXME */
+#define CODING_GZIP            1
+#define CODING_DEFLATE 2
+
 /* True globals, no need for thread safety */
 static int le_zp;
+static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
+
 
 function_entry php_zlib_functions[] = {
        PHP_FE(readgzfile,                                      NULL)
@@ -109,6 +114,8 @@ function_entry php_zlib_functions[] = {
        PHP_FE(gzuncompress,                NULL)
        PHP_FE(gzdeflate,                   NULL)
        PHP_FE(gzinflate,                   NULL)
+       PHP_FE(gzencode,                                        NULL)
+       PHP_FE(ob_gzhandler,                            NULL)
        {NULL, NULL, NULL}
 };
 
@@ -158,6 +165,9 @@ PHP_MINIT_FUNCTION(zlib)
        }
 #endif
 
+       REGISTER_LONG_CONSTANT("FORCE_GZIP", CODING_GZIP, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("FORCE_DEFLATE", CODING_DEFLATE, CONST_CS | CONST_PERSISTENT);
+
        return SUCCESS;
 }
 
@@ -201,7 +211,8 @@ static gzFile php_gzopen_wrapper(char *path, char *mode, int options)
 
 /* {{{ proto array gzfile(string filename [, int use_include_path])
    Read und uncompress entire .gz-file into an array */
-PHP_FUNCTION(gzfile) {
+PHP_FUNCTION(gzfile)
+{
        pval **filename, **arg2;
        gzFile zp;
        char *slashed, buf[8192];
@@ -257,7 +268,8 @@ PHP_FUNCTION(gzfile) {
 
 /* {{{ proto int gzopen(string filename, string mode [, int use_include_path])
    Open a .gz-file and return a .gz-file pointer */
-PHP_FUNCTION(gzopen) {
+PHP_FUNCTION(gzopen)
+{
        pval **arg1, **arg2, **arg3;
        gzFile *zp;
        char *p;
@@ -303,7 +315,8 @@ PHP_FUNCTION(gzopen) {
 
 /* {{{ proto int gzclose(int zp)
    Close an open .gz-file pointer */
-PHP_FUNCTION(gzclose) {
+PHP_FUNCTION(gzclose)
+{
        pval **arg1;
        gzFile *zp;
 
@@ -318,7 +331,8 @@ PHP_FUNCTION(gzclose) {
 
 /* {{{ proto int gzeof(int zp)
    Test for end-of-file on a .gz-file pointer */
-PHP_FUNCTION(gzeof) {
+PHP_FUNCTION(gzeof)
+{
        pval **arg1;
        gzFile *zp;
        
@@ -337,7 +351,8 @@ PHP_FUNCTION(gzeof) {
 
 /* {{{ proto string gzgets(int zp, int length)
    Get a line from .gz-file pointer */
-PHP_FUNCTION(gzgets) {
+PHP_FUNCTION(gzgets)
+{
        pval **arg1, **arg2;
        gzFile *zp;
        int len;
@@ -373,7 +388,8 @@ PHP_FUNCTION(gzgets) {
 
 /* {{{ proto string gzgetc(int zp)
    Get a character from .gz-file pointer */
-PHP_FUNCTION(gzgetc) {
+PHP_FUNCTION(gzgetc)
+{
        pval **arg1;
        gzFile *zp;
        int c;
@@ -456,7 +472,8 @@ PHP_FUNCTION(gzgetss)
 
 /* {{{ proto int gzwrite(int zp, string str [, int length])
    Binary-safe .gz-file write */
-PHP_FUNCTION(gzwrite) {
+PHP_FUNCTION(gzwrite)
+{
        pval **arg1, **arg2, **arg3=NULL;
        gzFile *zp;
        int ret;
@@ -502,7 +519,8 @@ PHP_FUNCTION(gzwrite) {
 
 /* {{{ proto int gzrewind(int zp)
    Rewind the position of a .gz-file pointer */
-PHP_FUNCTION(gzrewind) {
+PHP_FUNCTION(gzrewind)
+{
        pval **arg1;
        gzFile *zp;
        
@@ -519,7 +537,8 @@ PHP_FUNCTION(gzrewind) {
 
 /* {{{ proto int gztell(int zp)
    Get .gz-file pointer's read/write position */
-PHP_FUNCTION(gztell) {
+PHP_FUNCTION(gztell)
+{
        pval **arg1;
        long pos;
        gzFile *zp;
@@ -537,7 +556,8 @@ PHP_FUNCTION(gztell) {
 
 /* {{{ proto int gzseek(int zp, int offset)
    Seek on a file pointer */
-PHP_FUNCTION(gzseek) {
+PHP_FUNCTION(gzseek)
+{
        pval **arg1, **arg2;
        int ret;
        gzFile *zp;
@@ -559,7 +579,8 @@ PHP_FUNCTION(gzseek) {
  */
 /* {{{ proto int readgzfile(string filename [, int use_include_path])
    Output a .gz-file */
-PHP_FUNCTION(readgzfile) {
+PHP_FUNCTION(readgzfile)
+{
        pval **arg1, **arg2;
        char buf[8192];
        gzFile *zp;
@@ -610,7 +631,8 @@ PHP_FUNCTION(readgzfile) {
  */
 /* {{{ proto int gzpassthru(int zp)
    Output all remaining data from a .gz-file pointer */
-PHP_FUNCTION(gzpassthru) {
+PHP_FUNCTION(gzpassthru)
+{
        pval **arg1;
        gzFile *zp;
        char buf[8192];
@@ -992,8 +1014,198 @@ static FILE *zlib_fopen_wrapper(char *path, char *mode, int options, int *issock
 #endif
 
 
+static int php_do_deflate(uint str_length, Bytef **p_buffer, uint *p_buf_used ZLIBLS_DC)
+{
+       Bytef *buffer;
+       uInt prev_outlen, outlen;
+       int err;
+
+       outlen = sizeof(char) * (str_length * 1.001 + 12);
+       buffer = (Bytef *) emalloc(outlen+10+8); /* 10+8 for the header and trailer */
+       
+       ZLIBG(stream).next_out = buffer+10;
+       ZLIBG(stream).avail_out = outlen;
+
+       err = deflate(&ZLIBG(stream), Z_NO_FLUSH);
+       while (err == Z_OK && !ZLIBG(stream).avail_out) {
+               prev_outlen = outlen;
+               outlen *= 3;
+               buffer = realloc(buffer, outlen+10+8);
+               
+               ZLIBG(stream).next_out = buffer+10 + prev_outlen;
+               ZLIBG(stream).avail_out = prev_outlen * 2;
+
+               err = deflate(&ZLIBG(stream), Z_NO_FLUSH);
+       }
+
+       err = deflate(&ZLIBG(stream), Z_FINISH);
+
+       *p_buffer = buffer;
+       *p_buf_used = outlen - ZLIBG(stream).avail_out;
+       return err;
+}
+
+
+int php_deflate_string(const char *str, uint str_length, char **newstr, uint *new_length, int coding)
+{
+       Bytef *buffer;
+       uInt buf_used;
+       int err;
+       Bytef header_buffer[11];
+       Bytef trailer_buffer[9];
+       ZLIBLS_FETCH();
+
+       ZLIBG(compression_coding) = coding;
+
+       ZLIBG(stream).zalloc = Z_NULL;
+       ZLIBG(stream).zfree = Z_NULL;
+       ZLIBG(stream).opaque = Z_NULL;
+
+       switch (coding) {
+               case CODING_GZIP:
+                       /* windowBits is passed < 0 to suppress zlib header & trailer */
+                       if (deflateInit2(&ZLIBG(stream), Z_DEFAULT_COMPRESSION, Z_DEFLATED,
+                                       -MAX_WBITS, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY)
+                                               != Z_OK) {
+                               /* TODO: print out error */
+                               return FAILURE;
+                       }
+               
+                       /*
+                       sapi_add_header("Content-Encoding: gzip", sizeof("Content-Encoding: gzip") - 1, 1);
+                       sapi_send_headers();
+                       */
+
+                       /* 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:
+                       if (deflateInit(&ZLIBG(stream), Z_DEFAULT_COMPRESSION) != Z_OK) {
+                               /* TODO: print out error */
+                               return FAILURE;
+                       }
+                       /*
+                       sapi_add_header("Content-Encoding: deflate", sizeof("Content-Encoding: deflate") - 1, 1);
+                       */
+                       break;          
+       }
+
+
+       ZLIBG(stream).next_in = (Bytef*) str;
+       ZLIBG(stream).avail_in = (uInt) str_length;
+       
+       if (ZLIBG(compression_coding) == 1) {
+               ZLIBG(crc) = crc32(ZLIBG(crc), (const Bytef *)str, str_length);
+       }
+
+       err = php_do_deflate(str_length, &buffer, &buf_used ZLIBLS_CC);
+       /* TODO: error handling (err may be Z_STREAM_ERROR, Z_BUF_ERROR, ?) */
+
+
+       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);
+       }
+       
+
+       memcpy(buffer, header_buffer, 10);
+       memcpy(buffer+10+buf_used, trailer_buffer, 8);
+
+       *new_length = buf_used + 10 + 8;
+       *newstr = buffer;
+
+       return SUCCESS;
+}
+
+
+PHP_FUNCTION(gzencode)
+{
+       zval **zv_coding, **zv_string;
+       int coding;
+
+       switch(ZEND_NUM_ARGS()) {
+               case CODING_GZIP:
+                       if (zend_get_parameters_ex(1, &zv_string)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_string_ex(zv_string);
+                       coding = 1;
+                       break;
+               case CODING_DEFLATE:
+                       if (zend_get_parameters_ex(2, &zv_string, &zv_coding)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_string_ex(zv_string);
+                       convert_to_long_ex(zv_coding);
+                       coding = Z_LVAL_PP(zv_coding);
+                       break;
+               default:
+                       ZEND_WRONG_PARAM_COUNT();
+                       break;
+       }
+       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)==SUCCESS) {
+               Z_TYPE_P(return_value) = IS_STRING;
+       } else {
+               RETURN_FALSE;
+       }
+}
+
+
+PHP_FUNCTION(ob_gzhandler)
+{
+       int coding;
+       zval **zv_string;
+       zval **data, **a_encoding;
+
+       if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &zv_string)==FAILURE) {
+               ZEND_WRONG_PARAM_COUNT();
+       }
+
+       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 the original string */
+               *return_value = **zv_string;
+               zval_copy_ctor(return_value);
+               return;
+       }
+       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))) {
+               coding = CODING_GZIP;
+       } else if(php_memnstr(Z_STRVAL_PP(a_encoding), "deflate", 7, Z_STRVAL_PP(a_encoding) + Z_STRLEN_PP(a_encoding))) {
+               coding = CODING_DEFLATE;
+       } else {
+               RETURN_FALSE;
+       }
+       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)==SUCCESS) {
+               Z_TYPE_P(return_value) = IS_STRING;
+               switch (coding) {
+                       case CODING_GZIP:
+                               sapi_add_header("Content-Encoding: gzip", sizeof("Content-Encoding: gzip") - 1, 1);
+                               break;
+                       case CODING_DEFLATE:
+                               sapi_add_header("Content-Encoding: deflate", sizeof("Content-Encoding: deflate") - 1, 1);
+                               break;
+               }
+       } else {
+               /* return the original string */
+               *return_value = **zv_string;
+               zval_copy_ctor(return_value);
+       }
+}
+
 
-#endif /* HAVE_ZLIB */
 /*
  * Local variables:
  * tab-width: 4
index 563f1cd072b0e9c9786e4017cb3e4a75d9e28e05..67bd8019de64482c1f96edd31df19c1955b8296d 100644 (file)
@@ -271,6 +271,7 @@ SAPI_API void sapi_activate(SLS_D)
        SG(request_info).post_data = NULL;
        SG(request_info).current_user = NULL;
        SG(request_info).current_user_length = 0;
+       SG(request_info).no_headers = 0;
 
        /* It's possible to override this general case in the activate() callback, if
         * necessary.
@@ -363,7 +364,7 @@ SAPI_API int sapi_add_header_ex(char *header_line, uint header_line_len, zend_bo
        char *colon_offset;
        SLS_FETCH();
 
-       if (SG(headers_sent)) {
+       if (SG(headers_sent) && !SG(request_info).no_headers) {
                char *output_start_filename = php_get_output_start_filename();
                int output_start_lineno = php_get_output_start_lineno();
 
@@ -457,7 +458,7 @@ SAPI_API int sapi_send_headers()
        int ret = FAILURE;
        SLS_FETCH();
 
-       if (SG(headers_sent)) {
+       if (SG(headers_sent) || SG(request_info).no_headers) {
                return SUCCESS;
        }
 
index 86eb356104ab328e632ae449a9b2f1a0df5e16e0..9c2f06abe397f754d635fb6030733af55de4226b 100644 (file)
@@ -73,7 +73,8 @@ typedef struct {
 
        const char *content_type;
 
-       unsigned char headers_only;
+       zend_bool headers_only;
+       zend_bool no_headers;
 
        sapi_post_entry *post_entry;
 
index 2ef64e9af1c02abd4bc1a0e45b31bd64e44323bf..325a9802b5a6b8a908942c1f53feab9d615f8480 100644 (file)
@@ -223,6 +223,7 @@ PHP_INI_BEGIN()
        STD_PHP_INI_BOOLEAN("magic_quotes_runtime",     "0",            PHP_INI_ALL,            OnUpdateBool,                   magic_quotes_runtime,   php_core_globals,       core_globals)
        STD_PHP_INI_BOOLEAN("magic_quotes_sybase",      "0",            PHP_INI_ALL,            OnUpdateBool,                   magic_quotes_sybase,    php_core_globals,       core_globals)
        STD_PHP_INI_BOOLEAN("output_buffering",         "0",            PHP_INI_PERDIR|PHP_INI_SYSTEM,OnUpdateBool,     output_buffering,               php_core_globals,       core_globals)
+       STD_PHP_INI_ENTRY("output_handler",                     NULL,           PHP_INI_PERDIR|PHP_INI_SYSTEM,OnUpdateString,   output_handler,         php_core_globals,       core_globals)
        STD_PHP_INI_BOOLEAN("register_argc_argv",       "1",            PHP_INI_ALL,            OnUpdateBool,                   register_argc_argv,             php_core_globals,       core_globals)
        STD_PHP_INI_BOOLEAN("register_globals",         "1",            PHP_INI_ALL,            OnUpdateBool,                   register_globals,               php_core_globals,       core_globals)
        STD_PHP_INI_BOOLEAN("safe_mode",                        "0",            PHP_INI_SYSTEM,         OnUpdateBool,                   safe_mode,                              php_core_globals,       core_globals)
@@ -623,7 +624,15 @@ int php_request_startup(CLS_D ELS_DC PLS_DC SLS_DC)
                sapi_add_header(SAPI_PHP_VERSION_HEADER, sizeof(SAPI_PHP_VERSION_HEADER)-1, 1);
        }
 
-       if (PG(output_buffering)) {
+       if (PG(output_handler)) {
+               zval *output_handler;
+
+               ALLOC_INIT_ZVAL(output_handler);
+               Z_STRLEN_P(output_handler) = strlen(PG(output_handler));        /* this can be optimized */
+               Z_STRVAL_P(output_handler) = estrndup(PG(output_handler), Z_STRLEN_P(output_handler));
+               Z_TYPE_P(output_handler) = IS_STRING;
+               php_start_ob_buffer(output_handler);
+       } else if (PG(output_buffering)) {
                php_start_ob_buffer(NULL);
        } else if (PG(implicit_flush)) {
                php_start_implicit_flush();
@@ -656,11 +665,11 @@ void php_request_shutdown(void *dummy)
        PLS_FETCH();
 
        if (setjmp(EG(bailout))==0) {
-               sapi_send_headers();
+               php_end_ob_buffers(SG(request_info).headers_only?0:1);
        }
 
        if (setjmp(EG(bailout))==0) {
-               php_end_ob_buffers(SG(request_info).headers_only?0:1);
+               sapi_send_headers();
        }
 
        if (PG(modules_activated) && setjmp(EG(bailout))==0) {
index 97461c1e0a9f8bfc4abd515b6e4a26e687cf5400..aa313a4075bc987e47982d019a673faa651fb999 100644 (file)
@@ -65,6 +65,9 @@ struct _php_core_globals {
        zend_bool safe_mode;
        zend_bool sql_safe_mode;
        zend_bool enable_dl;
+
+       char *output_handler;
+
        char *safe_mode_exec_dir;
 
        long memory_limit;
index 8d098e7d975608a032d17a461abd8e7abcbb87df..43b5032271e76321a833e5e5ed35cea3ebd92fe1 100644 (file)
@@ -64,6 +64,12 @@ output_buffering     = Off   ; Output buffering allows you to send header lines (inclu
                                                        ; You can enable output buffering by in runtime by calling the output
                                                        ; buffering functions, or enable output buffering for all files
                                                        ; by setting this directive to On.
+output_handler         =               ; You can redirect all of the output of your scripts to a function,
+                                                       ; that can be responsible to process or log it.  For example,
+                                                       ; if you set the output_handler to "ob_gzhandler", than output
+                                                       ; will be transparently compressed for browsers that support gzip or
+                                                       ; deflate encoding.  Setting an output handler automatically turns on
+                                                       ; output buffering.
 implicit_flush         = Off   ; Implicit flush tells PHP to tell the output layer to flush itself
                                                        ; automatically after every output block.  This is equivalent to
                                                        ; calling the PHP function flush() after each and every call to print()
index f0d4ca6ae5c8fa034bddcc5508506069f71d10ae..1bdd0060aae586d79c2d80221e28aa1d69407231 100644 (file)
@@ -51,6 +51,12 @@ output_buffering     = Off   ; Output buffering allows you to send header lines (inclu
                                                        ; You can enable output buffering by in runtime by calling the output
                                                        ; buffering functions, or enable output buffering for all files
                                                        ; by setting this directive to On.
+output_handler         =               ; You can redirect all of the output of your scripts to a function,
+                                                       ; that can be responsible to process or log it.  For example,
+                                                       ; if you set the output_handler to "ob_gzhandler", than output
+                                                       ; will be transparently compressed for browsers that support gzip or
+                                                       ; deflate encoding.  Setting an output handler automatically turns on
+                                                       ; output buffering.
 implicit_flush         = Off   ; Implicit flush tells PHP to tell the output layer to flush itself
                                                        ; automatically after every output block.  This is equivalent to
                                                        ; calling the PHP function flush() after each and every call to print()
index f0d4ca6ae5c8fa034bddcc5508506069f71d10ae..1bdd0060aae586d79c2d80221e28aa1d69407231 100644 (file)
@@ -51,6 +51,12 @@ output_buffering     = Off   ; Output buffering allows you to send header lines (inclu
                                                        ; You can enable output buffering by in runtime by calling the output
                                                        ; buffering functions, or enable output buffering for all files
                                                        ; by setting this directive to On.
+output_handler         =               ; You can redirect all of the output of your scripts to a function,
+                                                       ; that can be responsible to process or log it.  For example,
+                                                       ; if you set the output_handler to "ob_gzhandler", than output
+                                                       ; will be transparently compressed for browsers that support gzip or
+                                                       ; deflate encoding.  Setting an output handler automatically turns on
+                                                       ; output buffering.
 implicit_flush         = Off   ; Implicit flush tells PHP to tell the output layer to flush itself
                                                        ; automatically after every output block.  This is equivalent to
                                                        ; calling the PHP function flush() after each and every call to print()
index e2cb151c37e02c1d80ad4b2edda49014dc9fa1fa..f6139a9dc82647830526dd021ab0eec80ad0943d 100644 (file)
@@ -92,8 +92,8 @@ int apache_php_module_main(request_rec *r, int display_source_mode CLS_DC ELS_DC
         if (setjmp(EG(bailout))!=0) {
                return OK;
        }
-       php_header();                   /* Make sure headers have been sent */
        php_end_ob_buffers(1);
+       php_header();                   /* Make sure headers have been sent */
        return (OK);
 }
 
index 67ed3b80b551b74848c4e06668dfd7e0e783db09..d966527c2687cd7b1d17ec3fa4a01bb64647e769 100644 (file)
@@ -548,6 +548,7 @@ any .htaccess restrictions anywhere on your site you can leave doc_root undefine
                                                }
                                        }
                                        if (no_headers) {
+                                               SG(request_info).no_headers = 1;
                                                SG(headers_sent) = 1;
                                        }
                                        cgi_started=1;
@@ -582,6 +583,7 @@ any .htaccess restrictions anywhere on your site you can leave doc_root undefine
                                        }
                                        if (no_headers) {
                                                SG(headers_sent) = 1;
+                                               SG(request_info).no_headers = 1;
                                        }
                                        cgi_started=1;
                                        php_print_info(0xFFFFFFFF);
@@ -630,6 +632,7 @@ any .htaccess restrictions anywhere on your site you can leave doc_root undefine
                                        }
                                        if (no_headers) {
                                                SG(headers_sent) = 1;
+                                               SG(request_info).no_headers = 1;
                                        }
                                        php_printf("%s\n", PHP_VERSION);
                                        php_end_ob_buffers(1);
@@ -677,6 +680,7 @@ any .htaccess restrictions anywhere on your site you can leave doc_root undefine
        }
        if (no_headers) {
                SG(headers_sent) = 1;
+               SG(request_info).no_headers = 1;
        }
        file_handle.filename = "-";
        file_handle.type = ZEND_HANDLE_FP;
@@ -766,9 +770,6 @@ any .htaccess restrictions anywhere on your site you can leave doc_root undefine
 #endif
        }
 
-       php_header();                   /* Make sure headers have been sent */
-
-       
 
        if (SG(request_info).path_translated) {
                persist_alloc(SG(request_info).path_translated);