-static inline int php_http_inflate_rounds(z_stream *Z, int flush, char **buf, size_t *len)
-{
- int status = 0, round = 0;
- php_http_buffer_t buffer;
-
- *buf = NULL;
- *len = 0;
-
- php_http_buffer_init_ex(&buffer, Z->avail_in, PHP_HTTP_BUFFER_INIT_PREALLOC);
-
- do {
- if (PHP_HTTP_BUFFER_NOMEM == php_http_buffer_resize_ex(&buffer, buffer.size, 0, 1)) {
- status = Z_MEM_ERROR;
- } else {
- Z->avail_out = buffer.free;
- Z->next_out = (Bytef *) buffer.data + buffer.used;
-#if 0
- 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);
-#endif
- status = inflate(Z, flush);
- php_http_buffer_account(&buffer, buffer.free - Z->avail_out);
-#if 0
- 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);
-#endif
- PHP_HTTP_INFLATE_BUFFER_SIZE_ALIGN(buffer.size);
- }
- } while ((Z_BUF_ERROR == status || (Z_OK == status && Z->avail_in)) && ++round < PHP_HTTP_INFLATE_ROUNDS);
-
- if (status == Z_OK || status == Z_STREAM_END) {
- php_http_buffer_shrink(&buffer);
- php_http_buffer_fix(&buffer);
- *buf = buffer.data;
- *len = buffer.used;
- } else {
- php_http_buffer_dtor(&buffer);
- }
-
- return status;
-}
-
-ZEND_RESULT_CODE php_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;
-
- PHP_HTTP_DEFLATE_LEVEL_SET(flags, level);
- PHP_HTTP_DEFLATE_WBITS_SET(flags, wbits);
- PHP_HTTP_DEFLATE_STRATEGY_SET(flags, strategy);
-
- memset(&Z, 0, sizeof(z_stream));
- *encoded = NULL;
- *encoded_len = 0;
-
- status = deflateInit2(&Z, level, Z_DEFLATED, wbits, MAX_MEM_LEVEL, strategy);
- if (Z_OK == status) {
- *encoded_len = PHP_HTTP_DEFLATE_BUFFER_SIZE_GUESS(data_len);
- *encoded = emalloc(*encoded_len);
-
- Z.next_in = (Bytef *) data;
- Z.next_out = (Bytef *) *encoded;
- Z.avail_in = data_len;
- Z.avail_out = *encoded_len;
-
- status = deflate(&Z, Z_FINISH);
- deflateEnd(&Z);
-
- if (Z_STREAM_END == status) {
- /* size buffer down to actual length */
- *encoded = erealloc(*encoded, Z.total_out + 1);
- (*encoded)[*encoded_len = Z.total_out] = '\0';
- return SUCCESS;
- } else {
- PTR_SET(*encoded, NULL);
- *encoded_len = 0;
- }
- }
-
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not deflate data: %s", zError(status));
- return FAILURE;
-}
-
-ZEND_RESULT_CODE php_http_encoding_inflate(const char *data, size_t data_len, char **decoded, size_t *decoded_len TSRMLS_DC)
-{
- z_stream Z;
- int status, wbits = PHP_HTTP_WINDOW_BITS_ANY;
-
- memset(&Z, 0, sizeof(z_stream));
-
-retry_raw_inflate:
- status = inflateInit2(&Z, wbits);
- if (Z_OK == status) {
- Z.next_in = (Bytef *) data;
- Z.avail_in = data_len + 1; /* include the terminating NULL, see #61287 */
-
- switch (status = php_http_inflate_rounds(&Z, Z_NO_FLUSH, decoded, decoded_len)) {
- case Z_STREAM_END:
- inflateEnd(&Z);
- return SUCCESS;
-
- case Z_OK:
- status = Z_DATA_ERROR;
- break;
-
- case Z_DATA_ERROR:
- /* raw deflated data? */
- if (PHP_HTTP_WINDOW_BITS_ANY == wbits) {
- inflateEnd(&Z);
- wbits = PHP_HTTP_WINDOW_BITS_RAW;
- goto retry_raw_inflate;
- }
- break;
- }
- inflateEnd(&Z);
-
- if (*decoded_len && *decoded) {
- efree(*decoded);
- }
- }
-
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not inflate data: %s", zError(status));
- return FAILURE;
-}
-
-php_http_encoding_stream_t *php_http_encoding_stream_init(php_http_encoding_stream_t *s, php_http_encoding_stream_ops_t *ops, unsigned flags TSRMLS_DC)