From: Razvan Crainea <razvan@opensips.org>
Date: Wed, 31 Jan 2018 11:27:07 +0200
Subject: [PATCH] pvar: fix $hdr() to allow variable headers
(cherry picked from commit b7862ccdd5290ebd8d41e2f5b0aadc6e93f1e8dd)
diff --git a/pvar.c b/pvar.c
index 4dd0ee543..8dad234b9 100644
--- a/pvar.c
+++ b/pvar.c
@@ -2116,6 +2116,38 @@ static int pv_get_avp(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
}
+static int pv_resolve_hdr_name(str *in, pv_value_t *tv)
+{
+ struct hdr_field hdr;
+ str s;
+ if(in->len>=PV_LOCAL_BUF_SIZE-1)
+ {
+ LM_ERR("name too long\n");
+ return -1;
+ }
+ memcpy(pv_local_buf, in->s, in->len);
+ pv_local_buf[in->len] = ':';
+ s.s = pv_local_buf;
+ s.len = in->len+1;
+
+ if (parse_hname2(s.s, s.s + ((s.len<4)?4:s.len), &hdr)==0)
+ {
+ LM_ERR("error parsing header name [%.*s]\n", s.len, s.s);
+ return -1;
+ }
+ if (hdr.type!=HDR_OTHER_T && hdr.type!=HDR_ERROR_T)
+ {
+ LM_DBG("using hdr type (%d) instead of <%.*s>\n",
+ hdr.type, in->len, in->s);
+ tv->flags = 0;
+ tv->ri = hdr.type;
+ } else {
+ tv->flags = PV_VAL_STR;
+ tv->rs = *in;
+ }
+ return 0;
+}
+
static int pv_get_hdr_prolog(struct sip_msg *msg, pv_param_t *param, pv_value_t *res, pv_value_t* tv)
{
if(msg==NULL || res==NULL || param==NULL)
@@ -2129,6 +2161,8 @@ static int pv_get_hdr_prolog(struct sip_msg *msg, pv_param_t *param, pv_value_t
LM_ERR("invalid name\n");
return -1;
}
+ if (pv_resolve_hdr_name(&tv->rs, tv) < 0)
+ return -1;
} else {
if(param->pvn.u.isname.type == AVP_NAME_STR)
{
@@ -2985,10 +3019,9 @@ int pv_parse_scriptvar_name(pv_spec_p sp, str *in)
int pv_parse_hdr_name(pv_spec_p sp, str *in)
{
- str s;
char *p;
pv_spec_p nsp = 0;
- struct hdr_field hdr;
+ pv_value_t tv;
if(in==NULL || in->s==NULL || sp==NULL)
return -1;
@@ -3016,35 +3049,21 @@ int pv_parse_hdr_name(pv_spec_p sp, str *in)
return 0;
}
- if(in->len>=PV_LOCAL_BUF_SIZE-1)
- {
- LM_ERR("name too long\n");
+ if (pv_resolve_hdr_name(in, &tv) < 0)
return -1;
- }
- memcpy(pv_local_buf, in->s, in->len);
- pv_local_buf[in->len] = ':';
- s.s = pv_local_buf;
- s.len = in->len+1;
- if (parse_hname2(s.s, s.s + ((s.len<4)?4:s.len), &hdr)==0)
- {
- LM_ERR("error parsing header name [%.*s]\n", s.len, s.s);
- goto error;
- }
sp->pvp.pvn.type = PV_NAME_INTSTR;
- if (hdr.type!=HDR_OTHER_T && hdr.type!=HDR_ERROR_T)
+ if (!tv.flags)
{
LM_DBG("using hdr type (%d) instead of <%.*s>\n",
- hdr.type, in->len, in->s);
+ tv.ri, in->len, in->s);
sp->pvp.pvn.u.isname.type = 0;
- sp->pvp.pvn.u.isname.name.n = hdr.type;
+ sp->pvp.pvn.u.isname.name.n = tv.ri;
} else {
sp->pvp.pvn.u.isname.type = AVP_NAME_STR;
sp->pvp.pvn.u.isname.name.s = *in;
}
return 0;
-error:
- return -1;
}
int pv_parse_avp_name(pv_spec_p sp, str *in)