Ver código fonte

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

- return true/false based on matching header content
Daniel-Constantin Mierla 5 anos atrás
pai
commit
b84b67a084
1 arquivos alterados com 165 adições e 0 exclusões
  1. 165 0
      src/core/kemi.c

+ 165 - 0
src/core/kemi.c

@@ -33,6 +33,7 @@
 #include "strutils.h"
 #include "strutils.h"
 #include "select_buf.h"
 #include "select_buf.h"
 #include "pvar.h"
 #include "pvar.h"
+#include "trim.h"
 #include "mem/shm.h"
 #include "mem/shm.h"
 #include "parser/parse_uri.h"
 #include "parser/parse_uri.h"
 #include "parser/parse_from.h"
 #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)
 	return sr_kemi_hdr_get_mode(msg, hname, idx, SR_KEMI_XVAL_NULL_PRINT);
 	return sr_kemi_hdr_get_mode(msg, hname, idx, SR_KEMI_XVAL_NULL_PRINT);
 }
 }
 
 
+/**
+ *
+ */
+static int sr_kemi_hdr_match_content(sip_msg_t *msg, str *hname, str *op,
+		str *mval, str *hidx)
+{
+	hdr_field_t *hf;
+	hdr_field_t hfm;
+	int opval = 0;
+	int hidxval = 0;
+	int matched = 0;
+	int hnum = 0;
+	str hbody = STR_NULL;
+
+	if(hname==NULL || hname->s==NULL || msg==NULL) {
+		return SR_KEMI_FALSE;
+	}
+
+	if (parse_hname2_str(hname, &hfm)==0) {
+		LM_ERR("error parsing header name [%.*s]\n", hname->len, hname->s);
+		return SR_KEMI_FALSE;
+	}
+
+	if (parse_headers(msg, HDR_EOH_F, 0) == -1) {
+		LM_ERR("error while parsing message\n");
+		return SR_KEMI_FALSE;
+	}
+
+	if(op->len == 2) {
+		if(strncasecmp(op->s, "eq", 2) == 0) {
+			opval = 1;
+		} if(strncasecmp(op->s, "ne", 2) == 0) {
+			opval = 2;
+		} if(strncasecmp(op->s, "sw", 2) == 0) {
+			opval = 3;
+		} if(strncasecmp(op->s, "in", 2) == 0) {
+			opval = 4;
+		} if(strncasecmp(op->s, "re", 2) == 0) {
+			opval = 5;
+			LM_ERR("operator not implemented: %.*s\n", op->len, op->s);
+			return SR_KEMI_FALSE;
+		} else {
+			LM_ERR("invalid operator: %.*s\n", op->len, op->s);
+			return SR_KEMI_FALSE;
+		}
+	} else {
+		LM_ERR("invalid operator: %.*s\n", op->len, op->s);
+		return SR_KEMI_FALSE;
+	}
+
+
+	if(hidx->len >= 1) {
+		if(hidx->s[0]=='f' || hidx->s[0]=='F') {
+			/* first */
+			hidxval = 1;
+		} else if(hidx->s[0]=='l' || hidx->s[0]=='L') {
+			/* last */
+			hidxval = 2;
+		} else if(hidx->s[0]=='a' || hidx->s[0]=='a') {
+			/* all */
+			hidxval = 3;
+		} else if(hidx->s[0]=='o' || hidx->s[0]=='O') {
+			/* one - at least one */
+			hidxval = 4;
+		} else {
+			LM_ERR("invalid header index: %.*s\n", hidx->len, hidx->s);
+			return SR_KEMI_FALSE;
+		}
+	} else {
+		LM_ERR("invalid header index: %.*s\n", hidx->len, hidx->s);
+		return SR_KEMI_FALSE;
+	}
+
+	LM_DBG("searching hf: %.*s\n", hname->len, hname->s);
+	for (hf=msg->headers; hf; hf=hf->next) {
+		if (hfm.type!=HDR_OTHER_T && hfm.type!=HDR_ERROR_T) {
+			if (hfm.type!=hf->type) {
+				continue;
+			}
+		} else {
+			if (hf->name.len!=hname->len) {
+				continue;
+			}
+			if(strncasecmp(hf->name.s, hname->s, hname->len)!=0) {
+				continue;
+			}
+		}
+		hnum++;
+		matched = 0;
+		hbody = hf->body;
+		trim(&hbody);
+		switch(opval) {
+			case 1:
+			case 2:
+				if(mval->len != hbody.len) {
+					if(opval == 2) {
+						/* ne */
+						matched = 1;
+					}
+				} else {
+					if(strncasecmp(mval->s, hbody.s, hbody.len) == 0) {
+						if(opval == 1) {
+							/* eq */
+							matched = 1;
+						}
+					}
+				}
+				break;
+			case 3:
+				/* sw */
+				if(hbody.len >= mval->len) {
+					if(strncasecmp(hbody.s, mval->s, mval->len) == 0) {
+						matched = 1;
+					}
+				}
+				break;
+			case 4:
+				/* in */
+				if(hbody.len >= mval->len) {
+					if(str_casesearch(&hbody, mval) != NULL) {
+						matched = 1;
+					}
+				}
+				break;
+			case 5:
+				/* re */
+				break;
+		}
+		if(hnum==1 && hidxval==1) {
+			/* first */
+			if(matched == 1) {
+				return SR_KEMI_TRUE;
+			} else {
+				return SR_KEMI_FALSE;
+			}
+		}
+		if(hidxval==3) {
+			/* all */
+			if(matched == 0) {
+				return SR_KEMI_FALSE;
+			}
+		}
+		if(hidxval==4) {
+			/* one */
+			if(matched == 1) {
+				return SR_KEMI_TRUE;
+			}
+		}
+	}
+
+	/* last - all */
+	if(matched == 1) {
+		return SR_KEMI_TRUE;
+	} else {
+		return SR_KEMI_FALSE;
+	}
+}
+
+
 /**
 /**
  *
  *
  */
  */
@@ -2488,6 +2648,11 @@ static sr_kemi_t _sr_kemi_hdr[] = {
 		{ SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
 		{ SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
 			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
 			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
 	},
 	},
+	{ str_init("hdr"), str_init("match_content"),
+		SR_KEMIP_BOOL, sr_kemi_hdr_match_content,
+		{ SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR,
+			SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE }
+	},
 
 
 	{ {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
 	{ {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
 };
 };