|
@@ -33,6 +33,7 @@
|
|
|
#include "strutils.h"
|
|
|
#include "select_buf.h"
|
|
|
#include "pvar.h"
|
|
|
+#include "trim.h"
|
|
|
#include "mem/shm.h"
|
|
|
#include "parser/parse_uri.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);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ *
|
|
|
+ */
|
|
|
+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_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 } }
|
|
|
};
|