-PHP_HTTP_API STATUS _http_encode(http_encoding_type type, int level, const char *data, size_t data_len, char **encoded, size_t *encoded_len TSRMLS_DC)
-{
- STATUS status = SUCCESS;
-
- switch (type)
- {
- case HTTP_ENCODING_ANY:
- case HTTP_ENCODING_GZIP:
- status = http_encoding_gzencode(level, data, data_len, encoded, encoded_len);
- break;
-
- case HTTP_ENCODING_DEFLATE:
- status = http_encoding_deflate(level, data, data_len, encoded, encoded_len);
- break;
-
- case HTTP_ENCODING_COMPRESS:
- status = http_encoding_compress(level, data, data_len, encoded, encoded_len);
- break;
-
- case HTTP_ENCODING_NONE:
- default:
- *encoded = estrndup(data, data_len);
- *encoded_len = data_len;
- break;
- }
-
- return status;
-}
-
-PHP_HTTP_API STATUS _http_decode(http_encoding_type type, const char *data, size_t data_len, char **decoded, size_t *decoded_len TSRMLS_DC)
-{
- STATUS status = SUCCESS;
-
- switch (type)
- {
- case HTTP_ENCODING_ANY:
- if ( SUCCESS != http_encoding_gzdecode(data, data_len, decoded, decoded_len) &&
- SUCCESS != http_encoding_inflate(data, data_len, decoded, decoded_len) &&
- SUCCESS != http_encoding_uncompress(data, data_len, decoded, decoded_len)) {
- status = FAILURE;
- }
- 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_ENCODING_BUFLEN(data_len));
-
- if (Z_OK == (status = compress2((Bytef *) *encoded, (uLongf *) encoded_len, (const Bytef *) 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;
- }
- }
- }
- } while (++max < HTTP_ENCODING_MAXTRY && status == Z_BUF_ERROR);
-
- efree(*decoded);
- http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Could not inflate data: %s", zError(status));
- return FAILURE;
-}
-
-PHP_HTTP_API STATUS _http_encoding_uncompress(const char *data, size_t data_len, char **decoded, size_t *decoded_len TSRMLS_DC)
-{
- int max = 0;
- STATUS status;
-
- do {
- http_init_uncompress_buffer(data_len, decoded, decoded_len, &max);
- if (Z_OK == (status = uncompress((Bytef *) *decoded, (uLongf *) decoded_len, (const Bytef *) data, data_len))) {
- http_finish_buffer(*decoded_len, decoded);
- return SUCCESS;
- }
- } while (++max < HTTP_ENCODING_MAXTRY && status == Z_BUF_ERROR);
-
- efree(*decoded);
- http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Could not uncompress data: %s", zError(status));
- return FAILURE;
-}
-
-#define HTTP_ENCODING_STREAM_ERROR(status, tofree) \
- { \
- if (tofree) efree(tofree); \
- http_error_ex(HE_WARNING, HTTP_E_ENCODING, "GZIP stream error: %s", zError(status)); \
- return FAILURE; \
- }
-
-PHP_HTTP_API STATUS _http_encoding_stream_init(http_encoding_stream *s, int gzip, int level, char **encoded, size_t *encoded_len TSRMLS_DC)
-{
- STATUS status;
-
- memset(s, 0, sizeof(http_encoding_stream));
- if (Z_OK != (status = deflateInit2(&s->Z, level, Z_DEFLATED, -MAX_WBITS, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY))) {
- HTTP_ENCODING_STREAM_ERROR(status, NULL);
- }
-
- if (s->gzip = gzip) {
- s->crc = crc32(0L, Z_NULL, 0);
- *encoded_len = sizeof(http_encoding_gzip_header);
- *encoded = emalloc(*encoded_len);
- memcpy(*encoded, http_encoding_gzip_header, *encoded_len);
- } else {
- *encoded_len = 0;
- *encoded = NULL;
- }
-
- return SUCCESS;
-}
-
-PHP_HTTP_API STATUS _http_encoding_stream_update(http_encoding_stream *s, const char *data, size_t data_len, char **encoded, size_t *encoded_len TSRMLS_DC)
-{
- STATUS status;
-
- *encoded_len = HTTP_ENCODING_BUFLEN(data_len);
- *encoded = emalloc(*encoded_len);
-
- s->Z.next_in = (Bytef *) data;
- s->Z.avail_in = data_len;
- s->Z.next_out = (Bytef *) *encoded;
- s->Z.avail_out = *encoded_len;
-
- status = deflate(&s->Z, Z_SYNC_FLUSH);
-
- if (Z_OK != status && Z_STREAM_END != status) {
- HTTP_ENCODING_STREAM_ERROR(status, *encoded);
- }
- *encoded_len -= s->Z.avail_out;
-
- if (s->gzip) {
- s->crc = crc32(s->crc, (const Bytef *) data, data_len);
- }
-
- return SUCCESS;
-}
-
-PHP_HTTP_API STATUS _http_encoding_stream_finish(http_encoding_stream *s, char **encoded, size_t *encoded_len TSRMLS_DC)
-{
- STATUS status;
-
- *encoded_len = 1024;
- *encoded = emalloc(*encoded_len);
-
- s->Z.next_out = (Bytef *) *encoded;
- s->Z.avail_out = *encoded_len;
-
- if (Z_STREAM_END != (status = deflate(&s->Z, Z_FINISH)) || Z_OK != (status = deflateEnd(&s->Z))) {
- HTTP_ENCODING_STREAM_ERROR(status, *encoded);
- }
-
- *encoded_len -= s->Z.avail_out;
- if (s->gzip) {
- if (s->Z.avail_out < 8) {
- *encoded = erealloc(*encoded, *encoded_len + 8);
- }
- (*encoded)[(*encoded_len)++] = (char) (s->crc & 0xFF);
- (*encoded)[(*encoded_len)++] = (char) ((s->crc >> 8) & 0xFF);
- (*encoded)[(*encoded_len)++] = (char) ((s->crc >> 16) & 0xFF);
- (*encoded)[(*encoded_len)++] = (char) ((s->crc >> 24) & 0xFF);
- (*encoded)[(*encoded_len)++] = (char) ((s->Z.total_in) & 0xFF);
- (*encoded)[(*encoded_len)++] = (char) ((s->Z.total_in >> 8) & 0xFF);
- (*encoded)[(*encoded_len)++] = (char) ((s->Z.total_in >> 16) & 0xFF);
- (*encoded)[(*encoded_len)++] = (char) ((s->Z.total_in >> 24) & 0xFF);
- }
-
- return SUCCESS;
-}
-