summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorluqiuwen <[email protected]>2019-01-08 19:25:17 +0600
committerluqiuwen <[email protected]>2019-01-08 19:25:17 +0600
commita3beec84f90ff6ed797f37327f7cca1ba2ac547e (patch)
tree58ea5036f21443e38c0071364418cb8f11d342f6
parent41eca75fa3e9199a8c19df761a31cb0aad7dc660 (diff)
修正执行gzip/br压缩时,不能动态申请缓冲区导致压缩缓冲区不足的问题
-rw-r--r--plugin/protocol/http/src/http_convert.cpp86
1 files changed, 46 insertions, 40 deletions
diff --git a/plugin/protocol/http/src/http_convert.cpp b/plugin/protocol/http/src/http_convert.cpp
index ce0c84b..c8d548e 100644
--- a/plugin/protocol/http/src/http_convert.cpp
+++ b/plugin/protocol/http/src/http_convert.cpp
@@ -270,71 +270,74 @@ __errout:
return NULL;
}
-#define SZ_IOVEC 2
-#define SZ_RESERVE_SPACE 512
+#define SZ_RESERVE_SPACE 8192
static int __hf_content_compress_write_zlib(struct hf_content_compress * cv_object,
const unsigned char * in_data, size_t sz_in_data, struct evbuffer * out_ev_buf, int end)
{
- struct evbuffer_iovec v[SZ_IOVEC];
+ struct evbuffer_iovec v[1];
/* Reserve the space, because the length of the compressed data will be short
* than uncompressed data in usually, we set the reserve space as much as sz_in_data */
- size_t __sz_reserve_space = sz_in_data > SZ_RESERVE_SPACE ? sz_in_data : SZ_RESERVE_SPACE;
- int iov_count = evbuffer_reserve_space(out_ev_buf, __sz_reserve_space, v, SZ_IOVEC);
- if (iov_count < 1 || iov_count > SZ_IOVEC) return -1;
+ size_t __sz_reserve_chunk = sz_in_data > SZ_RESERVE_SPACE ? sz_in_data : SZ_RESERVE_SPACE;
+ int iov_count = evbuffer_reserve_space(out_ev_buf, __sz_reserve_chunk, v, 1);
+ if (iov_count != 1) return -1;
z_stream * z = cv_object->z_stream_ptr;
z->next_in = (unsigned char *) in_data;
z->avail_in = (unsigned int) sz_in_data;
- unsigned int iov_offset = 0;
- z->next_out = (unsigned char *) v[iov_offset].iov_base;
- z->avail_out = (unsigned int) v[iov_offset].iov_len;
+ z->next_out = (unsigned char *) v[0].iov_base;
+ z->avail_out = (unsigned int) v[0].iov_len;
int flush = end ? Z_FINISH : Z_NO_FLUSH;
- int ret = 0;
+ int deflate_ret = 0;
do
{
- ret = deflate(z, flush);
- assert(ret != Z_STREAM_ERROR);
- assert(iov_offset < SZ_IOVEC);
+ deflate_ret = deflate(z, flush);
+ assert(deflate_ret != Z_STREAM_ERROR);
- if (z->avail_out == 0 || z->avail_in == 0)
+ if (z->avail_in == 0 || z->avail_out == 0)
{
- unsigned int len = (unsigned int) v[iov_offset].iov_len - z->avail_out;
- v[iov_offset].iov_len = (size_t) len;
-
- iov_offset++;
- z->next_out = (unsigned char *) v[iov_offset].iov_base;
- z->avail_out = (unsigned int) v[iov_offset].iov_len;
+ v[0].iov_len = (unsigned int) v[0].iov_len - z->avail_out;
+ int ret = evbuffer_commit_space(out_ev_buf, v, iov_count);
+ if(ret < 0) return -2;
+
+ /* Need more space */
+ if(z->avail_out == 0)
+ {
+ iov_count = evbuffer_reserve_space(out_ev_buf, __sz_reserve_chunk, v, 1);
+ if(unlikely(iov_count != 1)) return -3;
+
+ z->next_out = (unsigned char *) v[0].iov_base;
+ z->avail_out = (unsigned int) v[0].iov_len;
+ }
}
}
while (z->avail_in > 0);
- assert(end == 0 || ret == Z_STREAM_END);
+ assert(end == 0 || deflate_ret == Z_STREAM_END);
- (void) ret;
- return evbuffer_commit_space(out_ev_buf, v, iov_count);
+ (void) deflate_ret;
+ return 0;
}
static int __hf_content_compress_write_br(struct hf_content_compress * cv_object,
const unsigned char * in_data, size_t sz_in_data, struct evbuffer * out_ev_buf, int end)
{
- struct evbuffer_iovec v[SZ_IOVEC];
+ struct evbuffer_iovec v[1];
/* Reserve the space, because the length of the compressed data will be short
* than uncompressed data in usually, we set the reserve space as much as sz_in_data */
- size_t __sz_reserve_space = sz_in_data > SZ_RESERVE_SPACE ? sz_in_data : SZ_RESERVE_SPACE;
- int iov_count = evbuffer_reserve_space(out_ev_buf, __sz_reserve_space, v, SZ_IOVEC);
- if (iov_count < 1 || iov_count > SZ_IOVEC) return -1;
+ size_t __sz_reserve_chunk = sz_in_data > SZ_RESERVE_SPACE ? sz_in_data : SZ_RESERVE_SPACE;
+ int iov_count = evbuffer_reserve_space(out_ev_buf, __sz_reserve_chunk, v, 1);
+ if (iov_count != 1) return -1;
const unsigned char * next_in = in_data;
size_t avail_in = sz_in_data;
- unsigned int iov_offset = 0;
- unsigned char * next_out = (unsigned char *)v[iov_offset].iov_base;
- size_t avail_out = v[iov_offset].iov_len;
+ unsigned char * next_out = (unsigned char *)v[0].iov_base;
+ size_t avail_out = v[0].iov_len;
enum BrotliEncoderOperation op = end ? BROTLI_OPERATION_FINISH : BROTLI_OPERATION_PROCESS;
int ret = 0;
@@ -349,21 +352,24 @@ static int __hf_content_compress_write_br(struct hf_content_compress * cv_object
return ret;
}
- assert(iov_offset < SZ_IOVEC);
if (avail_out == 0 || avail_in == 0)
{
- size_t len = v[iov_offset].iov_len - avail_out;
- v[iov_offset].iov_len = len;
-
- iov_offset++;
- next_out = (unsigned char *) v[iov_offset].iov_base;
- avail_out = (unsigned int) v[iov_offset].iov_len;
+ v[0].iov_len = v[0].iov_len - avail_out;
+ ret = evbuffer_commit_space(out_ev_buf, v, iov_count);
+ if(ret < 0) return -2;
+
+ if(avail_out == 0)
+ {
+ iov_count = evbuffer_reserve_space(out_ev_buf, __sz_reserve_chunk, v, 1);
+ if(unlikely(iov_count != 1)) return -3;
+
+ next_out = (unsigned char *) v[0].iov_base;
+ avail_out = (unsigned int) v[0].iov_len;
+ }
}
}
while (avail_in > 0);
-
- (void) ret;
- return evbuffer_commit_space(out_ev_buf, v, iov_count);
+ return 0;
}
int hf_content_compress_write(struct hf_content_compress * cv_object,