Module: sip-router
Branch: master
Commit: 1f41271e1c1b879217835b8b3fdbdc2680138f25
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=1f41271…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)gmail.com>
Date: Sun Jun 21 23:31:43 2009 +0200
nathelper(k): support for multipart/mixed body
---
modules_k/nathelper/nhelpr_funcs.c | 71 +++++++++++++++++++++++++++++++++++-
1 files changed, 69 insertions(+), 2 deletions(-)
diff --git a/modules_k/nathelper/nhelpr_funcs.c b/modules_k/nathelper/nhelpr_funcs.c
index 788153c..4d5bd99 100644
--- a/modules_k/nathelper/nhelpr_funcs.c
+++ b/modules_k/nathelper/nhelpr_funcs.c
@@ -46,6 +46,8 @@
#include "../../parser/contact/parse_contact.h"
#include "../../parser/parse_uri.h"
#include "../../parser/parse_content.h"
+#include "../../parser/parser_f.h"
+#include "../../parser/sdp/sdp_helpr_funcs.h"
#define READ(val) \
(*(val + 0) + (*(val + 1) << 8) + (*(val + 2) << 16) + (*(val + 3) <<
24))
@@ -65,6 +67,12 @@
+/**
+ * return:
+ * -1: error
+ * 1: text or sdp
+ * 2: multipart
+ */
int check_content_type(struct sip_msg *msg)
{
static unsigned int appl[16] = {
@@ -101,6 +109,10 @@ int check_content_type(struct sip_msg *msg)
}
trim_len(str_type.len,str_type.s,msg->content_type->body);
+ if (str_type.len>=15 && (*str_type.s=='m' ||
*str_type.s=='M')
+ && strncasecmp(str_type.s, "multipart/mixed", 15) == 0) {
+ return 2;
+ }
p = str_type.s;
advance(p,4,str_type,error_1);
x = READ(p-4);
@@ -157,6 +169,11 @@ int extract_body(struct sip_msg *msg, str *body )
{
char c;
int skip;
+ int ret;
+ str mpdel;
+ char *rest, *p1, *p2;
+ struct hdr_field hf;
+ unsigned int mime;
body->s = get_body(msg);
if (body->s==0) {
@@ -183,7 +200,7 @@ int extract_body(struct sip_msg *msg, str *body )
/* no need for parse_headers(msg, EOH), get_body will
* parse everything */
/*is the content type correct?*/
- if (check_content_type(msg)==-1)
+ if((ret = check_content_type(msg))==1)
{
LM_ERR("content type mismatching\n");
goto error;
@@ -202,7 +219,57 @@ int extract_body(struct sip_msg *msg, str *body )
/*LM_DBG("DEBUG:extract_body:=|%.*s|\n",body->len,body->s);*/
- return 1;
+ if(ret!=2)
+ return 1;
+ /* multipart body */
+ if(get_mixed_part_delimiter(&msg->content_type->body,&mpdel) < 0) {
+ goto error;
+ }
+ p1 = find_sdp_line_delimiter(body->s, body->s+body->len, mpdel);
+ if (p1 == NULL) {
+ LM_ERR("empty multipart content\n");
+ return -1;
+ }
+ p2=p1;
+ c = 0;
+ for(;;)
+ {
+ p1 = p2;
+ if (p1 == NULL || p1 >= body->s+body->len)
+ break; /* No parts left */
+ p2 = find_next_sdp_line_delimiter(p1, body->s+body->len,
+ mpdel, body->s+body->len);
+ /* p2 is text limit for application parsing */
+ rest = eat_line(p1 + mpdel.len + 2, p2 - p1 - mpdel.len - 2);
+ if ( rest > p2 ) {
+ LM_ERR("Unparsable <%.*s>\n", (int)(p1-p1), p1);
+ return -1;
+ }
+ while( rest<p2 ) {
+ memset(&hf,0, sizeof(struct hdr_field));
+ rest = get_sdp_hdr_field(rest, p2, &hf);
+ if(hf.type==HDR_EOH_T)
+ break;
+ if(hf.type==HDR_ERROR_T)
+ return -1;
+ if(hf.type==HDR_CONTENTTYPE_T) {
+ if(decode_mime_type(hf.body.s, hf.body.s + hf.body.len,
+ &mime)==NULL)
+ return -1;
+ if (((((unsigned int)mime)>>16) == TYPE_APPLICATION)
+ && ((mime&0x00ff) == SUBTYPE_SDP)) {
+ c = 1;
+ }
+ }
+ } /* end of while */
+ if(c==1)
+ {
+ body->s = rest;
+ body->len = p2-rest;
+ return 1;
+ }
+ }
+
error:
return -1;
}