From 213951e5268262c6dbea4b05b852510132f3367b Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Thu, 22 Dec 2005 21:30:53 +0000 Subject: [PATCH] - add flush() to encoding stream (filters) --- http_encoding_api.c | 76 ++++++++++++++++++++++++++++++++++------- http_filter_api.c | 34 +++++++++++++++--- http_url_api.c | 2 +- php_http_encoding_api.h | 5 +++ 4 files changed, 99 insertions(+), 18 deletions(-) diff --git a/http_encoding_api.c b/http_encoding_api.c index 0b68397..3cabd06 100644 --- a/http_encoding_api.c +++ b/http_encoding_api.c @@ -193,7 +193,7 @@ PHP_HTTP_API const char *_http_encoding_dechunk(const char *encoded, size_t enco #define HTTP_WINDOW_BITS_ANY 0x0000002f #define HTTP_WINDOW_BITS_RAW -0x000000f -STATUS _http_encoding_deflate(int flags, const char *data, size_t data_len, char **encoded, size_t *encoded_len TSRMLS_DC) +PHP_HTTP_API STATUS _http_encoding_deflate(int flags, const char *data, size_t data_len, char **encoded, size_t *encoded_len TSRMLS_DC) { int status, level, wbits, strategy; z_stream Z; @@ -234,7 +234,7 @@ STATUS _http_encoding_deflate(int flags, const char *data, size_t data_len, char return FAILURE; } -STATUS _http_encoding_inflate(const char *data, size_t data_len, char **decoded, size_t *decoded_len TSRMLS_DC) +PHP_HTTP_API STATUS _http_encoding_inflate(const char *data, size_t data_len, char **decoded, size_t *decoded_len TSRMLS_DC) { int status, max = 0, wbits = HTTP_WINDOW_BITS_ANY; z_stream Z; @@ -287,7 +287,7 @@ retry_inflate: } -http_encoding_stream *_http_encoding_deflate_stream_init(http_encoding_stream *s, int flags TSRMLS_DC) +PHP_HTTP_API http_encoding_stream *_http_encoding_deflate_stream_init(http_encoding_stream *s, int flags TSRMLS_DC) { int status, level, wbits, strategy, free_stream; @@ -318,7 +318,7 @@ http_encoding_stream *_http_encoding_deflate_stream_init(http_encoding_stream *s return NULL; } -http_encoding_stream *_http_encoding_inflate_stream_init(http_encoding_stream *s, int flags TSRMLS_DC) +PHP_HTTP_API http_encoding_stream *_http_encoding_inflate_stream_init(http_encoding_stream *s, int flags TSRMLS_DC) { int status, wbits, free_stream; @@ -347,7 +347,7 @@ http_encoding_stream *_http_encoding_inflate_stream_init(http_encoding_stream *s return NULL; } -STATUS _http_encoding_deflate_stream_update(http_encoding_stream *s, const char *data, size_t data_len, char **encoded, size_t *encoded_len TSRMLS_DC) +PHP_HTTP_API STATUS _http_encoding_deflate_stream_update(http_encoding_stream *s, const char *data, size_t data_len, char **encoded, size_t *encoded_len TSRMLS_DC) { int status; @@ -382,7 +382,7 @@ STATUS _http_encoding_deflate_stream_update(http_encoding_stream *s, const char return FAILURE; } -STATUS _http_encoding_inflate_stream_update(http_encoding_stream *s, const char *data, size_t data_len, char **decoded, size_t *decoded_len TSRMLS_DC) +PHP_HTTP_API STATUS _http_encoding_inflate_stream_update(http_encoding_stream *s, const char *data, size_t data_len, char **decoded, size_t *decoded_len TSRMLS_DC) { int status, max = 0; @@ -437,7 +437,59 @@ retry_raw_inflate: return FAILURE; } -STATUS _http_encoding_deflate_stream_finish(http_encoding_stream *s, char **encoded, size_t *encoded_len TSRMLS_DC) +PHP_HTTP_API STATUS _http_encoding_deflate_stream_flush(http_encoding_stream *s, char **encoded, size_t *encoded_len TSRMLS_DC) +{ + int status; + + s->stream.avail_in = 0; + s->stream.next_in = NULL; + s->stream.avail_out = *encoded_len = 0x800; + s->stream.next_out = *encoded = emalloc(*encoded_len); + + switch (status = deflate(&s->stream, Z_SYNC_FLUSH)) + { + case Z_OK: + case Z_STREAM_END: + *encoded_len = 0x800 - s->stream.avail_out; + *encoded = erealloc(*encoded, *encoded_len + 1); + (*encoded)[*encoded_len] = '\0'; + return SUCCESS; + break; + } + + STR_SET(*encoded, NULL); + *encoded_len = 0; + http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Failed to flush deflate stream: %s", zError(status)); + return FAILURE; +} + +PHP_HTTP_API STATUS _http_encoding_inflate_stream_flush(http_encoding_stream *s, char **decoded, size_t *decoded_len TSRMLS_DC) +{ + int status; + + s->stream.avail_in = 0; + s->stream.next_in = NULL; + s->stream.avail_out = *decoded_len = 0x800; + s->stream.next_out = *decoded = emalloc(*decoded_len); + + switch (status = inflate(&s->stream, Z_SYNC_FLUSH)) + { + case Z_OK: + case Z_STREAM_END: + *decoded_len = 0x800 - s->stream.avail_out; + *decoded = erealloc(*decoded, *decoded_len + 1); + (*decoded)[*decoded_len] = '\0'; + return SUCCESS; + break; + } + + STR_SET(*decoded, NULL); + *decoded_len = 0; + http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Failed to flush inflate stream: %s", zError(status)); + return FAILURE; +} + +PHP_HTTP_API STATUS _http_encoding_deflate_stream_finish(http_encoding_stream *s, char **encoded, size_t *encoded_len TSRMLS_DC) { int status; @@ -469,7 +521,7 @@ STATUS _http_encoding_deflate_stream_finish(http_encoding_stream *s, char **enco return FAILURE; } -STATUS _http_encoding_inflate_stream_finish(http_encoding_stream *s, char **decoded, size_t *decoded_len TSRMLS_DC) +PHP_HTTP_API STATUS _http_encoding_inflate_stream_finish(http_encoding_stream *s, char **decoded, size_t *decoded_len TSRMLS_DC) { int status; @@ -497,7 +549,7 @@ STATUS _http_encoding_inflate_stream_finish(http_encoding_stream *s, char **deco return FAILURE; } -void _http_encoding_deflate_stream_dtor(http_encoding_stream *s TSRMLS_DC) +PHP_HTTP_API void _http_encoding_deflate_stream_dtor(http_encoding_stream *s TSRMLS_DC) { if (s) { if (s->stream.opaque) { @@ -507,7 +559,7 @@ void _http_encoding_deflate_stream_dtor(http_encoding_stream *s TSRMLS_DC) } } -void _http_encoding_inflate_stream_dtor(http_encoding_stream *s TSRMLS_DC) +PHP_HTTP_API void _http_encoding_inflate_stream_dtor(http_encoding_stream *s TSRMLS_DC) { if (s) { if (s->stream.opaque) { @@ -517,7 +569,7 @@ void _http_encoding_inflate_stream_dtor(http_encoding_stream *s TSRMLS_DC) } } -void _http_encoding_deflate_stream_free(http_encoding_stream **s TSRMLS_DC) +PHP_HTTP_API void _http_encoding_deflate_stream_free(http_encoding_stream **s TSRMLS_DC) { if (s) { http_encoding_deflate_stream_dtor(*s); @@ -528,7 +580,7 @@ void _http_encoding_deflate_stream_free(http_encoding_stream **s TSRMLS_DC) } } -void _http_encoding_inflate_stream_free(http_encoding_stream **s TSRMLS_DC) +PHP_HTTP_API void _http_encoding_inflate_stream_free(http_encoding_stream **s TSRMLS_DC) { if (s) { http_encoding_inflate_stream_dtor(*s); diff --git a/http_filter_api.c b/http_filter_api.c index 1836b27..a942c1f 100644 --- a/http_filter_api.c +++ b/http_filter_api.c @@ -131,7 +131,7 @@ static HTTP_FILTER_FUNCTION(chunked_decode) if (PHPSTR_LEN(buffer) < buffer->hexlen) { /* flush anyway? */ - if (flags == PSFS_FLAG_FLUSH_INC) { + if (flags & PSFS_FLAG_FLUSH_INC) { /* flush all data (should only be chunk data) */ out_avail = 1; @@ -210,7 +210,7 @@ static HTTP_FILTER_FUNCTION(chunked_decode) } /* flush before close, but only if we are already waiting for more data */ - if (flags == PSFS_FLAG_FLUSH_CLOSE && buffer->hexlen && PHPSTR_LEN(buffer)) { + if ((flags & PSFS_FLAG_FLUSH_CLOSE) && buffer->hexlen && PHPSTR_LEN(buffer)) { out_avail = 1; NEW_BUCKET(PHPSTR_VAL(buffer), PHPSTR_LEN(buffer)); phpstr_reset(PHPSTR(buffer)); @@ -269,7 +269,7 @@ static HTTP_FILTER_FUNCTION(chunked_encode) } /* terminate with "0" */ - if (flags == PSFS_FLAG_FLUSH_CLOSE) { + if (flags & PSFS_FLAG_FLUSH_CLOSE) { out_avail = 1; NEW_BUCKET("0" HTTP_CRLF, lenof("0" HTTP_CRLF)); } @@ -329,7 +329,19 @@ static HTTP_FILTER_FUNCTION(deflate) } /* flush & close */ - if (flags == PSFS_FLAG_FLUSH_CLOSE) { + if (flags & PSFS_FLAG_FLUSH_INC) { + char *encoded = NULL; + size_t encoded_len = 0; + + http_encoding_deflate_stream_flush(buffer, &encoded, &encoded_len); + if (encoded) { + out_avail = 1; + NEW_BUCKET(encoded, encoded_len); + efree(encoded); + } + } + + if (flags & PSFS_FLAG_FLUSH_CLOSE) { char *encoded = NULL; size_t encoded_len = 0; @@ -382,7 +394,19 @@ static HTTP_FILTER_FUNCTION(inflate) } /* flush & close */ - if (flags == PSFS_FLAG_FLUSH_CLOSE) { + if (flags & PSFS_FLAG_FLUSH_INC) { + char *decoded = NULL; + size_t decoded_len = 0; + + http_encoding_inflate_stream_flush(buffer, &decoded, &decoded_len); + if (decoded) { + out_avail = 1; + NEW_BUCKET(decoded, decoded_len); + efree(decoded); + } + } + + if (flags & PSFS_FLAG_FLUSH_CLOSE) { char *decoded = NULL; size_t decoded_len = 0; diff --git a/http_url_api.c b/http_url_api.c index dcc5062..0720460 100644 --- a/http_url_api.c +++ b/http_url_api.c @@ -301,7 +301,7 @@ PHP_HTTP_API STATUS _http_urlencode_hash_recursive(HashTable *ht, phpstr *str, c } else { zval *val; - MAKE_STD_ZVAL(val); + ALLOC_ZVAL(val); *val = **data; INIT_PZVAL(val); zval_copy_ctor(val); diff --git a/php_http_encoding_api.h b/php_http_encoding_api.h index 70cc42b..a8a55bf 100644 --- a/php_http_encoding_api.h +++ b/php_http_encoding_api.h @@ -25,6 +25,7 @@ PHP_HTTP_API zend_bool _http_encoding_response_start(size_t content_length TSRML extern PHP_MINIT_FUNCTION(http_encoding); +/* 100% compression should be fairly good */ #define HTTP_ENCODING_MAXTRY 100 /* safe padding */ #define HTTP_ENCODING_SAFPAD 28 @@ -70,6 +71,8 @@ PHP_HTTP_API STATUS _http_encoding_inflate(const char *data, size_t data_len, ch PHP_HTTP_API http_encoding_stream *_http_encoding_deflate_stream_init(http_encoding_stream *s, int flags TSRMLS_DC); #define http_encoding_deflate_stream_update(s, d, dl, e, el) _http_encoding_deflate_stream_update((s), (d), (dl), (e), (el) TSRMLS_CC) PHP_HTTP_API STATUS _http_encoding_deflate_stream_update(http_encoding_stream *s, const char *data, size_t data_len, char **encoded, size_t *encoded_len TSRMLS_DC); +#define http_encoding_deflate_stream_flush(s, e, el) _http_encoding_deflate_stream_flush((s), (e), (el) TSRMLS_CC) +PHP_HTTP_API STATUS _http_encoding_deflate_stream_flush(http_encoding_stream *s, char **encoded, size_t *encoded_len TSRMLS_DC); #define http_encoding_deflate_stream_finish(s, e, el) _http_encoding_deflate_stream_finish((s), (e), (el) TSRMLS_CC) PHP_HTTP_API STATUS _http_encoding_deflate_stream_finish(http_encoding_stream *s, char **encoded, size_t *encoded_len TSRMLS_DC); #define http_encoding_deflate_stream_dtor(s) _http_encoding_deflate_stream_dtor((s) TSRMLS_CC) @@ -81,6 +84,8 @@ PHP_HTTP_API void _http_encoding_deflate_stream_free(http_encoding_stream **s TS PHP_HTTP_API http_encoding_stream *_http_encoding_inflate_stream_init(http_encoding_stream *s, int flags TSRMLS_DC); #define http_encoding_inflate_stream_update(s, d, dl, e, el) _http_encoding_inflate_stream_update((s), (d), (dl), (e), (el) TSRMLS_CC) PHP_HTTP_API STATUS _http_encoding_inflate_stream_update(http_encoding_stream *s, const char *data, size_t data_len, char **decoded, size_t *decoded_len TSRMLS_DC); +#define http_encoding_inflate_stream_flush(s, d, dl) _http_encoding_inflate_stream_flush((s), (d), (dl) TSRMLS_CC) +PHP_HTTP_API STATUS _http_encoding_inflate_stream_flush(http_encoding_stream *s, char **decoded, size_t *decoded_len TSRMLS_DC); #define http_encoding_inflate_stream_finish(s, e, el) _http_encoding_inflate_stream_finish((s), (e), (el) TSRMLS_CC) PHP_HTTP_API STATUS _http_encoding_inflate_stream_finish(http_encoding_stream *s, char **decoded, size_t *decoded_len TSRMLS_DC); #define http_encoding_inflate_stream_dtor(s) _http_encoding_inflate_stream_dtor((s) TSRMLS_CC) -- 2.30.2