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; + 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; - iov_offset++; - z->next_out = (unsigned char *) v[iov_offset].iov_base; - z->avail_out = (unsigned int) v[iov_offset].iov_len; + /* 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; + 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; - iov_offset++; - next_out = (unsigned char *) v[iov_offset].iov_base; - avail_out = (unsigned int) v[iov_offset].iov_len; + 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,