Blob Blame Raw
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)