X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=http_encoding_api.c;h=9e0976c58d2b33c5511d80a88cd7b7f3e4b931f7;hp=1975295c00e5a36056473f4c65cf96964f66fa8c;hb=dcc8cebf561d1e69e77b85fcd73b6a6c56b44748;hpb=13e641e4455b1f86520de7c6390b2b7659d65e54 diff --git a/http_encoding_api.c b/http_encoding_api.c index 1975295..9e0976c 100644 --- a/http_encoding_api.c +++ b/http_encoding_api.c @@ -6,7 +6,7 @@ | modification, are permitted provided that the conditions mentioned | | in the accompanying LICENSE file are met. | +--------------------------------------------------------------------+ - | Copyright (c) 2004-2006, Michael Wallner | + | Copyright (c) 2004-2010, Michael Wallner | +--------------------------------------------------------------------+ */ @@ -158,17 +158,22 @@ PHP_HTTP_API const char *_http_encoding_dechunk(const char *encoded, size_t enco /* }}} */ /* {{{ int http_encoding_response_start(size_t) */ -PHP_HTTP_API int _http_encoding_response_start(size_t content_length TSRMLS_DC) +PHP_HTTP_API int _http_encoding_response_start(size_t content_length, zend_bool ignore_http_ohandler TSRMLS_DC) { - if ( php_ob_handler_used("ob_gzhandler" TSRMLS_CC) || - php_ob_handler_used("zlib output compression" TSRMLS_CC)) { - HTTP_G->send.deflate.encoding = 0; - } else if (HTTP_G->send.deflate.encoding) { - HTTP_G->send.deflate.encoding = 0; + int response = HTTP_G->send.deflate.response; + int ohandler = php_ob_handler_used("ob_gzhandler" TSRMLS_CC) || php_ob_handler_used("zlib output compression" TSRMLS_CC); + + if (!ohandler && !ignore_http_ohandler) { + ohandler = php_ob_handler_used("ob_deflatehandler" TSRMLS_CC) || php_ob_handler_used("http deflate" TSRMLS_CC); + } + + if (response && !ohandler) { #ifdef HTTP_HAVE_ZLIB HashTable *selected; zval zsupported; + HTTP_G->send.deflate.encoding = 0; + INIT_PZVAL(&zsupported); array_init(&zsupported); add_next_index_stringl(&zsupported, "gzip", lenof("gzip"), 1); @@ -201,18 +206,19 @@ PHP_HTTP_API int _http_encoding_response_start(size_t content_length TSRMLS_DC) zval_dtor(&zsupported); #else + HTTP_G->send.deflate.encoding = 0; php_start_ob_buffer_named("ob_gzhandler", 0, 0 TSRMLS_CC); #endif /* HTTP_HAVE_ZLIB */ + } else if (content_length && !ohandler) { + /* emit a content-length header */ + char cl_header_str[128]; + size_t cl_header_len; + cl_header_len = snprintf(cl_header_str, sizeof(cl_header_str), "Content-Length: %zu", content_length); + http_send_header_string_ex(cl_header_str, cl_header_len, 1); } else { HTTP_G->send.deflate.encoding = 0; - if (content_length) { - /* emit a content-length header */ - char cl_header_str[128]; - size_t cl_header_len; - cl_header_len = snprintf(cl_header_str, lenof(cl_header_str), "Content-Length: %zu", content_length); - http_send_header_string_ex(cl_header_str, cl_header_len, 1); - } } + return HTTP_G->send.deflate.encoding; } /* }}} */ @@ -321,10 +327,13 @@ retry_raw_inflate: Z.avail_in = data_len; switch (status = http_inflate_rounds(&Z, Z_NO_FLUSH, decoded, decoded_len)) { - case Z_OK: case Z_STREAM_END: inflateEnd(&Z); return SUCCESS; + + case Z_OK: + status = Z_DATA_ERROR; + break; case Z_DATA_ERROR: /* raw deflated data? */ @@ -335,6 +344,10 @@ retry_raw_inflate: } } inflateEnd(&Z); + + if (decoded_len && *decoded) { + efree(*decoded); + } } http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Could not inflate data: %s", zError(status)); @@ -652,6 +665,8 @@ PHP_HTTP_API void _http_encoding_inflate_stream_free(http_encoding_stream **s TS /* {{{ void http_ob_deflatehandler(char *, uint, char **, uint *, int) */ void _http_ob_deflatehandler(char *output, uint output_len, char **handled_output, uint *handled_output_len, int mode TSRMLS_DC) { + int encoding; + *handled_output = NULL; *handled_output_len = 0; @@ -663,9 +678,11 @@ void _http_ob_deflatehandler(char *output, uint output_len, char **handled_outpu return; } - HTTP_G->send.deflate.encoding = !0; + HTTP_G->send.deflate.response = 1; + encoding = http_encoding_response_start(0, 1); + HTTP_G->send.deflate.response = 0; - switch (http_encoding_response_start(0)) { + switch (encoding) { case HTTP_ENCODING_GZIP: flags = HTTP_DEFLATE_TYPE_GZIP; break; @@ -684,7 +701,10 @@ void _http_ob_deflatehandler(char *output, uint output_len, char **handled_outpu if (HTTP_G->send.deflate.stream) { if (output_len) { - http_encoding_deflate_stream_update((http_encoding_stream *) HTTP_G->send.deflate.stream, output, output_len, handled_output, handled_output_len); + size_t tmp_len; + + http_encoding_deflate_stream_update((http_encoding_stream *) HTTP_G->send.deflate.stream, output, output_len, handled_output, &tmp_len); + *handled_output_len = tmp_len; } if (mode & PHP_OUTPUT_HANDLER_END) { @@ -723,7 +743,10 @@ void _http_ob_inflatehandler(char *output, uint output_len, char **handled_outpu if (HTTP_G->send.inflate.stream) { if (output_len) { - http_encoding_inflate_stream_update((http_encoding_stream *) HTTP_G->send.inflate.stream, output, output_len, handled_output, handled_output_len); + size_t tmp_len; + + http_encoding_inflate_stream_update((http_encoding_stream *) HTTP_G->send.inflate.stream, output, output_len, handled_output, &tmp_len); + *handled_output_len = tmp_len; } if (mode & PHP_OUTPUT_HANDLER_END) {