- if (data[2] != (const char) Z_DEFLATED) {
- http_error_ex(error_level TSRMLS_CC, HTTP_E_ENCODING, "Unrecognized compression format (%d)", (int) (data[2] & 0xFF));
- /* still try to decode */
- }
- if ((data[3] & 0x4) == 0x4) {
- if (data_len < offset + 2) {
- goto really_bad_gzip_header;
- }
- /* there are extra fields, the length follows the common header as 2 bytes LSB */
- offset += (unsigned) ((data[offset] & 0xFF));
- offset += 1;
- offset += (unsigned) ((data[offset] & 0xFF) << 8);
- offset += 1;
- }
- if ((data[3] & 0x8) == 0x8) {
- if (data_len <= offset) {
- goto really_bad_gzip_header;
- }
- /* there's a file name */
- offset += strlen(&data[offset]) + 1 /*NUL*/;
- }
- if ((data[3] & 0x10) == 0x10) {
- if (data_len <= offset) {
- goto really_bad_gzip_header;
- }
- /* there's a comment */
- offset += strlen(&data[offset]) + 1 /* NUL */;
- }
- if ((data[3] & 0x2) == 0x2) {
- /* there's a CRC16 of the header */
- offset += 2;
- if (data_len <= offset) {
- goto really_bad_gzip_header;
+ status = deflateInit2(&Z, level, Z_DEFLATED, wbits, MAX_MEM_LEVEL, strategy);
+ if (Z_OK == status) {
+ *encoded_len = HTTP_DEFLATE_BUFFER_SIZE_GUESS(data_len);
+ *encoded = emalloc_rel(*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_rel(*encoded, Z.total_out + 1);
+ (*encoded)[*encoded_len = Z.total_out] = '\0';
+ return SUCCESS;