Module: sip-router
Branch: master
Commit: 617a444fcbe84290a701228bd78e279bbde4818e
URL:    
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=617a444fcbe84290a701228bd78e279bbde4818e

Author: Daniel-Constantin Mierla <[email protected]>
Committer: Daniel-Constantin Mierla <[email protected]>
Date:   Thu Jul 11 15:27:16 2013 +0200

pv: added transformations for url encode/decode

- patch by JoshE, FS#311

---

 modules/pv/pv_trans.c |  110 +++++++++++++++++++++++++++++++++++++++++++++++++
 modules/pv/pv_trans.h |    3 +-
 2 files changed, 112 insertions(+), 1 deletions(-)

diff --git a/modules/pv/pv_trans.c b/modules/pv/pv_trans.c
index e4e5455..abfff74 100644
--- a/modules/pv/pv_trans.c
+++ b/modules/pv/pv_trans.c
@@ -104,6 +104,82 @@ char *tr_set_crt_buffer(void)
                val->rs.s = _tr_buffer; \
        } while(0);
 
+/* -- helper functions */
+
+/* Converts a hex character to its integer value */
+static char pv_from_hex(char ch)
+{
+       return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
+}
+
+/* Converts an integer value to its hex character */
+static char pv_to_hex(char code)
+{
+       static char hex[] = "0123456789abcdef";
+       return hex[code & 15];
+}
+
+/*! \brief
+ *  URL Encodes a string for use in a HTTP query
+ */
+static int urlencode_param(str *sin, str *sout)
+{
+       char *at, *p;
+
+       at = sout->s;
+       p  = sin->s;
+
+       if (sin==NULL || sout==NULL || sin->s==NULL || sout->s==NULL ||
+                       sin->len<0 || sout->len < 3*sin->len+1)
+               return -1;
+
+       while (p < sin->s+sin->len) {
+               if (isalnum(*p) || *p == '-' || *p == '_' || *p == '.' || *p == 
'~')
+                       *at++ = *p;
+               else if (*p == ' ')
+                       *at++ = '+';
+               else
+                       *at++ = '%', *at++ = pv_to_hex(*p >> 4), *at++ = 
pv_to_hex(*p & 15);
+               p++;
+       }
+
+       *at = 0;
+       sout->len = at - sout->s;
+       LM_DBG("urlencoded string is <%s>\n", sout->s);
+
+       return 0;
+}
+
+/* URL Decode a string */
+static int urldecode_param(str *sin, str *sout) {
+       char *at, *p;
+
+       at = sout->s;
+       p  = sin->s;
+
+       while (p < sin->s+sin->len) {
+               if (*p == '%') {
+                       if (p[1] && p[2]) {
+                               *at++ = pv_from_hex(p[1]) << 4 | 
pv_from_hex(p[2]);
+                               p += 2;
+                       }
+               } else if (*p == '+') {
+                       *at++ = ' ';
+               } else {
+                       *at++ = *p;
+               }
+               p++;
+       }
+
+       *at = 0;
+       sout->len = at - sout->s;
+
+       LM_DBG("urldecoded string is <%s>\n", sout->s);
+       return 0;
+}
+
+/* -- transformations functions */
+
 /*!
  * \brief Evaluate string transformations
  * \param msg SIP message
@@ -827,6 +903,34 @@ int tr_eval_string(struct sip_msg *msg, tr_param_t *tp, 
int subtype,
                        val->rs.len = j;
                        break;
 
+               case TR_S_URLENCODEPARAM:
+                       if(!(val->flags&PV_VAL_STR))
+                               val->rs.s = int2str(val->ri, &val->rs.len);
+                       if(val->rs.len>TR_BUFFER_SIZE-1)
+                               return -1;
+                       st.s = _tr_buffer;
+                       st.len = TR_BUFFER_SIZE;
+                       if (urlencode_param(&val->rs, &st) < 0)
+                               return -1;
+                       memset(val, 0, sizeof(pv_value_t));
+                       val->flags = PV_VAL_STR;
+                       val->rs = st;
+                       break;
+
+               case TR_S_URLDECODEPARAM:
+                       if(!(val->flags&PV_VAL_STR))
+                               val->rs.s = int2str(val->ri, &val->rs.len);
+                       if(val->rs.len>TR_BUFFER_SIZE-1)
+                               return -1;
+                       st.s = _tr_buffer;
+                       st.len = TR_BUFFER_SIZE;
+                       if (urldecode_param(&val->rs, &st) < 0)
+                               return -1;
+                       memset(val, 0, sizeof(pv_value_t));
+                       val->flags = PV_VAL_STR;
+                       val->rs = st;
+                       break;
+
                default:
                        LM_ERR("unknown subtype %d\n",
                                        subtype);
@@ -2061,6 +2165,12 @@ char* tr_parse_string(str* in, trans_t *t)
                        goto error;
                }
                goto done;
+       } else if(name.len==15 && strncasecmp(name.s, "urlencode.param", 
15)==0) {
+               t->subtype = TR_S_URLENCODEPARAM;
+               goto done;
+       } else if(name.len==15 && strncasecmp(name.s, "urldecode.param", 
15)==0) {
+               t->subtype = TR_S_URLDECODEPARAM;
+               goto done;
        }
 
        LM_ERR("unknown transformation: %.*s/%.*s/%d!\n", in->len, in->s,
diff --git a/modules/pv/pv_trans.h b/modules/pv/pv_trans.h
index e2aa494..8544d8c 100644
--- a/modules/pv/pv_trans.h
+++ b/modules/pv/pv_trans.h
@@ -41,7 +41,8 @@ enum _tr_s_subtype {
        TR_S_ESCAPECOMMON, TR_S_UNESCAPECOMMON, TR_S_ESCAPEUSER, 
TR_S_UNESCAPEUSER,
        TR_S_ESCAPEPARAM, TR_S_UNESCAPEPARAM, TR_S_TOLOWER, TR_S_TOUPPER,
        TR_S_STRIP, TR_S_STRIPTAIL, TR_S_PREFIXES, TR_S_PREFIXES_QUOT, 
TR_S_REPLACE,
-       TR_S_TIMEFORMAT, TR_S_TRIM, TR_S_RTRIM, TR_S_LTRIM, TR_S_RM, 
TR_S_STRIPTO
+       TR_S_TIMEFORMAT, TR_S_TRIM, TR_S_RTRIM, TR_S_LTRIM, TR_S_RM, 
TR_S_STRIPTO,
+       TR_S_URLENCODEPARAM, TR_S_URLDECODEPARAM
 };
 enum _tr_uri_subtype {
        TR_URI_NONE=0, TR_URI_USER, TR_URI_HOST, TR_URI_PASSWD, TR_URI_PORT,


_______________________________________________
sr-dev mailing list
[email protected]
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev

Reply via email to