Browse code

pv_headers: rework pvh_remove_header_param

* 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

Victor Seva authored on 22/06/2022 13:12:33 • Victor Seva committed on 28/06/2022 10:56:35
Showing 3 changed files
... ...
@@ -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 */