- break;
-
- case HTTP_ENCODING_GZIP:
- status = http_encoding_gzdecode(data, data_len, decoded, decoded_len);
- break;
-
- case HTTP_ENCODING_DEFLATE:
- status = http_encoding_inflate(data, data_len, decoded, decoded_len);
- break;
-
- case HTTP_ENCODING_COMPRESS:
- status = http_encoding_uncompress(data, data_len, decoded, decoded_len);
- break;
-
- case HTTP_ENCODING_NONE:
- default:
- *decoded = estrndup(data, data_len);
- *decoded_len = data_len;
- break;
- }
-
- return status;
-}
-
-PHP_HTTP_API STATUS _http_encoding_gzencode(int level, const char *data, size_t data_len, char **encoded, size_t *encoded_len TSRMLS_DC)
-{
- z_stream Z;
- STATUS status = Z_OK;
-
- http_init_gzencode_buffer(&Z, data, data_len, encoded);
-
- if ( (Z_OK == (status = deflateInit2(&Z, level, Z_DEFLATED, -MAX_WBITS, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY))) &&
- (Z_STREAM_END == (status = deflate(&Z, Z_FINISH))) &&
- (Z_OK == (status = deflateEnd(&Z)))) {
- *encoded_len = http_finish_gzencode_buffer(&Z, data, data_len, encoded);
- return SUCCESS;
- }
-
- efree(*encoded);
- http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Could not gzencode data: %s", zError(status));
- return FAILURE;
-}
-
-PHP_HTTP_API STATUS _http_encoding_deflate(int level, const char *data, size_t data_len, char **encoded, size_t *encoded_len TSRMLS_DC)
-{
- z_stream Z;
- STATUS status = Z_OK;
-
- http_init_deflate_buffer(&Z, data, data_len, encoded);
-
- if ( (Z_OK == (status = deflateInit2(&Z, level, Z_DEFLATED, -MAX_WBITS, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY))) &&
- (Z_STREAM_END == (status = deflate(&Z, Z_FINISH))) &&
- (Z_OK == (status = deflateEnd(&Z)))) {
- *encoded_len = http_finish_buffer(Z.total_out, encoded);
- return SUCCESS;
- }
-
- efree(encoded);
- http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Could not deflate data: %s", zError(status));
- return FAILURE;
-}
-
-PHP_HTTP_API STATUS _http_encoding_compress(int level, const char *data, size_t data_len, char **encoded, size_t *encoded_len TSRMLS_DC)
-{
- STATUS status;
-
- *encoded = emalloc(*encoded_len = HTTP_GZBUFLEN(data_len));
-
- if (Z_OK == (status = compress2(*encoded, encoded_len, data, data_len, level))) {
- http_finish_buffer(*encoded_len, encoded);
- return SUCCESS;
- }
-
- efree(encoded);
- http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Could not compress data: %s", zError(status));
- return FAILURE;
-}
-
-PHP_HTTP_API STATUS _http_encoding_gzdecode(const char *data, size_t data_len, char **decoded, size_t *decoded_len TSRMLS_DC)
-{
- const char *encoded;
- size_t encoded_len;
-
- if ( (SUCCESS == http_verify_gzencode_buffer(data, data_len, &encoded, &encoded_len, HE_NOTICE)) &&
- (SUCCESS == http_encoding_inflate(encoded, encoded_len, decoded, decoded_len))) {
- http_verify_gzdecode_buffer(data, data_len, *decoded, *decoded_len, HE_NOTICE);
- return SUCCESS;
- }
-
- return FAILURE;
-}
-
-PHP_HTTP_API STATUS _http_encoding_inflate(const char *data, size_t data_len, char **decoded, size_t *decoded_len TSRMLS_DC)
-{
- int max = 0;
- STATUS status;
- z_stream Z;
-
- do {
- http_init_inflate_buffer(&Z, data, data_len, decoded, decoded_len, max++);
- if (Z_OK == (status = inflateInit2(&Z, -MAX_WBITS))) {
- if (Z_STREAM_END == (status = inflate(&Z, Z_FINISH))) {
- if (Z_OK == (status = inflateEnd(&Z))) {
- *decoded_len = http_finish_buffer(Z.total_out, decoded);
- return SUCCESS;
+ } else {
+#ifndef HTTP_HAVE_ZLIB
+ HTTP_G(send).gzip_encoding = 0;
+ php_start_ob_buffer_named("ob_gzhandler", 0, 0 TSRMLS_CC);
+#else
+ HashTable *selected;
+ zval zsupported;
+
+ INIT_PZVAL(&zsupported);
+ array_init(&zsupported);
+ add_next_index_stringl(&zsupported, "gzip", lenof("gzip"), 1);
+ add_next_index_stringl(&zsupported, "x-gzip", lenof("x-gzip"), 1);
+ add_next_index_stringl(&zsupported, "deflate", lenof("deflate"), 1);
+
+ HTTP_G(send).gzip_encoding = 0;
+
+ if ((selected = http_negotiate_encoding(&zsupported))) {
+ STATUS hs = FAILURE;
+ char *encoding = NULL;
+ ulong idx;
+
+ if (HASH_KEY_IS_STRING == zend_hash_get_current_key(selected, &encoding, &idx, 0) && encoding) {
+ if (!strcmp(encoding, "gzip") || !strcmp(encoding, "x-gzip")) {
+ if (SUCCESS == (hs = http_send_header_string("Content-Encoding: gzip"))) {
+ HTTP_G(send).gzip_encoding = HTTP_ENCODING_GZIP;
+ }
+ } else if (!strcmp(encoding, "deflate")) {
+ if (SUCCESS == (hs = http_send_header_string("Content-Encoding: deflate"))) {
+ HTTP_G(send).gzip_encoding = HTTP_ENCODING_DEFLATE;
+ }
+ }
+ if (SUCCESS == hs) {
+ http_send_header_string("Vary: Accept-Encoding");
+ }