Annotation of embedaddon/php/ext/zlib/zlib.c, revision 1.1.1.3
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | PHP Version 5 |
4: +----------------------------------------------------------------------+
1.1.1.3 ! misho 5: | Copyright (c) 1997-2013 The PHP Group |
1.1 misho 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: */
1.1.1.3 ! misho 190: if ((output_context->op & PHP_OUTPUT_HANDLER_START)
! 191: && (output_context->op != (PHP_OUTPUT_HANDLER_START|PHP_OUTPUT_HANDLER_CLEAN|PHP_OUTPUT_HANDLER_FINAL))
! 192: ) {
1.1.1.2 misho 193: sapi_add_header_ex(ZEND_STRL("Vary: Accept-Encoding"), 1, 1 TSRMLS_CC);
194: }
195: return FAILURE;
196: }
1.1 misho 197:
1.1.1.2 misho 198: if (SUCCESS != php_zlib_output_handler_ex(ctx, output_context)) {
1.1 misho 199: return FAILURE;
200: }
201:
1.1.1.2 misho 202: if (!(output_context->op & PHP_OUTPUT_HANDLER_CLEAN)) {
203: int flags;
204:
205: if (SUCCESS == php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_GET_FLAGS, &flags TSRMLS_CC)) {
206: /* only run this once */
207: if (!(flags & PHP_OUTPUT_HANDLER_STARTED)) {
208: if (SG(headers_sent) || !ZLIBG(output_compression)) {
209: deflateEnd(&ctx->Z);
210: return FAILURE;
211: }
212: switch (ZLIBG(compression_coding)) {
213: case PHP_ZLIB_ENCODING_GZIP:
214: sapi_add_header_ex(ZEND_STRL("Content-Encoding: gzip"), 1, 1 TSRMLS_CC);
215: break;
216: case PHP_ZLIB_ENCODING_DEFLATE:
217: sapi_add_header_ex(ZEND_STRL("Content-Encoding: deflate"), 1, 1 TSRMLS_CC);
218: break;
219: default:
220: deflateEnd(&ctx->Z);
221: return FAILURE;
222: }
223: sapi_add_header_ex(ZEND_STRL("Vary: Accept-Encoding"), 1, 1 TSRMLS_CC);
224: php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_IMMUTABLE, NULL TSRMLS_CC);
225: }
226: }
227: }
1.1 misho 228:
229: return SUCCESS;
230: }
231: /* }}} */
232:
1.1.1.2 misho 233: /* {{{ php_zlib_output_handler_context_init() */
234: static php_zlib_context *php_zlib_output_handler_context_init(TSRMLS_D)
1.1 misho 235: {
1.1.1.2 misho 236: php_zlib_context *ctx = (php_zlib_context *) ecalloc(1, sizeof(php_zlib_context));
237: ctx->Z.zalloc = php_zlib_alloc;
238: ctx->Z.zfree = php_zlib_free;
239: return ctx;
1.1 misho 240: }
241: /* }}} */
242:
1.1.1.2 misho 243: /* {{{ php_zlib_output_handler_context_dtor() */
244: static void php_zlib_output_handler_context_dtor(void *opaq TSRMLS_DC)
1.1 misho 245: {
1.1.1.2 misho 246: php_zlib_context *ctx = (php_zlib_context *) opaq;
1.1 misho 247:
1.1.1.2 misho 248: if (ctx) {
249: if (ctx->buffer.data) {
250: efree(ctx->buffer.data);
251: }
252: efree(ctx);
253: }
1.1 misho 254: }
255: /* }}} */
256:
1.1.1.2 misho 257: /* {{{ php_zlib_output_handler_init() */
258: 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 259: {
1.1.1.2 misho 260: php_output_handler *h = NULL;
1.1 misho 261:
1.1.1.2 misho 262: if (!ZLIBG(output_compression)) {
263: ZLIBG(output_compression) = chunk_size ? chunk_size : PHP_OUTPUT_HANDLER_DEFAULT_SIZE;
264: }
1.1 misho 265:
1.1.1.3 ! misho 266: ZLIBG(handler_registered) = 1;
! 267:
1.1.1.2 misho 268: if ((h = php_output_handler_create_internal(handler_name, handler_name_len, php_zlib_output_handler, chunk_size, flags TSRMLS_CC))) {
269: php_output_handler_set_context(h, php_zlib_output_handler_context_init(TSRMLS_C), php_zlib_output_handler_context_dtor TSRMLS_CC);
270: }
271:
272: return h;
1.1 misho 273: }
274: /* }}} */
275:
1.1.1.2 misho 276: /* {{{ php_zlib_output_compression_start() */
277: static void php_zlib_output_compression_start(TSRMLS_D)
1.1 misho 278: {
1.1.1.2 misho 279: zval *zoh;
280: php_output_handler *h;
1.1 misho 281:
1.1.1.2 misho 282: switch (ZLIBG(output_compression)) {
283: case 0:
284: break;
285: case 1:
286: ZLIBG(output_compression) = PHP_OUTPUT_HANDLER_DEFAULT_SIZE;
287: /* break omitted intentionally */
288: default:
1.1.1.3 ! misho 289: if ( php_zlib_output_encoding(TSRMLS_C) &&
! 290: (h = php_zlib_output_handler_init(ZEND_STRL(PHP_ZLIB_OUTPUT_HANDLER_NAME), ZLIBG(output_compression), PHP_OUTPUT_HANDLER_STDFLAGS TSRMLS_CC)) &&
1.1.1.2 misho 291: (SUCCESS == php_output_handler_start(h TSRMLS_CC))) {
292: if (ZLIBG(output_handler) && *ZLIBG(output_handler)) {
293: MAKE_STD_ZVAL(zoh);
294: ZVAL_STRING(zoh, ZLIBG(output_handler), 1);
295: php_output_start_user(zoh, ZLIBG(output_compression), PHP_OUTPUT_HANDLER_STDFLAGS TSRMLS_CC);
296: zval_ptr_dtor(&zoh);
297: }
298: }
299: break;
300: }
1.1 misho 301: }
302: /* }}} */
303:
1.1.1.2 misho 304: /* {{{ php_zlib_encode() */
305: 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 306: {
1.1.1.2 misho 307: int status;
308: z_stream Z;
1.1 misho 309:
1.1.1.2 misho 310: memset(&Z, 0, sizeof(z_stream));
311: Z.zalloc = php_zlib_alloc;
312: Z.zfree = php_zlib_free;
313:
314: if (Z_OK == (status = deflateInit2(&Z, level, Z_DEFLATED, encoding, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY))) {
315: *out_len = PHP_ZLIB_BUFFER_SIZE_GUESS(in_len);
316: *out_buf = emalloc(*out_len);
317:
318: Z.next_in = (Bytef *) in_buf;
319: Z.next_out = (Bytef *) *out_buf;
320: Z.avail_in = in_len;
321: Z.avail_out = *out_len;
322:
323: status = deflate(&Z, Z_FINISH);
324: deflateEnd(&Z);
325:
326: if (Z_STREAM_END == status) {
327: /* size buffer down to actual length */
328: *out_buf = erealloc(*out_buf, Z.total_out + 1);
329: (*out_buf)[*out_len = Z.total_out] = '\0';
330: return SUCCESS;
331: } else {
332: efree(*out_buf);
333: }
1.1 misho 334: }
335:
1.1.1.2 misho 336: *out_buf = NULL;
337: *out_len = 0;
1.1 misho 338:
1.1.1.2 misho 339: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", zError(status));
340: return FAILURE;
341: }
342: /* }}} */
1.1 misho 343:
1.1.1.2 misho 344: /* {{{ php_zlib_inflate_rounds() */
345: static inline int php_zlib_inflate_rounds(z_stream *Z, size_t max, char **buf, size_t *len)
346: {
347: int status, round = 0;
348: php_zlib_buffer buffer = {NULL, NULL, 0, 0, 0};
1.1 misho 349:
1.1.1.2 misho 350: *buf = NULL;
351: *len = 0;
1.1 misho 352:
1.1.1.2 misho 353: buffer.size = (max && (max < Z->avail_in)) ? max : Z->avail_in;
1.1 misho 354:
1.1.1.2 misho 355: do {
356: if ((max && (max <= buffer.used)) || !(buffer.aptr = erealloc_recoverable(buffer.data, buffer.size))) {
357: status = Z_MEM_ERROR;
1.1 misho 358: } else {
1.1.1.2 misho 359: buffer.data = buffer.aptr;
360: Z->avail_out = buffer.free = buffer.size - buffer.used;
361: Z->next_out = (Bytef *) buffer.data + buffer.used;
362: #if 0
363: 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);
364: #endif
365: status = inflate(Z, Z_NO_FLUSH);
366:
367: buffer.used += buffer.free - Z->avail_out;
368: buffer.free = Z->avail_out;
369: #if 0
370: 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);
371: #endif
372: buffer.size += (buffer.size >> 3) + 1;
1.1 misho 373: }
1.1.1.2 misho 374: } while ((Z_BUF_ERROR == status || (Z_OK == status && Z->avail_in)) && ++round < 100);
375:
376: if (status == Z_STREAM_END) {
377: buffer.data = erealloc(buffer.data, buffer.used + 1);
378: buffer.data[buffer.used] = '\0';
379: *buf = buffer.data;
380: *len = buffer.used;
381: } else {
382: if (buffer.data) {
383: efree(buffer.data);
384: }
385: /* HACK: See zlib/examples/zpipe.c inf() function for explanation. */
386: /* This works as long as this function is not used for streaming. Required to catch very short invalid data. */
387: status = (status == Z_OK) ? Z_DATA_ERROR : status;
1.1 misho 388: }
1.1.1.2 misho 389: return status;
1.1 misho 390: }
391: /* }}} */
392:
1.1.1.2 misho 393: /* {{{ php_zlib_decode() */
394: 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 395: {
1.1.1.2 misho 396: int status = Z_DATA_ERROR;
397: z_stream Z;
1.1 misho 398:
1.1.1.2 misho 399: memset(&Z, 0, sizeof(z_stream));
400: Z.zalloc = php_zlib_alloc;
401: Z.zfree = php_zlib_free;
402:
403: if (in_len) {
404: retry_raw_inflate:
405: status = inflateInit2(&Z, encoding);
406: if (Z_OK == status) {
407: Z.next_in = (Bytef *) in_buf;
408: Z.avail_in = in_len + 1; /* NOTE: data must be zero terminated */
409:
410: switch (status = php_zlib_inflate_rounds(&Z, max_len, out_buf, out_len)) {
411: case Z_STREAM_END:
412: inflateEnd(&Z);
413: return SUCCESS;
414:
415: case Z_DATA_ERROR:
416: /* raw deflated data? */
417: if (PHP_ZLIB_ENCODING_ANY == encoding) {
418: inflateEnd(&Z);
419: encoding = PHP_ZLIB_ENCODING_RAW;
420: goto retry_raw_inflate;
421: }
422: }
423: inflateEnd(&Z);
424: }
1.1 misho 425: }
426:
1.1.1.2 misho 427: *out_buf = NULL;
428: *out_len = 0;
1.1 misho 429:
1.1.1.2 misho 430: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", zError(status));
431: return FAILURE;
432: }
433: /* }}} */
1.1 misho 434:
1.1.1.2 misho 435: /* {{{ php_zlib_cleanup_ob_gzhandler_mess() */
436: static void php_zlib_cleanup_ob_gzhandler_mess(TSRMLS_D)
437: {
438: if (ZLIBG(ob_gzhandler)) {
439: deflateEnd(&(ZLIBG(ob_gzhandler)->Z));
440: php_zlib_output_handler_context_dtor(ZLIBG(ob_gzhandler) TSRMLS_CC);
441: ZLIBG(ob_gzhandler) = NULL;
1.1 misho 442: }
443: }
444: /* }}} */
445:
1.1.1.2 misho 446: /* {{{ proto string ob_gzhandler(string data, int flags)
447: Legacy hack */
448: static PHP_FUNCTION(ob_gzhandler)
1.1 misho 449: {
1.1.1.2 misho 450: char *in_str;
451: int in_len;
1.1 misho 452: long flags = 0;
1.1.1.2 misho 453: php_output_context ctx = {0};
454: int encoding, rv;
1.1 misho 455:
1.1.1.2 misho 456: /*
457: * NOTE that the real ob_gzhandler is an alias to "zlib output compression".
458: * This is a really bad hack, because
459: * - we have to initialize a php_zlib_context on demand
460: * - we have to clean it up in RSHUTDOWN
461: * - OG(running) is not set or set to any other output handler
462: * - we have to mess around with php_output_context */
1.1 misho 463:
1.1.1.2 misho 464: if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &in_str, &in_len, &flags)) {
1.1 misho 465: RETURN_FALSE;
466: }
467:
1.1.1.2 misho 468: if (!(encoding = php_zlib_output_encoding(TSRMLS_C))) {
469: RETURN_FALSE;
1.1 misho 470: }
471:
1.1.1.2 misho 472: if (flags & PHP_OUTPUT_HANDLER_START) {
473: switch (encoding) {
474: case PHP_ZLIB_ENCODING_GZIP:
475: sapi_add_header_ex(ZEND_STRL("Content-Encoding: gzip"), 1, 1 TSRMLS_CC);
476: break;
477: case PHP_ZLIB_ENCODING_DEFLATE:
478: sapi_add_header_ex(ZEND_STRL("Content-Encoding: deflate"), 1, 1 TSRMLS_CC);
479: break;
480: }
481: sapi_add_header_ex(ZEND_STRL("Vary: Accept-Encoding"), 1, 1 TSRMLS_CC);
1.1 misho 482: }
483:
1.1.1.2 misho 484: if (!ZLIBG(ob_gzhandler)) {
485: ZLIBG(ob_gzhandler) = php_zlib_output_handler_context_init(TSRMLS_C);
1.1 misho 486: }
487:
1.1.1.2 misho 488: TSRMLS_SET_CTX(ctx.tsrm_ls);
489: ctx.op = flags;
490: ctx.in.data = in_str;
491: ctx.in.used = in_len;
492:
493: rv = php_zlib_output_handler_ex(ZLIBG(ob_gzhandler), &ctx);
494:
495: if (SUCCESS != rv) {
496: if (ctx.out.data && ctx.out.free) {
497: efree(ctx.out.data);
498: }
499: php_zlib_cleanup_ob_gzhandler_mess(TSRMLS_C);
500: RETURN_FALSE;
1.1 misho 501: }
502:
1.1.1.2 misho 503: if (ctx.out.data) {
504: RETVAL_STRINGL(ctx.out.data, ctx.out.used, 1);
505: if (ctx.out.free) {
506: efree(ctx.out.data);
507: }
1.1 misho 508: } else {
1.1.1.2 misho 509: RETVAL_EMPTY_STRING();
1.1 misho 510: }
511: }
512: /* }}} */
513:
1.1.1.2 misho 514: /* {{{ proto string zlib_get_coding_type(void)
515: Returns the coding type used for output compression */
516: static PHP_FUNCTION(zlib_get_coding_type)
517: {
518: if (zend_parse_parameters_none() == FAILURE) {
1.1 misho 519: return;
520: }
1.1.1.2 misho 521: switch (ZLIBG(compression_coding)) {
522: case PHP_ZLIB_ENCODING_GZIP:
523: RETURN_STRINGL("gzip", sizeof("gzip") - 1, 1);
524: case PHP_ZLIB_ENCODING_DEFLATE:
525: RETURN_STRINGL("deflate", sizeof("deflate") - 1, 1);
526: default:
527: RETURN_FALSE;
1.1 misho 528: }
529: }
530: /* }}} */
531:
1.1.1.2 misho 532: /* {{{ proto array gzfile(string filename [, int use_include_path])
533: Read and uncompress entire .gz-file into an array */
534: static PHP_FUNCTION(gzfile)
535: {
536: char *filename;
537: int filename_len;
538: int flags = REPORT_ERRORS;
539: char buf[8192] = {0};
540: register int i = 0;
541: long use_include_path = 0;
542: php_stream *stream;
1.1 misho 543:
1.1.1.2 misho 544: if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|l", &filename, &filename_len, &use_include_path)) {
1.1 misho 545: return;
546: }
547:
1.1.1.2 misho 548: if (use_include_path) {
549: flags |= USE_PATH;
1.1 misho 550: }
551:
1.1.1.2 misho 552: /* using a stream here is a bit more efficient (resource wise) than php_gzopen_wrapper */
553: stream = php_stream_gzopen(NULL, filename, "rb", flags, NULL, NULL STREAMS_CC TSRMLS_CC);
1.1 misho 554:
1.1.1.2 misho 555: if (!stream) {
556: /* Error reporting is already done by stream code */
1.1 misho 557: RETURN_FALSE;
558: }
559:
1.1.1.2 misho 560: /* Initialize return array */
561: array_init(return_value);
1.1 misho 562:
1.1.1.2 misho 563: /* Now loop through the file and do the magic quotes thing if needed */
564: memset(buf, 0, sizeof(buf));
565:
566: while (php_stream_gets(stream, buf, sizeof(buf) - 1) != NULL) {
567: add_index_string(return_value, i++, buf, 1);
1.1 misho 568: }
1.1.1.2 misho 569: php_stream_close(stream);
1.1 misho 570: }
571: /* }}} */
572:
1.1.1.2 misho 573: /* {{{ proto resource gzopen(string filename, string mode [, int use_include_path])
574: Open a .gz-file and return a .gz-file pointer */
575: static PHP_FUNCTION(gzopen)
576: {
577: char *filename;
578: char *mode;
579: int filename_len, mode_len;
580: int flags = REPORT_ERRORS;
581: php_stream *stream;
582: long use_include_path = 0;
1.1 misho 583:
1.1.1.2 misho 584: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &filename, &filename_len, &mode, &mode_len, &use_include_path) == FAILURE) {
1.1 misho 585: return;
586: }
587:
1.1.1.2 misho 588: if (use_include_path) {
589: flags |= USE_PATH;
1.1 misho 590: }
591:
1.1.1.2 misho 592: stream = php_stream_gzopen(NULL, filename, mode, flags, NULL, NULL STREAMS_CC TSRMLS_CC);
1.1 misho 593:
1.1.1.2 misho 594: if (!stream) {
1.1 misho 595: RETURN_FALSE;
596: }
1.1.1.2 misho 597: php_stream_to_zval(stream, return_value);
598: }
599: /* }}} */
1.1 misho 600:
1.1.1.2 misho 601: /* {{{ proto int readgzfile(string filename [, int use_include_path])
602: Output a .gz-file */
603: static PHP_FUNCTION(readgzfile)
604: {
605: char *filename;
606: int filename_len;
607: int flags = REPORT_ERRORS;
608: php_stream *stream;
609: int size;
610: long use_include_path = 0;
1.1 misho 611:
1.1.1.2 misho 612: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &filename, &filename_len, &use_include_path) == FAILURE) {
613: return;
614: }
1.1 misho 615:
1.1.1.2 misho 616: if (use_include_path) {
617: flags |= USE_PATH;
1.1 misho 618: }
619:
1.1.1.2 misho 620: stream = php_stream_gzopen(NULL, filename, "rb", flags, NULL, NULL STREAMS_CC TSRMLS_CC);
621:
622: if (!stream) {
1.1 misho 623: RETURN_FALSE;
624: }
1.1.1.2 misho 625: size = php_stream_passthru(stream);
626: php_stream_close(stream);
627: RETURN_LONG(size);
1.1 misho 628: }
629: /* }}} */
630:
1.1.1.2 misho 631: #define PHP_ZLIB_ENCODE_FUNC(name, default_encoding) \
632: static PHP_FUNCTION(name) \
633: { \
634: char *in_buf, *out_buf; \
635: int in_len; \
636: size_t out_len; \
637: long level = -1; \
638: long encoding = default_encoding; \
639: if (default_encoding) { \
640: if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &in_buf, &in_len, &level, &encoding)) { \
641: return; \
642: } \
643: } else { \
644: if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|l", &in_buf, &in_len, &encoding, &level)) { \
645: return; \
646: } \
647: } \
648: if (level < -1 || level > 9) { \
649: php_error_docref(NULL TSRMLS_CC, E_WARNING, "compression level (%ld) must be within -1..9", level); \
650: RETURN_FALSE; \
651: } \
652: switch (encoding) { \
653: case PHP_ZLIB_ENCODING_RAW: \
654: case PHP_ZLIB_ENCODING_GZIP: \
655: case PHP_ZLIB_ENCODING_DEFLATE: \
656: break; \
657: default: \
658: php_error_docref(NULL TSRMLS_CC, E_WARNING, "encoding mode must be either ZLIB_ENCODING_RAW, ZLIB_ENCODING_GZIP or ZLIB_ENCODING_DEFLATE"); \
659: RETURN_FALSE; \
660: } \
661: if (SUCCESS != php_zlib_encode(in_buf, in_len, &out_buf, &out_len, encoding, level TSRMLS_CC)) { \
662: RETURN_FALSE; \
663: } \
664: RETURN_STRINGL(out_buf, out_len, 0); \
665: }
666:
667: #define PHP_ZLIB_DECODE_FUNC(name, encoding) \
668: static PHP_FUNCTION(name) \
669: { \
670: char *in_buf, *out_buf; \
671: int in_len; \
672: size_t out_len; \
673: long max_len = 0; \
674: if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &in_buf, &in_len, &max_len)) { \
675: return; \
676: } \
677: if (max_len < 0) { \
678: php_error_docref(NULL TSRMLS_CC, E_WARNING, "length (%ld) must be greater or equal zero", max_len); \
679: RETURN_FALSE; \
680: } \
681: if (SUCCESS != php_zlib_decode(in_buf, in_len, &out_buf, &out_len, encoding, max_len TSRMLS_CC)) { \
682: RETURN_FALSE; \
683: } \
684: RETURN_STRINGL(out_buf, out_len, 0); \
685: }
686:
687: /* {{{ proto binary zlib_encode(binary data, int encoding[, int level = -1])
688: Compress data with the specified encoding */
689: PHP_ZLIB_ENCODE_FUNC(zlib_encode, 0);
690: /* }}} */
691:
692: /* {{{ proto binary zlib_decode(binary data[, int max_decoded_len])
693: Uncompress any raw/gzip/zlib encoded data */
694: PHP_ZLIB_DECODE_FUNC(zlib_decode, PHP_ZLIB_ENCODING_ANY);
1.1.1.3 ! misho 695: /* }}} */
1.1.1.2 misho 696:
697: /* NOTE: The naming of these userland functions was quite unlucky */
698: /* {{{ proto binary gzdeflate(binary data[, int level = -1[, int encoding = ZLIB_ENCODING_RAW])
699: Encode data with the raw deflate encoding */
700: PHP_ZLIB_ENCODE_FUNC(gzdeflate, PHP_ZLIB_ENCODING_RAW);
701: /* }}} */
702:
703: /* {{{ proto binary gzencode(binary data[, int level = -1[, int encoding = ZLIB_ENCODING_GZIP])
704: Encode data with the gzip encoding */
705: PHP_ZLIB_ENCODE_FUNC(gzencode, PHP_ZLIB_ENCODING_GZIP);
706: /* }}} */
1.1.1.3 ! misho 707:
1.1.1.2 misho 708: /* {{{ proto binary gzcompress(binary data[, int level = -1[, int encoding = ZLIB_ENCODING_DEFLATE])
709: Encode data with the zlib encoding */
710: PHP_ZLIB_ENCODE_FUNC(gzcompress, PHP_ZLIB_ENCODING_DEFLATE);
711: /* }}} */
1.1.1.3 ! misho 712:
1.1.1.2 misho 713: /* {{{ proto binary gzinflate(binary data[, int max_decoded_len])
714: Decode raw deflate encoded data */
715: PHP_ZLIB_DECODE_FUNC(gzinflate, PHP_ZLIB_ENCODING_RAW);
716: /* }}} */
1.1.1.3 ! misho 717:
1.1.1.2 misho 718: /* {{{ proto binary gzdecode(binary data[, int max_decoded_len])
719: Decode gzip encoded data */
720: PHP_ZLIB_DECODE_FUNC(gzdecode, PHP_ZLIB_ENCODING_GZIP);
721: /* }}} */
1.1.1.3 ! misho 722:
1.1.1.2 misho 723: /* {{{ proto binary gzuncompress(binary data[, int max_decoded_len])
724: Decode zlib encoded data */
725: PHP_ZLIB_DECODE_FUNC(gzuncompress, PHP_ZLIB_ENCODING_DEFLATE);
726: /* }}} */
1.1 misho 727:
1.1.1.2 misho 728: #ifdef COMPILE_DL_ZLIB
729: ZEND_GET_MODULE(php_zlib)
730: #endif
1.1 misho 731:
1.1.1.2 misho 732: /* {{{ arginfo */
733: ZEND_BEGIN_ARG_INFO_EX(arginfo_ob_gzhandler, 0, 0, 2)
734: ZEND_ARG_INFO(0, data)
735: ZEND_ARG_INFO(0, flags)
736: ZEND_END_ARG_INFO()
1.1 misho 737:
1.1.1.2 misho 738: ZEND_BEGIN_ARG_INFO(arginfo_zlib_get_coding_type, 0)
739: ZEND_END_ARG_INFO()
740:
741: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzfile, 0, 0, 1)
742: ZEND_ARG_INFO(0, filename)
743: ZEND_ARG_INFO(0, use_include_path)
744: ZEND_END_ARG_INFO()
745:
746: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzopen, 0, 0, 2)
747: ZEND_ARG_INFO(0, filename)
748: ZEND_ARG_INFO(0, mode)
749: ZEND_ARG_INFO(0, use_include_path)
750: ZEND_END_ARG_INFO()
1.1 misho 751:
1.1.1.2 misho 752: ZEND_BEGIN_ARG_INFO_EX(arginfo_readgzfile, 0, 0, 1)
753: ZEND_ARG_INFO(0, filename)
754: ZEND_ARG_INFO(0, use_include_path)
755: ZEND_END_ARG_INFO()
1.1 misho 756:
1.1.1.2 misho 757: ZEND_BEGIN_ARG_INFO_EX(arginfo_zlib_encode, 0, 0, 2)
758: ZEND_ARG_INFO(0, data)
759: ZEND_ARG_INFO(0, encoding)
760: ZEND_ARG_INFO(0, level)
761: ZEND_END_ARG_INFO()
1.1 misho 762:
1.1.1.2 misho 763: ZEND_BEGIN_ARG_INFO_EX(arginfo_zlib_decode, 0, 0, 1)
764: ZEND_ARG_INFO(0, data)
765: ZEND_ARG_INFO(0, max_decoded_len)
766: ZEND_END_ARG_INFO()
1.1 misho 767:
1.1.1.2 misho 768: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzdeflate, 0, 0, 1)
769: ZEND_ARG_INFO(0, data)
770: ZEND_ARG_INFO(0, level)
771: ZEND_ARG_INFO(0, encoding)
772: ZEND_END_ARG_INFO()
1.1 misho 773:
1.1.1.2 misho 774: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzencode, 0, 0, 1)
775: ZEND_ARG_INFO(0, data)
776: ZEND_ARG_INFO(0, level)
777: ZEND_ARG_INFO(0, encoding)
778: ZEND_END_ARG_INFO()
1.1 misho 779:
1.1.1.2 misho 780: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzcompress, 0, 0, 1)
781: ZEND_ARG_INFO(0, data)
782: ZEND_ARG_INFO(0, level)
783: ZEND_ARG_INFO(0, encoding)
784: ZEND_END_ARG_INFO()
1.1 misho 785:
1.1.1.2 misho 786: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzinflate, 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_gzdecode, 0, 0, 1)
792: ZEND_ARG_INFO(0, data)
793: ZEND_ARG_INFO(0, max_decoded_len)
794: ZEND_END_ARG_INFO()
1.1 misho 795:
1.1.1.2 misho 796: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzuncompress, 0, 0, 1)
797: ZEND_ARG_INFO(0, data)
798: ZEND_ARG_INFO(0, max_decoded_len)
799: ZEND_END_ARG_INFO()
1.1 misho 800:
1.1.1.2 misho 801: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzputs, 0, 0, 2)
802: ZEND_ARG_INFO(0, fp)
803: ZEND_ARG_INFO(0, str)
804: ZEND_ARG_INFO(0, length)
805: ZEND_END_ARG_INFO()
1.1 misho 806:
1.1.1.2 misho 807: ZEND_BEGIN_ARG_INFO(arginfo_gzpassthru, 0)
808: ZEND_ARG_INFO(0, fp)
809: ZEND_END_ARG_INFO()
1.1 misho 810:
1.1.1.2 misho 811: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzseek, 0, 0, 2)
812: ZEND_ARG_INFO(0, fp)
813: ZEND_ARG_INFO(0, offset)
814: ZEND_ARG_INFO(0, whence)
815: ZEND_END_ARG_INFO()
1.1 misho 816:
1.1.1.2 misho 817: ZEND_BEGIN_ARG_INFO(arginfo_gzread, 0)
818: ZEND_ARG_INFO(0, fp)
819: ZEND_ARG_INFO(0, length)
820: ZEND_END_ARG_INFO()
1.1 misho 821:
1.1.1.2 misho 822: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzgetss, 0, 0, 1)
823: ZEND_ARG_INFO(0, fp)
824: ZEND_ARG_INFO(0, length)
825: ZEND_ARG_INFO(0, allowable_tags)
826: ZEND_END_ARG_INFO()
1.1 misho 827:
1.1.1.2 misho 828: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzgets, 0, 0, 1)
829: ZEND_ARG_INFO(0, fp)
830: ZEND_ARG_INFO(0, length)
831: ZEND_END_ARG_INFO()
1.1 misho 832: /* }}} */
833:
1.1.1.2 misho 834: /* {{{ php_zlib_functions[] */
835: static const zend_function_entry php_zlib_functions[] = {
836: PHP_FE(readgzfile, arginfo_readgzfile)
837: PHP_FALIAS(gzrewind, rewind, arginfo_gzpassthru)
838: PHP_FALIAS(gzclose, fclose, arginfo_gzpassthru)
839: PHP_FALIAS(gzeof, feof, arginfo_gzpassthru)
840: PHP_FALIAS(gzgetc, fgetc, arginfo_gzpassthru)
841: PHP_FALIAS(gzgets, fgets, arginfo_gzgets)
842: PHP_FALIAS(gzgetss, fgetss, arginfo_gzgetss)
843: PHP_FALIAS(gzread, fread, arginfo_gzread)
844: PHP_FE(gzopen, arginfo_gzopen)
845: PHP_FALIAS(gzpassthru, fpassthru, arginfo_gzpassthru)
846: PHP_FALIAS(gzseek, fseek, arginfo_gzseek)
847: PHP_FALIAS(gztell, ftell, arginfo_gzpassthru)
848: PHP_FALIAS(gzwrite, fwrite, arginfo_gzputs)
849: PHP_FALIAS(gzputs, fwrite, arginfo_gzputs)
850: PHP_FE(gzfile, arginfo_gzfile)
851: PHP_FE(gzcompress, arginfo_gzcompress)
852: PHP_FE(gzuncompress, arginfo_gzuncompress)
853: PHP_FE(gzdeflate, arginfo_gzdeflate)
854: PHP_FE(gzinflate, arginfo_gzinflate)
855: PHP_FE(gzencode, arginfo_gzencode)
856: PHP_FE(gzdecode, arginfo_gzdecode)
857: PHP_FE(zlib_encode, arginfo_zlib_encode)
858: PHP_FE(zlib_decode, arginfo_zlib_decode)
859: PHP_FE(zlib_get_coding_type, arginfo_zlib_get_coding_type)
860: PHP_FE(ob_gzhandler, arginfo_ob_gzhandler)
861: PHP_FE_END
862: };
863: /* }}} */
1.1 misho 864:
1.1.1.2 misho 865: /* {{{ OnUpdate_zlib_output_compression */
866: static PHP_INI_MH(OnUpdate_zlib_output_compression)
867: {
868: int status, int_value;
869: char *ini_value;
1.1 misho 870:
1.1.1.2 misho 871: if (new_value == NULL) {
872: return FAILURE;
1.1 misho 873: }
874:
1.1.1.2 misho 875: if (!strncasecmp(new_value, "off", sizeof("off"))) {
876: new_value = "0";
877: new_value_length = sizeof("0");
878: } else if (!strncasecmp(new_value, "on", sizeof("on"))) {
879: new_value = "1";
880: new_value_length = sizeof("1");
1.1 misho 881: }
882:
1.1.1.2 misho 883: int_value = zend_atoi(new_value, new_value_length);
884: ini_value = zend_ini_string("output_handler", sizeof("output_handler"), 0);
1.1 misho 885:
1.1.1.2 misho 886: if (ini_value && *ini_value && int_value) {
887: php_error_docref("ref.outcontrol" TSRMLS_CC, E_CORE_ERROR, "Cannot use both zlib.output_compression and output_handler together!!");
888: return FAILURE;
1.1 misho 889: }
1.1.1.2 misho 890: if (stage == PHP_INI_STAGE_RUNTIME) {
891: status = php_output_get_status(TSRMLS_C);
892: if (status & PHP_OUTPUT_SENT) {
893: php_error_docref("ref.outcontrol" TSRMLS_CC, E_WARNING, "Cannot change zlib.output_compression - headers already sent");
894: return FAILURE;
1.1 misho 895: }
896: }
897:
1.1.1.2 misho 898: status = OnUpdateLong(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
899:
1.1.1.3 ! misho 900: ZLIBG(output_compression) = ZLIBG(output_compression_default);
1.1.1.2 misho 901: if (stage == PHP_INI_STAGE_RUNTIME && int_value) {
902: if (!php_output_handler_started(ZEND_STRL(PHP_ZLIB_OUTPUT_HANDLER_NAME) TSRMLS_CC)) {
903: php_zlib_output_compression_start(TSRMLS_C);
1.1 misho 904: }
905: }
1.1.1.2 misho 906:
907: return status;
1.1 misho 908: }
909: /* }}} */
910:
1.1.1.2 misho 911: /* {{{ OnUpdate_zlib_output_handler */
912: static PHP_INI_MH(OnUpdate_zlib_output_handler)
1.1 misho 913: {
1.1.1.2 misho 914: if (stage == PHP_INI_STAGE_RUNTIME && (php_output_get_status(TSRMLS_C) & PHP_OUTPUT_SENT)) {
915: php_error_docref("ref.outcontrol" TSRMLS_CC, E_WARNING, "Cannot change zlib.output_handler - headers already sent");
916: return FAILURE;
1.1 misho 917: }
918:
1.1.1.2 misho 919: return OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
1.1 misho 920: }
1.1.1.2 misho 921: /* }}} */
922:
923: /* {{{ INI */
924: PHP_INI_BEGIN()
1.1.1.3 ! misho 925: STD_PHP_INI_BOOLEAN("zlib.output_compression", "0", PHP_INI_ALL, OnUpdate_zlib_output_compression, output_compression_default, zend_zlib_globals, zlib_globals)
1.1.1.2 misho 926: STD_PHP_INI_ENTRY("zlib.output_compression_level", "-1", PHP_INI_ALL, OnUpdateLong, output_compression_level, zend_zlib_globals, zlib_globals)
927: STD_PHP_INI_ENTRY("zlib.output_handler", "", PHP_INI_ALL, OnUpdate_zlib_output_handler, output_handler, zend_zlib_globals, zlib_globals)
928: PHP_INI_END()
1.1 misho 929:
930: /* }}} */
931:
1.1.1.2 misho 932: /* {{{ PHP_MINIT_FUNCTION */
933: static PHP_MINIT_FUNCTION(zlib)
1.1 misho 934: {
1.1.1.2 misho 935: php_register_url_stream_wrapper("compress.zlib", &php_stream_gzip_wrapper TSRMLS_CC);
936: php_stream_filter_register_factory("zlib.*", &php_zlib_filter_factory TSRMLS_CC);
1.1 misho 937:
1.1.1.2 misho 938: php_output_handler_alias_register(ZEND_STRL("ob_gzhandler"), php_zlib_output_handler_init TSRMLS_CC);
939: php_output_handler_conflict_register(ZEND_STRL("ob_gzhandler"), php_zlib_output_conflict_check TSRMLS_CC);
940: php_output_handler_conflict_register(ZEND_STRL(PHP_ZLIB_OUTPUT_HANDLER_NAME), php_zlib_output_conflict_check TSRMLS_CC);
941:
942: REGISTER_LONG_CONSTANT("FORCE_GZIP", PHP_ZLIB_ENCODING_GZIP, CONST_CS|CONST_PERSISTENT);
943: REGISTER_LONG_CONSTANT("FORCE_DEFLATE", PHP_ZLIB_ENCODING_DEFLATE, CONST_CS|CONST_PERSISTENT);
944:
945: REGISTER_LONG_CONSTANT("ZLIB_ENCODING_RAW", PHP_ZLIB_ENCODING_RAW, CONST_CS|CONST_PERSISTENT);
946: REGISTER_LONG_CONSTANT("ZLIB_ENCODING_GZIP", PHP_ZLIB_ENCODING_GZIP, CONST_CS|CONST_PERSISTENT);
947: REGISTER_LONG_CONSTANT("ZLIB_ENCODING_DEFLATE", PHP_ZLIB_ENCODING_DEFLATE, CONST_CS|CONST_PERSISTENT);
948: REGISTER_INI_ENTRIES();
949: return SUCCESS;
1.1 misho 950: }
951: /* }}} */
952:
1.1.1.2 misho 953: /* {{{ PHP_MSHUTDOWN_FUNCTION */
954: static PHP_MSHUTDOWN_FUNCTION(zlib)
1.1 misho 955: {
1.1.1.2 misho 956: php_unregister_url_stream_wrapper("zlib" TSRMLS_CC);
957: php_stream_filter_unregister_factory("zlib.*" TSRMLS_CC);
1.1 misho 958:
1.1.1.2 misho 959: UNREGISTER_INI_ENTRIES();
1.1 misho 960:
1.1.1.2 misho 961: return SUCCESS;
1.1 misho 962: }
963: /* }}} */
964:
1.1.1.2 misho 965: /* {{{ PHP_RINIT_FUNCTION */
966: static PHP_RINIT_FUNCTION(zlib)
1.1 misho 967: {
1.1.1.2 misho 968: ZLIBG(compression_coding) = 0;
1.1.1.3 ! misho 969: if (!ZLIBG(handler_registered)) {
! 970: ZLIBG(output_compression) = ZLIBG(output_compression_default);
! 971: php_zlib_output_compression_start(TSRMLS_C);
! 972: }
1.1 misho 973:
1.1.1.2 misho 974: return SUCCESS;
975: }
976: /* }}} */
1.1 misho 977:
1.1.1.3 ! misho 978: /* {{{ PHP_RSHUTDOWN_FUNCTION */
1.1.1.2 misho 979: static PHP_RSHUTDOWN_FUNCTION(zlib)
980: {
981: php_zlib_cleanup_ob_gzhandler_mess(TSRMLS_C);
1.1.1.3 ! misho 982: ZLIBG(handler_registered) = 0;
1.1 misho 983:
1.1.1.2 misho 984: return SUCCESS;
985: }
1.1.1.3 ! misho 986: /* }}} */
1.1 misho 987:
1.1.1.2 misho 988: /* {{{ PHP_MINFO_FUNCTION */
989: static PHP_MINFO_FUNCTION(zlib)
990: {
991: php_info_print_table_start();
992: php_info_print_table_header(2, "ZLib Support", "enabled");
993: php_info_print_table_row(2, "Stream Wrapper", "compress.zlib://");
994: php_info_print_table_row(2, "Stream Filter", "zlib.inflate, zlib.deflate");
995: php_info_print_table_row(2, "Compiled Version", ZLIB_VERSION);
996: php_info_print_table_row(2, "Linked Version", (char *) zlibVersion());
997: php_info_print_table_end();
1.1 misho 998:
1.1.1.2 misho 999: DISPLAY_INI_ENTRIES();
1.1 misho 1000: }
1001: /* }}} */
1002:
1.1.1.2 misho 1003: /* {{{ ZEND_MODULE_GLOBALS_CTOR */
1004: static ZEND_MODULE_GLOBALS_CTOR_D(zlib)
1.1 misho 1005: {
1.1.1.2 misho 1006: zlib_globals->ob_gzhandler = NULL;
1.1.1.3 ! misho 1007: zlib_globals->handler_registered = 0;
1.1 misho 1008: }
1009: /* }}} */
1010:
1.1.1.2 misho 1011: /* {{{ php_zlib_module_entry */
1012: zend_module_entry php_zlib_module_entry = {
1013: STANDARD_MODULE_HEADER,
1014: "zlib",
1015: php_zlib_functions,
1016: PHP_MINIT(zlib),
1017: PHP_MSHUTDOWN(zlib),
1018: PHP_RINIT(zlib),
1019: PHP_RSHUTDOWN(zlib),
1020: PHP_MINFO(zlib),
1021: "2.0",
1022: PHP_MODULE_GLOBALS(zlib),
1023: ZEND_MODULE_GLOBALS_CTOR_N(zlib),
1024: NULL,
1025: NULL,
1026: STANDARD_MODULE_PROPERTIES_EX
1027: };
1028: /* }}} */
1029:
1.1 misho 1030: /*
1031: * Local variables:
1032: * tab-width: 4
1033: * c-basic-offset: 4
1034: * End:
1035: * vim600: sw=4 ts=4 fdm=marker
1036: * vim<600: sw=4 ts=4
1037: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>