增加对GZIP压缩编码的解压缩功能及单元测试用例

This commit is contained in:
Lu Qiuwen
2018-09-26 21:31:17 +08:00
parent c7eeda0fb1
commit 8a4f02fbb8
6 changed files with 427 additions and 29 deletions

View File

@@ -1,18 +1,23 @@
### PLUGIN ### PLUGIN
add_library(http src/http_entry.cpp src/http_half.cpp) add_library(http src/http_entry.cpp src/http_half.cpp src/http_convert.cpp)
target_include_directories(http PRIVATE include/internal) target_include_directories(http PRIVATE include/internal)
target_include_directories(http PUBLIC incluce/external) target_include_directories(http PUBLIC incluce/external)
target_link_libraries(http common) target_link_libraries(http common)
target_link_libraries(http http-parser-static) target_link_libraries(http http-parser-static)
target_link_libraries(http libevent-static) target_link_libraries(http libevent-static)
target_link_libraries(http z)
### UNITTEST CASE ### UNITTEST CASE
add_executable(test-http-half test/test_http_half.cpp) add_executable(test-http-half test/test_http_half.cpp)
target_include_directories(test-http-half PRIVATE include/internal) target_include_directories(test-http-half PRIVATE include/internal)
target_link_libraries(test-http-half gtest common http) target_link_libraries(test-http-half gtest common http)
add_executable(test-http-convert test/test_http_convert.cpp)
target_include_directories(test-http-convert PRIVATE include/internal)
target_link_libraries(test-http-convert gtest common http)
include(GoogleTest) include(GoogleTest)
gtest_discover_tests(test-http-half) gtest_discover_tests(test-http-half)
gtest_discover_tests(test-http-convert)

View File

@@ -0,0 +1,19 @@
#pragma once
#include <tfe_http.h>
#include <http_half.h>
struct hf_content_converter;
enum hf_content_conv_work_mode
{
HF_CONTENT_CONV_COMPRASS,
HF_CONTENT_CONV_UNCOMPRASS
};
int hf_content_converter_write(struct hf_content_converter * cv_object,
struct http_half_private * hf_private, tfe_http_event http_ev, const unsigned char * data, size_t datalen);
void hf_content_converter_destroy(struct hf_content_converter * cv_object);
struct hf_content_converter * hf_content_converter_create(enum hf_content_conv_work_mode mode,
unsigned int content_encode, hf_private_cb * data_cb, void * data_cb_user);

View File

@@ -21,6 +21,15 @@ struct http_header_private
char * value; char * value;
}; };
#define BV(x) (1 << x)
#define HTTP_ACCEPT_ENCODING_IDENTITY BV(0)
#define HTTP_ACCEPT_ENCODING_GZIP BV(1)
#define HTTP_ACCEPT_ENCODING_DEFLATE BV(2)
#define HTTP_ACCEPT_ENCODING_COMPRESS BV(3)
#define HTTP_ACCEPT_ENCODING_BZIP2 BV(4)
#define HTTP_ACCEPT_ENCODING_X_GZIP BV(5)
#define HTTP_ACCEPT_ENCODING_X_BZIP2 BV(6)
TAILQ_HEAD(http_header_private_list, http_header_private); TAILQ_HEAD(http_header_private_list, http_header_private);
struct http_half_private struct http_half_private
{ {
@@ -54,6 +63,9 @@ struct http_half_private
struct evbuffer * evbuf_uri; struct evbuffer * evbuf_uri;
char * url_storage; char * url_storage;
/* Content-Encoding */
uint16_t content_encoding;
/* Header Parser */ /* Header Parser */
struct evbuffer * evbuf_header_field; struct evbuffer * evbuf_header_field;
struct evbuffer * evbuf_header_value; struct evbuffer * evbuf_header_value;
@@ -104,8 +116,6 @@ struct http_session_private * hs_private_create(struct http_connection_private *
void hs_private_destory(struct http_session_private * hs_private); void hs_private_destory(struct http_session_private * hs_private);
void hs_private_hf_private_set(struct http_session_private * hs_private, void hs_private_hf_private_set(struct http_session_private * hs_private,
struct http_half_private * hf, enum tfe_http_direction); struct http_half_private * hf, enum tfe_http_direction);

View File

@@ -0,0 +1,121 @@
#include <zlib.h>
#include <http_common.h>
#include <http_half.h>
#include <http_convert.h>
struct hf_content_converter
{
/* MODE AND CALLBACKS */
enum hf_content_conv_work_mode mode;
unsigned int content_encode;
hf_private_cb * data_cb;
void * data_cb_user;
/* ZLIB STREAM */
z_stream * z_stream_ptr;
unsigned char * chunk;
size_t sz_chunk;
};
void hf_content_converter_destroy(struct hf_content_converter * cv_object)
{
if (cv_object->z_stream_ptr && cv_object->mode == HF_CONTENT_CONV_COMPRASS)
{
(void)deflateEnd(cv_object->z_stream_ptr);
free(cv_object->z_stream_ptr);
}
if (cv_object->z_stream_ptr && cv_object->mode == HF_CONTENT_CONV_UNCOMPRASS)
{
(void)inflateEnd(cv_object->z_stream_ptr);
free(cv_object->z_stream_ptr);
}
cv_object->z_stream_ptr = NULL;
free(cv_object);
}
struct hf_content_converter * hf_content_converter_create(enum hf_content_conv_work_mode mode,
unsigned int content_encode, hf_private_cb * data_cb, void * data_cb_user)
{
struct hf_content_converter * cv_object = ALLOC(struct hf_content_converter, 1);
assert(data_cb != NULL);
cv_object->mode = mode;
cv_object->content_encode = content_encode;
cv_object->data_cb = data_cb;
cv_object->data_cb_user = data_cb_user;
/* ZSTREAM */
cv_object->z_stream_ptr = ALLOC(z_stream, 1);
cv_object->z_stream_ptr->zalloc = NULL;
cv_object->z_stream_ptr->zfree = NULL;
cv_object->z_stream_ptr->opaque = NULL;
cv_object->z_stream_ptr->avail_in = 0;
cv_object->z_stream_ptr->next_in = Z_NULL;
/* CHUNK, 4K */
#define CHUNK_SIZE (1024 * 1024 * 4)
cv_object->chunk = (unsigned char *)malloc(CHUNK_SIZE);
cv_object->sz_chunk = CHUNK_SIZE;
int ret = 0;
if (content_encode == HTTP_ACCEPT_ENCODING_GZIP)
{
ret = inflateInit2(cv_object->z_stream_ptr, MAX_WBITS + 16);
}
else if (content_encode == HTTP_ACCEPT_ENCODING_DEFLATE)
{
ret = inflateInit(cv_object->z_stream_ptr);
}
if (ret != Z_OK) goto __errout;
return cv_object;
__errout:
free(cv_object->z_stream_ptr);
free(cv_object->chunk);
free(cv_object);
return NULL;
}
int hf_content_converter_write(struct hf_content_converter * cv_object,
struct http_half_private * hf_private, tfe_http_event http_ev, const unsigned char * data, size_t datalen)
{
z_stream * z_stream_ptr = cv_object->z_stream_ptr;
z_stream_ptr->avail_in = (unsigned int)datalen;
z_stream_ptr->next_in = (unsigned char *)data;
if (z_stream_ptr->avail_in == 0)
{
(void)inflateEnd(z_stream_ptr);
return Z_ERRNO;
}
int ret = 0;
do
{
z_stream_ptr->avail_out = (unsigned int) cv_object->sz_chunk;
z_stream_ptr->next_out = cv_object->chunk;
ret = inflate(z_stream_ptr, Z_NO_FLUSH);
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
if (ret == Z_NEED_DICT || ret == Z_DATA_ERROR || ret == Z_MEM_ERROR)
{
goto __error;
}
unsigned int have = (unsigned int) cv_object->sz_chunk - z_stream_ptr->avail_out;
if (have > 0 && cv_object->data_cb != NULL)
{
cv_object->data_cb(hf_private, http_ev, cv_object->chunk, (size_t) have, cv_object->data_cb_user);
}
} while (z_stream_ptr->avail_out == 0);
return ret;
__error:
(void)inflateEnd(z_stream_ptr);
return ret;
}

View File

@@ -61,6 +61,36 @@ static enum tfe_http_std_field __str_header_field_to_std_field_id(const char * s
return TFE_HTTP_UNKNOWN_FIELD; return TFE_HTTP_UNKNOWN_FIELD;
} }
uint16_t __hf_content_encoding_parse(const char * str_content_encoding)
{
if (strcasestr(str_content_encoding, "gzip") != NULL)
{
return HTTP_ACCEPT_ENCODING_GZIP;
}
if (strcasestr(str_content_encoding, "x-gzip") != NULL)
{
return HTTP_ACCEPT_ENCODING_X_GZIP;
}
if (strcasestr(str_content_encoding, "deflate") != NULL)
{
return HTTP_ACCEPT_ENCODING_DEFLATE;
}
if (strcasestr(str_content_encoding, "bzip2") != NULL)
{
return HTTP_ACCEPT_ENCODING_BZIP2;
}
if (strcasestr(str_content_encoding, "x-bzip2") != NULL)
{
return HTTP_ACCEPT_ENCODING_X_BZIP2;
}
return HTTP_ACCEPT_ENCODING_IDENTITY;
}
/* To flush header field and value which stash in evbuffer */ /* To flush header field and value which stash in evbuffer */
static void __http_half_header_kv_complete(struct http_half_private * hf_private) static void __http_half_header_kv_complete(struct http_half_private * hf_private)
{ {
@@ -120,12 +150,7 @@ void __hf_public_req_fill_from_private(struct http_half_private * hf_private, st
/* accept-encoding, host is located in header's K-V structure */ /* accept-encoding, host is located in header's K-V structure */
hf_req_spec->method = (enum tfe_http_std_method) parser->method; hf_req_spec->method = (enum tfe_http_std_method) parser->method;
const static struct http_field_name __host_field_name = const static struct http_field_name __host_field_name = {TFE_HTTP_HOST, NULL};
{
.field_id = TFE_HTTP_HOST,
.field_name = NULL
};
hf_req_spec->host = (char *) tfe_http_field_read(hf_public, &__host_field_name); hf_req_spec->host = (char *) tfe_http_field_read(hf_public, &__host_field_name);
/* uri is stored in underlay evbuffer, we need to append a terminal zero */ /* uri is stored in underlay evbuffer, we need to append a terminal zero */
@@ -157,31 +182,25 @@ void __hf_public_resp_fill_from_private(struct http_half_private * hf_private, s
hf_resp_spec->resp_code = parser->status_code; hf_resp_spec->resp_code = parser->status_code;
/* Content Type */ /* Content Type */
const static struct http_field_name __cont_encoding_type_name = const static struct http_field_name __cont_encoding_type_name = {TFE_HTTP_CONT_TYPE, NULL};
{
.field_id = TFE_HTTP_CONT_TYPE,
.field_name = NULL
};
hf_resp_spec->content_type = (char *) tfe_http_field_read(hf_public, &__cont_encoding_type_name); hf_resp_spec->content_type = (char *) tfe_http_field_read(hf_public, &__cont_encoding_type_name);
/* Content Length */ /* Content Length */
const static struct http_field_name __cont_encoding_length_name = const static struct http_field_name __cont_encoding_length_name = {TFE_HTTP_CONT_LENGTH, NULL};
{
.field_id = TFE_HTTP_CONT_LENGTH,
.field_name = NULL
};
hf_resp_spec->content_length = (char *) tfe_http_field_read(hf_public, &__cont_encoding_length_name); hf_resp_spec->content_length = (char *) tfe_http_field_read(hf_public, &__cont_encoding_length_name);
/* Content Encoding */ /* Content Encoding */
const static struct http_field_name __cont_encoding_field_name = const static struct http_field_name __cont_encoding_field_name = {TFE_HTTP_CONT_ENCODING, NULL};
{
.field_id = TFE_HTTP_CONT_ENCODING,
.field_name = NULL
};
hf_resp_spec->content_encoding = (char *) tfe_http_field_read(hf_public, &__cont_encoding_field_name); hf_resp_spec->content_encoding = (char *) tfe_http_field_read(hf_public, &__cont_encoding_field_name);
if (hf_resp_spec->content_encoding != NULL)
{
hf_private->content_encoding = __hf_content_encoding_parse(hf_resp_spec->content_encoding);
}
else
{
hf_private->content_encoding = HTTP_ACCEPT_ENCODING_IDENTITY;
}
} }
/* ================================================================================================================== /* ==================================================================================================================
@@ -656,7 +675,7 @@ struct tfe_http_session_ops __http_session_ops =
void __construct_request_line(struct http_half_private * hf_private) void __construct_request_line(struct http_half_private * hf_private)
{ {
enum tfe_http_std_method __std_method = (enum tfe_http_std_method ) hf_private->method_or_status; enum tfe_http_std_method __std_method = (enum tfe_http_std_method) hf_private->method_or_status;
const char * __str_method = http_std_method_to_string(__std_method); const char * __str_method = http_std_method_to_string(__std_method);
if (__str_method == NULL) if (__str_method == NULL)
{ {

View File

@@ -0,0 +1,224 @@
#include <gtest/gtest.h>
#include <http_convert.h>
unsigned char __64x[] = {
0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
0x58, 0x58, 0x58, 0x58
};
unsigned char __64x_gz[] = {
0x1f, 0x8b, 0x08, 0x08, 0x56, 0x77, 0xab, 0x5b, 0x00, 0x03, 0x36, 0x34,
0x78, 0x00, 0x8b, 0x88, 0xa0, 0x0c, 0x00, 0x00, 0x7b, 0xab, 0x2a, 0xf2,
0x40, 0x00, 0x00, 0x00
};
unsigned char monkey[] = {
0x7a, 0x6e, 0x78, 0x63, 0x76, 0x6e, 0x6d, 0x7a, 0x2c, 0x78, 0x76, 0x6e,
0x6d, 0x2e, 0x2c, 0x7a, 0x78, 0x63, 0x6e, 0x76, 0x2e, 0x2c, 0x78, 0x63,
0x6e, 0x2e, 0x7a, 0x2c, 0x76, 0x6e, 0x2e, 0x7a, 0x76, 0x6e, 0x2e, 0x7a,
0x78, 0x63, 0x76, 0x6e, 0x2e, 0x2c, 0x7a, 0x78, 0x63, 0x6e, 0x2e, 0x76,
0x6e, 0x2e, 0x76, 0x2c, 0x7a, 0x6e, 0x6d, 0x2e, 0x2c, 0x76, 0x6e, 0x7a,
0x78, 0x2e, 0x2c, 0x76, 0x6e, 0x7a, 0x78, 0x63, 0x2e, 0x76, 0x6e, 0x2e,
0x7a, 0x2c, 0x76, 0x6e, 0x7a, 0x2e, 0x2c, 0x6e, 0x76, 0x2e, 0x7a, 0x2c,
0x6e, 0x76, 0x6d, 0x7a, 0x78, 0x63, 0x2c, 0x6e, 0x76, 0x7a, 0x78, 0x63,
0x76, 0x63, 0x6e, 0x6d, 0x2e, 0x2c, 0x76, 0x63, 0x7a, 0x78, 0x76, 0x6e,
0x7a, 0x78, 0x63, 0x6e, 0x76, 0x6d, 0x78, 0x63, 0x2e, 0x7a, 0x6d, 0x63,
0x6e, 0x76, 0x7a, 0x6d, 0x2e, 0x2c, 0x6e, 0x76, 0x6d, 0x63, 0x2c, 0x6e,
0x7a, 0x78, 0x6d, 0x63, 0x2c, 0x76, 0x6e, 0x2e, 0x6d, 0x6e, 0x6e, 0x6d,
0x7a, 0x78, 0x63, 0x2c, 0x76, 0x6e, 0x78, 0x63, 0x6e, 0x6d, 0x76, 0x2c,
0x7a, 0x6e, 0x76, 0x7a, 0x78, 0x63, 0x6e, 0x6d, 0x76, 0x2c, 0x2e, 0x78,
0x63, 0x6e, 0x76, 0x6d, 0x2c, 0x7a, 0x78, 0x63, 0x6e, 0x7a, 0x78, 0x76,
0x2e, 0x7a, 0x78, 0x2c, 0x71, 0x77, 0x65, 0x72, 0x79, 0x77, 0x65, 0x75,
0x72, 0x71, 0x69, 0x6f, 0x77, 0x65, 0x75, 0x70, 0x72, 0x6f, 0x70, 0x71,
0x77, 0x75, 0x74, 0x69, 0x6f, 0x77, 0x65, 0x75, 0x70, 0x71, 0x72, 0x69,
0x6f, 0x77, 0x65, 0x75, 0x74, 0x69, 0x6f, 0x70, 0x77, 0x65, 0x75, 0x72,
0x69, 0x6f, 0x70, 0x77, 0x65, 0x75, 0x72, 0x69, 0x6f, 0x70, 0x71, 0x77,
0x75, 0x72, 0x69, 0x6f, 0x70, 0x75, 0x74, 0x69, 0x6f, 0x70, 0x71, 0x77,
0x75, 0x72, 0x69, 0x6f, 0x77, 0x75, 0x71, 0x65, 0x72, 0x69, 0x6f, 0x75,
0x70, 0x71, 0x77, 0x65, 0x72, 0x6f, 0x70, 0x75, 0x77, 0x65, 0x72, 0x6f,
0x70, 0x71, 0x77, 0x75, 0x72, 0x77, 0x65, 0x75, 0x71, 0x72, 0x69, 0x6f,
0x70, 0x75, 0x72, 0x6f, 0x70, 0x71, 0x77, 0x75, 0x72, 0x69, 0x6f, 0x70,
0x75, 0x71, 0x77, 0x72, 0x69, 0x6f, 0x70, 0x75, 0x71, 0x77, 0x65, 0x6f,
0x70, 0x72, 0x75, 0x69, 0x6f, 0x71, 0x77, 0x65, 0x75, 0x72, 0x71, 0x77,
0x65, 0x75, 0x72, 0x69, 0x6f, 0x75, 0x71, 0x77, 0x65, 0x6f, 0x70, 0x72,
0x75, 0x69, 0x6f, 0x75, 0x70, 0x71, 0x69, 0x79, 0x74, 0x69, 0x6f, 0x71,
0x74, 0x79, 0x69, 0x6f, 0x77, 0x74, 0x79, 0x71, 0x70, 0x74, 0x79, 0x70,
0x72, 0x79, 0x6f, 0x71, 0x77, 0x65, 0x75, 0x74, 0x69, 0x6f, 0x69, 0x6f,
0x71, 0x74, 0x77, 0x65, 0x71, 0x72, 0x75, 0x6f, 0x77, 0x71, 0x65, 0x79,
0x74, 0x69, 0x6f, 0x77, 0x71, 0x75, 0x69, 0x6f, 0x75, 0x72, 0x6f, 0x77,
0x65, 0x74, 0x79, 0x6f, 0x71, 0x77, 0x75, 0x70, 0x69, 0x6f, 0x74, 0x77,
0x65, 0x75, 0x71, 0x69, 0x6f, 0x72, 0x77, 0x65, 0x75, 0x71, 0x72, 0x6f,
0x69, 0x70, 0x69, 0x74, 0x75, 0x71, 0x77, 0x69, 0x6f, 0x72, 0x71, 0x77,
0x74, 0x69, 0x6f, 0x77, 0x65, 0x75, 0x72, 0x69, 0x6f, 0x75, 0x79, 0x74,
0x75, 0x69, 0x6f, 0x65, 0x72, 0x79, 0x74, 0x75, 0x69, 0x6f, 0x77, 0x65,
0x72, 0x79, 0x75, 0x69, 0x74, 0x6f, 0x77, 0x65, 0x79, 0x74, 0x75, 0x69,
0x77, 0x65, 0x79, 0x75, 0x69, 0x74, 0x79, 0x65, 0x72, 0x75, 0x69, 0x72,
0x74, 0x79, 0x75, 0x71, 0x72, 0x69, 0x71, 0x77, 0x65, 0x75, 0x72, 0x6f,
0x70, 0x71, 0x77, 0x65, 0x69, 0x72, 0x75, 0x69, 0x6f, 0x71, 0x77, 0x65,
0x75, 0x72, 0x69, 0x6f, 0x71, 0x77, 0x75, 0x65, 0x72, 0x69, 0x6f, 0x71,
0x77, 0x79, 0x75, 0x69, 0x74, 0x75, 0x69, 0x65, 0x72, 0x77, 0x6f, 0x74,
0x75, 0x65, 0x72, 0x79, 0x75, 0x69, 0x6f, 0x74, 0x77, 0x65, 0x79, 0x72,
0x74, 0x75, 0x69, 0x77, 0x65, 0x72, 0x74, 0x79, 0x69, 0x6f, 0x77, 0x65,
0x72, 0x79, 0x72, 0x75, 0x65, 0x69, 0x6f, 0x71, 0x70, 0x74, 0x79, 0x69,
0x6f, 0x72, 0x75, 0x79, 0x69, 0x6f, 0x70, 0x71, 0x77, 0x74, 0x6a, 0x6b,
0x61, 0x73, 0x64, 0x66, 0x68, 0x6c, 0x61, 0x66, 0x68, 0x6c, 0x61, 0x73,
0x64, 0x68, 0x66, 0x6a, 0x6b, 0x6c, 0x61, 0x73, 0x68, 0x6a, 0x6b, 0x66,
0x68, 0x61, 0x73, 0x6a, 0x6b, 0x6c, 0x66, 0x68, 0x6b, 0x6c, 0x61, 0x73,
0x6a, 0x64, 0x66, 0x68, 0x6b, 0x6c, 0x61, 0x73, 0x64, 0x68, 0x66, 0x6a,
0x6b, 0x61, 0x6c, 0x73, 0x64, 0x68, 0x66, 0x6b, 0x6c, 0x61, 0x73, 0x64,
0x68, 0x6a, 0x6b, 0x66, 0x6c, 0x61, 0x68, 0x73, 0x6a, 0x64, 0x6b, 0x66,
0x68, 0x6b, 0x6c, 0x61, 0x73, 0x66, 0x68, 0x6a, 0x6b, 0x61, 0x73, 0x64,
0x66, 0x68, 0x61, 0x73, 0x66, 0x6a, 0x6b, 0x61, 0x73, 0x64, 0x68, 0x66,
0x6b, 0x6c, 0x73, 0x64, 0x68, 0x61, 0x6c, 0x67, 0x68, 0x68, 0x61, 0x66,
0x3b, 0x68, 0x64, 0x6b, 0x6c, 0x61, 0x73, 0x66, 0x68, 0x6a, 0x6b, 0x6c,
0x61, 0x73, 0x68, 0x6a, 0x6b, 0x6c, 0x66, 0x61, 0x73, 0x64, 0x68, 0x66,
0x61, 0x73, 0x64, 0x6a, 0x6b, 0x6c, 0x66, 0x68, 0x73, 0x64, 0x6a, 0x6b,
0x6c, 0x61, 0x66, 0x73, 0x64, 0x3b, 0x68, 0x6b, 0x6c, 0x64, 0x61, 0x64,
0x66, 0x6a, 0x6a, 0x6b, 0x6c, 0x61, 0x73, 0x64, 0x68, 0x66, 0x6a, 0x61,
0x73, 0x64, 0x64, 0x66, 0x6a, 0x6b, 0x6c, 0x66, 0x68, 0x61, 0x6b, 0x6a,
0x6b, 0x6c, 0x61, 0x73, 0x64, 0x6a, 0x66, 0x6b, 0x6c, 0x3b, 0x61, 0x73,
0x64, 0x6a, 0x66, 0x61, 0x73, 0x66, 0x6c, 0x6a, 0x61, 0x73, 0x64, 0x66,
0x68, 0x6a, 0x6b, 0x6c, 0x61, 0x73, 0x64, 0x66, 0x68, 0x6a, 0x6b, 0x61,
0x67, 0x68, 0x6a, 0x6b, 0x61, 0x73, 0x68, 0x66, 0x3b, 0x64, 0x6a, 0x66,
0x6b, 0x6c, 0x61, 0x73, 0x64, 0x6a, 0x66, 0x6b, 0x6c, 0x6a, 0x61, 0x73,
0x64, 0x6b, 0x6c, 0x66, 0x6a, 0x6b, 0x6c, 0x61, 0x73, 0x64, 0x6a, 0x66,
0x6b, 0x6c, 0x6a, 0x61, 0x73, 0x64, 0x66, 0x6b, 0x6c, 0x6a, 0x61, 0x6b,
0x6c, 0x66, 0x6a
};
unsigned char monkey_gz[] = {
0x1f, 0x8b, 0x08, 0x08, 0x56, 0x77, 0xab, 0x5b, 0x00, 0x03, 0x6d, 0x6f,
0x6e, 0x6b, 0x65, 0x79, 0x00, 0x55, 0x50, 0x59, 0x92, 0xec, 0x20, 0x0c,
0xbb, 0x50, 0x2a, 0x17, 0xe8, 0xd3, 0x50, 0x09, 0x0c, 0x64, 0x63, 0x69,
0x08, 0x81, 0xd3, 0x3f, 0xc9, 0xf4, 0x4c, 0xd7, 0xfb, 0x88, 0xe5, 0x45,
0x96, 0x45, 0xfa, 0xf5, 0x2c, 0xf7, 0x75, 0xf6, 0xe9, 0x41, 0x9c, 0xa7,
0xfe, 0x2c, 0xd7, 0x3d, 0x4f, 0x88, 0x73, 0x9f, 0x6e, 0x04, 0x7e, 0x64,
0x8c, 0xd1, 0x8c, 0xe4, 0x9e, 0x3a, 0x99, 0xf7, 0xd5, 0x9f, 0x11, 0x17,
0x76, 0xc9, 0xee, 0xf3, 0x84, 0xe5, 0x8e, 0x70, 0xa2, 0x0b, 0xe0, 0xe6,
0x22, 0xe4, 0xa5, 0x3f, 0x42, 0xc5, 0x08, 0xfc, 0x7e, 0x22, 0xe9, 0x27,
0xe9, 0x27, 0x78, 0xfd, 0x41, 0x84, 0xc6, 0x79, 0x5d, 0xb2, 0x78, 0xc3,
0xd3, 0x75, 0xf2, 0x0e, 0x15, 0x98, 0xcd, 0xb2, 0x29, 0x16, 0x20, 0x04,
0x47, 0x53, 0xac, 0x3a, 0xb5, 0xaa, 0x4b, 0x8a, 0xce, 0x03, 0x42, 0xf2,
0x21, 0xd6, 0x92, 0x47, 0x11, 0x93, 0x20, 0xaa, 0x40, 0xca, 0x17, 0x40,
0x21, 0xc8, 0x64, 0xe4, 0xb5, 0x44, 0x0d, 0xc0, 0x0e, 0x04, 0x31, 0x91,
0xc8, 0x11, 0x36, 0xa2, 0x70, 0xd3, 0x77, 0x2d, 0xd6, 0x0f, 0x68, 0x1f,
0x52, 0x71, 0x3e, 0x8a, 0x81, 0xa1, 0xfd, 0xed, 0x42, 0xcb, 0x35, 0x5c,
0x88, 0xb9, 0x41, 0x3f, 0xb7, 0x18, 0x72, 0x0b, 0xa9, 0x09, 0x1b, 0x6d,
0x0e, 0xaa, 0x8e, 0xa9, 0xf8, 0x1a, 0x35, 0x79, 0x35, 0x72, 0x29, 0xc1,
0x71, 0x26, 0xa9, 0x04, 0xe7, 0x33, 0xaf, 0x3b, 0x3f, 0x4c, 0x78, 0x17,
0x5c, 0x86, 0x3c, 0xea, 0x58, 0xc7, 0x0b, 0x79, 0xaf, 0x65, 0xac, 0xe1,
0x27, 0x10, 0xf8, 0x33, 0x8a, 0xcb, 0x40, 0x96, 0x88, 0x28, 0x9a, 0x86,
0x99, 0x94, 0x1b, 0x9f, 0x21, 0x1e, 0xf9, 0x0e, 0xed, 0xfe, 0x7c, 0x13,
0x8a, 0x16, 0x20, 0xbd, 0x38, 0x9d, 0xaa, 0xcf, 0x45, 0x94, 0x68, 0xa0,
0x25, 0x91, 0x4a, 0xf2, 0x0a, 0x74, 0x53, 0xd1, 0xe0, 0x06, 0x96, 0xa9,
0x34, 0xf9, 0x81, 0x79, 0xdb, 0xd5, 0x7b, 0x35, 0xf6, 0x50, 0xfc, 0xde,
0xab, 0x35, 0xdb, 0x0e, 0xb4, 0xdb, 0x6e, 0xac, 0x7a, 0x23, 0x37, 0x96,
0xf5, 0xb6, 0x0e, 0x94, 0xb9, 0x3a, 0x88, 0xa3, 0x04, 0xef, 0x50, 0x16,
0xf3, 0x7d, 0x10, 0x8c, 0xfd, 0x08, 0x22, 0x95, 0x8c, 0x44, 0x44, 0x75,
0xfc, 0x58, 0xab, 0xcc, 0xcb, 0xae, 0xbf, 0xac, 0x71, 0xe5, 0x30, 0xc2,
0x41, 0x90, 0x5b, 0x02, 0xca, 0xbc, 0xd7, 0x17, 0xd4, 0x56, 0xb5, 0x9a,
0x6d, 0xfb, 0x3d, 0x8b, 0xb8, 0x1a, 0x21, 0xa9, 0x7d, 0x34, 0x37, 0x48,
0xbf, 0x04, 0xa1, 0x78, 0x6c, 0x72, 0x76, 0x4c, 0xc4, 0xc5, 0x8f, 0x58,
0xb1, 0xe6, 0x25, 0xc4, 0x0f, 0x9f, 0x2c, 0x68, 0x6c, 0xff, 0x35, 0x04,
0xd8, 0xfd, 0x07, 0xec, 0x10, 0x9d, 0x29, 0x4b, 0x03, 0x00, 0x00
};
unsigned int monkey_gz_len = 407;
unsigned int monkey_len = 843;
unsigned int __64x_len = 64;
unsigned int __64x_gz_len = 28;
struct callback_ctx
{
unsigned char * data;
unsigned int sz_data;
};
int __gzip_64x_data_callback(struct http_half_private * hf_private,
tfe_http_event ev, const unsigned char * data, size_t len, void * user)
{
auto * __ctx = (struct callback_ctx *)user;
memcpy(__ctx->data + __ctx->sz_data, data, len);
__ctx->sz_data += len;
return 0;
}
class HttpConvertUncompress : public ::testing::Test
{
protected:
void SetUp() override
{
__ctx = new struct callback_ctx;
__ctx->data = new unsigned char[2048];
__ctx->sz_data = 0;
cv_object = hf_content_converter_create(HF_CONTENT_CONV_UNCOMPRASS,
HTTP_ACCEPT_ENCODING_GZIP, __gzip_64x_data_callback, __ctx);
ASSERT_TRUE(cv_object != NULL);
}
void TearDown() override
{
delete[] __ctx->data;
delete __ctx;
hf_content_converter_destroy(cv_object);
}
protected:
struct callback_ctx * __ctx{};
struct hf_content_converter * cv_object{};
};
TEST_F(HttpConvertUncompress, Gzip64x)
{
int ret = hf_content_converter_write(cv_object, NULL, EV_HTTP_REQ_BODY_CONT,
(const unsigned char *)__64x_gz, (size_t)__64x_gz_len);
EXPECT_EQ(ret, 1);
EXPECT_EQ(__ctx->sz_data, __64x_len);
EXPECT_EQ(memcmp(__ctx->data, __64x, __64x_len), 0);
}
TEST_F(HttpConvertUncompress, GzipMonkey)
{
int ret = hf_content_converter_write(cv_object, NULL, EV_HTTP_REQ_BODY_CONT,
(const unsigned char *)monkey_gz, (size_t)monkey_gz_len);
EXPECT_EQ(ret, 1);
EXPECT_EQ(__ctx->sz_data, monkey_len);
EXPECT_EQ(memcmp(__ctx->data, monkey, monkey_len), 0);
}
TEST_F(HttpConvertUncompress, GzipMonkeyFrag)
{
unsigned frag_length = monkey_gz_len / 2;
int ret = 0;
ret = hf_content_converter_write(cv_object, NULL, EV_HTTP_REQ_BODY_CONT,
(const unsigned char *)monkey_gz, frag_length);
EXPECT_EQ(ret, 0);
ret = hf_content_converter_write(cv_object, NULL, EV_HTTP_REQ_BODY_CONT,
(const unsigned char *)monkey_gz + frag_length, monkey_gz_len - frag_length);
EXPECT_EQ(ret, 1);
EXPECT_EQ(__ctx->sz_data, monkey_len);
EXPECT_EQ(memcmp(__ctx->data, monkey, monkey_len), 0);
}
void tfe_stream_write_access_log(const struct tfe_stream * stream, int level, const char * fmt, ...)
{
return;
}
int main(int argc, char ** argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}