Commit bbc9bcba authored by Ghislain MARY's avatar Ghislain MARY

Build multipart body handler from compressed memory body handler with multipart content-type.

parent ea3d94ac
......@@ -88,6 +88,7 @@ BELLESIP_EXPORT belle_sip_file_body_handler_t *belle_sip_file_body_handler_new(c
#define BELLE_SIP_MULTIPART_BODY_HANDLER(obj) BELLE_SIP_CAST(obj,belle_sip_multipart_body_handler_t)
BELLESIP_EXPORT belle_sip_multipart_body_handler_t *belle_sip_multipart_body_handler_new(belle_sip_body_handler_progress_callback_t progress_cb, void *data, belle_sip_body_handler_t *first_part, const char *boundary);
BELLESIP_EXPORT belle_sip_multipart_body_handler_t *belle_sip_multipart_body_handler_new_from_buffer(void *buffer, size_t bufsize, const char *boundary);
BELLESIP_EXPORT void belle_sip_multipart_body_handler_add_part(belle_sip_multipart_body_handler_t *obj, belle_sip_body_handler_t *part);
BELLESIP_EXPORT const belle_sip_list_t* belle_sip_multipart_body_handler_get_parts(const belle_sip_multipart_body_handler_t *obj);
......
......@@ -637,20 +637,39 @@ BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_BEGIN(belle_sip_multipart_body_handler_t)
}
BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_END
belle_sip_multipart_body_handler_t *belle_sip_multipart_body_handler_new(belle_sip_body_handler_progress_callback_t progress_cb, void *data,
belle_sip_body_handler_t *first_part, const char *boundary){
belle_sip_multipart_body_handler_t *obj=belle_sip_object_new(belle_sip_multipart_body_handler_t);
belle_sip_body_handler_init((belle_sip_body_handler_t*)obj,progress_cb,data);
static void belle_sip_multipart_body_handler_set_boundary(belle_sip_multipart_body_handler_t *obj, const char *boundary) {
if (obj->boundary != NULL) {
belle_sip_free(obj->boundary);
}
if (boundary != NULL) {
obj->boundary = belle_sip_strdup(boundary);
} else {
obj->boundary = belle_sip_strdup(BELLESIP_MULTIPART_BOUNDARY);
}
}
belle_sip_multipart_body_handler_t *belle_sip_multipart_body_handler_new(belle_sip_body_handler_progress_callback_t progress_cb, void *data,
belle_sip_body_handler_t *first_part, const char *boundary){
belle_sip_multipart_body_handler_t *obj=belle_sip_object_new(belle_sip_multipart_body_handler_t);
belle_sip_body_handler_init((belle_sip_body_handler_t*)obj,progress_cb,data);
belle_sip_multipart_body_handler_set_boundary(obj, boundary);
obj->base.expected_size = strlen(obj->boundary) + 8; /* body's length will be part length(including boundary) + multipart end. 8 is for "\r\n--" and "--\r\n" */
if (first_part) belle_sip_multipart_body_handler_add_part(obj,first_part);
return obj;
}
belle_sip_multipart_body_handler_t *belle_sip_multipart_body_handler_new_from_buffer(void *buffer, size_t bufsize, const char *boundary) {
belle_sip_multipart_body_handler_t *obj_multipart = belle_sip_object_new(belle_sip_multipart_body_handler_t);
belle_sip_body_handler_t *obj = (belle_sip_body_handler_t *)obj_multipart;
belle_sip_body_handler_init((belle_sip_body_handler_t *)obj, belle_sip_multipart_body_handler_progress_cb, NULL);
belle_sip_multipart_body_handler_set_boundary(obj_multipart, boundary);
obj_multipart->base.expected_size = bufsize;
belle_sip_body_handler_begin_transfer(obj);
belle_sip_body_handler_recv_chunk(obj, NULL, (uint8_t *)buffer, bufsize);
belle_sip_body_handler_end_transfer(obj);
return obj_multipart;
}
#define DEFAULT_HEADER_STRING_SIZE 512
void belle_sip_multipart_body_handler_add_part(belle_sip_multipart_body_handler_t *obj, belle_sip_body_handler_t *part){
obj->base.expected_size+=part->expected_size+strlen(obj->boundary) + 4; /* add the separator length to the body length as each part start with a separator. 4 is for "--" and "\r\n" */
......
......@@ -305,7 +305,18 @@ static void uncompress_body_if_required(belle_sip_message_t *msg) {
if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(bh, belle_sip_memory_body_handler_t)) {
mbh = BELLE_SIP_MEMORY_BODY_HANDLER(bh);
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_message_remove_header_from_ptr(msg, ceh);
if (content_type
&& (strcmp(belle_sip_header_content_type_get_type(content_type), "multipart") == 0)) {
const char *unparsed_value = belle_sip_header_get_unparsed_value(BELLE_SIP_HEADER(content_type));
const char *boundary = strstr(unparsed_value, ";boundary=");
if (boundary != NULL) boundary += 10;
if (boundary[0] == '\0') boundary = NULL;
bh = (belle_sip_body_handler_t *)belle_sip_multipart_body_handler_new_from_buffer(
belle_sip_memory_body_handler_get_buffer(mbh), belle_sip_body_handler_get_size((belle_sip_body_handler_t *)mbh), boundary);
belle_sip_message_set_body_handler(msg, bh);
}
}
} else {
belle_sip_warning("message [%p] has Content-Encoding [%s] that cannot be unapplied", msg, content_encoding);
......@@ -364,8 +375,11 @@ static int check_body(belle_sip_channel_t *obj){
BELLE_SIP_INVOKE_LISTENERS_ARG1_ARG2(obj->listeners,belle_sip_channel_listener_t,on_message_headers,obj,msg);
/*check if the listener has setup a body handler, otherwise create a default one*/
if ((bh=belle_sip_message_get_body_handler(msg))==NULL){
belle_sip_header_t *content_encoding = belle_sip_message_get_header(msg, "Content-Encoding");
belle_sip_header_content_type_t *content_type = belle_sip_message_get_header_by_type(msg, belle_sip_header_content_type_t);
if (content_type
if (content_encoding != NULL) {
belle_sip_message_set_body_handler(msg, (bh = (belle_sip_body_handler_t *)belle_sip_memory_body_handler_new(NULL, NULL)));
} else if (content_type
&& (strcmp(belle_sip_header_content_type_get_type(content_type), "multipart") == 0)) {
const char *unparsed_value = belle_sip_header_get_unparsed_value(BELLE_SIP_HEADER(content_type));
const char *boundary = strstr(unparsed_value, ";boundary=");
......
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