+#ifdef HTTP_HAVE_ZLIB
+
+static HTTP_FILTER_FUNCTION(deflate)
+{
+ int out_avail = 0;
+ php_stream_bucket *ptr, *nxt;
+ HTTP_FILTER_BUFFER(inflate) *buffer = (HTTP_FILTER_BUFFER(deflate) *) this->abstract;
+
+ if (bytes_consumed) {
+ *bytes_consumed = 0;
+ }
+
+ /* new data available? */
+ if (buckets_in->head) {
+
+ /* fetch available bucket data */
+ for (ptr = buckets_in->head; ptr; ptr = nxt) {
+ char *encoded = NULL;
+ size_t encoded_len = 0;
+
+ nxt = ptr->next;
+ if (bytes_consumed) {
+ *bytes_consumed += ptr->buflen;
+ }
+
+ if (ptr->buflen) {
+ http_encoding_deflate_stream_update(buffer, ptr->buf, ptr->buflen, &encoded, &encoded_len);
+ if (encoded) {
+ if (encoded_len) {
+ out_avail = 1;
+ NEW_BUCKET(encoded, encoded_len);
+ }
+ efree(encoded);
+ }
+ }
+
+ php_stream_bucket_unlink(ptr TSRMLS_CC);
+ php_stream_bucket_delref(ptr TSRMLS_CC);
+ }
+ }
+
+ /* 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) {
+ if (encoded_len) {
+ out_avail = 1;
+ NEW_BUCKET(encoded, encoded_len);
+ }
+ efree(encoded);
+ }
+ }
+
+ if (flags & PSFS_FLAG_FLUSH_CLOSE) {
+ char *encoded = NULL;
+ size_t encoded_len = 0;
+
+ http_encoding_deflate_stream_finish(buffer, &encoded, &encoded_len);
+ if (encoded) {
+ if (encoded_len) {
+ out_avail = 1;
+ NEW_BUCKET(encoded, encoded_len);
+ }
+ efree(encoded);
+ }
+ }
+
+ return out_avail ? PSFS_PASS_ON : PSFS_FEED_ME;
+}
+
+static HTTP_FILTER_FUNCTION(inflate)
+{
+ int out_avail = 0;
+ php_stream_bucket *ptr, *nxt;
+ HTTP_FILTER_BUFFER(inflate) *buffer = (HTTP_FILTER_BUFFER(inflate) *) this->abstract;
+
+ if (bytes_consumed) {
+ *bytes_consumed = 0;
+ }
+
+ /* new data available? */
+ if (buckets_in->head) {
+
+ /* fetch available bucket data */
+ for (ptr = buckets_in->head; ptr; ptr = nxt) {
+ char *decoded = NULL;
+ size_t decoded_len = 0;
+
+ nxt = ptr->next;
+ if (bytes_consumed) {
+ *bytes_consumed += ptr->buflen;
+ }
+
+ if (ptr->buflen) {
+ http_encoding_inflate_stream_update(buffer, ptr->buf, ptr->buflen, &decoded, &decoded_len);
+ if (decoded) {
+ if (decoded_len) {
+ out_avail = 1;
+ NEW_BUCKET(decoded, decoded_len);
+ }
+ efree(decoded);
+ }
+ }
+
+ php_stream_bucket_unlink(ptr TSRMLS_CC);
+ php_stream_bucket_delref(ptr TSRMLS_CC);
+ }
+ }
+
+ /* 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) {
+ if (decoded_len) {
+ out_avail = 1;
+ NEW_BUCKET(decoded, decoded_len);
+ }
+ efree(decoded);
+ }
+ }
+
+ if (flags & PSFS_FLAG_FLUSH_CLOSE) {
+ char *decoded = NULL;
+ size_t decoded_len = 0;
+
+ http_encoding_inflate_stream_finish(buffer, &decoded, &decoded_len);
+ if (decoded) {
+ if (decoded_len) {
+ out_avail = 1;
+ NEW_BUCKET(decoded, decoded_len);
+ }
+ efree(decoded);
+ }
+ }
+
+ return out_avail ? PSFS_PASS_ON : PSFS_FEED_ME;
+}
+
+static HTTP_FILTER_DESTRUCTOR(deflate)
+{
+ HTTP_FILTER_BUFFER(deflate) *buffer = (HTTP_FILTER_BUFFER(deflate) *) this->abstract;
+ http_encoding_deflate_stream_free(&buffer);
+}
+
+static HTTP_FILTER_DESTRUCTOR(inflate)
+{
+ HTTP_FILTER_BUFFER(inflate) *buffer = (HTTP_FILTER_BUFFER(inflate) *) this->abstract;
+ http_encoding_inflate_stream_free(&buffer);
+}
+
+static HTTP_FILTER_OPS(deflate) = {
+ HTTP_FILTER_FUNC(deflate),
+ HTTP_FILTER_DTOR(deflate),
+ "http.deflate"
+};
+
+static HTTP_FILTER_OPS(inflate) = {
+ HTTP_FILTER_FUNC(inflate),
+ HTTP_FILTER_DTOR(inflate),
+ "http.inflate"
+};
+
+#endif /* HTTP_HAVE_ZLIB */
+