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