Commit 4a7fb340 authored by Ghislain MARY's avatar Ghislain MARY
Browse files

Improve body compression handling.

parent 91f5b727
...@@ -52,7 +52,7 @@ BELLESIP_EXPORT belle_sip_memory_body_handler_t *belle_sip_memory_body_handler_n ...@@ -52,7 +52,7 @@ BELLESIP_EXPORT belle_sip_memory_body_handler_t *belle_sip_memory_body_handler_n
BELLESIP_EXPORT void *belle_sip_memory_body_handler_get_buffer(const belle_sip_memory_body_handler_t *obj); BELLESIP_EXPORT void *belle_sip_memory_body_handler_get_buffer(const belle_sip_memory_body_handler_t *obj);
BELLESIP_EXPORT void belle_sip_memory_body_handler_set_buffer(belle_sip_memory_body_handler_t *obj, void *buffer); BELLESIP_EXPORT void belle_sip_memory_body_handler_set_buffer(belle_sip_memory_body_handler_t *obj, void *buffer);
BELLESIP_EXPORT void belle_sip_memory_body_handler_apply_encoding(belle_sip_memory_body_handler_t *obj, const char *encoding); BELLESIP_EXPORT int belle_sip_memory_body_handler_apply_encoding(belle_sip_memory_body_handler_t *obj, const char *encoding);
BELLESIP_EXPORT int belle_sip_memory_body_handler_unapply_encoding(belle_sip_memory_body_handler_t *obj, const char *encoding); BELLESIP_EXPORT int belle_sip_memory_body_handler_unapply_encoding(belle_sip_memory_body_handler_t *obj, const char *encoding);
/* /*
......
...@@ -255,10 +255,14 @@ void belle_sip_memory_body_handler_set_buffer(belle_sip_memory_body_handler_t *o ...@@ -255,10 +255,14 @@ void belle_sip_memory_body_handler_set_buffer(belle_sip_memory_body_handler_t *o
obj->buffer = (uint8_t *)buffer; obj->buffer = (uint8_t *)buffer;
} }
#define BELLE_SIP_MEMORY_BODY_HANDLER_MINIMUM_DEFLATE_INPUT_SIZE 256
#define BELLE_SIP_MEMORY_BODY_HANDLER_ZLIB_INITIAL_SIZE 2048 #define BELLE_SIP_MEMORY_BODY_HANDLER_ZLIB_INITIAL_SIZE 2048
void belle_sip_memory_body_handler_apply_encoding(belle_sip_memory_body_handler_t *obj, const char *encoding) { int belle_sip_memory_body_handler_apply_encoding(belle_sip_memory_body_handler_t *obj, const char *encoding) {
if ((obj->buffer == NULL) || (obj->encoding_applied == TRUE)) return; if (obj->encoding_applied == TRUE)
return 0;
if (!obj->buffer || (belle_sip_body_handler_get_size(BELLE_SIP_BODY_HANDLER(obj)) < BELLE_SIP_MEMORY_BODY_HANDLER_MINIMUM_DEFLATE_INPUT_SIZE))
return -1;
#ifdef HAVE_ZLIB #ifdef HAVE_ZLIB
if (strcmp(encoding, "deflate") == 0) { if (strcmp(encoding, "deflate") == 0) {
...@@ -275,7 +279,10 @@ void belle_sip_memory_body_handler_apply_encoding(belle_sip_memory_body_handler_ ...@@ -275,7 +279,10 @@ void belle_sip_memory_body_handler_apply_encoding(belle_sip_memory_body_handler_
strm.zfree = Z_NULL; strm.zfree = Z_NULL;
strm.opaque = Z_NULL; strm.opaque = Z_NULL;
ret = deflateInit(&strm, Z_DEFAULT_COMPRESSION); ret = deflateInit(&strm, Z_DEFAULT_COMPRESSION);
if (ret != Z_OK) return; if (ret != Z_OK) {
belle_sip_free(outbuf);
return -1;
}
strm.avail_in = (uInt)initial_size; strm.avail_in = (uInt)initial_size;
strm.next_in = obj->buffer; strm.next_in = obj->buffer;
do { do {
...@@ -293,15 +300,22 @@ void belle_sip_memory_body_handler_apply_encoding(belle_sip_memory_body_handler_ ...@@ -293,15 +300,22 @@ void belle_sip_memory_body_handler_apply_encoding(belle_sip_memory_body_handler_
} while (strm.avail_out == 0); } while (strm.avail_out == 0);
deflateEnd(&strm); deflateEnd(&strm);
final_size = outbuf_ptr - outbuf; final_size = outbuf_ptr - outbuf;
if ((final_size + 27) >= initial_size) { // 27 is the size of the Content-Encoding header
belle_sip_message("Body not compressed because its size would have increased");
belle_sip_free(outbuf);
return -1;
}
belle_sip_message("Body has been compressed: %u->%u:\n%s", (unsigned int)initial_size, (unsigned int)final_size, obj->buffer); belle_sip_message("Body has been compressed: %u->%u:\n%s", (unsigned int)initial_size, (unsigned int)final_size, obj->buffer);
belle_sip_free(obj->buffer); belle_sip_free(obj->buffer);
obj->buffer = outbuf; obj->buffer = outbuf;
belle_sip_body_handler_set_size(BELLE_SIP_BODY_HANDLER(obj), final_size); belle_sip_body_handler_set_size(BELLE_SIP_BODY_HANDLER(obj), final_size);
obj->encoding_applied = TRUE; obj->encoding_applied = TRUE;
return 0;
} else } else
#endif #endif
{ {
belle_sip_warning("%s: unknown encoding '%s'", __FUNCTION__, encoding); belle_sip_warning("%s: unknown encoding '%s'", __FUNCTION__, encoding);
return -1;
} }
} }
......
...@@ -331,6 +331,8 @@ static void uncompress_body_if_required(belle_sip_message_t *msg) { ...@@ -331,6 +331,8 @@ static void uncompress_body_if_required(belle_sip_message_t *msg) {
mbh = BELLE_SIP_MEMORY_BODY_HANDLER(bh); mbh = BELLE_SIP_MEMORY_BODY_HANDLER(bh);
if (belle_sip_memory_body_handler_unapply_encoding(mbh, content_encoding) == 0) { if (belle_sip_memory_body_handler_unapply_encoding(mbh, content_encoding) == 0) {
belle_sip_header_content_type_t *content_type = belle_sip_message_get_header_by_type(msg, belle_sip_header_content_type_t); belle_sip_header_content_type_t *content_type = belle_sip_message_get_header_by_type(msg, belle_sip_header_content_type_t);
belle_sip_header_content_length_t *content_length = belle_sip_message_get_header_by_type(msg, belle_sip_header_content_length_t);
belle_sip_header_content_length_set_content_length(content_length, belle_sip_body_handler_get_size(BELLE_SIP_BODY_HANDLER(mbh)));
belle_sip_message_remove_header_from_ptr(msg, ceh); belle_sip_message_remove_header_from_ptr(msg, ceh);
if (content_type if (content_type
&& (strcmp(belle_sip_header_content_type_get_type(content_type), "multipart") == 0)) { && (strcmp(belle_sip_header_content_type_get_type(content_type), "multipart") == 0)) {
...@@ -1226,7 +1228,10 @@ static void compress_body_if_required(belle_sip_message_t *msg) { ...@@ -1226,7 +1228,10 @@ static void compress_body_if_required(belle_sip_message_t *msg) {
} }
if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(bh, belle_sip_memory_body_handler_t)) { if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(bh, belle_sip_memory_body_handler_t)) {
mbh = BELLE_SIP_MEMORY_BODY_HANDLER(bh); mbh = BELLE_SIP_MEMORY_BODY_HANDLER(bh);
belle_sip_memory_body_handler_apply_encoding(mbh, content_encoding); int ret = belle_sip_memory_body_handler_apply_encoding(mbh, content_encoding);
/* Remove Content-Encoding header if it could not be applied */
if (ret < 0)
belle_sip_message_remove_header_from_ptr(msg, ceh);
} else { } else {
belle_sip_warning("message [%p] has Content-Encoding [%s] that cannot be applied", msg, content_encoding); belle_sip_warning("message [%p] has Content-Encoding [%s] that cannot be applied", msg, content_encoding);
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment