diff options
Diffstat (limited to 'decoders/http/http_content_decompress.c')
| -rw-r--r-- | decoders/http/http_content_decompress.c | 268 |
1 files changed, 0 insertions, 268 deletions
diff --git a/decoders/http/http_content_decompress.c b/decoders/http/http_content_decompress.c deleted file mode 100644 index 922c624..0000000 --- a/decoders/http/http_content_decompress.c +++ /dev/null @@ -1,268 +0,0 @@ -#include <zlib.h> -#include <string.h> -#include <assert.h> -#include <brotli/decode.h> -#include "http_decoder_private.h" - -#define HTTP_DECOMPRESS_BUFFER_SIZE (4096) - -struct http_content_decompress -{ - enum http_content_encoding encoding; - z_stream *z_stream_ptr; - BrotliDecoderState *br_state; - char *buffer; - size_t buffer_size; -}; - -void http_content_decompress_ownership_borrow(struct http_content_decompress *decompress) -{ - decompress->buffer = NULL; // ownership move to data->decompress_buffer_list, will be freed when message has been processed by all plugins -} - -enum http_content_encoding http_content_encoding_str2int(const char *content_encoding, size_t encoding_str_len) -{ - if (http_strncasecmp_safe("gzip", content_encoding, 4, encoding_str_len) == 0) - { - return HTTP_CONTENT_ENCODING_GZIP; - } - if (http_strncasecmp_safe("deflate", content_encoding, 7, encoding_str_len) == 0) - { - return HTTP_CONTENT_ENCODING_DEFLATE; - } - if (http_strncasecmp_safe("br", content_encoding, 2, encoding_str_len) == 0) - { - return HTTP_CONTENT_ENCODING_BR; - } - return HTTP_CONTENT_ENCODING_NONE; -} - -const char *http_content_encoding_int2str(enum http_content_encoding content_encoding) -{ - if (content_encoding == HTTP_CONTENT_ENCODING_GZIP) - { - return "gzip"; - } - if (content_encoding == HTTP_CONTENT_ENCODING_DEFLATE) - { - return "deflate"; - } - if (content_encoding == HTTP_CONTENT_ENCODING_BR) - { - return "br"; - } - return "unknown"; -} - -struct http_content_decompress *http_content_decompress_create(enum http_content_encoding encoding) -{ - struct http_content_decompress *decompress = - CALLOC(struct http_content_decompress, 1); - assert(decompress); - - decompress->encoding = encoding; - decompress->z_stream_ptr = NULL; - decompress->br_state = NULL; - - if (encoding == HTTP_CONTENT_ENCODING_GZIP || encoding == HTTP_CONTENT_ENCODING_DEFLATE) - { - decompress->z_stream_ptr = CALLOC(z_stream, 1); - assert(decompress->z_stream_ptr); - - decompress->z_stream_ptr->zalloc = NULL; - decompress->z_stream_ptr->zfree = NULL; - decompress->z_stream_ptr->opaque = NULL; - decompress->z_stream_ptr->avail_in = 0; - decompress->z_stream_ptr->next_in = Z_NULL; - - if (encoding == HTTP_CONTENT_ENCODING_GZIP) - { - if (inflateInit2(decompress->z_stream_ptr, MAX_WBITS + 16) != Z_OK) - { - goto error; - } - } - if (encoding == HTTP_CONTENT_ENCODING_DEFLATE) - { - if (inflateInit2(decompress->z_stream_ptr, -MAX_WBITS) != Z_OK) - { - goto error; - } - } - } - - if (encoding == HTTP_CONTENT_ENCODING_BR) - { - decompress->br_state = BrotliDecoderCreateInstance(NULL, NULL, NULL); - if (decompress->br_state == NULL) - { - goto error; - } - } - return decompress; - -error: - http_content_decompress_destroy(decompress); - return NULL; -} - -void http_content_decompress_destroy(struct http_content_decompress *decompress) -{ - if (NULL == decompress) - { - return; - } - if (decompress->z_stream_ptr != NULL) - { - inflateEnd(decompress->z_stream_ptr); - FREE(decompress->z_stream_ptr); - } - if (decompress->br_state) - { - BrotliDecoderDestroyInstance(decompress->br_state); - decompress->br_state = NULL; - } - FREE(decompress->buffer); - FREE(decompress); -} - -static int http_content_decompress_write_zlib(struct http_content_decompress *decompress, - const char *indata, size_t indata_len, - char **outdata, size_t *outdata_len) -{ - z_stream *z_stream_ptr = decompress->z_stream_ptr; - z_stream_ptr->avail_in = (unsigned int)indata_len; - z_stream_ptr->next_in = (unsigned char *)indata; - z_stream_ptr->avail_out = (unsigned int)HTTP_DECOMPRESS_BUFFER_SIZE; - z_stream_ptr->next_out = (unsigned char *)decompress->buffer; - *outdata = NULL; - *outdata_len = 0; - size_t total_have = 0; - int no_buffer; - - do - { - int ret = inflate(z_stream_ptr, Z_NO_FLUSH); - if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT || ret == Z_DATA_ERROR || ret == Z_MEM_ERROR) - { - (void)inflateEnd(z_stream_ptr); - return -1; - } - size_t have = HTTP_DECOMPRESS_BUFFER_SIZE - z_stream_ptr->avail_out; - if (have > 0) - { - total_have += have; - if (0 == z_stream_ptr->avail_out) - { - decompress->buffer_size += HTTP_DECOMPRESS_BUFFER_SIZE; - decompress->buffer = REALLOC(char, decompress->buffer, decompress->buffer_size); - z_stream_ptr->avail_out = HTTP_DECOMPRESS_BUFFER_SIZE; - z_stream_ptr->next_out = (unsigned char *)decompress->buffer + total_have; - *outdata = decompress->buffer; - *outdata_len = total_have; - no_buffer = 1; - } - else - { - *outdata = decompress->buffer; - *outdata_len = total_have; - no_buffer = 0; - } - } - else - { - break; - } - if (Z_STREAM_END == ret) - { - break; - } - } while (no_buffer == 1); - return 0; -} - -static int http_content_decompress_write_br(struct http_content_decompress *decompress, - const char *indata, size_t indata_len, - char **outdata, size_t *outdata_len) -{ - size_t available_in = indata_len; - const unsigned char *next_in = (const unsigned char *)indata; - size_t available_out = HTTP_DECOMPRESS_BUFFER_SIZE; - unsigned char *next_out = (unsigned char *)decompress->buffer; - - *outdata = NULL; - *outdata_len = 0; - size_t total_have = 0; - int no_buffer; - - do - { - int ret = BrotliDecoderDecompressStream(decompress->br_state, &available_in, - &next_in, &available_out, &next_out, NULL); - if (ret == BROTLI_DECODER_RESULT_ERROR) - { - // BrotliDecoderErrorCode errcode = BrotliDecoderGetErrorCode(decompress->br_state); - *outdata = NULL; - *outdata_len = 0; - return -1; - } - size_t have = HTTP_DECOMPRESS_BUFFER_SIZE - available_out; - if (have > 0) - { - total_have += have; - if (0 == available_out) - { - decompress->buffer_size += HTTP_DECOMPRESS_BUFFER_SIZE; - decompress->buffer = REALLOC(char, decompress->buffer, decompress->buffer_size); - available_out = HTTP_DECOMPRESS_BUFFER_SIZE; - next_out = (unsigned char *)decompress->buffer + total_have; - *outdata = decompress->buffer; - *outdata_len = total_have; - no_buffer = 1; - } - else - { - *outdata = decompress->buffer; - *outdata_len = have; - no_buffer = 0; - } - } - else - { - break; - } - } while (no_buffer == 1); - return 0; -} - -int http_content_decompress_write(struct http_content_decompress *decompress, - const char *indata, size_t indata_len, - char **outdata, size_t *outdata_len) -{ - assert(decompress); - assert(indata); - assert(indata_len > 0); - assert(outdata); - assert(outdata_len); - *outdata = NULL; - *outdata_len = 0; - - if (NULL == decompress->buffer) - { - decompress->buffer = CALLOC(char, HTTP_DECOMPRESS_BUFFER_SIZE); - assert(decompress->buffer); - decompress->buffer_size = HTTP_DECOMPRESS_BUFFER_SIZE; - } - - if (decompress->encoding == HTTP_CONTENT_ENCODING_GZIP || - decompress->encoding == HTTP_CONTENT_ENCODING_DEFLATE) - { - return http_content_decompress_write_zlib(decompress, indata, indata_len, outdata, outdata_len); - } - if (decompress->encoding == HTTP_CONTENT_ENCODING_BR) - { - return http_content_decompress_write_br(decompress, indata, indata_len, outdata, outdata_len); - } - assert(0); - return -1; -}
\ No newline at end of file |
