diff --git a/libs/sofia-sip/libsofia-sip-ua/msg/msg_mime.c b/libs/sofia-sip/libsofia-sip-ua/msg/msg_mime.c index f2704e830a..4fe75a24de 100644 --- a/libs/sofia-sip/libsofia-sip-ua/msg/msg_mime.c +++ b/libs/sofia-sip/libsofia-sip-ua/msg/msg_mime.c @@ -378,7 +378,7 @@ msg_multipart_t *msg_multipart_parse(su_home_t *home, msg_t msg[1] = {{{ SU_HOME_INIT(msg) }}}; size_t len, m, blen; char *boundary, *p, *next, save; - char const *b, *end; + char *b, *end; msg_param_t param; p = pl->pl_data; len = pl->pl_len; end = p + len; @@ -438,8 +438,11 @@ msg_multipart_t *msg_multipart_parse(su_home_t *home, *mmp = mp; mmp = &mp->mp_next; /* Put delimiter transport-padding CRLF here */ - mp->mp_common->h_data = b; + + *b = '\0'; mp->mp_common->h_len = p - b; + b += strlen(boundary) - 2; + mp->mp_common->h_data = b; /* .. and body-part here */ mp->mp_data = p; @@ -449,14 +452,17 @@ msg_multipart_t *msg_multipart_parse(su_home_t *home, /* We found close-delimiter */ assert(mp); if (!mp) - break; /* error */ + break; /* error */ mp->mp_close_delim = (msg_payload_t *) - msg_header_alloc(msg_home(msg), msg_payload_class, 0); + msg_header_alloc(msg_home(msg), msg_payload_class, 0); if (!mp->mp_close_delim) - break; /* error */ + break; /* error */ /* Include also transport-padding and epilogue in the close-delimiter */ - mp->mp_close_delim->pl_data = next; + *next = '\0'; mp->mp_close_delim->pl_len = p + len - next; + next += strlen(boundary) - 2; + mp->mp_close_delim->pl_data = next; + break; } @@ -515,8 +521,8 @@ msg_multipart_t *msg_multipart_parse(su_home_t *home, mp->mp_data = boundary; mp->mp_len = (unsigned)blen; /* XXX */ - assert(mp->mp_payload || mp->mp_separator); - + if (!(mp->mp_payload || mp->mp_separator)) continue; + if (mp->mp_close_delim) { msg_header_t **tail; diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c index 83e5f91658..032c0a04f2 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c @@ -44,6 +44,7 @@ #include #include #include +#include #define NTA_INCOMING_MAGIC_T struct nua_server_request #define NTA_OUTGOING_MAGIC_T struct nua_client_request @@ -2114,7 +2115,7 @@ nua_session_server_init(nua_server_request_t *sr) msg_t *msg = sr->sr_response.msg; sip_t *sip = sr->sr_response.sip; - sip_t const *request = sr->sr_request.sip; + sip_t *request = (sip_t *) sr->sr_request.sip; if (!sr->sr_initial) sr->sr_usage = nua_dialog_usage_get(nh->nh_ds, nua_session_usage, NULL); @@ -2135,6 +2136,54 @@ nua_session_server_init(nua_server_request_t *sr) /* XXX - soa should know what it supports */ sip_add_dup(msg, sip, (sip_header_t *)a); + /* if we see there is a multipart content-type, + parse it into the sip structre and find the SDP and replace it + into the request as the requested content */ + if (request->sip_content_type && + su_casenmatch(request->sip_content_type->c_type, "multipart/", 10)) { + msg_multipart_t *mp, *mpp; + + if (request->sip_multipart) { + mp = request->sip_multipart; + } else { + mp = msg_multipart_parse(msg_home(msg), + request->sip_content_type, + (sip_payload_t *)request->sip_payload); + request->sip_multipart = mp; + } + + if (mp) { + int sdp = 0; + + /* extract the SDP and set the primary content-type and payload to that SDP as if it was the only content so SOA will work */ + for(mpp = mp; mpp; mpp = mpp->mp_next) { + if (mpp->mp_content_type && mpp->mp_content_type->c_type && + mpp->mp_payload && mpp->mp_payload->pl_data && + su_casenmatch(mpp->mp_content_type->c_type, "application/sdp", 15)) { + + request->sip_content_type = msg_content_type_dup(msg_home(msg), mpp->mp_content_type); + + if (request->sip_content_length) { + request->sip_content_length->l_length = mpp->mp_payload->pl_len; + } + + request->sip_payload->pl_data = su_strdup(msg_home(msg), mpp->mp_payload->pl_data); + request->sip_payload->pl_len = mpp->mp_payload->pl_len; + + sdp++; + + break; + } + } + + /* insist on the existance of a SDP in the content or refuse the request */ + if (!sdp) { + return SR_STATUS1(sr, SIP_406_NOT_ACCEPTABLE); + } + } + } + + /* Make sure caller uses application/sdp without compression */ if (nta_check_session_content(NULL, request, a, TAG_END())) { sip_add_make(msg, sip, sip_accept_encoding_class, "");