From 8940cf950cb763ba5145a35d80ffc71f64f450ca Mon Sep 17 00:00:00 2001 From: Juha Heinanen Date: Fri, 13 Nov 2015 08:50:01 +0200 Subject: [PATCH] modules/sdpops: added sloppy option to sdp_content function --- modules/sdpops/README | 13 +++--- modules/sdpops/doc/sdpops_admin.xml | 7 +++- modules/sdpops/sdpops_mod.c | 64 +++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 7 deletions(-) diff --git a/modules/sdpops/README b/modules/sdpops/README index 8558a6f7420..1c24eb77492 100644 --- a/modules/sdpops/README +++ b/modules/sdpops/README @@ -42,7 +42,7 @@ Daniel-Constantin Mierla 4.14. sdp_with_codecs_by_name(list) 4.15. sdp_print(level) 4.16. sdp_get(avpvar) - 4.17. sdp_content() + 4.17. sdp_content([sloppy]) 4.18. sdp_with_ice() 4.19. sdp_get_line_startswith(avpvar, string) @@ -97,7 +97,7 @@ Chapter 1. Admin Guide 4.14. sdp_with_codecs_by_name(list) 4.15. sdp_print(level) 4.16. sdp_get(avpvar) - 4.17. sdp_content() + 4.17. sdp_content([sloppy]) 4.18. sdp_with_ice() 4.19. sdp_get_line_startswith(avpvar, string) @@ -149,7 +149,7 @@ Chapter 1. Admin Guide 4.14. sdp_with_codecs_by_name(list) 4.15. sdp_print(level) 4.16. sdp_get(avpvar) - 4.17. sdp_content() + 4.17. sdp_content([sloppy]) 4.18. sdp_with_ice() 4.19. sdp_get_line_startswith(avpvar, string) @@ -418,9 +418,12 @@ sdp_print("1"); sdp_get("$avp(sdp)"); ... -4.17. sdp_content() +4.17. sdp_content([sloppy]) - Return true if the SIP message has SDP body or a SDP part in body. + Return true if the SIP message has SDP body or a SDP part in body. If + an argument is given, the function does not parse message body, but + returns true if Content-Type is "application/sdp" or if that string + exists in "multipart/mixed" body. This function can be used from ANY_ROUTE. diff --git a/modules/sdpops/doc/sdpops_admin.xml b/modules/sdpops/doc/sdpops_admin.xml index e93ea6b14e9..a091a8a8922 100644 --- a/modules/sdpops/doc/sdpops_admin.xml +++ b/modules/sdpops/doc/sdpops_admin.xml @@ -470,10 +470,13 @@ sdp_get("$avp(sdp)");
- <function moreinfo="none">sdp_content()</function> + <function moreinfo="none">sdp_content([sloppy])</function> - Return true if the SIP message has SDP body or a SDP part in body. + Return true if the SIP message has SDP body or a SDP part in + body. If an argument is given, the function does not parse message + body, but returns true if Content-Type is "application/sdp" or + if that string exists in "multipart/mixed" body. This function can be used from ANY_ROUTE. diff --git a/modules/sdpops/sdpops_mod.c b/modules/sdpops/sdpops_mod.c index 7c9a5492e27..105fb7e14e0 100644 --- a/modules/sdpops/sdpops_mod.c +++ b/modules/sdpops/sdpops_mod.c @@ -36,6 +36,7 @@ #include "../../trim.h" #include "../../data_lump.h" #include "../../ut.h" +#include "../../parser/parse_content.h" #include "api.h" #include "sdpops_data.h" @@ -59,6 +60,7 @@ static int w_sdp_remove_transport(sip_msg_t* msg, char* transport, char *bar); static int w_sdp_print(sip_msg_t* msg, char* level, char *bar); static int w_sdp_get(sip_msg_t* msg, char *bar); static int w_sdp_content(sip_msg_t* msg, char* foo, char *bar); +static int w_sdp_content_sloppy(sip_msg_t* msg, char* foo, char *bar); static int w_sdp_with_ice(sip_msg_t* msg, char* foo, char *bar); static int w_sdp_get_line_startswith(sip_msg_t* msg, char *foo, char *bar); @@ -104,6 +106,8 @@ static cmd_export_t cmds[] = { 1, 0, 0, ANY_ROUTE}, {"sdp_content", (cmd_function)w_sdp_content, 0, 0, 0, ANY_ROUTE}, + {"sdp_content", (cmd_function)w_sdp_content_sloppy, + 1, 0, 0, ANY_ROUTE}, {"sdp_with_ice", (cmd_function)w_sdp_with_ice, 0, 0, 0, ANY_ROUTE}, {"sdp_get_line_startswith", (cmd_function)w_sdp_get_line_startswith, @@ -1521,6 +1525,66 @@ static int w_sdp_content(sip_msg_t* msg, char* foo, char *bar) return -1; } +/* + * Find the first case insensitive occurrence of find in s, where the + * search is limited to the first slen characters of s. + * Based on FreeBSD strnstr. + */ +char* strnistr(const char *s, const char *find, size_t slen) +{ + char c, sc; + size_t len; + + if ((c = *find++) != '\0') { + len = strlen(find); + do { + do { + if ((sc = *s++) == '\0' || slen-- < 1) + return (NULL); + } while (sc != c); + if (len > slen) + return (NULL); + } while (strncasecmp(s, find, len) != 0); + s--; + } + return ((char *)s); +} + +/** + * + */ +static int w_sdp_content_sloppy(sip_msg_t* msg, char* foo, char *bar) +{ + str body; + int mime; + + body.s = get_body(msg); + if (body.s == NULL) return -1; + body.len = msg->len - (int)(body.s - msg->buf); + if (body.len == 0) return -1; + + mime = parse_content_type_hdr(msg); + if (mime < 0) return -1; /* error */ + if (mime == 0) return 1; /* default is application/sdp */ + + switch (((unsigned int)mime) >> 16) { + case TYPE_APPLICATION: + if ((mime & 0x00ff) == SUBTYPE_SDP) return 1; else return -1; + case TYPE_MULTIPART: + if ((mime & 0x00ff) == SUBTYPE_MIXED) { + if (strnistr(body.s, "application/sdp", body.len) == NULL) { + return -1; + } else { + return 1; + } + } else { + return -1; + } + default: + return -1; + } +} + /** * */