]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
patch incomplete multipart parsing code
authorAnthony Minessale <anthm@freeswitch.org>
Tue, 1 Jun 2010 22:08:55 +0000 (17:08 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Tue, 1 Jun 2010 22:13:32 +0000 (17:13 -0500)
libs/sofia-sip/libsofia-sip-ua/msg/msg_mime.c
libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c

index f2704e830a50594b7001b18e7a50b91f475df06c..4fe75a24defb7343e2f9de67da3ef8dcc1f714dc 100644 (file)
@@ -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;
 
index 83e5f9165895789ad5f94ffd9579a0b5badb648a..032c0a04f2b73486f8da85b487a56b2558690ee4 100644 (file)
@@ -44,6 +44,7 @@
 #include <sofia-sip/sip_status.h>
 #include <sofia-sip/sip_util.h>
 #include <sofia-sip/su_uniqueid.h>
+#include <sofia-sip/msg_mime_protos.h>
 
 #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, "");