Annotation of embedaddon/php/ext/zlib/zlib.c, revision 1.1.1.2
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | PHP Version 5 |
4: +----------------------------------------------------------------------+
5: | Copyright (c) 1997-2012 The PHP Group |
6: +----------------------------------------------------------------------+
7: | This source file is subject to version 3.01 of the PHP license, |
8: | that is bundled with this package in the file LICENSE, and is |
9: | available through the world-wide-web at the following url: |
10: | http://www.php.net/license/3_01.txt |
11: | If you did not receive a copy of the PHP license and are unable to |
12: | obtain it through the world-wide-web, please send a note to |
13: | license@php.net so we can mail you a copy immediately. |
14: +----------------------------------------------------------------------+
15: | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> |
1.1.1.2 ! misho 16: | Stefan Röhrich <sr@linux.de> |
1.1 misho 17: | Zeev Suraski <zeev@zend.com> |
18: | Jade Nicoletti <nicoletti@nns.ch> |
1.1.1.2 ! misho 19: | Michael Wallner <mike@php.net> |
1.1 misho 20: +----------------------------------------------------------------------+
21: */
22:
1.1.1.2 ! misho 23: /* $Id$ */
1.1 misho 24:
25: #ifdef HAVE_CONFIG_H
26: #include "config.h"
27: #endif
28:
29: #include "php.h"
30: #include "SAPI.h"
31: #include "php_ini.h"
32: #include "ext/standard/info.h"
1.1.1.2 ! misho 33: #include "ext/standard/file.h"
! 34: #include "ext/standard/php_string.h"
1.1 misho 35: #include "php_zlib.h"
36:
1.1.1.2 ! misho 37: ZEND_DECLARE_MODULE_GLOBALS(zlib);
1.1 misho 38:
39: /* {{{ Memory management wrappers */
40:
41: static voidpf php_zlib_alloc(voidpf opaque, uInt items, uInt size)
42: {
43: return (voidpf)safe_emalloc(items, size, 0);
44: }
45:
46: static void php_zlib_free(voidpf opaque, voidpf address)
47: {
48: efree((void*)address);
49: }
50: /* }}} */
51:
1.1.1.2 ! misho 52: /* {{{ php_zlib_output_conflict_check() */
! 53: static int php_zlib_output_conflict_check(const char *handler_name, size_t handler_name_len TSRMLS_DC)
1.1 misho 54: {
1.1.1.2 ! misho 55: if (php_output_get_level(TSRMLS_C) > 0) {
! 56: if (php_output_handler_conflict(handler_name, handler_name_len, ZEND_STRL(PHP_ZLIB_OUTPUT_HANDLER_NAME) TSRMLS_CC)
! 57: || php_output_handler_conflict(handler_name, handler_name_len, ZEND_STRL("ob_gzhandler") TSRMLS_CC)
! 58: || php_output_handler_conflict(handler_name, handler_name_len, ZEND_STRL("mb_output_handler") TSRMLS_CC)
! 59: || php_output_handler_conflict(handler_name, handler_name_len, ZEND_STRL("URL-Rewriter") TSRMLS_CC)) {
! 60: return FAILURE;
! 61: }
1.1 misho 62: }
1.1.1.2 ! misho 63: return SUCCESS;
! 64: }
! 65: /* }}} */
1.1 misho 66:
1.1.1.2 ! misho 67: /* {{{ php_zlib_output_encoding() */
! 68: static int php_zlib_output_encoding(TSRMLS_D)
! 69: {
! 70: zval **enc;
1.1 misho 71:
1.1.1.2 ! misho 72: if (!ZLIBG(compression_coding)) {
! 73: zend_is_auto_global(ZEND_STRL("_SERVER") TSRMLS_CC);
! 74: if (PG(http_globals)[TRACK_VARS_SERVER] && SUCCESS == zend_hash_find(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER]), "HTTP_ACCEPT_ENCODING", sizeof("HTTP_ACCEPT_ENCODING"), (void *) &enc)) {
! 75: convert_to_string(*enc);
! 76: if (strstr(Z_STRVAL_PP(enc), "gzip")) {
! 77: ZLIBG(compression_coding) = PHP_ZLIB_ENCODING_GZIP;
! 78: } else if (strstr(Z_STRVAL_PP(enc), "deflate")) {
! 79: ZLIBG(compression_coding) = PHP_ZLIB_ENCODING_DEFLATE;
! 80: }
! 81: }
1.1 misho 82: }
1.1.1.2 ! misho 83: return ZLIBG(compression_coding);
! 84: }
! 85: /* }}} */
1.1 misho 86:
1.1.1.2 ! misho 87: /* {{{ php_zlib_output_handler_ex() */
! 88: static int php_zlib_output_handler_ex(php_zlib_context *ctx, php_output_context *output_context)
! 89: {
! 90: int flags = Z_SYNC_FLUSH;
! 91: PHP_OUTPUT_TSRMLS(output_context);
! 92:
! 93: if (output_context->op & PHP_OUTPUT_HANDLER_START) {
! 94: /* start up */
! 95: if (Z_OK != deflateInit2(&ctx->Z, ZLIBG(output_compression_level), Z_DEFLATED, ZLIBG(compression_coding), MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY)) {
! 96: return FAILURE;
! 97: }
1.1 misho 98: }
99:
1.1.1.2 ! misho 100: if (output_context->op & PHP_OUTPUT_HANDLER_CLEAN) {
! 101: /* free buffers */
! 102: deflateEnd(&ctx->Z);
! 103:
! 104: if (output_context->op & PHP_OUTPUT_HANDLER_FINAL) {
! 105: /* discard */
! 106: return SUCCESS;
! 107: } else {
! 108: /* restart */
! 109: if (Z_OK != deflateInit2(&ctx->Z, ZLIBG(output_compression_level), Z_DEFLATED, ZLIBG(compression_coding), MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY)) {
! 110: return FAILURE;
! 111: }
! 112: ctx->buffer.used = 0;
! 113: }
! 114: } else {
! 115: if (output_context->in.used) {
! 116: /* append input */
! 117: if (ctx->buffer.free < output_context->in.used) {
! 118: if (!(ctx->buffer.aptr = erealloc_recoverable(ctx->buffer.data, ctx->buffer.used + ctx->buffer.free + output_context->in.used))) {
! 119: deflateEnd(&ctx->Z);
! 120: return FAILURE;
! 121: }
! 122: ctx->buffer.data = ctx->buffer.aptr;
! 123: ctx->buffer.free += output_context->in.used;
! 124: }
! 125: memcpy(ctx->buffer.data + ctx->buffer.used, output_context->in.data, output_context->in.used);
! 126: ctx->buffer.free -= output_context->in.used;
! 127: ctx->buffer.used += output_context->in.used;
! 128: }
! 129: output_context->out.size = PHP_ZLIB_BUFFER_SIZE_GUESS(output_context->in.used);
! 130: output_context->out.data = emalloc(output_context->out.size);
! 131: output_context->out.free = 1;
! 132: output_context->out.used = 0;
! 133:
! 134: ctx->Z.avail_in = ctx->buffer.used;
! 135: ctx->Z.next_in = (Bytef *) ctx->buffer.data;
! 136: ctx->Z.avail_out = output_context->out.size;
! 137: ctx->Z.next_out = (Bytef *) output_context->out.data;
! 138:
! 139: if (output_context->op & PHP_OUTPUT_HANDLER_FINAL) {
! 140: flags = Z_FINISH;
! 141: } else if (output_context->op & PHP_OUTPUT_HANDLER_FLUSH) {
! 142: flags = Z_FULL_FLUSH;
! 143: }
! 144:
! 145: switch (deflate(&ctx->Z, flags)) {
! 146: case Z_OK:
! 147: if (flags == Z_FINISH) {
! 148: deflateEnd(&ctx->Z);
! 149: return FAILURE;
! 150: }
! 151: case Z_STREAM_END:
! 152: if (ctx->Z.avail_in) {
! 153: memmove(ctx->buffer.data, ctx->buffer.data + ctx->buffer.used - ctx->Z.avail_in, ctx->Z.avail_in);
! 154: }
! 155: ctx->buffer.free += ctx->buffer.used - ctx->Z.avail_in;
! 156: ctx->buffer.used = ctx->Z.avail_in;
! 157: output_context->out.used = output_context->out.size - ctx->Z.avail_out;
! 158: break;
! 159: default:
! 160: deflateEnd(&ctx->Z);
! 161: return FAILURE;
! 162: }
1.1 misho 163:
1.1.1.2 ! misho 164: if (output_context->op & PHP_OUTPUT_HANDLER_FINAL) {
! 165: deflateEnd(&ctx->Z);
! 166: }
1.1 misho 167: }
168:
1.1.1.2 ! misho 169: return SUCCESS;
1.1 misho 170: }
171: /* }}} */
172:
1.1.1.2 ! misho 173: /* {{{ php_zlib_output_handler() */
! 174: static int php_zlib_output_handler(void **handler_context, php_output_context *output_context)
1.1 misho 175: {
1.1.1.2 ! misho 176: php_zlib_context *ctx = *(php_zlib_context **) handler_context;
! 177: PHP_OUTPUT_TSRMLS(output_context);
1.1 misho 178:
1.1.1.2 ! misho 179: if (!php_zlib_output_encoding(TSRMLS_C)) {
! 180: /* "Vary: Accept-Encoding" header sent along uncompressed content breaks caching in MSIE,
! 181: so let's just send it with successfully compressed content or unless the complete
! 182: buffer gets discarded, see http://bugs.php.net/40325;
! 183:
! 184: Test as follows:
! 185: +Vary: $ HTTP_ACCEPT_ENCODING=gzip ./sapi/cgi/php <<<'<?php ob_start("ob_gzhandler"); echo "foo\n";'
! 186: +Vary: $ HTTP_ACCEPT_ENCODING= ./sapi/cgi/php <<<'<?php ob_start("ob_gzhandler"); echo "foo\n";'
! 187: -Vary: $ HTTP_ACCEPT_ENCODING=gzip ./sapi/cgi/php <<<'<?php ob_start("ob_gzhandler"); echo "foo\n"; ob_end_clean();'
! 188: -Vary: $ HTTP_ACCEPT_ENCODING= ./sapi/cgi/php <<<'<?php ob_start("ob_gzhandler"); echo "foo\n"; ob_end_clean();'
! 189: */
! 190: if (output_context->op != (PHP_OUTPUT_HANDLER_START|PHP_OUTPUT_HANDLER_CLEAN|PHP_OUTPUT_HANDLER_FINAL)) {
! 191: sapi_add_header_ex(ZEND_STRL("Vary: Accept-Encoding"), 1, 1 TSRMLS_CC);
! 192: }
! 193: return FAILURE;
! 194: }
1.1 misho 195:
1.1.1.2 ! misho 196: if (SUCCESS != php_zlib_output_handler_ex(ctx, output_context)) {
1.1 misho 197: return FAILURE;
198: }
199:
1.1.1.2 ! misho 200: if (!(output_context->op & PHP_OUTPUT_HANDLER_CLEAN)) {
! 201: int flags;
! 202:
! 203: if (SUCCESS == php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_GET_FLAGS, &flags TSRMLS_CC)) {
! 204: /* only run this once */
! 205: if (!(flags & PHP_OUTPUT_HANDLER_STARTED)) {
! 206: if (SG(headers_sent) || !ZLIBG(output_compression)) {
! 207: deflateEnd(&ctx->Z);
! 208: return FAILURE;
! 209: }
! 210: switch (ZLIBG(compression_coding)) {
! 211: case PHP_ZLIB_ENCODING_GZIP:
! 212: sapi_add_header_ex(ZEND_STRL("Content-Encoding: gzip"), 1, 1 TSRMLS_CC);
! 213: break;
! 214: case PHP_ZLIB_ENCODING_DEFLATE:
! 215: sapi_add_header_ex(ZEND_STRL("Content-Encoding: deflate"), 1, 1 TSRMLS_CC);
! 216: break;
! 217: default:
! 218: deflateEnd(&ctx->Z);
! 219: return FAILURE;
! 220: }
! 221: sapi_add_header_ex(ZEND_STRL("Vary: Accept-Encoding"), 1, 1 TSRMLS_CC);
! 222: php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_IMMUTABLE, NULL TSRMLS_CC);
! 223: }
! 224: }
! 225: }
1.1 misho 226:
227: return SUCCESS;
228: }
229: /* }}} */
230:
1.1.1.2 ! misho 231: /* {{{ php_zlib_output_handler_context_init() */
! 232: static php_zlib_context *php_zlib_output_handler_context_init(TSRMLS_D)
1.1 misho 233: {
1.1.1.2 ! misho 234: php_zlib_context *ctx = (php_zlib_context *) ecalloc(1, sizeof(php_zlib_context));
! 235: ctx->Z.zalloc = php_zlib_alloc;
! 236: ctx->Z.zfree = php_zlib_free;
! 237: return ctx;
1.1 misho 238: }
239: /* }}} */
240:
1.1.1.2 ! misho 241: /* {{{ php_zlib_output_handler_context_dtor() */
! 242: static void php_zlib_output_handler_context_dtor(void *opaq TSRMLS_DC)
1.1 misho 243: {
1.1.1.2 ! misho 244: php_zlib_context *ctx = (php_zlib_context *) opaq;
1.1 misho 245:
1.1.1.2 ! misho 246: if (ctx) {
! 247: if (ctx->buffer.data) {
! 248: efree(ctx->buffer.data);
! 249: }
! 250: efree(ctx);
! 251: }
1.1 misho 252: }
253: /* }}} */
254:
1.1.1.2 ! misho 255: /* {{{ php_zlib_output_handler_init() */
! 256: static php_output_handler *php_zlib_output_handler_init(const char *handler_name, size_t handler_name_len, size_t chunk_size, int flags TSRMLS_DC)
1.1 misho 257: {
1.1.1.2 ! misho 258: php_output_handler *h = NULL;
1.1 misho 259:
1.1.1.2 ! misho 260: if (!ZLIBG(output_compression)) {
! 261: ZLIBG(output_compression) = chunk_size ? chunk_size : PHP_OUTPUT_HANDLER_DEFAULT_SIZE;
! 262: }
1.1 misho 263:
1.1.1.2 ! misho 264: if ((h = php_output_handler_create_internal(handler_name, handler_name_len, php_zlib_output_handler, chunk_size, flags TSRMLS_CC))) {
! 265: php_output_handler_set_context(h, php_zlib_output_handler_context_init(TSRMLS_C), php_zlib_output_handler_context_dtor TSRMLS_CC);
! 266: }
! 267:
! 268: return h;
1.1 misho 269: }
270: /* }}} */
271:
1.1.1.2 ! misho 272: /* {{{ php_zlib_output_compression_start() */
! 273: static void php_zlib_output_compression_start(TSRMLS_D)
1.1 misho 274: {
1.1.1.2 ! misho 275: zval *zoh;
! 276: php_output_handler *h;
1.1 misho 277:
1.1.1.2 ! misho 278: switch (ZLIBG(output_compression)) {
! 279: case 0:
! 280: break;
! 281: case 1:
! 282: ZLIBG(output_compression) = PHP_OUTPUT_HANDLER_DEFAULT_SIZE;
! 283: /* break omitted intentionally */
! 284: default:
! 285: if ( (h = php_zlib_output_handler_init(ZEND_STRL(PHP_ZLIB_OUTPUT_HANDLER_NAME), ZLIBG(output_compression), PHP_OUTPUT_HANDLER_STDFLAGS TSRMLS_CC)) &&
! 286: (SUCCESS == php_output_handler_start(h TSRMLS_CC))) {
! 287: if (ZLIBG(output_handler) && *ZLIBG(output_handler)) {
! 288: MAKE_STD_ZVAL(zoh);
! 289: ZVAL_STRING(zoh, ZLIBG(output_handler), 1);
! 290: php_output_start_user(zoh, ZLIBG(output_compression), PHP_OUTPUT_HANDLER_STDFLAGS TSRMLS_CC);
! 291: zval_ptr_dtor(&zoh);
! 292: }
! 293: }
! 294: break;
! 295: }
1.1 misho 296: }
297: /* }}} */
298:
1.1.1.2 ! misho 299: /* {{{ php_zlib_encode() */
! 300: static int php_zlib_encode(const char *in_buf, size_t in_len, char **out_buf, size_t *out_len, int encoding, int level TSRMLS_DC)
1.1 misho 301: {
1.1.1.2 ! misho 302: int status;
! 303: z_stream Z;
1.1 misho 304:
1.1.1.2 ! misho 305: memset(&Z, 0, sizeof(z_stream));
! 306: Z.zalloc = php_zlib_alloc;
! 307: Z.zfree = php_zlib_free;
! 308:
! 309: if (Z_OK == (status = deflateInit2(&Z, level, Z_DEFLATED, encoding, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY))) {
! 310: *out_len = PHP_ZLIB_BUFFER_SIZE_GUESS(in_len);
! 311: *out_buf = emalloc(*out_len);
! 312:
! 313: Z.next_in = (Bytef *) in_buf;
! 314: Z.next_out = (Bytef *) *out_buf;
! 315: Z.avail_in = in_len;
! 316: Z.avail_out = *out_len;
! 317:
! 318: status = deflate(&Z, Z_FINISH);
! 319: deflateEnd(&Z);
! 320:
! 321: if (Z_STREAM_END == status) {
! 322: /* size buffer down to actual length */
! 323: *out_buf = erealloc(*out_buf, Z.total_out + 1);
! 324: (*out_buf)[*out_len = Z.total_out] = '\0';
! 325: return SUCCESS;
! 326: } else {
! 327: efree(*out_buf);
! 328: }
1.1 misho 329: }
330:
1.1.1.2 ! misho 331: *out_buf = NULL;
! 332: *out_len = 0;
1.1 misho 333:
1.1.1.2 ! misho 334: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", zError(status));
! 335: return FAILURE;
! 336: }
! 337: /* }}} */
1.1 misho 338:
1.1.1.2 ! misho 339: /* {{{ php_zlib_inflate_rounds() */
! 340: static inline int php_zlib_inflate_rounds(z_stream *Z, size_t max, char **buf, size_t *len)
! 341: {
! 342: int status, round = 0;
! 343: php_zlib_buffer buffer = {NULL, NULL, 0, 0, 0};
1.1 misho 344:
1.1.1.2 ! misho 345: *buf = NULL;
! 346: *len = 0;
1.1 misho 347:
1.1.1.2 ! misho 348: buffer.size = (max && (max < Z->avail_in)) ? max : Z->avail_in;
1.1 misho 349:
1.1.1.2 ! misho 350: do {
! 351: if ((max && (max <= buffer.used)) || !(buffer.aptr = erealloc_recoverable(buffer.data, buffer.size))) {
! 352: status = Z_MEM_ERROR;
1.1 misho 353: } else {
1.1.1.2 ! misho 354: buffer.data = buffer.aptr;
! 355: Z->avail_out = buffer.free = buffer.size - buffer.used;
! 356: Z->next_out = (Bytef *) buffer.data + buffer.used;
! 357: #if 0
! 358: fprintf(stderr, "\n%3d: %3d PRIOR: size=%7lu,\tfree=%7lu,\tused=%7lu,\tavail_in=%7lu,\tavail_out=%7lu\n", round, status, buffer.size, buffer.free, buffer.used, Z->avail_in, Z->avail_out);
! 359: #endif
! 360: status = inflate(Z, Z_NO_FLUSH);
! 361:
! 362: buffer.used += buffer.free - Z->avail_out;
! 363: buffer.free = Z->avail_out;
! 364: #if 0
! 365: fprintf(stderr, "%3d: %3d AFTER: size=%7lu,\tfree=%7lu,\tused=%7lu,\tavail_in=%7lu,\tavail_out=%7lu\n", round, status, buffer.size, buffer.free, buffer.used, Z->avail_in, Z->avail_out);
! 366: #endif
! 367: buffer.size += (buffer.size >> 3) + 1;
1.1 misho 368: }
1.1.1.2 ! misho 369: } while ((Z_BUF_ERROR == status || (Z_OK == status && Z->avail_in)) && ++round < 100);
! 370:
! 371: if (status == Z_STREAM_END) {
! 372: buffer.data = erealloc(buffer.data, buffer.used + 1);
! 373: buffer.data[buffer.used] = '\0';
! 374: *buf = buffer.data;
! 375: *len = buffer.used;
! 376: } else {
! 377: if (buffer.data) {
! 378: efree(buffer.data);
! 379: }
! 380: /* HACK: See zlib/examples/zpipe.c inf() function for explanation. */
! 381: /* This works as long as this function is not used for streaming. Required to catch very short invalid data. */
! 382: status = (status == Z_OK) ? Z_DATA_ERROR : status;
1.1 misho 383: }
1.1.1.2 ! misho 384: return status;
1.1 misho 385: }
386: /* }}} */
387:
1.1.1.2 ! misho 388: /* {{{ php_zlib_decode() */
! 389: static int php_zlib_decode(const char *in_buf, size_t in_len, char **out_buf, size_t *out_len, int encoding, size_t max_len TSRMLS_DC)
1.1 misho 390: {
1.1.1.2 ! misho 391: int status = Z_DATA_ERROR;
! 392: z_stream Z;
1.1 misho 393:
1.1.1.2 ! misho 394: memset(&Z, 0, sizeof(z_stream));
! 395: Z.zalloc = php_zlib_alloc;
! 396: Z.zfree = php_zlib_free;
! 397:
! 398: if (in_len) {
! 399: retry_raw_inflate:
! 400: status = inflateInit2(&Z, encoding);
! 401: if (Z_OK == status) {
! 402: Z.next_in = (Bytef *) in_buf;
! 403: Z.avail_in = in_len + 1; /* NOTE: data must be zero terminated */
! 404:
! 405: switch (status = php_zlib_inflate_rounds(&Z, max_len, out_buf, out_len)) {
! 406: case Z_STREAM_END:
! 407: inflateEnd(&Z);
! 408: return SUCCESS;
! 409:
! 410: case Z_DATA_ERROR:
! 411: /* raw deflated data? */
! 412: if (PHP_ZLIB_ENCODING_ANY == encoding) {
! 413: inflateEnd(&Z);
! 414: encoding = PHP_ZLIB_ENCODING_RAW;
! 415: goto retry_raw_inflate;
! 416: }
! 417: }
! 418: inflateEnd(&Z);
! 419: }
1.1 misho 420: }
421:
1.1.1.2 ! misho 422: *out_buf = NULL;
! 423: *out_len = 0;
1.1 misho 424:
1.1.1.2 ! misho 425: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", zError(status));
! 426: return FAILURE;
! 427: }
! 428: /* }}} */
1.1 misho 429:
1.1.1.2 ! misho 430: /* {{{ php_zlib_cleanup_ob_gzhandler_mess() */
! 431: static void php_zlib_cleanup_ob_gzhandler_mess(TSRMLS_D)
! 432: {
! 433: if (ZLIBG(ob_gzhandler)) {
! 434: deflateEnd(&(ZLIBG(ob_gzhandler)->Z));
! 435: php_zlib_output_handler_context_dtor(ZLIBG(ob_gzhandler) TSRMLS_CC);
! 436: ZLIBG(ob_gzhandler) = NULL;
1.1 misho 437: }
438: }
439: /* }}} */
440:
1.1.1.2 ! misho 441: /* {{{ proto string ob_gzhandler(string data, int flags)
! 442: Legacy hack */
! 443: static PHP_FUNCTION(ob_gzhandler)
1.1 misho 444: {
1.1.1.2 ! misho 445: char *in_str;
! 446: int in_len;
1.1 misho 447: long flags = 0;
1.1.1.2 ! misho 448: php_output_context ctx = {0};
! 449: int encoding, rv;
1.1 misho 450:
1.1.1.2 ! misho 451: /*
! 452: * NOTE that the real ob_gzhandler is an alias to "zlib output compression".
! 453: * This is a really bad hack, because
! 454: * - we have to initialize a php_zlib_context on demand
! 455: * - we have to clean it up in RSHUTDOWN
! 456: * - OG(running) is not set or set to any other output handler
! 457: * - we have to mess around with php_output_context */
1.1 misho 458:
1.1.1.2 ! misho 459: if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &in_str, &in_len, &flags)) {
1.1 misho 460: RETURN_FALSE;
461: }
462:
1.1.1.2 ! misho 463: if (!(encoding = php_zlib_output_encoding(TSRMLS_C))) {
! 464: RETURN_FALSE;
1.1 misho 465: }
466:
1.1.1.2 ! misho 467: if (flags & PHP_OUTPUT_HANDLER_START) {
! 468: switch (encoding) {
! 469: case PHP_ZLIB_ENCODING_GZIP:
! 470: sapi_add_header_ex(ZEND_STRL("Content-Encoding: gzip"), 1, 1 TSRMLS_CC);
! 471: break;
! 472: case PHP_ZLIB_ENCODING_DEFLATE:
! 473: sapi_add_header_ex(ZEND_STRL("Content-Encoding: deflate"), 1, 1 TSRMLS_CC);
! 474: break;
! 475: }
! 476: sapi_add_header_ex(ZEND_STRL("Vary: Accept-Encoding"), 1, 1 TSRMLS_CC);
1.1 misho 477: }
478:
1.1.1.2 ! misho 479: if (!ZLIBG(ob_gzhandler)) {
! 480: ZLIBG(ob_gzhandler) = php_zlib_output_handler_context_init(TSRMLS_C);
1.1 misho 481: }
482:
1.1.1.2 ! misho 483: TSRMLS_SET_CTX(ctx.tsrm_ls);
! 484: ctx.op = flags;
! 485: ctx.in.data = in_str;
! 486: ctx.in.used = in_len;
! 487:
! 488: rv = php_zlib_output_handler_ex(ZLIBG(ob_gzhandler), &ctx);
! 489:
! 490: if (SUCCESS != rv) {
! 491: if (ctx.out.data && ctx.out.free) {
! 492: efree(ctx.out.data);
! 493: }
! 494: php_zlib_cleanup_ob_gzhandler_mess(TSRMLS_C);
! 495: RETURN_FALSE;
1.1 misho 496: }
497:
1.1.1.2 ! misho 498: if (ctx.out.data) {
! 499: RETVAL_STRINGL(ctx.out.data, ctx.out.used, 1);
! 500: if (ctx.out.free) {
! 501: efree(ctx.out.data);
! 502: }
1.1 misho 503: } else {
1.1.1.2 ! misho 504: RETVAL_EMPTY_STRING();
1.1 misho 505: }
506: }
507: /* }}} */
508:
1.1.1.2 ! misho 509: /* {{{ proto string zlib_get_coding_type(void)
! 510: Returns the coding type used for output compression */
! 511: static PHP_FUNCTION(zlib_get_coding_type)
! 512: {
! 513: if (zend_parse_parameters_none() == FAILURE) {
1.1 misho 514: return;
515: }
1.1.1.2 ! misho 516: switch (ZLIBG(compression_coding)) {
! 517: case PHP_ZLIB_ENCODING_GZIP:
! 518: RETURN_STRINGL("gzip", sizeof("gzip") - 1, 1);
! 519: case PHP_ZLIB_ENCODING_DEFLATE:
! 520: RETURN_STRINGL("deflate", sizeof("deflate") - 1, 1);
! 521: default:
! 522: RETURN_FALSE;
1.1 misho 523: }
524: }
525: /* }}} */
526:
1.1.1.2 ! misho 527: /* {{{ proto array gzfile(string filename [, int use_include_path])
! 528: Read and uncompress entire .gz-file into an array */
! 529: static PHP_FUNCTION(gzfile)
! 530: {
! 531: char *filename;
! 532: int filename_len;
! 533: int flags = REPORT_ERRORS;
! 534: char buf[8192] = {0};
! 535: register int i = 0;
! 536: long use_include_path = 0;
! 537: php_stream *stream;
1.1 misho 538:
1.1.1.2 ! misho 539: if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|l", &filename, &filename_len, &use_include_path)) {
1.1 misho 540: return;
541: }
542:
1.1.1.2 ! misho 543: if (use_include_path) {
! 544: flags |= USE_PATH;
1.1 misho 545: }
546:
1.1.1.2 ! misho 547: /* using a stream here is a bit more efficient (resource wise) than php_gzopen_wrapper */
! 548: stream = php_stream_gzopen(NULL, filename, "rb", flags, NULL, NULL STREAMS_CC TSRMLS_CC);
1.1 misho 549:
1.1.1.2 ! misho 550: if (!stream) {
! 551: /* Error reporting is already done by stream code */
1.1 misho 552: RETURN_FALSE;
553: }
554:
1.1.1.2 ! misho 555: /* Initialize return array */
! 556: array_init(return_value);
1.1 misho 557:
1.1.1.2 ! misho 558: /* Now loop through the file and do the magic quotes thing if needed */
! 559: memset(buf, 0, sizeof(buf));
! 560:
! 561: while (php_stream_gets(stream, buf, sizeof(buf) - 1) != NULL) {
! 562: add_index_string(return_value, i++, buf, 1);
1.1 misho 563: }
1.1.1.2 ! misho 564: php_stream_close(stream);
1.1 misho 565: }
566: /* }}} */
567:
1.1.1.2 ! misho 568: /* {{{ proto resource gzopen(string filename, string mode [, int use_include_path])
! 569: Open a .gz-file and return a .gz-file pointer */
! 570: static PHP_FUNCTION(gzopen)
! 571: {
! 572: char *filename;
! 573: char *mode;
! 574: int filename_len, mode_len;
! 575: int flags = REPORT_ERRORS;
! 576: php_stream *stream;
! 577: long use_include_path = 0;
1.1 misho 578:
1.1.1.2 ! misho 579: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &filename, &filename_len, &mode, &mode_len, &use_include_path) == FAILURE) {
1.1 misho 580: return;
581: }
582:
1.1.1.2 ! misho 583: if (use_include_path) {
! 584: flags |= USE_PATH;
1.1 misho 585: }
586:
1.1.1.2 ! misho 587: stream = php_stream_gzopen(NULL, filename, mode, flags, NULL, NULL STREAMS_CC TSRMLS_CC);
1.1 misho 588:
1.1.1.2 ! misho 589: if (!stream) {
1.1 misho 590: RETURN_FALSE;
591: }
1.1.1.2 ! misho 592: php_stream_to_zval(stream, return_value);
! 593: }
! 594: /* }}} */
1.1 misho 595:
1.1.1.2 ! misho 596: /* {{{ proto int readgzfile(string filename [, int use_include_path])
! 597: Output a .gz-file */
! 598: static PHP_FUNCTION(readgzfile)
! 599: {
! 600: char *filename;
! 601: int filename_len;
! 602: int flags = REPORT_ERRORS;
! 603: php_stream *stream;
! 604: int size;
! 605: long use_include_path = 0;
1.1 misho 606:
1.1.1.2 ! misho 607: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &filename, &filename_len, &use_include_path) == FAILURE) {
! 608: return;
! 609: }
1.1 misho 610:
1.1.1.2 ! misho 611: if (use_include_path) {
! 612: flags |= USE_PATH;
1.1 misho 613: }
614:
1.1.1.2 ! misho 615: stream = php_stream_gzopen(NULL, filename, "rb", flags, NULL, NULL STREAMS_CC TSRMLS_CC);
! 616:
! 617: if (!stream) {
1.1 misho 618: RETURN_FALSE;
619: }
1.1.1.2 ! misho 620: size = php_stream_passthru(stream);
! 621: php_stream_close(stream);
! 622: RETURN_LONG(size);
1.1 misho 623: }
624: /* }}} */
625:
1.1.1.2 ! misho 626: #define PHP_ZLIB_ENCODE_FUNC(name, default_encoding) \
! 627: static PHP_FUNCTION(name) \
! 628: { \
! 629: char *in_buf, *out_buf; \
! 630: int in_len; \
! 631: size_t out_len; \
! 632: long level = -1; \
! 633: long encoding = default_encoding; \
! 634: if (default_encoding) { \
! 635: if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &in_buf, &in_len, &level, &encoding)) { \
! 636: return; \
! 637: } \
! 638: } else { \
! 639: if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|l", &in_buf, &in_len, &encoding, &level)) { \
! 640: return; \
! 641: } \
! 642: } \
! 643: if (level < -1 || level > 9) { \
! 644: php_error_docref(NULL TSRMLS_CC, E_WARNING, "compression level (%ld) must be within -1..9", level); \
! 645: RETURN_FALSE; \
! 646: } \
! 647: switch (encoding) { \
! 648: case PHP_ZLIB_ENCODING_RAW: \
! 649: case PHP_ZLIB_ENCODING_GZIP: \
! 650: case PHP_ZLIB_ENCODING_DEFLATE: \
! 651: break; \
! 652: default: \
! 653: php_error_docref(NULL TSRMLS_CC, E_WARNING, "encoding mode must be either ZLIB_ENCODING_RAW, ZLIB_ENCODING_GZIP or ZLIB_ENCODING_DEFLATE"); \
! 654: RETURN_FALSE; \
! 655: } \
! 656: if (SUCCESS != php_zlib_encode(in_buf, in_len, &out_buf, &out_len, encoding, level TSRMLS_CC)) { \
! 657: RETURN_FALSE; \
! 658: } \
! 659: RETURN_STRINGL(out_buf, out_len, 0); \
! 660: }
! 661:
! 662: #define PHP_ZLIB_DECODE_FUNC(name, encoding) \
! 663: static PHP_FUNCTION(name) \
! 664: { \
! 665: char *in_buf, *out_buf; \
! 666: int in_len; \
! 667: size_t out_len; \
! 668: long max_len = 0; \
! 669: if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &in_buf, &in_len, &max_len)) { \
! 670: return; \
! 671: } \
! 672: if (max_len < 0) { \
! 673: php_error_docref(NULL TSRMLS_CC, E_WARNING, "length (%ld) must be greater or equal zero", max_len); \
! 674: RETURN_FALSE; \
! 675: } \
! 676: if (SUCCESS != php_zlib_decode(in_buf, in_len, &out_buf, &out_len, encoding, max_len TSRMLS_CC)) { \
! 677: RETURN_FALSE; \
! 678: } \
! 679: RETURN_STRINGL(out_buf, out_len, 0); \
! 680: }
! 681:
! 682: /* {{{ proto binary zlib_encode(binary data, int encoding[, int level = -1])
! 683: Compress data with the specified encoding */
! 684: PHP_ZLIB_ENCODE_FUNC(zlib_encode, 0);
! 685: /* }}} */
! 686:
! 687: /* {{{ proto binary zlib_decode(binary data[, int max_decoded_len])
! 688: Uncompress any raw/gzip/zlib encoded data */
! 689: PHP_ZLIB_DECODE_FUNC(zlib_decode, PHP_ZLIB_ENCODING_ANY);
! 690:
! 691: /* NOTE: The naming of these userland functions was quite unlucky */
! 692: /* {{{ proto binary gzdeflate(binary data[, int level = -1[, int encoding = ZLIB_ENCODING_RAW])
! 693: Encode data with the raw deflate encoding */
! 694: PHP_ZLIB_ENCODE_FUNC(gzdeflate, PHP_ZLIB_ENCODING_RAW);
! 695: /* }}} */
! 696:
! 697: /* {{{ proto binary gzencode(binary data[, int level = -1[, int encoding = ZLIB_ENCODING_GZIP])
! 698: Encode data with the gzip encoding */
! 699: PHP_ZLIB_ENCODE_FUNC(gzencode, PHP_ZLIB_ENCODING_GZIP);
! 700: /* }}} */
! 701: /* {{{ proto binary gzcompress(binary data[, int level = -1[, int encoding = ZLIB_ENCODING_DEFLATE])
! 702: Encode data with the zlib encoding */
! 703: PHP_ZLIB_ENCODE_FUNC(gzcompress, PHP_ZLIB_ENCODING_DEFLATE);
! 704: /* }}} */
! 705: /* {{{ proto binary gzinflate(binary data[, int max_decoded_len])
! 706: Decode raw deflate encoded data */
! 707: PHP_ZLIB_DECODE_FUNC(gzinflate, PHP_ZLIB_ENCODING_RAW);
! 708: /* }}} */
! 709: /* {{{ proto binary gzdecode(binary data[, int max_decoded_len])
! 710: Decode gzip encoded data */
! 711: PHP_ZLIB_DECODE_FUNC(gzdecode, PHP_ZLIB_ENCODING_GZIP);
! 712: /* }}} */
! 713: /* {{{ proto binary gzuncompress(binary data[, int max_decoded_len])
! 714: Decode zlib encoded data */
! 715: PHP_ZLIB_DECODE_FUNC(gzuncompress, PHP_ZLIB_ENCODING_DEFLATE);
! 716: /* }}} */
1.1 misho 717:
1.1.1.2 ! misho 718: #ifdef COMPILE_DL_ZLIB
! 719: ZEND_GET_MODULE(php_zlib)
! 720: #endif
1.1 misho 721:
1.1.1.2 ! misho 722: /* {{{ arginfo */
! 723: ZEND_BEGIN_ARG_INFO_EX(arginfo_ob_gzhandler, 0, 0, 2)
! 724: ZEND_ARG_INFO(0, data)
! 725: ZEND_ARG_INFO(0, flags)
! 726: ZEND_END_ARG_INFO()
1.1 misho 727:
1.1.1.2 ! misho 728: ZEND_BEGIN_ARG_INFO(arginfo_zlib_get_coding_type, 0)
! 729: ZEND_END_ARG_INFO()
! 730:
! 731: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzfile, 0, 0, 1)
! 732: ZEND_ARG_INFO(0, filename)
! 733: ZEND_ARG_INFO(0, use_include_path)
! 734: ZEND_END_ARG_INFO()
! 735:
! 736: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzopen, 0, 0, 2)
! 737: ZEND_ARG_INFO(0, filename)
! 738: ZEND_ARG_INFO(0, mode)
! 739: ZEND_ARG_INFO(0, use_include_path)
! 740: ZEND_END_ARG_INFO()
1.1 misho 741:
1.1.1.2 ! misho 742: ZEND_BEGIN_ARG_INFO_EX(arginfo_readgzfile, 0, 0, 1)
! 743: ZEND_ARG_INFO(0, filename)
! 744: ZEND_ARG_INFO(0, use_include_path)
! 745: ZEND_END_ARG_INFO()
1.1 misho 746:
1.1.1.2 ! misho 747: ZEND_BEGIN_ARG_INFO_EX(arginfo_zlib_encode, 0, 0, 2)
! 748: ZEND_ARG_INFO(0, data)
! 749: ZEND_ARG_INFO(0, encoding)
! 750: ZEND_ARG_INFO(0, level)
! 751: ZEND_END_ARG_INFO()
1.1 misho 752:
1.1.1.2 ! misho 753: ZEND_BEGIN_ARG_INFO_EX(arginfo_zlib_decode, 0, 0, 1)
! 754: ZEND_ARG_INFO(0, data)
! 755: ZEND_ARG_INFO(0, max_decoded_len)
! 756: ZEND_END_ARG_INFO()
1.1 misho 757:
1.1.1.2 ! misho 758: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzdeflate, 0, 0, 1)
! 759: ZEND_ARG_INFO(0, data)
! 760: ZEND_ARG_INFO(0, level)
! 761: ZEND_ARG_INFO(0, encoding)
! 762: ZEND_END_ARG_INFO()
1.1 misho 763:
1.1.1.2 ! misho 764: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzencode, 0, 0, 1)
! 765: ZEND_ARG_INFO(0, data)
! 766: ZEND_ARG_INFO(0, level)
! 767: ZEND_ARG_INFO(0, encoding)
! 768: ZEND_END_ARG_INFO()
1.1 misho 769:
1.1.1.2 ! misho 770: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzcompress, 0, 0, 1)
! 771: ZEND_ARG_INFO(0, data)
! 772: ZEND_ARG_INFO(0, level)
! 773: ZEND_ARG_INFO(0, encoding)
! 774: ZEND_END_ARG_INFO()
1.1 misho 775:
1.1.1.2 ! misho 776: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzinflate, 0, 0, 1)
! 777: ZEND_ARG_INFO(0, data)
! 778: ZEND_ARG_INFO(0, max_decoded_len)
! 779: ZEND_END_ARG_INFO()
1.1 misho 780:
1.1.1.2 ! misho 781: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzdecode, 0, 0, 1)
! 782: ZEND_ARG_INFO(0, data)
! 783: ZEND_ARG_INFO(0, max_decoded_len)
! 784: ZEND_END_ARG_INFO()
1.1 misho 785:
1.1.1.2 ! misho 786: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzuncompress, 0, 0, 1)
! 787: ZEND_ARG_INFO(0, data)
! 788: ZEND_ARG_INFO(0, max_decoded_len)
! 789: ZEND_END_ARG_INFO()
1.1 misho 790:
1.1.1.2 ! misho 791: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzputs, 0, 0, 2)
! 792: ZEND_ARG_INFO(0, fp)
! 793: ZEND_ARG_INFO(0, str)
! 794: ZEND_ARG_INFO(0, length)
! 795: ZEND_END_ARG_INFO()
1.1 misho 796:
1.1.1.2 ! misho 797: ZEND_BEGIN_ARG_INFO(arginfo_gzpassthru, 0)
! 798: ZEND_ARG_INFO(0, fp)
! 799: ZEND_END_ARG_INFO()
1.1 misho 800:
1.1.1.2 ! misho 801: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzseek, 0, 0, 2)
! 802: ZEND_ARG_INFO(0, fp)
! 803: ZEND_ARG_INFO(0, offset)
! 804: ZEND_ARG_INFO(0, whence)
! 805: ZEND_END_ARG_INFO()
1.1 misho 806:
1.1.1.2 ! misho 807: ZEND_BEGIN_ARG_INFO(arginfo_gzread, 0)
! 808: ZEND_ARG_INFO(0, fp)
! 809: ZEND_ARG_INFO(0, length)
! 810: ZEND_END_ARG_INFO()
1.1 misho 811:
1.1.1.2 ! misho 812: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzgetss, 0, 0, 1)
! 813: ZEND_ARG_INFO(0, fp)
! 814: ZEND_ARG_INFO(0, length)
! 815: ZEND_ARG_INFO(0, allowable_tags)
! 816: ZEND_END_ARG_INFO()
1.1 misho 817:
1.1.1.2 ! misho 818: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzgets, 0, 0, 1)
! 819: ZEND_ARG_INFO(0, fp)
! 820: ZEND_ARG_INFO(0, length)
! 821: ZEND_END_ARG_INFO()
1.1 misho 822: /* }}} */
823:
1.1.1.2 ! misho 824: /* {{{ php_zlib_functions[] */
! 825: static const zend_function_entry php_zlib_functions[] = {
! 826: PHP_FE(readgzfile, arginfo_readgzfile)
! 827: PHP_FALIAS(gzrewind, rewind, arginfo_gzpassthru)
! 828: PHP_FALIAS(gzclose, fclose, arginfo_gzpassthru)
! 829: PHP_FALIAS(gzeof, feof, arginfo_gzpassthru)
! 830: PHP_FALIAS(gzgetc, fgetc, arginfo_gzpassthru)
! 831: PHP_FALIAS(gzgets, fgets, arginfo_gzgets)
! 832: PHP_FALIAS(gzgetss, fgetss, arginfo_gzgetss)
! 833: PHP_FALIAS(gzread, fread, arginfo_gzread)
! 834: PHP_FE(gzopen, arginfo_gzopen)
! 835: PHP_FALIAS(gzpassthru, fpassthru, arginfo_gzpassthru)
! 836: PHP_FALIAS(gzseek, fseek, arginfo_gzseek)
! 837: PHP_FALIAS(gztell, ftell, arginfo_gzpassthru)
! 838: PHP_FALIAS(gzwrite, fwrite, arginfo_gzputs)
! 839: PHP_FALIAS(gzputs, fwrite, arginfo_gzputs)
! 840: PHP_FE(gzfile, arginfo_gzfile)
! 841: PHP_FE(gzcompress, arginfo_gzcompress)
! 842: PHP_FE(gzuncompress, arginfo_gzuncompress)
! 843: PHP_FE(gzdeflate, arginfo_gzdeflate)
! 844: PHP_FE(gzinflate, arginfo_gzinflate)
! 845: PHP_FE(gzencode, arginfo_gzencode)
! 846: PHP_FE(gzdecode, arginfo_gzdecode)
! 847: PHP_FE(zlib_encode, arginfo_zlib_encode)
! 848: PHP_FE(zlib_decode, arginfo_zlib_decode)
! 849: PHP_FE(zlib_get_coding_type, arginfo_zlib_get_coding_type)
! 850: PHP_FE(ob_gzhandler, arginfo_ob_gzhandler)
! 851: PHP_FE_END
! 852: };
! 853: /* }}} */
1.1 misho 854:
1.1.1.2 ! misho 855: /* {{{ OnUpdate_zlib_output_compression */
! 856: static PHP_INI_MH(OnUpdate_zlib_output_compression)
! 857: {
! 858: int status, int_value;
! 859: char *ini_value;
1.1 misho 860:
1.1.1.2 ! misho 861: if (new_value == NULL) {
! 862: return FAILURE;
1.1 misho 863: }
864:
1.1.1.2 ! misho 865: if (!strncasecmp(new_value, "off", sizeof("off"))) {
! 866: new_value = "0";
! 867: new_value_length = sizeof("0");
! 868: } else if (!strncasecmp(new_value, "on", sizeof("on"))) {
! 869: new_value = "1";
! 870: new_value_length = sizeof("1");
1.1 misho 871: }
872:
1.1.1.2 ! misho 873: int_value = zend_atoi(new_value, new_value_length);
! 874: ini_value = zend_ini_string("output_handler", sizeof("output_handler"), 0);
1.1 misho 875:
1.1.1.2 ! misho 876: if (ini_value && *ini_value && int_value) {
! 877: php_error_docref("ref.outcontrol" TSRMLS_CC, E_CORE_ERROR, "Cannot use both zlib.output_compression and output_handler together!!");
! 878: return FAILURE;
1.1 misho 879: }
1.1.1.2 ! misho 880: if (stage == PHP_INI_STAGE_RUNTIME) {
! 881: status = php_output_get_status(TSRMLS_C);
! 882: if (status & PHP_OUTPUT_SENT) {
! 883: php_error_docref("ref.outcontrol" TSRMLS_CC, E_WARNING, "Cannot change zlib.output_compression - headers already sent");
! 884: return FAILURE;
! 885: } else if ((status & PHP_OUTPUT_WRITTEN) && int_value) {
! 886: php_error_docref("ref.outcontrol" TSRMLS_CC, E_WARNING, "Cannot enable zlib.output_compression - there has already been output");
! 887: return FAILURE;
1.1 misho 888: }
889: }
890:
1.1.1.2 ! misho 891: status = OnUpdateLong(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
! 892:
! 893: if (stage == PHP_INI_STAGE_RUNTIME && int_value) {
! 894: if (!php_output_handler_started(ZEND_STRL(PHP_ZLIB_OUTPUT_HANDLER_NAME) TSRMLS_CC)) {
! 895: php_zlib_output_compression_start(TSRMLS_C);
1.1 misho 896: }
897: }
1.1.1.2 ! misho 898:
! 899: return status;
1.1 misho 900: }
901: /* }}} */
902:
1.1.1.2 ! misho 903: /* {{{ OnUpdate_zlib_output_handler */
! 904: static PHP_INI_MH(OnUpdate_zlib_output_handler)
1.1 misho 905: {
1.1.1.2 ! misho 906: if (stage == PHP_INI_STAGE_RUNTIME && (php_output_get_status(TSRMLS_C) & PHP_OUTPUT_SENT)) {
! 907: php_error_docref("ref.outcontrol" TSRMLS_CC, E_WARNING, "Cannot change zlib.output_handler - headers already sent");
! 908: return FAILURE;
1.1 misho 909: }
910:
1.1.1.2 ! misho 911: return OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
1.1 misho 912: }
1.1.1.2 ! misho 913: /* }}} */
! 914:
! 915: /* {{{ INI */
! 916: PHP_INI_BEGIN()
! 917: STD_PHP_INI_BOOLEAN("zlib.output_compression", "0", PHP_INI_ALL, OnUpdate_zlib_output_compression, output_compression, zend_zlib_globals, zlib_globals)
! 918: STD_PHP_INI_ENTRY("zlib.output_compression_level", "-1", PHP_INI_ALL, OnUpdateLong, output_compression_level, zend_zlib_globals, zlib_globals)
! 919: STD_PHP_INI_ENTRY("zlib.output_handler", "", PHP_INI_ALL, OnUpdate_zlib_output_handler, output_handler, zend_zlib_globals, zlib_globals)
! 920: PHP_INI_END()
1.1 misho 921:
922: /* }}} */
923:
1.1.1.2 ! misho 924: /* {{{ PHP_MINIT_FUNCTION */
! 925: static PHP_MINIT_FUNCTION(zlib)
1.1 misho 926: {
1.1.1.2 ! misho 927: php_register_url_stream_wrapper("compress.zlib", &php_stream_gzip_wrapper TSRMLS_CC);
! 928: php_stream_filter_register_factory("zlib.*", &php_zlib_filter_factory TSRMLS_CC);
1.1 misho 929:
1.1.1.2 ! misho 930: php_output_handler_alias_register(ZEND_STRL("ob_gzhandler"), php_zlib_output_handler_init TSRMLS_CC);
! 931: php_output_handler_conflict_register(ZEND_STRL("ob_gzhandler"), php_zlib_output_conflict_check TSRMLS_CC);
! 932: php_output_handler_conflict_register(ZEND_STRL(PHP_ZLIB_OUTPUT_HANDLER_NAME), php_zlib_output_conflict_check TSRMLS_CC);
! 933:
! 934: REGISTER_LONG_CONSTANT("FORCE_GZIP", PHP_ZLIB_ENCODING_GZIP, CONST_CS|CONST_PERSISTENT);
! 935: REGISTER_LONG_CONSTANT("FORCE_DEFLATE", PHP_ZLIB_ENCODING_DEFLATE, CONST_CS|CONST_PERSISTENT);
! 936:
! 937: REGISTER_LONG_CONSTANT("ZLIB_ENCODING_RAW", PHP_ZLIB_ENCODING_RAW, CONST_CS|CONST_PERSISTENT);
! 938: REGISTER_LONG_CONSTANT("ZLIB_ENCODING_GZIP", PHP_ZLIB_ENCODING_GZIP, CONST_CS|CONST_PERSISTENT);
! 939: REGISTER_LONG_CONSTANT("ZLIB_ENCODING_DEFLATE", PHP_ZLIB_ENCODING_DEFLATE, CONST_CS|CONST_PERSISTENT);
! 940: REGISTER_INI_ENTRIES();
! 941: return SUCCESS;
1.1 misho 942: }
943: /* }}} */
944:
1.1.1.2 ! misho 945: /* {{{ PHP_MSHUTDOWN_FUNCTION */
! 946: static PHP_MSHUTDOWN_FUNCTION(zlib)
1.1 misho 947: {
1.1.1.2 ! misho 948: php_unregister_url_stream_wrapper("zlib" TSRMLS_CC);
! 949: php_stream_filter_unregister_factory("zlib.*" TSRMLS_CC);
1.1 misho 950:
1.1.1.2 ! misho 951: UNREGISTER_INI_ENTRIES();
1.1 misho 952:
1.1.1.2 ! misho 953: return SUCCESS;
1.1 misho 954: }
955: /* }}} */
956:
1.1.1.2 ! misho 957: /* {{{ PHP_RINIT_FUNCTION */
! 958: static PHP_RINIT_FUNCTION(zlib)
1.1 misho 959: {
1.1.1.2 ! misho 960: ZLIBG(compression_coding) = 0;
1.1 misho 961:
1.1.1.2 ! misho 962: php_zlib_output_compression_start(TSRMLS_C);
1.1 misho 963:
1.1.1.2 ! misho 964: return SUCCESS;
! 965: }
! 966: /* }}} */
1.1 misho 967:
1.1.1.2 ! misho 968: static PHP_RSHUTDOWN_FUNCTION(zlib)
! 969: {
! 970: ZLIBG(output_compression) = 0;
! 971: php_zlib_cleanup_ob_gzhandler_mess(TSRMLS_C);
1.1 misho 972:
1.1.1.2 ! misho 973: return SUCCESS;
! 974: }
1.1 misho 975:
1.1.1.2 ! misho 976: /* {{{ PHP_MINFO_FUNCTION */
! 977: static PHP_MINFO_FUNCTION(zlib)
! 978: {
! 979: php_info_print_table_start();
! 980: php_info_print_table_header(2, "ZLib Support", "enabled");
! 981: php_info_print_table_row(2, "Stream Wrapper", "compress.zlib://");
! 982: php_info_print_table_row(2, "Stream Filter", "zlib.inflate, zlib.deflate");
! 983: php_info_print_table_row(2, "Compiled Version", ZLIB_VERSION);
! 984: php_info_print_table_row(2, "Linked Version", (char *) zlibVersion());
! 985: php_info_print_table_end();
1.1 misho 986:
1.1.1.2 ! misho 987: DISPLAY_INI_ENTRIES();
1.1 misho 988: }
989: /* }}} */
990:
1.1.1.2 ! misho 991: /* {{{ ZEND_MODULE_GLOBALS_CTOR */
! 992: static ZEND_MODULE_GLOBALS_CTOR_D(zlib)
1.1 misho 993: {
1.1.1.2 ! misho 994: zlib_globals->ob_gzhandler = NULL;
1.1 misho 995: }
996: /* }}} */
997:
1.1.1.2 ! misho 998: /* {{{ php_zlib_module_entry */
! 999: zend_module_entry php_zlib_module_entry = {
! 1000: STANDARD_MODULE_HEADER,
! 1001: "zlib",
! 1002: php_zlib_functions,
! 1003: PHP_MINIT(zlib),
! 1004: PHP_MSHUTDOWN(zlib),
! 1005: PHP_RINIT(zlib),
! 1006: PHP_RSHUTDOWN(zlib),
! 1007: PHP_MINFO(zlib),
! 1008: "2.0",
! 1009: PHP_MODULE_GLOBALS(zlib),
! 1010: ZEND_MODULE_GLOBALS_CTOR_N(zlib),
! 1011: NULL,
! 1012: NULL,
! 1013: STANDARD_MODULE_PROPERTIES_EX
! 1014: };
! 1015: /* }}} */
! 1016:
1.1 misho 1017: /*
1018: * Local variables:
1019: * tab-width: 4
1020: * c-basic-offset: 4
1021: * End:
1022: * vim600: sw=4 ts=4 fdm=marker
1023: * vim<600: sw=4 ts=4
1024: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>