* fix KEMI interface, this is suppose to be called
like pvh_remove_header_param(header_name, string_to_remove)
* use pv buffer for temporal value
* use xavi interface to set the new value
(cherry picked from commit d9626dc9f341718ad7d78e62042695124ba52c32)
... | ... |
@@ -220,15 +220,47 @@ static int w_pvh_header_param_exists( |
220 | 220 |
return pvh_header_param_exists(msg, &hname, &value); |
221 | 221 |
} |
222 | 222 |
|
223 |
+static int ki_pvh_remove_header_param(struct sip_msg *msg, str *hname, str *toRemove) |
|
224 |
+{ |
|
225 |
+ int idx; |
|
226 |
+ int new_size; |
|
227 |
+ str dst = STR_NULL; |
|
228 |
+ sr_xavp_t *avi = pvh_xavi_get_child(msg, &xavi_name, hname); |
|
229 |
+ |
|
230 |
+ for(idx=0; avi != NULL; avi = xavi_get_next(avi)) { |
|
231 |
+ if (avi->val.type == SR_XTYPE_STR && avi->val.v.s.s != NULL) { |
|
232 |
+ if(str_casesearch(&avi->val.v.s, toRemove) != NULL) { |
|
233 |
+ new_size = pvh_remove_header_param_helper(&avi->val.v.s, toRemove, &dst); |
|
234 |
+ if(dst.len == 0) { |
|
235 |
+ LM_DBG("nothing left in the header:%.*s, remove it[%d]\n", |
|
236 |
+ STR_FMT(hname), idx); |
|
237 |
+ if(pvh_remove_header(msg, hname, idx) < 0) |
|
238 |
+ return -1; |
|
239 |
+ } else if(dst.len < 0 || new_size == avi->val.v.s.len) { |
|
240 |
+ LM_DBG("'%.*s' not found at '%.*s'\n", STR_FMT(toRemove), |
|
241 |
+ STR_FMT(&avi->val.v.s)); |
|
242 |
+ } else { |
|
243 |
+ LM_DBG("old_value:'%.*s' new_value:'%.*s'\n", |
|
244 |
+ STR_FMT(&avi->val.v.s), STR_FMT(&dst)); |
|
245 |
+ if(pvh_set_xavi(msg, &xavi_name, hname, &dst, SR_XTYPE_STR, idx, 0) < 0) { |
|
246 |
+ LM_ERR("can't set new value\n"); |
|
247 |
+ return -1; |
|
248 |
+ } |
|
249 |
+ } |
|
250 |
+ } else { |
|
251 |
+ LM_DBG("'%.*s' not found at '%.*s'\n", STR_FMT(toRemove), |
|
252 |
+ STR_FMT(&avi->val.v.s)); |
|
253 |
+ } |
|
254 |
+ } |
|
255 |
+ idx++; |
|
256 |
+ } |
|
257 |
+ return 1; |
|
258 |
+} |
|
259 |
+ |
|
223 | 260 |
static int w_pvh_remove_header_param(struct sip_msg *msg, char *p1, char *p2) |
224 | 261 |
{ |
225 |
- int ret = -1; |
|
226 |
- int idx = 0; |
|
227 | 262 |
str hname = STR_NULL; |
228 | 263 |
str value = STR_NULL; |
229 |
- sr_xavp_t *avi=NULL; |
|
230 |
- char tt[header_name_size]; |
|
231 |
- str br_xname = {tt, header_name_size}; |
|
232 | 264 |
|
233 | 265 |
if(fixup_get_svalue(msg, (gparam_p)p1, &hname) < 0) |
234 | 266 |
return -1; |
... | ... |
@@ -236,20 +268,7 @@ static int w_pvh_remove_header_param(struct sip_msg *msg, char *p1, char *p2) |
236 | 268 |
if(p2 && fixup_get_svalue(msg, (gparam_p)p2, &value) < 0) |
237 | 269 |
return -1; |
238 | 270 |
|
239 |
- pvh_get_branch_xname(msg, &xavi_name, &br_xname); |
|
240 |
- |
|
241 |
- avi = xavi_get_child(&br_xname, &hname); |
|
242 |
- |
|
243 |
- while(avi) |
|
244 |
- { |
|
245 |
- 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) { |
|
246 |
- ret = pvh_remove_header_param(msg, idx, &hname, &avi->val.v.s, &value) && ret; |
|
247 |
- } |
|
248 |
- idx++; |
|
249 |
- avi = xavi_get_next(avi); |
|
250 |
- } |
|
251 |
- |
|
252 |
- return ret; |
|
271 |
+ return ki_pvh_remove_header_param(msg, &hname, &value); |
|
253 | 272 |
} |
254 | 273 |
|
255 | 274 |
/* clang-format off */ |
... | ... |
@@ -594,9 +613,9 @@ static sr_kemi_t pvh_kemi_exports[] = { |
594 | 613 |
SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE} |
595 | 614 |
}, |
596 | 615 |
{ str_init("pv_headers"), str_init("pvh_remove_header_param"), |
597 |
- SR_KEMIP_INT, pvh_remove_header_param, |
|
598 |
- { SR_KEMIP_INT, SR_KEMIP_STR, SR_KEMIP_STR, |
|
599 |
- SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE} |
|
616 |
+ SR_KEMIP_INT, ki_pvh_remove_header_param, |
|
617 |
+ { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE, |
|
618 |
+ SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE} |
|
600 | 619 |
}, |
601 | 620 |
{{0, 0}, {0, 0}, 0, NULL, {0, 0, 0, 0, 0, 0}} |
602 | 621 |
}; |
... | ... |
@@ -22,7 +22,7 @@ |
22 | 22 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
23 | 23 |
* |
24 | 24 |
*/ |
25 |
- |
|
25 |
+#include "../../core/pvapi.h" |
|
26 | 26 |
#include "../../core/strutils.h" |
27 | 27 |
|
28 | 28 |
#include "pv_headers.h" |
... | ... |
@@ -381,73 +381,45 @@ int pvh_header_param_exists(struct sip_msg *msg, str *hname, str *hvalue) |
381 | 381 |
return -1; |
382 | 382 |
} |
383 | 383 |
|
384 |
-int pvh_remove_header_param(struct sip_msg *msg, int idx, str *hname, str *elements, str *toRemove) |
|
384 |
+int pvh_remove_header_param_helper(str *orig, const str *toRemove, str *dst) |
|
385 | 385 |
{ |
386 |
- int notTarget, writtenChars; |
|
386 |
+ int notTarget; |
|
387 |
+ int writtenChars = 0; |
|
387 | 388 |
int offset = 0; |
388 |
- int ret = -1; |
|
389 |
- char *next_token; |
|
389 |
+ char *saveptr = NULL; |
|
390 | 390 |
char *token; |
391 |
- char *result = (char*)pkg_malloc(elements->len - toRemove->len); |
|
392 |
- char *t = (char*)pkg_malloc(elements->len+1); |
|
393 |
- |
|
394 |
- if (result == NULL || t == NULL) |
|
395 |
- { |
|
396 |
- PKG_MEM_ERROR; |
|
397 |
- goto clean; |
|
398 |
- } |
|
399 |
- |
|
400 |
- snprintf(t, elements->len+1, "%s", elements->s); |
|
401 |
- |
|
402 |
- token = strtok_r(t, ", ", &next_token); |
|
403 |
- while(token) |
|
404 |
- { |
|
405 |
- notTarget = strncmp(token, toRemove->s, toRemove->len); |
|
406 |
- if (notTarget) |
|
407 |
- { |
|
408 |
- writtenChars = snprintf(result + offset, elements->len - offset, "%s", token); |
|
409 |
- if (writtenChars < 0 || writtenChars >= elements->len - offset) |
|
410 |
- { |
|
411 |
- break; |
|
412 |
- } |
|
413 |
- offset += writtenChars; |
|
414 |
- } |
|
415 |
- token = strtok_r(NULL, ", ", &next_token); |
|
416 |
- if (token && notTarget && elements->len - offset - toRemove->len > 2) |
|
417 |
- { |
|
418 |
- writtenChars = snprintf(result + offset, elements->len - offset, ", "); |
|
419 |
- if (writtenChars < 0 || writtenChars >= elements->len - offset) |
|
420 |
- { |
|
421 |
- break; |
|
422 |
- } |
|
391 |
+ char t[header_value_size]; |
|
392 |
+ char *result = pv_get_buffer(); |
|
393 |
+ int maxSize = pv_get_buffer_size(); |
|
394 |
+ |
|
395 |
+ memset(result, 0, maxSize); |
|
396 |
+ LM_DBG("orig:'%.*s' toRemove:'%.*s'\n", STR_FMT(orig), STR_FMT(toRemove)); |
|
397 |
+ strncpy(t, orig->s, orig->len); |
|
398 |
+ t[orig->len] = '\0'; |
|
399 |
+ token = strtok_r(t, ", ", &saveptr); |
|
400 |
+ dst->s = NULL; dst->len = -1; |
|
401 |
+ while(token) { |
|
402 |
+ notTarget = strncasecmp(token, toRemove->s, toRemove->len); |
|
403 |
+ LM_DBG("offset:%d token:%s notTarget:%d\n", offset, token, notTarget); |
|
404 |
+ if(notTarget) { |
|
405 |
+ writtenChars = snprintf(result + offset, maxSize - offset, "%s, ", token); |
|
406 |
+ if(writtenChars < 0) break; |
|
423 | 407 |
offset += writtenChars; |
408 |
+ } else { |
|
409 |
+ dst->len = 0; /* we found a token */ |
|
424 | 410 |
} |
411 |
+ token = strtok_r(NULL, ", ", &saveptr); |
|
425 | 412 |
} |
426 | 413 |
|
427 |
- if (elements->len-toRemove->len > 0) |
|
428 |
- { |
|
429 |
- snprintf(elements->s, (strlen(result)%elements->len)+1, "%s", result); |
|
430 |
- elements->len = strlen(result); |
|
431 |
- ret = 1; |
|
432 |
- } |
|
433 |
- else |
|
434 |
- { |
|
435 |
- ret = pvh_remove_header(msg, hname, idx); |
|
436 |
- } |
|
437 |
- |
|
438 |
-clean: |
|
439 |
- |
|
440 |
- if(t != NULL) |
|
441 |
- { |
|
442 |
- pkg_free(t); |
|
443 |
- t = NULL; |
|
444 |
- } |
|
445 |
- |
|
446 |
- if(result != NULL) |
|
447 |
- { |
|
448 |
- pkg_free(result); |
|
449 |
- result = NULL; |
|
414 |
+ if(offset > 0) { |
|
415 |
+ dst->s = result; |
|
416 |
+ if(offset > 2 && result[offset-2] == ',' && result[offset-1] == ' ') { |
|
417 |
+ LM_DBG("remove last separator\n"); |
|
418 |
+ offset = offset - 2; |
|
419 |
+ result[offset] = '\0'; |
|
420 |
+ } |
|
421 |
+ dst->len = offset; |
|
422 |
+ LM_DBG("offset:%d result:'%.*s'[%d]\n", offset, STR_FMT(dst), dst->len); |
|
450 | 423 |
} |
451 |
- |
|
452 |
- return ret; |
|
424 |
+ return offset; |
|
453 | 425 |
} |
... | ... |
@@ -39,6 +39,6 @@ int pvh_append_header(struct sip_msg *msg, str *hname, str *hvalue); |
39 | 39 |
int pvh_modify_header(struct sip_msg *msg, str *hname, str *hvalue, int indx); |
40 | 40 |
int pvh_remove_header(struct sip_msg *msg, str *hname, int indx); |
41 | 41 |
int pvh_header_param_exists(struct sip_msg *msg, str *hname, str *hvalue); |
42 |
-int pvh_remove_header_param(struct sip_msg *msg, int idx, str *hname, str *elements, str *toRemove); |
|
42 |
+int pvh_remove_header_param_helper(str *orig, const str *toRemove, str *dst); |
|
43 | 43 |
|
44 | 44 |
#endif /* PV_FUNC_H */ |