修正执行gzip/br压缩时,不能动态申请缓冲区导致压缩缓冲区不足的问题

This commit is contained in:
luqiuwen
2019-01-08 19:25:17 +06:00
parent 41eca75fa3
commit a3beec84f9

View File

@@ -270,71 +270,74 @@ __errout:
return NULL; return NULL;
} }
#define SZ_IOVEC 2 #define SZ_RESERVE_SPACE 8192
#define SZ_RESERVE_SPACE 512
static int __hf_content_compress_write_zlib(struct hf_content_compress * cv_object, 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) 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 /* 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 */ * 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; 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_space, v, SZ_IOVEC); int iov_count = evbuffer_reserve_space(out_ev_buf, __sz_reserve_chunk, v, 1);
if (iov_count < 1 || iov_count > SZ_IOVEC) return -1; if (iov_count != 1) return -1;
z_stream * z = cv_object->z_stream_ptr; z_stream * z = cv_object->z_stream_ptr;
z->next_in = (unsigned char *) in_data; z->next_in = (unsigned char *) in_data;
z->avail_in = (unsigned int) sz_in_data; z->avail_in = (unsigned int) sz_in_data;
unsigned int iov_offset = 0; z->next_out = (unsigned char *) v[0].iov_base;
z->next_out = (unsigned char *) v[iov_offset].iov_base; z->avail_out = (unsigned int) v[0].iov_len;
z->avail_out = (unsigned int) v[iov_offset].iov_len;
int flush = end ? Z_FINISH : Z_NO_FLUSH; int flush = end ? Z_FINISH : Z_NO_FLUSH;
int ret = 0; int deflate_ret = 0;
do do
{ {
ret = deflate(z, flush); deflate_ret = deflate(z, flush);
assert(ret != Z_STREAM_ERROR); assert(deflate_ret != Z_STREAM_ERROR);
assert(iov_offset < SZ_IOVEC);
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[0].iov_len = (unsigned int) v[0].iov_len - z->avail_out;
v[iov_offset].iov_len = (size_t) len; int ret = evbuffer_commit_space(out_ev_buf, v, iov_count);
if(ret < 0) return -2;
iov_offset++; /* Need more space */
z->next_out = (unsigned char *) v[iov_offset].iov_base; if(z->avail_out == 0)
z->avail_out = (unsigned int) v[iov_offset].iov_len; {
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); while (z->avail_in > 0);
assert(end == 0 || ret == Z_STREAM_END); assert(end == 0 || deflate_ret == Z_STREAM_END);
(void) ret; (void) deflate_ret;
return evbuffer_commit_space(out_ev_buf, v, iov_count); return 0;
} }
static int __hf_content_compress_write_br(struct hf_content_compress * cv_object, 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) 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 /* 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 */ * 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; 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_space, v, SZ_IOVEC); int iov_count = evbuffer_reserve_space(out_ev_buf, __sz_reserve_chunk, v, 1);
if (iov_count < 1 || iov_count > SZ_IOVEC) return -1; if (iov_count != 1) return -1;
const unsigned char * next_in = in_data; const unsigned char * next_in = in_data;
size_t avail_in = sz_in_data; size_t avail_in = sz_in_data;
unsigned int iov_offset = 0; unsigned char * next_out = (unsigned char *)v[0].iov_base;
unsigned char * next_out = (unsigned char *)v[iov_offset].iov_base; size_t avail_out = v[0].iov_len;
size_t avail_out = v[iov_offset].iov_len;
enum BrotliEncoderOperation op = end ? BROTLI_OPERATION_FINISH : BROTLI_OPERATION_PROCESS; enum BrotliEncoderOperation op = end ? BROTLI_OPERATION_FINISH : BROTLI_OPERATION_PROCESS;
int ret = 0; int ret = 0;
@@ -349,21 +352,24 @@ static int __hf_content_compress_write_br(struct hf_content_compress * cv_object
return ret; return ret;
} }
assert(iov_offset < SZ_IOVEC);
if (avail_out == 0 || avail_in == 0) if (avail_out == 0 || avail_in == 0)
{ {
size_t len = v[iov_offset].iov_len - avail_out; v[0].iov_len = v[0].iov_len - avail_out;
v[iov_offset].iov_len = len; ret = evbuffer_commit_space(out_ev_buf, v, iov_count);
if(ret < 0) return -2;
iov_offset++; if(avail_out == 0)
next_out = (unsigned char *) v[iov_offset].iov_base; {
avail_out = (unsigned int) v[iov_offset].iov_len; 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); while (avail_in > 0);
return 0;
(void) ret;
return evbuffer_commit_space(out_ev_buf, v, iov_count);
} }
int hf_content_compress_write(struct hf_content_compress * cv_object, int hf_content_compress_write(struct hf_content_compress * cv_object,