mirror of https://github.com/sipwise/kamailio.git
Previously, to remove a parameter from a header it was needed to create a complex method on the configuration file for each header/parameter. This modification moves this complexity to the 'pv_headers' module.
Two new functions:
* pvh_header_param_exists
* pvh_remove_header_param
Both functions take as parameters the name of the header and the name of the parameter.
It returns '-1' if the combination header/parameter:
- is not found (pvh_header_param_exists)
- couldn't be removed (pvh_remove_header_param).
Examples (proxy configuration):
if (pvh_header_param_exists("Supported", "100rel"))
{
// "100rel" is present on the "Supported" header
}
if (pvh_remove_header_param("Supported", "100rel"))
{
// "100rel" removed from header "Supported"
}
Change-Id: I2a95bcb54bf21d64cbf2c6f894b76e9f3cc7bdbc
mr11.0
parent
239867b6b2
commit
41c26235b5
@ -0,0 +1,33 @@
|
||||
From: Victor Seva <vseva@sipwise.com>
|
||||
Date: Tue, 12 Apr 2022 13:36:34 +0200
|
||||
Subject: pv_headers: fix build warning
|
||||
|
||||
pvh_func.c:392:35: warning: division 'sizeof (char *) / sizeof (char)'
|
||||
pvh_func.c:407:66: warning: division 'sizeof (char *) / sizeof (char)'
|
||||
---
|
||||
src/modules/pv_headers/pvh_func.c | 5 ++---
|
||||
1 file changed, 2 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/modules/pv_headers/pvh_func.c b/src/modules/pv_headers/pvh_func.c
|
||||
index 4ca72d2..c2a3f98 100644
|
||||
--- a/src/modules/pv_headers/pvh_func.c
|
||||
+++ b/src/modules/pv_headers/pvh_func.c
|
||||
@@ -389,8 +389,7 @@ int pvh_remove_header_param(struct sip_msg *msg, int idx, str *hname, str *eleme
|
||||
char *token;
|
||||
char *result = (char*)pkg_malloc(elements->len - toRemove->len);
|
||||
char *t = (char*)pkg_malloc(elements->len);
|
||||
- int maxSize = sizeof(elements->s)/sizeof(char);
|
||||
- maxSize = maxSize < elements->len?elements->len:maxSize;
|
||||
+ int maxSize = elements->len;
|
||||
|
||||
if (result == NULL || t == NULL)
|
||||
{
|
||||
@@ -404,7 +403,7 @@ int pvh_remove_header_param(struct sip_msg *msg, int idx, str *hname, str *eleme
|
||||
token = strtok_r(t, ", ", &next_token);
|
||||
while(token)
|
||||
{
|
||||
- int notTarget = strncmp(token, toRemove->s, sizeof(toRemove->s)/sizeof(char));
|
||||
+ int notTarget = strncmp(token, toRemove->s, toRemove->len);
|
||||
if (notTarget)
|
||||
{
|
||||
int n = snprintf(result + offset, maxSize - offset, "%s", token);
|
||||
@ -0,0 +1,289 @@
|
||||
From 7a3f71e7ce6b63fe1c32853c30d785bc9c1f2236 Mon Sep 17 00:00:00 2001
|
||||
From: Fabricio Santolin da Silva
|
||||
<fabricio.santolin-da-silva@al-enterprise.com>
|
||||
Date: Wed, 30 Mar 2022 16:42:41 +0200
|
||||
Subject: [PATCH] pv_headers: Add support to remove a specific value from a
|
||||
header
|
||||
|
||||
- To be used with headers containing values separated by commas
|
||||
- pvh_header_param_exists() check if the value is present to a given header
|
||||
- pvh_remove_header_param() remove the value from the given header or the entire header if no other value is present
|
||||
---
|
||||
src/modules/pv_headers/doc/functions.xml | 35 +++++++-
|
||||
src/modules/pv_headers/doc/pv_headers.xml | 6 ++
|
||||
src/modules/pv_headers/pv_headers.c | 61 ++++++++++++++
|
||||
src/modules/pv_headers/pvh_func.c | 97 +++++++++++++++++++++++
|
||||
src/modules/pv_headers/pvh_func.h | 2 +
|
||||
5 files changed, 200 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/modules/pv_headers/doc/functions.xml b/src/modules/pv_headers/doc/functions.xml
|
||||
index ef7f133779..e0d38d47ea 100644
|
||||
--- a/src/modules/pv_headers/doc/functions.xml
|
||||
+++ b/src/modules/pv_headers/doc/functions.xml
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
<section id="pv_headers.funtions" xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
<sectioninfo>
|
||||
- </sectioninfo>\
|
||||
+ </sectioninfo>
|
||||
|
||||
<title>Functions</title>
|
||||
<section id="pv_headers.f.pvh_collect_headers">
|
||||
@@ -128,4 +128,37 @@
|
||||
pvh_collect_headers()</link> or with <quote>auto_msg</quote> parameter enabled.
|
||||
</para>
|
||||
</section>
|
||||
+ <section id="pv_headers.f.pvh_header_param_exists">
|
||||
+ <title>
|
||||
+ <function moreinfo="none">pvh_value_exists(hname, hparameter)</function>
|
||||
+ </title>
|
||||
+ <para>
|
||||
+ Checks if the parameter <quote>hparameter</quote> is present in the header <quote>hname</quote> from XAVP.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ This function can be used from ANY_ROUTE but only after <link linked="pv_headers.f.pvh_collect_headers">
|
||||
+ pvh_collect_headers()</link> have been called or with <quote>auto_msg</quote> parameter enabled.
|
||||
+ </para>
|
||||
</section>
|
||||
+ <section id="pv_headers.f.pvh_remove_header_param">
|
||||
+ <title>
|
||||
+ <function moreinfo="none">pvh_remove_header_param(hname, hparameter)</function>
|
||||
+ </title>
|
||||
+ <para>
|
||||
+ Removes an existing parameter <quote>hparameter</quote> in the header <quote>hname</quote> from the XAVP.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ If there are multiple headers, only the one containing the parameter will be modified.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ The parameter can be located in any position (begining, middle or end) of the list of parameters.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ If the parameter is the only one present, the header will be removed.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ This function can be used from ANY_ROUTE but only after <link linked="pv_headers.f.pvh_collect_headers">
|
||||
+ pvh_collect_headers()</link> have been called or with <quote>auto_msg</quote> parameter enabled.
|
||||
+ </para>
|
||||
+ </section>
|
||||
+</section>
|
||||
diff --git a/src/modules/pv_headers/doc/pv_headers.xml b/src/modules/pv_headers/doc/pv_headers.xml
|
||||
index a5211b9288..47d40e1ae9 100644
|
||||
--- a/src/modules/pv_headers/doc/pv_headers.xml
|
||||
+++ b/src/modules/pv_headers/doc/pv_headers.xml
|
||||
@@ -26,6 +26,12 @@
|
||||
<email>vseva@sipwise.com</email>
|
||||
<affiliation><orgname>Sipwise GmbH</orgname></affiliation>
|
||||
</editor>
|
||||
+ <editor>
|
||||
+ <firstname>Fabricio</firstname>
|
||||
+ <surname>Santolin da Silva</surname>
|
||||
+ <email>fabricio.santolin-da-silva@al-enterprise.com</email>
|
||||
+ <affiliation><orgname>Alcatel-Lucent Enterprise</orgname></affiliation>
|
||||
+ </editor>
|
||||
</authorgroup>
|
||||
<copyright>
|
||||
<year>2018</year>
|
||||
diff --git a/src/modules/pv_headers/pv_headers.c b/src/modules/pv_headers/pv_headers.c
|
||||
index 6dfac3d18b..be43bb29f4 100644
|
||||
--- a/src/modules/pv_headers/pv_headers.c
|
||||
+++ b/src/modules/pv_headers/pv_headers.c
|
||||
@@ -205,6 +205,53 @@ static int w_pvh_remove_header(
|
||||
return pvh_remove_header(msg, &hname, indx);
|
||||
}
|
||||
|
||||
+static int w_pvh_header_param_exists(
|
||||
+ struct sip_msg *msg, char *p1, char *p2)
|
||||
+{
|
||||
+ str hname = STR_NULL;
|
||||
+ str value = STR_NULL;
|
||||
+
|
||||
+ if(fixup_get_svalue(msg, (gparam_p)p1, &hname) < 0)
|
||||
+ return -1;
|
||||
+
|
||||
+ if(p2 && fixup_get_svalue(msg, (gparam_p)p2, &value) < 0)
|
||||
+ return -1;
|
||||
+
|
||||
+ return pvh_header_param_exists(msg, &hname, &value);
|
||||
+}
|
||||
+
|
||||
+static int w_pvh_remove_header_param(struct sip_msg *msg, char *p1, char *p2)
|
||||
+{
|
||||
+ int ret = -1;
|
||||
+ int idx = 0;
|
||||
+ str hname = STR_NULL;
|
||||
+ str value = STR_NULL;
|
||||
+ sr_xavp_t *avi=NULL;
|
||||
+ char tt[header_name_size];
|
||||
+ str br_xname = {tt, header_name_size};
|
||||
+
|
||||
+ if(fixup_get_svalue(msg, (gparam_p)p1, &hname) < 0)
|
||||
+ return -1;
|
||||
+
|
||||
+ if(p2 && fixup_get_svalue(msg, (gparam_p)p2, &value) < 0)
|
||||
+ return -1;
|
||||
+
|
||||
+ pvh_get_branch_xname(msg, &xavi_name, &br_xname);
|
||||
+
|
||||
+ avi = xavi_get_child(&br_xname, &hname);
|
||||
+
|
||||
+ while(avi)
|
||||
+ {
|
||||
+ if (avi->val.type == SR_XTYPE_STR && avi->val.v.s.s != NULL && _strnstr(avi->val.v.s.s, value.s, avi->val.v.s.len) != NULL) {
|
||||
+ ret = pvh_remove_header_param(msg, idx, &hname, &avi->val.v.s, &value) && ret;
|
||||
+ }
|
||||
+ idx++;
|
||||
+ avi = xavi_get_next(avi);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
/* clang-format off */
|
||||
static cmd_export_t cmds[] = {
|
||||
{"pvh_collect_headers", (cmd_function)w_pvh_collect_headers, 0, 0, 0,
|
||||
@@ -225,6 +272,10 @@ static cmd_export_t cmds[] = {
|
||||
fixup_spve_null, fixup_free_spve_null, ANY_ROUTE},
|
||||
{"pvh_remove_header", (cmd_function)w_pvh_remove_header, 2,
|
||||
fixup_spve_spve, fixup_free_spve_spve, ANY_ROUTE},
|
||||
+ {"pvh_header_param_exists", (cmd_function)w_pvh_header_param_exists, 2,
|
||||
+ fixup_spve_spve, fixup_free_spve_spve, ANY_ROUTE},
|
||||
+ {"pvh_remove_header_param", (cmd_function)w_pvh_remove_header_param, 2,
|
||||
+ fixup_spve_spve, fixup_free_spve_spve, ANY_ROUTE},
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@@ -537,6 +588,16 @@ static sr_kemi_t pvh_kemi_exports[] = {
|
||||
{ SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
|
||||
SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE}
|
||||
},
|
||||
+ { str_init("pv_headers"), str_init("pvh_header_param_exists"),
|
||||
+ SR_KEMIP_INT, pvh_header_param_exists,
|
||||
+ { SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
|
||||
+ SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE}
|
||||
+ },
|
||||
+ { str_init("pv_headers"), str_init("pvh_remove_header_param"),
|
||||
+ SR_KEMIP_INT, pvh_remove_header_param,
|
||||
+ { SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
|
||||
+ SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE}
|
||||
+ },
|
||||
{{0, 0}, {0, 0}, 0, NULL, {0, 0, 0, 0, 0, 0}}
|
||||
};
|
||||
/* clang-format on */
|
||||
diff --git a/src/modules/pv_headers/pvh_func.c b/src/modules/pv_headers/pvh_func.c
|
||||
index 01a7d3d211..4ca72d217d 100644
|
||||
--- a/src/modules/pv_headers/pvh_func.c
|
||||
+++ b/src/modules/pv_headers/pvh_func.c
|
||||
@@ -357,3 +357,100 @@ int pvh_remove_header(struct sip_msg *msg, str *hname, int indx)
|
||||
|
||||
return 1;
|
||||
}
|
||||
+
|
||||
+int pvh_header_param_exists(struct sip_msg *msg, str *hname, str *hvalue)
|
||||
+{
|
||||
+ sr_xavp_t *avi=NULL;
|
||||
+ char head_name[header_name_size];
|
||||
+ str br_xname = {head_name, header_name_size};
|
||||
+
|
||||
+ avi = xavi_get(&xavi_name,NULL);
|
||||
+ pvh_get_branch_xname(msg, &xavi_name, &br_xname);
|
||||
+
|
||||
+ avi = xavi_get_child(&br_xname, hname);
|
||||
+
|
||||
+ while(avi)
|
||||
+ {
|
||||
+ if (avi->val.type == SR_XTYPE_STR && avi->val.v.s.s != NULL && _strnstr(avi->val.v.s.s, hvalue->s, avi->val.v.s.len) != NULL)
|
||||
+ {
|
||||
+ return 1;
|
||||
+ }
|
||||
+ avi = xavi_get_next(avi);
|
||||
+ }
|
||||
+
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+int pvh_remove_header_param(struct sip_msg *msg, int idx, str *hname, str *elements, str *toRemove)
|
||||
+{
|
||||
+ int offset = 0;
|
||||
+ int ret = -1;
|
||||
+ char *next_token;
|
||||
+ char *token;
|
||||
+ char *result = (char*)pkg_malloc(elements->len - toRemove->len);
|
||||
+ char *t = (char*)pkg_malloc(elements->len);
|
||||
+ int maxSize = sizeof(elements->s)/sizeof(char);
|
||||
+ maxSize = maxSize < elements->len?elements->len:maxSize;
|
||||
+
|
||||
+ if (result == NULL || t == NULL)
|
||||
+ {
|
||||
+ PKG_MEM_ERROR;
|
||||
+ goto clean;
|
||||
+ }
|
||||
+
|
||||
+ snprintf(result, elements->len - toRemove->len, "%*s", elements->len - toRemove->len, "");
|
||||
+ snprintf(t, elements->len+1, "%s", elements->s);
|
||||
+
|
||||
+ token = strtok_r(t, ", ", &next_token);
|
||||
+ while(token)
|
||||
+ {
|
||||
+ int notTarget = strncmp(token, toRemove->s, sizeof(toRemove->s)/sizeof(char));
|
||||
+ if (notTarget)
|
||||
+ {
|
||||
+ int n = snprintf(result + offset, maxSize - offset, "%s", token);
|
||||
+ if (n < 0 || n >= maxSize - offset)
|
||||
+ {
|
||||
+ break;
|
||||
+ }
|
||||
+ offset += n;
|
||||
+ }
|
||||
+ token = strtok_r(NULL, ", ", &next_token);
|
||||
+ if (token && notTarget && maxSize - offset - toRemove->len > 2)
|
||||
+ {
|
||||
+ int n = snprintf(result + offset, maxSize - offset, ", ");
|
||||
+ if (n < 0 || n >= maxSize - offset)
|
||||
+ {
|
||||
+ break;
|
||||
+ }
|
||||
+ offset += n;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (elements->len-toRemove->len > 0)
|
||||
+ {
|
||||
+ snprintf(elements->s, elements->len, "%*s", elements->len-toRemove->len, "");
|
||||
+ snprintf(elements->s, (strlen(result)%elements->len)+1, "%s", result);
|
||||
+ elements->len = strlen(result);
|
||||
+ ret = 1;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ ret = pvh_remove_header(msg, hname, idx);
|
||||
+ }
|
||||
+
|
||||
+clean:
|
||||
+
|
||||
+ if(t != NULL)
|
||||
+ {
|
||||
+ pkg_free(t);
|
||||
+ t = NULL;
|
||||
+ }
|
||||
+
|
||||
+ if(result != NULL)
|
||||
+ {
|
||||
+ pkg_free(result);
|
||||
+ result = NULL;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
diff --git a/src/modules/pv_headers/pvh_func.h b/src/modules/pv_headers/pvh_func.h
|
||||
index 6aaf5aa9f5..a4e0bfad3e 100644
|
||||
--- a/src/modules/pv_headers/pvh_func.h
|
||||
+++ b/src/modules/pv_headers/pvh_func.h
|
||||
@@ -38,5 +38,7 @@ int pvh_check_header(struct sip_msg *msg, str *hname);
|
||||
int pvh_append_header(struct sip_msg *msg, str *hname, str *hvalue);
|
||||
int pvh_modify_header(struct sip_msg *msg, str *hname, str *hvalue, int indx);
|
||||
int pvh_remove_header(struct sip_msg *msg, str *hname, int indx);
|
||||
+int pvh_header_param_exists(struct sip_msg *msg, str *hname, str *hvalue);
|
||||
+int pvh_remove_header_param(struct sip_msg *msg, int idx, str *hname, str *elements, str *toRemove);
|
||||
|
||||
#endif /* PV_FUNC_H */
|
||||
Loading…
Reference in new issue