Browse code

core: kemi - new function hdr.match_content(hname, op, mval, hidx)

- return true/false based on matching header content

Daniel-Constantin Mierla authored on 06/10/2020 10:56:09
Showing 1 changed files
... ...
@@ -33,6 +33,7 @@
33 33
 #include "strutils.h"
34 34
 #include "select_buf.h"
35 35
 #include "pvar.h"
36
+#include "trim.h"
36 37
 #include "mem/shm.h"
37 38
 #include "parser/parse_uri.h"
38 39
 #include "parser/parse_from.h"
... ...
@@ -2409,6 +2410,165 @@ static sr_kemi_xval_t* sr_kemi_hdr_getw_idx(sip_msg_t *msg, str *hname, int idx)
2409 2410
 	return sr_kemi_hdr_get_mode(msg, hname, idx, SR_KEMI_XVAL_NULL_PRINT);
2410 2411
 }
2411 2412
 
2413
+/**
2414
+ *
2415
+ */
2416
+static int sr_kemi_hdr_match_content(sip_msg_t *msg, str *hname, str *op,
2417
+		str *mval, str *hidx)
2418
+{
2419
+	hdr_field_t *hf;
2420
+	hdr_field_t hfm;
2421
+	int opval = 0;
2422
+	int hidxval = 0;
2423
+	int matched = 0;
2424
+	int hnum = 0;
2425
+	str hbody = STR_NULL;
2426
+
2427
+	if(hname==NULL || hname->s==NULL || msg==NULL) {
2428
+		return SR_KEMI_FALSE;
2429
+	}
2430
+
2431
+	if (parse_hname2_str(hname, &hfm)==0) {
2432
+		LM_ERR("error parsing header name [%.*s]\n", hname->len, hname->s);
2433
+		return SR_KEMI_FALSE;
2434
+	}
2435
+
2436
+	if (parse_headers(msg, HDR_EOH_F, 0) == -1) {
2437
+		LM_ERR("error while parsing message\n");
2438
+		return SR_KEMI_FALSE;
2439
+	}
2440
+
2441
+	if(op->len == 2) {
2442
+		if(strncasecmp(op->s, "eq", 2) == 0) {
2443
+			opval = 1;
2444
+		} if(strncasecmp(op->s, "ne", 2) == 0) {
2445
+			opval = 2;
2446
+		} if(strncasecmp(op->s, "sw", 2) == 0) {
2447
+			opval = 3;
2448
+		} if(strncasecmp(op->s, "in", 2) == 0) {
2449
+			opval = 4;
2450
+		} if(strncasecmp(op->s, "re", 2) == 0) {
2451
+			opval = 5;
2452
+			LM_ERR("operator not implemented: %.*s\n", op->len, op->s);
2453
+			return SR_KEMI_FALSE;
2454
+		} else {
2455
+			LM_ERR("invalid operator: %.*s\n", op->len, op->s);
2456
+			return SR_KEMI_FALSE;
2457
+		}
2458
+	} else {
2459
+		LM_ERR("invalid operator: %.*s\n", op->len, op->s);
2460
+		return SR_KEMI_FALSE;
2461
+	}
2462
+
2463
+
2464
+	if(hidx->len >= 1) {
2465
+		if(hidx->s[0]=='f' || hidx->s[0]=='F') {
2466
+			/* first */
2467
+			hidxval = 1;
2468
+		} else if(hidx->s[0]=='l' || hidx->s[0]=='L') {
2469
+			/* last */
2470
+			hidxval = 2;
2471
+		} else if(hidx->s[0]=='a' || hidx->s[0]=='a') {
2472
+			/* all */
2473
+			hidxval = 3;
2474
+		} else if(hidx->s[0]=='o' || hidx->s[0]=='O') {
2475
+			/* one - at least one */
2476
+			hidxval = 4;
2477
+		} else {
2478
+			LM_ERR("invalid header index: %.*s\n", hidx->len, hidx->s);
2479
+			return SR_KEMI_FALSE;
2480
+		}
2481
+	} else {
2482
+		LM_ERR("invalid header index: %.*s\n", hidx->len, hidx->s);
2483
+		return SR_KEMI_FALSE;
2484
+	}
2485
+
2486
+	LM_DBG("searching hf: %.*s\n", hname->len, hname->s);
2487
+	for (hf=msg->headers; hf; hf=hf->next) {
2488
+		if (hfm.type!=HDR_OTHER_T && hfm.type!=HDR_ERROR_T) {
2489
+			if (hfm.type!=hf->type) {
2490
+				continue;
2491
+			}
2492
+		} else {
2493
+			if (hf->name.len!=hname->len) {
2494
+				continue;
2495
+			}
2496
+			if(strncasecmp(hf->name.s, hname->s, hname->len)!=0) {
2497
+				continue;
2498
+			}
2499
+		}
2500
+		hnum++;
2501
+		matched = 0;
2502
+		hbody = hf->body;
2503
+		trim(&hbody);
2504
+		switch(opval) {
2505
+			case 1:
2506
+			case 2:
2507
+				if(mval->len != hbody.len) {
2508
+					if(opval == 2) {
2509
+						/* ne */
2510
+						matched = 1;
2511
+					}
2512
+				} else {
2513
+					if(strncasecmp(mval->s, hbody.s, hbody.len) == 0) {
2514
+						if(opval == 1) {
2515
+							/* eq */
2516
+							matched = 1;
2517
+						}
2518
+					}
2519
+				}
2520
+				break;
2521
+			case 3:
2522
+				/* sw */
2523
+				if(hbody.len >= mval->len) {
2524
+					if(strncasecmp(hbody.s, mval->s, mval->len) == 0) {
2525
+						matched = 1;
2526
+					}
2527
+				}
2528
+				break;
2529
+			case 4:
2530
+				/* in */
2531
+				if(hbody.len >= mval->len) {
2532
+					if(str_casesearch(&hbody, mval) != NULL) {
2533
+						matched = 1;
2534
+					}
2535
+				}
2536
+				break;
2537
+			case 5:
2538
+				/* re */
2539
+				break;
2540
+		}
2541
+		if(hnum==1 && hidxval==1) {
2542
+			/* first */
2543
+			if(matched == 1) {
2544
+				return SR_KEMI_TRUE;
2545
+			} else {
2546
+				return SR_KEMI_FALSE;
2547
+			}
2548
+		}
2549
+		if(hidxval==3) {
2550
+			/* all */
2551
+			if(matched == 0) {
2552
+				return SR_KEMI_FALSE;
2553
+			}
2554
+		}
2555
+		if(hidxval==4) {
2556
+			/* one */
2557
+			if(matched == 1) {
2558
+				return SR_KEMI_TRUE;
2559
+			}
2560
+		}
2561
+	}
2562
+
2563
+	/* last - all */
2564
+	if(matched == 1) {
2565
+		return SR_KEMI_TRUE;
2566
+	} else {
2567
+		return SR_KEMI_FALSE;
2568
+	}
2569
+}
2570
+
2571
+
2412 2572
 /**
2413 2573
  *
2414 2574
  */
... ...
@@ -2488,6 +2648,11 @@ static sr_kemi_t _sr_kemi_hdr[] = {
2488 2648
 		{ SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
2489 2649
 			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2490 2650
 	},
2651
+	{ str_init("hdr"), str_init("match_content"),
2652
+		SR_KEMIP_BOOL, sr_kemi_hdr_match_content,
2653
+		{ SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR,
2654
+			SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE }
2655
+	},
2491 2656
 
2492 2657
 	{ {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
2493 2658
 };