集成GZIP压缩模块,支持对GZIP压缩的应答执行替换业务,并增加了单元测试用例。
This commit is contained in:
@@ -65,8 +65,10 @@ struct http_half_private
|
|||||||
char * url_storage;
|
char * url_storage;
|
||||||
|
|
||||||
/* Content-Encoding */
|
/* Content-Encoding */
|
||||||
|
uint16_t accept_content_encoding;
|
||||||
uint16_t content_encoding;
|
uint16_t content_encoding;
|
||||||
struct hf_content_uncompress * cv_uncompress_object;
|
struct hf_content_uncompress * cv_uncompress_object;
|
||||||
|
struct hf_content_compress * cv_compress_object;
|
||||||
|
|
||||||
/* Header Parser */
|
/* Header Parser */
|
||||||
struct evbuffer * evbuf_header_field;
|
struct evbuffer * evbuf_header_field;
|
||||||
|
|||||||
@@ -157,7 +157,6 @@ void __hf_public_req_fill_from_private(struct http_half_private * hf_private, st
|
|||||||
/* 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 */
|
||||||
static const char __zero = 0;
|
static const char __zero = 0;
|
||||||
evbuffer_add(hf_private->evbuf_uri, &__zero, sizeof(__zero));
|
evbuffer_add(hf_private->evbuf_uri, &__zero, sizeof(__zero));
|
||||||
|
|
||||||
hf_req_spec->uri = (char *) evbuffer_pullup(hf_private->evbuf_uri, evbuffer_get_length(hf_private->evbuf_uri));
|
hf_req_spec->uri = (char *) evbuffer_pullup(hf_private->evbuf_uri, evbuffer_get_length(hf_private->evbuf_uri));
|
||||||
|
|
||||||
/* TODO: url is more complex. need to review RFC */
|
/* TODO: url is more complex. need to review RFC */
|
||||||
@@ -172,6 +171,18 @@ void __hf_public_req_fill_from_private(struct http_half_private * hf_private, st
|
|||||||
|
|
||||||
hf_req_spec->url = hf_private->url_storage;
|
hf_req_spec->url = hf_private->url_storage;
|
||||||
assert(hf_req_spec->url != NULL);
|
assert(hf_req_spec->url != NULL);
|
||||||
|
|
||||||
|
/* Accept-Encoding */
|
||||||
|
const static struct http_field_name __accept_encoding_name = {TFE_HTTP_ACCEPT_ENCODING, NULL};
|
||||||
|
const char * __str_accept_encoding = tfe_http_field_read(hf_public, &__accept_encoding_name);
|
||||||
|
if (__str_accept_encoding != NULL)
|
||||||
|
{
|
||||||
|
hf_private->accept_content_encoding = __hf_content_encoding_parse(__str_accept_encoding);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hf_private->accept_content_encoding = HTTP_ACCEPT_ENCODING_NONE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void __hf_public_resp_fill_from_private(struct http_half_private * hf_private, struct http_parser * parser)
|
void __hf_public_resp_fill_from_private(struct http_half_private * hf_private, struct http_parser * parser)
|
||||||
@@ -489,7 +500,18 @@ int hf_ops_append_body(struct tfe_http_half * half, char * buff, size_t size, in
|
|||||||
hf_private->evbuf_body = evbuffer_new();
|
hf_private->evbuf_body = evbuffer_new();
|
||||||
}
|
}
|
||||||
|
|
||||||
return evbuffer_add(hf_private->evbuf_body, buff, size);
|
int ret = 0;
|
||||||
|
if (hf_private->cv_compress_object)
|
||||||
|
{
|
||||||
|
ret = hf_content_compress_write(hf_private->cv_compress_object,
|
||||||
|
(const unsigned char *)buff, size, hf_private->evbuf_body, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = evbuffer_add(hf_private->evbuf_body, buff, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hf_private_destory(struct http_half_private * hf_private)
|
void hf_private_destory(struct http_half_private * hf_private)
|
||||||
@@ -686,6 +708,27 @@ struct tfe_http_half * hs_ops_response_create(struct tfe_http_session * session,
|
|||||||
|
|
||||||
hf_resp_private->method_or_status = resp_code;
|
hf_resp_private->method_or_status = resp_code;
|
||||||
hf_resp_private->is_setup_by_user = true;
|
hf_resp_private->is_setup_by_user = true;
|
||||||
|
|
||||||
|
/* Inherit from request in currect session */
|
||||||
|
struct http_session_private * ss_private = to_hs_private(session);
|
||||||
|
struct http_half_private * hf_req_private = to_hf_request_private(ss_private);
|
||||||
|
|
||||||
|
/* we must send content in encode that client asked,
|
||||||
|
* but dont need to be accordance with upstream server's response */
|
||||||
|
unsigned int content_encoding = HTTP_ACCEPT_ENCODING_NONE;
|
||||||
|
if (hf_req_private != NULL)
|
||||||
|
{
|
||||||
|
hf_resp_private->content_encoding = hf_req_private->accept_content_encoding;
|
||||||
|
content_encoding = hf_resp_private->content_encoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create content compress content */
|
||||||
|
if (content_encoding != HTTP_ACCEPT_ENCODING_NONE)
|
||||||
|
{
|
||||||
|
hf_resp_private->cv_compress_object = hf_content_compress_create(content_encoding);
|
||||||
|
assert(hf_resp_private->cv_compress_object != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
return to_hf_public(hf_resp_private);
|
return to_hf_public(hf_resp_private);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -760,6 +803,13 @@ void hf_private_construct(struct http_half_private * hf_private)
|
|||||||
|
|
||||||
/* delimitor between header and body */
|
/* delimitor between header and body */
|
||||||
evbuffer_add_printf(hf_private->evbuf_raw, "\r\n");
|
evbuffer_add_printf(hf_private->evbuf_raw, "\r\n");
|
||||||
|
|
||||||
|
/* Terminal the end of gzip stream */
|
||||||
|
if (hf_private->evbuf_body && hf_private->cv_compress_object)
|
||||||
|
{
|
||||||
|
hf_content_compress_write(hf_private->cv_compress_object, NULL, 0, hf_private->evbuf_body, 1);
|
||||||
|
}
|
||||||
|
|
||||||
/* add body */
|
/* add body */
|
||||||
if (hf_private->evbuf_body)
|
if (hf_private->evbuf_body)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -262,7 +262,7 @@ TEST_F(HttpConvertCompress, MonkeyToGzip)
|
|||||||
EXPECT_EQ(memcmp(uncompress_buf.data(), monkey, sizeof(monkey)), 0);
|
EXPECT_EQ(memcmp(uncompress_buf.data(), monkey, sizeof(monkey)), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(HttpConvertCompress, MonkeyToGzipStrem)
|
TEST_F(HttpConvertCompress, MonkeyToGzipStream)
|
||||||
{
|
{
|
||||||
unsigned frag_length = sizeof(monkey) / 2;
|
unsigned frag_length = sizeof(monkey) / 2;
|
||||||
|
|
||||||
@@ -286,6 +286,34 @@ TEST_F(HttpConvertCompress, MonkeyToGzipStrem)
|
|||||||
EXPECT_EQ(memcmp(uncompress_buf.data(), monkey, sizeof(monkey)), 0);
|
EXPECT_EQ(memcmp(uncompress_buf.data(), monkey, sizeof(monkey)), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(HttpConvertCompress, MonkeyToGzipStreamWithNullEnd)
|
||||||
|
{
|
||||||
|
unsigned frag_length = sizeof(monkey) / 2;
|
||||||
|
|
||||||
|
/* First frag */
|
||||||
|
int ret = hf_content_compress_write(cv_compress_object, monkey, frag_length, buf, 0);
|
||||||
|
ASSERT_EQ(ret, 0);
|
||||||
|
|
||||||
|
/* Last frag */
|
||||||
|
ret = hf_content_compress_write(cv_compress_object, monkey + frag_length, sizeof(monkey) - frag_length, buf, 0);
|
||||||
|
ASSERT_EQ(ret, 0);
|
||||||
|
|
||||||
|
/* End frag */
|
||||||
|
ret = hf_content_compress_write(cv_compress_object, NULL, 0, buf, 1);
|
||||||
|
ASSERT_EQ(ret, 0);
|
||||||
|
|
||||||
|
unsigned char * __raw_buf_ptr = evbuffer_pullup(buf, -1);
|
||||||
|
size_t __raw_buf_length = evbuffer_get_length(buf);
|
||||||
|
|
||||||
|
ret = hf_content_uncompress_write(cv_uncompress_object, NULL, EV_HTTP_REQ_BODY_CONT,
|
||||||
|
__raw_buf_ptr, __raw_buf_length);
|
||||||
|
|
||||||
|
ASSERT_TRUE(__raw_buf_ptr != NULL);
|
||||||
|
ASSERT_EQ(ret, 1);
|
||||||
|
EXPECT_EQ(uncompress_buf.size(), sizeof(monkey));
|
||||||
|
EXPECT_EQ(memcmp(uncompress_buf.data(), monkey, sizeof(monkey)), 0);
|
||||||
|
}
|
||||||
|
|
||||||
void tfe_stream_write_access_log(const struct tfe_stream * stream, int level, const char * fmt, ...)
|
void tfe_stream_write_access_log(const struct tfe_stream * stream, int level, const char * fmt, ...)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in New Issue
Block a user