1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #include "common.h"
30
31 #include "../daemon/httprequest.h"
32 #include "../daemon/log.h"
33
34 #include "../util/pblock.h"
35 #include "../util/util.h"
36 #include "../../ucx/map.h"
37
38 static UcxMap *var_names;
39
40 enum SAFVarNames {
41 COMMONSAF_INSERT_CLIENT =
1,
42 COMMONSAF_INSERT_VARS,
43 COMMONSAF_INSERT_REQPB,
44 COMMONSAF_INSERT_HEADERS,
45 COMMONSAF_INSERT_SRVHDRS,
46 COMMONSAF_SET_CLIENT,
47 COMMONSAF_SET_VARS,
48 COMMONSAF_SET_REQPB,
49 COMMONSAF_SET_HEADERS,
50 COMMONSAF_SET_SRVHDRS,
51 COMMONSAF_REMOVE_CLIENT,
52 COMMONSAF_REMOVE_VARS,
53 COMMONSAF_REMOVE_REQPB,
54 COMMONSAF_REMOVE_HEADERS,
55 COMMONSAF_REMOVE_SRVHDRS,
56 COMMONSAF_ABORT,
57 COMMONSAF_NOACTION,
58 COMMONSAF_ERROR,
59 COMMONSAF_ESCAPE,
60 COMMONSAF_FIND_PATHINFO_FORWARD,
61 COMMONSAF_HTTP_DOWNGRADE,
62 COMMONSAF_HTTP_UPGRADE,
63 COMMONSAF_KEEP_ALIVE,
64 COMMONSAF_NAME,
65 COMMONSAF_SENTHDRS,
66 COMMONSAF_STOP,
67 COMMONSAF_URL
68 };
69
70 #define COMMONSAF_RET_DEF 0
71 #define COMMONSAF_RET_NOACTION 1
72 #define COMMONSAF_RET_STOP 2
73 #define COMMONSAF_REQ_ABORTED -
1
74 #define COMMONSAF_RET_ERROR -
2
75
76 void common_saf_init() {
77 var_names = ucx_map_new(
32);
78
79 ucx_map_cstr_put(var_names,
"insert-client", (
intptr_t)
COMMONSAF_INSERT_CLIENT);
80 ucx_map_cstr_put(var_names,
"insert-vars", (
intptr_t)
COMMONSAF_INSERT_VARS);
81 ucx_map_cstr_put(var_names,
"insert-reqpb", (
intptr_t)
COMMONSAF_INSERT_REQPB);
82 ucx_map_cstr_put(var_names,
"insert-headers", (
intptr_t)
COMMONSAF_INSERT_HEADERS);
83 ucx_map_cstr_put(var_names,
"insert-srvhdrs", (
intptr_t)
COMMONSAF_INSERT_SRVHDRS);
84
85 ucx_map_cstr_put(var_names,
"set-client", (
intptr_t)
COMMONSAF_SET_CLIENT);
86 ucx_map_cstr_put(var_names,
"set-vars", (
intptr_t)
COMMONSAF_SET_VARS);
87 ucx_map_cstr_put(var_names,
"set-reqpb", (
intptr_t)
COMMONSAF_SET_REQPB);
88 ucx_map_cstr_put(var_names,
"set-headers", (
intptr_t)
COMMONSAF_SET_HEADERS);
89 ucx_map_cstr_put(var_names,
"set-srvhdrs", (
intptr_t)
COMMONSAF_SET_SRVHDRS);
90
91 ucx_map_cstr_put(var_names,
"remove-client", (
intptr_t)
COMMONSAF_REMOVE_CLIENT);
92 ucx_map_cstr_put(var_names,
"remove-vars", (
intptr_t)
COMMONSAF_REMOVE_VARS);
93 ucx_map_cstr_put(var_names,
"remove-reqpb", (
intptr_t)
COMMONSAF_REMOVE_REQPB);
94 ucx_map_cstr_put(var_names,
"remove-headers", (
intptr_t)
COMMONSAF_REMOVE_HEADERS);
95 ucx_map_cstr_put(var_names,
"remove-srvhdrs", (
intptr_t)
COMMONSAF_REMOVE_SRVHDRS);
96
97 ucx_map_cstr_put(var_names,
"abort", (
intptr_t)
COMMONSAF_ABORT);
98 ucx_map_cstr_put(var_names,
"noaction", (
intptr_t)
COMMONSAF_NOACTION);
99 ucx_map_cstr_put(var_names,
"error", (
intptr_t)
COMMONSAF_ERROR);
100 ucx_map_cstr_put(var_names,
"escape", (
intptr_t)
COMMONSAF_ESCAPE);
101 ucx_map_cstr_put(var_names,
"find-pathinfo-forward", (
intptr_t)
COMMONSAF_FIND_PATHINFO_FORWARD);
102 ucx_map_cstr_put(var_names,
"http-downgrade", (
intptr_t)
COMMONSAF_HTTP_DOWNGRADE);
103 ucx_map_cstr_put(var_names,
"http-upgrade", (
intptr_t)
COMMONSAF_HTTP_UPGRADE);
104 ucx_map_cstr_put(var_names,
"keep-alive", (
intptr_t)
COMMONSAF_KEEP_ALIVE);
105 ucx_map_cstr_put(var_names,
"name", (
intptr_t)
COMMONSAF_NAME);
106 }
107
108 int print_message(pblock *pb, Session *sn, Request *rq) {
109 char *msg = pblock_findval(
"msg", pb);
110 if(msg) {
111 log_ereport(
LOG_INFORM,
"%s", msg);
112 }
113
114 return REQ_NOACTION;
115 }
116
117 static void var_set(
char *value, pblock *pb, WSBool insert) {
118 sstr_t n;
119 sstr_t v;
120 v.ptr =
NULL;
121
122 n.ptr = value;
123 int i;
124 int len = strlen(value);
125 for(i=
1;i<len;i++) {
126 if(value[i] ==
'=') {
127 n.length = i;
128 v = sstrsubs(sstrn(value, len), i +
1);
129 break;
130 }
131 }
132 if(!v.ptr || v.length ==
0) {
133 log_ereport(
134 LOG_MISCONFIG,
135 "set-variable: string ''%s'' has not name=value format",
136 value);
137 return;
138 }
139
140 if(!insert) {
141
142 }
143 pblock_nvlinsert(n.ptr, n.length, v.ptr, v.length, pb);
144 }
145
146 static int set_var(Session *sn, Request *rq,
char *var,
char *value) {
147 intptr_t v = (
intptr_t)ucx_map_cstr_get(var_names, var);
148 switch(v) {
149 default:
break;
150 case COMMONSAF_INSERT_CLIENT: var_set(value, sn->client,
TRUE);
break;
151 case COMMONSAF_INSERT_VARS: var_set(value, rq->vars,
TRUE);
break;
152 case COMMONSAF_INSERT_REQPB: var_set(value, rq->reqpb,
TRUE);
break;
153 case COMMONSAF_INSERT_HEADERS: var_set(value, rq->headers,
TRUE);
break;
154 case COMMONSAF_INSERT_SRVHDRS: var_set(value, rq->srvhdrs,
TRUE);
break;
155 case COMMONSAF_SET_CLIENT: var_set(value, sn->client,
FALSE);
break;
156 case COMMONSAF_SET_VARS: var_set(value, rq->vars,
FALSE);
break;
157 case COMMONSAF_SET_REQPB: var_set(value, rq->reqpb,
FALSE);
break;
158 case COMMONSAF_SET_HEADERS: var_set(value, rq->headers,
FALSE);
break;
159 case COMMONSAF_SET_SRVHDRS: var_set(value, rq->srvhdrs,
FALSE);
break;
160 case COMMONSAF_REMOVE_CLIENT: pblock_remove(value, sn->client);
break;
161 case COMMONSAF_REMOVE_VARS: pblock_remove(value, rq->vars);
break;
162 case COMMONSAF_REMOVE_HEADERS: pblock_remove(value, rq->headers);
break;
163 case COMMONSAF_REMOVE_SRVHDRS: pblock_remove(value, rq->srvhdrs);
break;
164 case COMMONSAF_ABORT:
return COMMONSAF_REQ_ABORTED;
165 case COMMONSAF_NOACTION:
return COMMONSAF_RET_NOACTION;
166 case COMMONSAF_ERROR: {
167 int len = strlen(value);
168 WSBool isnum =
TRUE;
169 int i;
170 for(i=
0;i<len;i++) {
171 if(!isdigit(value[i])) {
172 isnum =
FALSE;
173 break;
174 }
175 }
176
177 int64_t status;
178 int ret = util_strtoint(value, &status);
179 if(status <
100 || ret >
999 || !ret) {
180 log_ereport(
181 LOG_MISCONFIG,
182 "set-variable: error value must contain a 3-digit http status code");
183 protocol_status(sn, rq,
500,
NULL);
184 return COMMONSAF_RET_ERROR;
185 }
186
187 char *msg = isnum ?
NULL : sstrtrim(sstr(value + i)).ptr;
188 protocol_status(sn, rq, (
int)status, msg);
189
190 return COMMONSAF_REQ_ABORTED;
191 }
192 case COMMONSAF_ESCAPE:
break;
193 case COMMONSAF_FIND_PATHINFO_FORWARD:
break;
194 case COMMONSAF_HTTP_DOWNGRADE:
break;
195 case COMMONSAF_HTTP_UPGRADE:
break;
196 case COMMONSAF_KEEP_ALIVE: {
197 rq->rq_attr.keep_alive = util_getboolean(var,
0);
198 break;
199 }
200 case COMMONSAF_NAME: {
201 pblock_kvinsert(pb_key_name, value, strlen(value), rq->vars);
202 break;
203 }
204 case COMMONSAF_SENTHDRS:
break;
205 case COMMONSAF_STOP:
return COMMONSAF_RET_STOP;
206 case COMMONSAF_URL:
break;
207 }
208 return COMMONSAF_RET_DEF;
209 }
210
211 int set_variable(pblock *pb, Session *sn, Request *rq) {
212 int ret =
REQ_NOACTION;
213 int set =
0;
214
215 for(
int i=
0;i<pb->hsize;i++) {
216 pb_entry *entry = pb->ht[i];
217 while(entry) {
218 int r = set_var(sn, rq, entry->param->name, entry->param->value);
219 switch(r) {
220 default:
221 case COMMONSAF_RET_DEF:
break;
222 case COMMONSAF_RET_NOACTION: set =
1; ret =
REQ_NOACTION;
break;
223 case COMMONSAF_RET_STOP: set =
1; ret =
REQ_PROCEED;
break;
224 case COMMONSAF_REQ_ABORTED: ret = set ? ret :
REQ_ABORTED;
break;
225 case COMMONSAF_RET_ERROR:
return REQ_ABORTED;
226 }
227 entry = entry->next;
228 }
229 }
230
231 return ret;
232 }
233