Browse code

Select framework extended to "fixup call" if demanded using flag FIXUP_CALL.

When this flag is included in the flags column, then during the select
resolution, the "fixup" call to the resolved function is done.

During this call the res & msg parameters set to NULL.
The function can change the parsed select structure, e.g. param.type from
SEL_PARAM_STR into SEL_PARAM_DIV, etc.

Currently used for select_anyheader:
- changes _ into - to support headers including dashes (use e.g. @msg.max_forwards)
- calls parse_hname2 to speed-up headers lookup for known headers

Michal Matyska authored on 17/02/2006 12:50:41
Showing 4 changed files
... ...
@@ -58,6 +58,14 @@ int resolve_select(select_t* s)
58 58
 	s->f[0] = NULL;
59 59
 	while (param_idx<s->n) {
60 60
 		accept = 0;
61
+		switch (s->params[param_idx].type) {
62
+		case SEL_PARAM_STR:
63
+			DBG("resolve_select: '%.*s'\n", s->params[param_idx].v.s.len, s->params[param_idx].v.s.s);
64
+			break;
65
+		case SEL_PARAM_INT:
66
+			DBG("resolve_select: [%d]\n", s->params[param_idx].v.i);
67
+			break;
68
+		}
61 69
 		for (t=select_list; t; t=t->next) {
62 70
 			table_idx = 0;	
63 71
 			if (!t->table) continue;
... ...
@@ -109,6 +117,10 @@ int resolve_select(select_t* s)
109 109
 				goto not_found;
110 110
 			}
111 111
 		}
112
+		if (t->table[table_idx].flags & FIXUP_CALL) {
113
+			if (t->table[table_idx].new_f(NULL, s, NULL)<0) goto not_found;
114
+		}
115
+		
112 116
 		if (t->table[table_idx].flags & NESTED) {
113 117
 			if (nested < MAX_NESTED_CALLS-1) { /* need space for final function */
114 118
 				s->f[nested++] = f;
... ...
@@ -136,6 +148,7 @@ int resolve_select(select_t* s)
136 136
 	} else {
137 137
 		s->f[nested] = f;
138 138
 	}
139
+		
139 140
 	return 0;
140 141
 	
141 142
 not_found:
... ...
@@ -85,6 +85,13 @@
85 85
  */
86 86
 #define NESTED		1<<13
87 87
 
88
+/* "fixup call" would be done, when the structure is resolved to this node
89
+ * which means call with res and msg NULL
90
+ *
91
+ * if the fixup call return value <0, the select resolution will fail
92
+ */
93
+#define FIXUP_CALL	1<<14
94
+
88 95
 /*
89 96
  * Selector call parameter
90 97
  */
... ...
@@ -28,6 +28,7 @@
28 28
  * --------
29 29
  *  2005-12-19  select framework, basic core functions (mma)
30 30
  *  2006-01-19  multiple nested calls, IS_ALIAS -> NESTED flag renamed (mma)
31
+ *  2006-02-17  fixup call for select_anyhdr (mma)
31 32
  */
32 33
 
33 34
  
... ...
@@ -44,6 +45,8 @@
44 44
 #include "parser/parse_uri.h"
45 45
 #include "parser/parse_event.h"
46 46
 #include "parser/parse_rr.h"
47
+#include "mem/mem.h"
48
+#include "parser/parse_hname2.h"
47 49
 
48 50
 #define RETURN0_res(x) {*res=x;return 0;}
49 51
 #define TRIM_RET0_res(x) {*res=x;trim(res);return 0;} 
... ...
@@ -457,9 +460,38 @@ int select_anyheader(str* res, select_t* s, struct sip_msg* msg)
457 457
 {
458 458
 	struct hdr_field *hf, *hf0;
459 459
 	int hi;
460
+	char c;
461
+	struct hdr_field hdr;
460 462
 	
461
-	if(msg==NULL)
462
-		return -1;
463
+	if(msg==NULL) {
464
+		if (res!=NULL) return -1;
465
+
466
+		/* "fixup" call, res & msg are NULL */
467
+		if (s->n <2) return -1;
468
+
469
+		if (s->params[1].type==SEL_PARAM_STR) {
470
+				/* replace _ with - (for P-xxx headers) */
471
+			for (hi=s->params[1].v.s.len-1; hi>0; hi--)
472
+				if (s->params[1].v.s.s[hi]=='_')
473
+					s->params[1].v.s.s[hi]='-';
474
+				/* if header name is parseable, parse it and set SEL_PARAM_DIV */
475
+			c=s->params[1].v.s.s[s->params[1].v.s.len];
476
+			s->params[1].v.s.s[s->params[1].v.s.len]=':';
477
+			if (parse_hname2(s->params[1].v.s.s,s->params[1].v.s.s+(s->params[1].v.s.len<3?4:s->params[1].v.s.len+1),
478
+						&hdr)==0) {
479
+				ERR("select_anyhdr:fixup_call:parse error\n");
480
+				return -1;
481
+			}
482
+			s->params[1].v.s.s[s->params[1].v.s.len]=c;
483
+			
484
+			if (hdr.type!=HDR_OTHER_T && hdr.type!=HDR_ERROR_T) {
485
+				pkg_free(s->params[1].v.s.s);
486
+				s->params[1].type = SEL_PARAM_DIV;
487
+				s->params[1].v.i = hdr.type;
488
+			}
489
+		}
490
+		return 1;
491
+	}
463 492
 
464 493
 	hf0 = NULL;
465 494
 
... ...
@@ -139,8 +139,6 @@ static select_row_t select_core[] = {
139 139
 	{ select_any_uri, SEL_PARAM_STR, STR_STATIC_INIT("host"), select_uri_host, 0},
140 140
 	{ select_any_uri, SEL_PARAM_STR, STR_STATIC_INIT("port"), select_uri_port, 0},
141 141
 	{ select_any_uri, SEL_PARAM_STR, STR_STATIC_INIT("params"), select_uri_params, 0},
142
-	{ NULL, SEL_PARAM_STR, STR_STATIC_INIT("msg"), select_msgheader, SEL_PARAM_EXPECTED},
143
-	{ select_msgheader, SEL_PARAM_STR, STR_NULL, select_anyheader, OPTIONAL | CONSUME_NEXT_INT},
144 142
 	{ NULL, SEL_PARAM_STR, STR_STATIC_INIT("event"), select_event, 0},
145 143
 
146 144
 	{ NULL, SEL_PARAM_STR, STR_STATIC_INIT("record_route"), select_rr, 0},
... ...
@@ -149,10 +147,12 @@ static select_row_t select_core[] = {
149 149
 	{ select_rr, SEL_PARAM_STR, STR_STATIC_INIT("name"), select_rr_name, 0}, 
150 150
 	{ select_rr, SEL_PARAM_STR, STR_STATIC_INIT("params"), select_rr_params, CONSUME_NEXT_STR},
151 151
 
152
-        { NULL, SEL_PARAM_STR, STR_STATIC_INIT("cseq"), select_cseq, 0},
153
-        { select_cseq, SEL_PARAM_STR, STR_STATIC_INIT("num"), select_cseq_num, 0},
154
-        { select_cseq, SEL_PARAM_STR, STR_STATIC_INIT("method"), select_cseq_method, 0},
152
+	{ NULL, SEL_PARAM_STR, STR_STATIC_INIT("cseq"), select_cseq, 0},
153
+	{ select_cseq, SEL_PARAM_STR, STR_STATIC_INIT("num"), select_cseq_num, 0},
154
+	{ select_cseq, SEL_PARAM_STR, STR_STATIC_INIT("method"), select_cseq_method, 0},
155 155
 
156
+	{ NULL, SEL_PARAM_STR, STR_STATIC_INIT("msg"), select_msgheader, SEL_PARAM_EXPECTED},
157
+	{ select_msgheader, SEL_PARAM_STR, STR_NULL, select_anyheader, OPTIONAL | CONSUME_NEXT_INT | FIXUP_CALL},
156 158
 	{ NULL, SEL_PARAM_INT, STR_NULL, NULL, 0}
157 159
 };
158 160