增加对GZIP压缩编码的解压缩功能及单元测试用例
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
19
plugin/protocol/http/include/internal/http_convert.h
Normal file
19
plugin/protocol/http/include/internal/http_convert.h
Normal 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);
|
||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
121
plugin/protocol/http/src/http_convert.cpp
Normal file
121
plugin/protocol/http/src/http_convert.cpp
Normal 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;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ==================================================================================================================
|
/* ==================================================================================================================
|
||||||
|
|||||||
224
plugin/protocol/http/test/test_http_convert.cpp
Normal file
224
plugin/protocol/http/test/test_http_convert.cpp
Normal 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();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user