Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

- Import Jade Nicoletti's transparent gzip encoding support as an output

  handler.  Works quite nicely!
- Fix buglets in output buffering
- Add output_handler INI directive
  • Loading branch information...
commit 0f7f5c2c0e616445d14b49641e85dbddcc1651e5 1 parent 9b42296
Zeev Suraski zsuraski authored
3  NEWS
@@ -2,6 +2,9 @@ PHP 4.0 NEWS
2 2 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
3 3
4 4 ?? ??? 2000, Version 4.0.4
  5 +- Added 'output_handler' INI directive (Zeev)
  6 +- Fixed some buglets in the output buffering mechanism (Zeev)
  7 +- Added transparent gzip compression support (Jade Nicoletti, Zeev)
5 8 - Major overhaul of domxml. Added basic XPath support as well (Uwe)
6 9 - Added 'r' flag to date() which generates an RFC822 formatted date, e.g.
7 10 "Thu, 9 Nov 2000 16:33:01 -0500" (Colin)
20 ext/zlib/php_zlib.h
@@ -22,10 +22,16 @@
22 22 #ifndef PHP_ZLIB_H
23 23 #define PHP_ZLIB_H
24 24
25   -#if HAVE_ZLIB
  25 +#include <zlib.h>
  26 +
26 27
27 28 typedef struct {
28 29 int gzgetss_state;
  30 +
  31 + /* variables for transparent gzip encoding */
  32 + int compression_coding;
  33 + z_stream stream;
  34 + uLong crc;
29 35 } php_zlib_globals;
30 36
31 37 extern zend_module_entry php_zlib_module_entry;
@@ -52,21 +58,25 @@ PHP_FUNCTION(gzcompress);
52 58 PHP_FUNCTION(gzuncompress);
53 59 PHP_FUNCTION(gzdeflate);
54 60 PHP_FUNCTION(gzinflate);
  61 +PHP_FUNCTION(gzencode);
  62 +PHP_FUNCTION(ob_gzhandler);
55 63
56 64 #ifdef ZTS
57 65 #define ZLIBLS_D php_zlib_globals *zlib_globals
  66 +#define ZLIBLS_DC , ZLIBLS_D
  67 +#define ZLIBLS_C zlib_globals
  68 +#define ZLIBLS_CC , ZLIBLS_C
58 69 #define ZLIBG(v) (zlib_globals->v)
59 70 #define ZLIBLS_FETCH() php_zlib_globals *zlib_globals = ts_resource(zlib_globals_id)
60 71 #else
61 72 #define ZLIBLS_D
  73 +#define ZLIBLS_DC
  74 +#define ZLIBLS_C
  75 +#define ZLIBLS_CC
62 76 #define ZLIBG(v) (zlib_globals.v)
63 77 #define ZLIBLS_FETCH()
64 78 #endif
65 79
66   -#else
67   -#define zlib_module_ptr NULL
68   -#endif /* HAVE_ZLIB */
69   -
70 80 #define phpext_zlib_ptr zlib_module_ptr
71 81
72 82 #endif /* PHP_ZLIB_H */
242 ext/zlib/zlib.c
@@ -29,6 +29,7 @@
29 29 #endif
30 30
31 31 #include "php.h"
  32 +#include "SAPI.h"
32 33
33 34 #include <stdlib.h>
34 35 #include <errno.h>
@@ -57,12 +58,10 @@
57 58 #include <pwd.h>
58 59 #endif
59 60 #endif
60   -#if HAVE_ZLIB
61 61 #if defined(HAVE_UNISTD_H) && defined(PHP_WIN32)
62 62 #undef HAVE_UNISTD_H
63 63 #endif
64 64
65   -#include <zlib.h>
66 65
67 66 #ifdef COMPILE_DL_ZLIB
68 67 #ifndef PUTS
@@ -86,8 +85,14 @@ static php_zlib_globals zlib_globals;
86 85 static FILE *zlib_fopen_wrapper(char *path, char *mode, int options, int *issock, int *socketd, char **opened_path);
87 86 #endif
88 87
  88 +#define OS_CODE 0x03 /* FIXME */
  89 +#define CODING_GZIP 1
  90 +#define CODING_DEFLATE 2
  91 +
89 92 /* True globals, no need for thread safety */
90 93 static int le_zp;
  94 +static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
  95 +
91 96
92 97 function_entry php_zlib_functions[] = {
93 98 PHP_FE(readgzfile, NULL)
@@ -109,6 +114,8 @@ function_entry php_zlib_functions[] = {
109 114 PHP_FE(gzuncompress, NULL)
110 115 PHP_FE(gzdeflate, NULL)
111 116 PHP_FE(gzinflate, NULL)
  117 + PHP_FE(gzencode, NULL)
  118 + PHP_FE(ob_gzhandler, NULL)
112 119 {NULL, NULL, NULL}
113 120 };
114 121
@@ -158,6 +165,9 @@ PHP_MINIT_FUNCTION(zlib)
158 165 }
159 166 #endif
160 167
  168 + REGISTER_LONG_CONSTANT("FORCE_GZIP", CODING_GZIP, CONST_CS | CONST_PERSISTENT);
  169 + REGISTER_LONG_CONSTANT("FORCE_DEFLATE", CODING_DEFLATE, CONST_CS | CONST_PERSISTENT);
  170 +
161 171 return SUCCESS;
162 172 }
163 173
@@ -201,7 +211,8 @@ static gzFile php_gzopen_wrapper(char *path, char *mode, int options)
201 211
202 212 /* {{{ proto array gzfile(string filename [, int use_include_path])
203 213 Read und uncompress entire .gz-file into an array */
204   -PHP_FUNCTION(gzfile) {
  214 +PHP_FUNCTION(gzfile)
  215 +{
205 216 pval **filename, **arg2;
206 217 gzFile zp;
207 218 char *slashed, buf[8192];
@@ -257,7 +268,8 @@ PHP_FUNCTION(gzfile) {
257 268
258 269 /* {{{ proto int gzopen(string filename, string mode [, int use_include_path])
259 270 Open a .gz-file and return a .gz-file pointer */
260   -PHP_FUNCTION(gzopen) {
  271 +PHP_FUNCTION(gzopen)
  272 +{
261 273 pval **arg1, **arg2, **arg3;
262 274 gzFile *zp;
263 275 char *p;
@@ -303,7 +315,8 @@ PHP_FUNCTION(gzopen) {
303 315
304 316 /* {{{ proto int gzclose(int zp)
305 317 Close an open .gz-file pointer */
306   -PHP_FUNCTION(gzclose) {
  318 +PHP_FUNCTION(gzclose)
  319 +{
307 320 pval **arg1;
308 321 gzFile *zp;
309 322
@@ -318,7 +331,8 @@ PHP_FUNCTION(gzclose) {
318 331
319 332 /* {{{ proto int gzeof(int zp)
320 333 Test for end-of-file on a .gz-file pointer */
321   -PHP_FUNCTION(gzeof) {
  334 +PHP_FUNCTION(gzeof)
  335 +{
322 336 pval **arg1;
323 337 gzFile *zp;
324 338
@@ -337,7 +351,8 @@ PHP_FUNCTION(gzeof) {
337 351
338 352 /* {{{ proto string gzgets(int zp, int length)
339 353 Get a line from .gz-file pointer */
340   -PHP_FUNCTION(gzgets) {
  354 +PHP_FUNCTION(gzgets)
  355 +{
341 356 pval **arg1, **arg2;
342 357 gzFile *zp;
343 358 int len;
@@ -373,7 +388,8 @@ PHP_FUNCTION(gzgets) {
373 388
374 389 /* {{{ proto string gzgetc(int zp)
375 390 Get a character from .gz-file pointer */
376   -PHP_FUNCTION(gzgetc) {
  391 +PHP_FUNCTION(gzgetc)
  392 +{
377 393 pval **arg1;
378 394 gzFile *zp;
379 395 int c;
@@ -456,7 +472,8 @@ PHP_FUNCTION(gzgetss)
456 472
457 473 /* {{{ proto int gzwrite(int zp, string str [, int length])
458 474 Binary-safe .gz-file write */
459   -PHP_FUNCTION(gzwrite) {
  475 +PHP_FUNCTION(gzwrite)
  476 +{
460 477 pval **arg1, **arg2, **arg3=NULL;
461 478 gzFile *zp;
462 479 int ret;
@@ -502,7 +519,8 @@ PHP_FUNCTION(gzwrite) {
502 519
503 520 /* {{{ proto int gzrewind(int zp)
504 521 Rewind the position of a .gz-file pointer */
505   -PHP_FUNCTION(gzrewind) {
  522 +PHP_FUNCTION(gzrewind)
  523 +{
506 524 pval **arg1;
507 525 gzFile *zp;
508 526
@@ -519,7 +537,8 @@ PHP_FUNCTION(gzrewind) {
519 537
520 538 /* {{{ proto int gztell(int zp)
521 539 Get .gz-file pointer's read/write position */
522   -PHP_FUNCTION(gztell) {
  540 +PHP_FUNCTION(gztell)
  541 +{
523 542 pval **arg1;
524 543 long pos;
525 544 gzFile *zp;
@@ -537,7 +556,8 @@ PHP_FUNCTION(gztell) {
537 556
538 557 /* {{{ proto int gzseek(int zp, int offset)
539 558 Seek on a file pointer */
540   -PHP_FUNCTION(gzseek) {
  559 +PHP_FUNCTION(gzseek)
  560 +{
541 561 pval **arg1, **arg2;
542 562 int ret;
543 563 gzFile *zp;
@@ -559,7 +579,8 @@ PHP_FUNCTION(gzseek) {
559 579 */
560 580 /* {{{ proto int readgzfile(string filename [, int use_include_path])
561 581 Output a .gz-file */
562   -PHP_FUNCTION(readgzfile) {
  582 +PHP_FUNCTION(readgzfile)
  583 +{
563 584 pval **arg1, **arg2;
564 585 char buf[8192];
565 586 gzFile *zp;
@@ -610,7 +631,8 @@ PHP_FUNCTION(readgzfile) {
610 631 */
611 632 /* {{{ proto int gzpassthru(int zp)
612 633 Output all remaining data from a .gz-file pointer */
613   -PHP_FUNCTION(gzpassthru) {
  634 +PHP_FUNCTION(gzpassthru)
  635 +{
614 636 pval **arg1;
615 637 gzFile *zp;
616 638 char buf[8192];
@@ -992,8 +1014,198 @@ static FILE *zlib_fopen_wrapper(char *path, char *mode, int options, int *issock
992 1014 #endif
993 1015
994 1016
  1017 +static int php_do_deflate(uint str_length, Bytef **p_buffer, uint *p_buf_used ZLIBLS_DC)
  1018 +{
  1019 + Bytef *buffer;
  1020 + uInt prev_outlen, outlen;
  1021 + int err;
  1022 +
  1023 + outlen = sizeof(char) * (str_length * 1.001 + 12);
  1024 + buffer = (Bytef *) emalloc(outlen+10+8); /* 10+8 for the header and trailer */
  1025 +
  1026 + ZLIBG(stream).next_out = buffer+10;
  1027 + ZLIBG(stream).avail_out = outlen;
  1028 +
  1029 + err = deflate(&ZLIBG(stream), Z_NO_FLUSH);
  1030 + while (err == Z_OK && !ZLIBG(stream).avail_out) {
  1031 + prev_outlen = outlen;
  1032 + outlen *= 3;
  1033 + buffer = realloc(buffer, outlen+10+8);
  1034 +
  1035 + ZLIBG(stream).next_out = buffer+10 + prev_outlen;
  1036 + ZLIBG(stream).avail_out = prev_outlen * 2;
  1037 +
  1038 + err = deflate(&ZLIBG(stream), Z_NO_FLUSH);
  1039 + }
  1040 +
  1041 + err = deflate(&ZLIBG(stream), Z_FINISH);
  1042 +
  1043 + *p_buffer = buffer;
  1044 + *p_buf_used = outlen - ZLIBG(stream).avail_out;
  1045 + return err;
  1046 +}
  1047 +
  1048 +
  1049 +int php_deflate_string(const char *str, uint str_length, char **newstr, uint *new_length, int coding)
  1050 +{
  1051 + Bytef *buffer;
  1052 + uInt buf_used;
  1053 + int err;
  1054 + Bytef header_buffer[11];
  1055 + Bytef trailer_buffer[9];
  1056 + ZLIBLS_FETCH();
  1057 +
  1058 + ZLIBG(compression_coding) = coding;
  1059 +
  1060 + ZLIBG(stream).zalloc = Z_NULL;
  1061 + ZLIBG(stream).zfree = Z_NULL;
  1062 + ZLIBG(stream).opaque = Z_NULL;
  1063 +
  1064 + switch (coding) {
  1065 + case CODING_GZIP:
  1066 + /* windowBits is passed < 0 to suppress zlib header & trailer */
  1067 + if (deflateInit2(&ZLIBG(stream), Z_DEFAULT_COMPRESSION, Z_DEFLATED,
  1068 + -MAX_WBITS, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY)
  1069 + != Z_OK) {
  1070 + /* TODO: print out error */
  1071 + return FAILURE;
  1072 + }
  1073 +
  1074 + /*
  1075 + sapi_add_header("Content-Encoding: gzip", sizeof("Content-Encoding: gzip") - 1, 1);
  1076 + sapi_send_headers();
  1077 + */
  1078 +
  1079 + /* Write a very simple .gz header: */
  1080 + sprintf(header_buffer, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0],
  1081 + gz_magic[1], Z_DEFLATED, 0 /*flags*/,
  1082 + 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
  1083 + ZLIBG(crc) = crc32(0L, Z_NULL, 0);
  1084 + break;
  1085 + case CODING_DEFLATE:
  1086 + if (deflateInit(&ZLIBG(stream), Z_DEFAULT_COMPRESSION) != Z_OK) {
  1087 + /* TODO: print out error */
  1088 + return FAILURE;
  1089 + }
  1090 + /*
  1091 + sapi_add_header("Content-Encoding: deflate", sizeof("Content-Encoding: deflate") - 1, 1);
  1092 + */
  1093 + break;
  1094 + }
  1095 +
  1096 +
  1097 + ZLIBG(stream).next_in = (Bytef*) str;
  1098 + ZLIBG(stream).avail_in = (uInt) str_length;
  1099 +
  1100 + if (ZLIBG(compression_coding) == 1) {
  1101 + ZLIBG(crc) = crc32(ZLIBG(crc), (const Bytef *)str, str_length);
  1102 + }
  1103 +
  1104 + err = php_do_deflate(str_length, &buffer, &buf_used ZLIBLS_CC);
  1105 + /* TODO: error handling (err may be Z_STREAM_ERROR, Z_BUF_ERROR, ?) */
  1106 +
  1107 +
  1108 + if (ZLIBG(compression_coding) == 1) {
  1109 + /* write crc & stream.total_in in LSB order */
  1110 + sprintf(trailer_buffer, "%c%c%c%c%c%c%c%c",
  1111 + (char) ZLIBG(crc) & 0xFF,
  1112 + (char) (ZLIBG(crc) >> 8) & 0xFF,
  1113 + (char) (ZLIBG(crc) >> 16) & 0xFF,
  1114 + (char) (ZLIBG(crc) >> 24) & 0xFF,
  1115 + (char) ZLIBG(stream).total_in & 0xFF,
  1116 + (char) (ZLIBG(stream).total_in >> 8) & 0xFF,
  1117 + (char) (ZLIBG(stream).total_in >> 16) & 0xFF,
  1118 + (char) (ZLIBG(stream).total_in >> 24) & 0xFF);
  1119 + }
  1120 +
  1121 +
  1122 + memcpy(buffer, header_buffer, 10);
  1123 + memcpy(buffer+10+buf_used, trailer_buffer, 8);
  1124 +
  1125 + *new_length = buf_used + 10 + 8;
  1126 + *newstr = buffer;
  1127 +
  1128 + return SUCCESS;
  1129 +}
  1130 +
  1131 +
  1132 +PHP_FUNCTION(gzencode)
  1133 +{
  1134 + zval **zv_coding, **zv_string;
  1135 + int coding;
  1136 +
  1137 + switch(ZEND_NUM_ARGS()) {
  1138 + case CODING_GZIP:
  1139 + if (zend_get_parameters_ex(1, &zv_string)==FAILURE) {
  1140 + RETURN_FALSE;
  1141 + }
  1142 + convert_to_string_ex(zv_string);
  1143 + coding = 1;
  1144 + break;
  1145 + case CODING_DEFLATE:
  1146 + if (zend_get_parameters_ex(2, &zv_string, &zv_coding)==FAILURE) {
  1147 + RETURN_FALSE;
  1148 + }
  1149 + convert_to_string_ex(zv_string);
  1150 + convert_to_long_ex(zv_coding);
  1151 + coding = Z_LVAL_PP(zv_coding);
  1152 + break;
  1153 + default:
  1154 + ZEND_WRONG_PARAM_COUNT();
  1155 + break;
  1156 + }
  1157 + 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) {
  1158 + Z_TYPE_P(return_value) = IS_STRING;
  1159 + } else {
  1160 + RETURN_FALSE;
  1161 + }
  1162 +}
  1163 +
  1164 +
  1165 +PHP_FUNCTION(ob_gzhandler)
  1166 +{
  1167 + int coding;
  1168 + zval **zv_string;
  1169 + zval **data, **a_encoding;
  1170 +
  1171 + if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &zv_string)==FAILURE) {
  1172 + ZEND_WRONG_PARAM_COUNT();
  1173 + }
  1174 +
  1175 + if (zend_hash_find(&EG(symbol_table), "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"), (void **) &data)==FAILURE
  1176 + || Z_TYPE_PP(data)!=IS_ARRAY
  1177 + || zend_hash_find(Z_ARRVAL_PP(data), "HTTP_ACCEPT_ENCODING", sizeof("HTTP_ACCEPT_ENCODING"), (void **) &a_encoding)==FAILURE) {
  1178 + /* return the original string */
  1179 + *return_value = **zv_string;
  1180 + zval_copy_ctor(return_value);
  1181 + return;
  1182 + }
  1183 + convert_to_string_ex(a_encoding);
  1184 + if (php_memnstr(Z_STRVAL_PP(a_encoding), "gzip", 4, Z_STRVAL_PP(a_encoding) + Z_STRLEN_PP(a_encoding))) {
  1185 + coding = CODING_GZIP;
  1186 + } else if(php_memnstr(Z_STRVAL_PP(a_encoding), "deflate", 7, Z_STRVAL_PP(a_encoding) + Z_STRLEN_PP(a_encoding))) {
  1187 + coding = CODING_DEFLATE;
  1188 + } else {
  1189 + RETURN_FALSE;
  1190 + }
  1191 + 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) {
  1192 + Z_TYPE_P(return_value) = IS_STRING;
  1193 + switch (coding) {
  1194 + case CODING_GZIP:
  1195 + sapi_add_header("Content-Encoding: gzip", sizeof("Content-Encoding: gzip") - 1, 1);
  1196 + break;
  1197 + case CODING_DEFLATE:
  1198 + sapi_add_header("Content-Encoding: deflate", sizeof("Content-Encoding: deflate") - 1, 1);
  1199 + break;
  1200 + }
  1201 + } else {
  1202 + /* return the original string */
  1203 + *return_value = **zv_string;
  1204 + zval_copy_ctor(return_value);
  1205 + }
  1206 +}
  1207 +
995 1208
996   -#endif /* HAVE_ZLIB */
997 1209 /*
998 1210 * Local variables:
999 1211 * tab-width: 4
5 main/SAPI.c
@@ -271,6 +271,7 @@ SAPI_API void sapi_activate(SLS_D)
271 271 SG(request_info).post_data = NULL;
272 272 SG(request_info).current_user = NULL;
273 273 SG(request_info).current_user_length = 0;
  274 + SG(request_info).no_headers = 0;
274 275
275 276 /* It's possible to override this general case in the activate() callback, if
276 277 * necessary.
@@ -363,7 +364,7 @@ SAPI_API int sapi_add_header_ex(char *header_line, uint header_line_len, zend_bo
363 364 char *colon_offset;
364 365 SLS_FETCH();
365 366
366   - if (SG(headers_sent)) {
  367 + if (SG(headers_sent) && !SG(request_info).no_headers) {
367 368 char *output_start_filename = php_get_output_start_filename();
368 369 int output_start_lineno = php_get_output_start_lineno();
369 370
@@ -457,7 +458,7 @@ SAPI_API int sapi_send_headers()
457 458 int ret = FAILURE;
458 459 SLS_FETCH();
459 460
460   - if (SG(headers_sent)) {
  461 + if (SG(headers_sent) || SG(request_info).no_headers) {
461 462 return SUCCESS;
462 463 }
463 464
3  main/SAPI.h
@@ -73,7 +73,8 @@ typedef struct {
73 73
74 74 const char *content_type;
75 75
76   - unsigned char headers_only;
  76 + zend_bool headers_only;
  77 + zend_bool no_headers;
77 78
78 79 sapi_post_entry *post_entry;
79 80
15 main/main.c
@@ -223,6 +223,7 @@ PHP_INI_BEGIN()
223 223 STD_PHP_INI_BOOLEAN("magic_quotes_runtime", "0", PHP_INI_ALL, OnUpdateBool, magic_quotes_runtime, php_core_globals, core_globals)
224 224 STD_PHP_INI_BOOLEAN("magic_quotes_sybase", "0", PHP_INI_ALL, OnUpdateBool, magic_quotes_sybase, php_core_globals, core_globals)
225 225 STD_PHP_INI_BOOLEAN("output_buffering", "0", PHP_INI_PERDIR|PHP_INI_SYSTEM,OnUpdateBool, output_buffering, php_core_globals, core_globals)
  226 + STD_PHP_INI_ENTRY("output_handler", NULL, PHP_INI_PERDIR|PHP_INI_SYSTEM,OnUpdateString, output_handler, php_core_globals, core_globals)
226 227 STD_PHP_INI_BOOLEAN("register_argc_argv", "1", PHP_INI_ALL, OnUpdateBool, register_argc_argv, php_core_globals, core_globals)
227 228 STD_PHP_INI_BOOLEAN("register_globals", "1", PHP_INI_ALL, OnUpdateBool, register_globals, php_core_globals, core_globals)
228 229 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)
623 624 sapi_add_header(SAPI_PHP_VERSION_HEADER, sizeof(SAPI_PHP_VERSION_HEADER)-1, 1);
624 625 }
625 626
626   - if (PG(output_buffering)) {
  627 + if (PG(output_handler)) {
  628 + zval *output_handler;
  629 +
  630 + ALLOC_INIT_ZVAL(output_handler);
  631 + Z_STRLEN_P(output_handler) = strlen(PG(output_handler)); /* this can be optimized */
  632 + Z_STRVAL_P(output_handler) = estrndup(PG(output_handler), Z_STRLEN_P(output_handler));
  633 + Z_TYPE_P(output_handler) = IS_STRING;
  634 + php_start_ob_buffer(output_handler);
  635 + } else if (PG(output_buffering)) {
627 636 php_start_ob_buffer(NULL);
628 637 } else if (PG(implicit_flush)) {
629 638 php_start_implicit_flush();
@@ -656,11 +665,11 @@ void php_request_shutdown(void *dummy)
656 665 PLS_FETCH();
657 666
658 667 if (setjmp(EG(bailout))==0) {
659   - sapi_send_headers();
  668 + php_end_ob_buffers(SG(request_info).headers_only?0:1);
660 669 }
661 670
662 671 if (setjmp(EG(bailout))==0) {
663   - php_end_ob_buffers(SG(request_info).headers_only?0:1);
  672 + sapi_send_headers();
664 673 }
665 674
666 675 if (PG(modules_activated) && setjmp(EG(bailout))==0) {
3  main/php_globals.h
@@ -65,6 +65,9 @@ struct _php_core_globals {
65 65 zend_bool safe_mode;
66 66 zend_bool sql_safe_mode;
67 67 zend_bool enable_dl;
  68 +
  69 + char *output_handler;
  70 +
68 71 char *safe_mode_exec_dir;
69 72
70 73 long memory_limit;
6 php.ini-dist
@@ -64,6 +64,12 @@ output_buffering = Off ; Output buffering allows you to send header lines (inclu
64 64 ; You can enable output buffering by in runtime by calling the output
65 65 ; buffering functions, or enable output buffering for all files
66 66 ; by setting this directive to On.
  67 +output_handler = ; You can redirect all of the output of your scripts to a function,
  68 + ; that can be responsible to process or log it. For example,
  69 + ; if you set the output_handler to "ob_gzhandler", than output
  70 + ; will be transparently compressed for browsers that support gzip or
  71 + ; deflate encoding. Setting an output handler automatically turns on
  72 + ; output buffering.
67 73 implicit_flush = Off ; Implicit flush tells PHP to tell the output layer to flush itself
68 74 ; automatically after every output block. This is equivalent to
69 75 ; calling the PHP function flush() after each and every call to print()
6 php.ini-optimized
@@ -51,6 +51,12 @@ output_buffering = Off ; Output buffering allows you to send header lines (inclu
51 51 ; You can enable output buffering by in runtime by calling the output
52 52 ; buffering functions, or enable output buffering for all files
53 53 ; by setting this directive to On.
  54 +output_handler = ; You can redirect all of the output of your scripts to a function,
  55 + ; that can be responsible to process or log it. For example,
  56 + ; if you set the output_handler to "ob_gzhandler", than output
  57 + ; will be transparently compressed for browsers that support gzip or
  58 + ; deflate encoding. Setting an output handler automatically turns on
  59 + ; output buffering.
54 60 implicit_flush = Off ; Implicit flush tells PHP to tell the output layer to flush itself
55 61 ; automatically after every output block. This is equivalent to
56 62 ; calling the PHP function flush() after each and every call to print()
6 php.ini-recommended
@@ -51,6 +51,12 @@ output_buffering = Off ; Output buffering allows you to send header lines (inclu
2  sapi/apache/sapi_apache.c
@@ -92,8 +92,8 @@ int apache_php_module_main(request_rec *r, int display_source_mode CLS_DC ELS_DC
92 92 if (setjmp(EG(bailout))!=0) {
93 93 return OK;
94 94 }
95   - php_header(); /* Make sure headers have been sent */
96 95 php_end_ob_buffers(1);
  96 + php_header(); /* Make sure headers have been sent */
97 97 return (OK);
98 98 }
99 99
7 sapi/cgi/cgi_main.c
@@ -548,6 +548,7 @@ any .htaccess restrictions anywhere on your site you can leave doc_root undefine
548 548 }
549 549 }
550 550 if (no_headers) {
  551 + SG(request_info).no_headers = 1;
551 552 SG(headers_sent) = 1;
552 553 }
553 554 cgi_started=1;
@@ -582,6 +583,7 @@ any .htaccess restrictions anywhere on your site you can leave doc_root undefine
582 583 }
583 584 if (no_headers) {
584 585 SG(headers_sent) = 1;
  586 + SG(request_info).no_headers = 1;
585 587 }
586 588 cgi_started=1;
587 589 php_print_info(0xFFFFFFFF);
@@ -630,6 +632,7 @@ any .htaccess restrictions anywhere on your site you can leave doc_root undefine
630 632 }
631 633 if (no_headers) {
632 634 SG(headers_sent) = 1;
  635 + SG(request_info).no_headers = 1;
633 636 }
634 637 php_printf("%s\n", PHP_VERSION);
635 638 php_end_ob_buffers(1);
@@ -677,6 +680,7 @@ any .htaccess restrictions anywhere on your site you can leave doc_root undefine
677 680 }
678 681 if (no_headers) {
679 682 SG(headers_sent) = 1;
  683 + SG(request_info).no_headers = 1;
680 684 }
681 685 file_handle.filename = "-";
682 686 file_handle.type = ZEND_HANDLE_FP;
@@ -766,9 +770,6 @@ any .htaccess restrictions anywhere on your site you can leave doc_root undefine
766 770 #endif
767 771 }
768 772
769   - php_header(); /* Make sure headers have been sent */
770   -
771   -
772 773
773 774 if (SG(request_info).path_translated) {
774 775 persist_alloc(SG(request_info).path_translated);

0 comments on commit 0f7f5c2

Please sign in to comment.
Something went wrong with that request. Please try again.