1 #ifdef UWSGI_ROUTING
2 #include "uwsgi.h"
3
4 extern struct uwsgi_server uwsgi;
5
uwsgi_register_route_var(char * name,char * (* func)(struct wsgi_request *,char *,uint16_t,uint16_t *))6 struct uwsgi_route_var *uwsgi_register_route_var(char *name, char *(*func)(struct wsgi_request *, char *, uint16_t, uint16_t *)) {
7
8 struct uwsgi_route_var *old_urv = NULL,*urv = uwsgi.route_vars;
9 while(urv) {
10 if (!strcmp(urv->name, name)) {
11 return urv;
12 }
13 old_urv = urv;
14 urv = urv->next;
15 }
16
17 urv = uwsgi_calloc(sizeof(struct uwsgi_route_var));
18 urv->name = name;
19 urv->name_len = strlen(name);
20 urv->func = func;
21
22 if (old_urv) {
23 old_urv->next = urv;
24 }
25 else {
26 uwsgi.route_vars = urv;
27 }
28
29 return urv;
30 }
31
uwsgi_get_route_var(char * name,uint16_t name_len)32 struct uwsgi_route_var *uwsgi_get_route_var(char *name, uint16_t name_len) {
33 struct uwsgi_route_var *urv = uwsgi.route_vars;
34 while(urv) {
35 if (!uwsgi_strncmp(urv->name, urv->name_len, name, name_len)) {
36 return urv;
37 }
38 urv = urv->next;
39 }
40 return NULL;
41 }
42
uwsgi_routing_translate(struct wsgi_request * wsgi_req,struct uwsgi_route * ur,char * subject,uint16_t subject_len,char * data,size_t data_len)43 struct uwsgi_buffer *uwsgi_routing_translate(struct wsgi_request *wsgi_req, struct uwsgi_route *ur, char *subject, uint16_t subject_len, char *data, size_t data_len) {
44
45 char *pass1 = data;
46 size_t pass1_len = data_len;
47
48 if (ur->condition_ub[wsgi_req->async_id] && ur->ovn[wsgi_req->async_id] > 0) {
49 pass1 = uwsgi_regexp_apply_ovec(ur->condition_ub[wsgi_req->async_id]->buf, ur->condition_ub[wsgi_req->async_id]->pos, data, data_len, ur->ovector[wsgi_req->async_id], ur->ovn[wsgi_req->async_id]);
50 pass1_len = strlen(pass1);
51 }
52 // cannot fail
53 else if (subject) {
54 pass1 = uwsgi_regexp_apply_ovec(subject, subject_len, data, data_len, ur->ovector[wsgi_req->async_id], ur->ovn[wsgi_req->async_id]);
55 pass1_len = strlen(pass1);
56 }
57
58 struct uwsgi_buffer *ub = uwsgi_buffer_new(pass1_len);
59 size_t i;
60 int status = 0;
61 char *key = NULL;
62 size_t keylen = 0;
63 for(i=0;i<pass1_len;i++) {
64 switch(status) {
65 case 0:
66 if (pass1[i] == '$') {
67 status = 1;
68 break;
69 }
70 if (uwsgi_buffer_append(ub, pass1 + i, 1)) goto error;
71 break;
72 case 1:
73 if (pass1[i] == '{') {
74 status = 2;
75 key = pass1+i+1;
76 keylen = 0;
77 break;
78 }
79 status = 0;
80 key = NULL;
81 keylen = 0;
82 if (uwsgi_buffer_append(ub, "$", 1)) goto error;
83 if (uwsgi_buffer_append(ub, pass1 + i, 1)) goto error;
84 break;
85 case 2:
86 if (pass1[i] == '}') {
87 uint16_t vallen = 0;
88 int need_free = 0;
89 char *value = NULL;
90 char *bracket = memchr(key, '[', keylen);
91 if (bracket && keylen > 0 && key[keylen-1] == ']') {
92 struct uwsgi_route_var *urv = uwsgi_get_route_var(key, bracket - key);
93 if (urv) {
94 need_free = urv->need_free;
95 value = urv->func(wsgi_req, bracket + 1, keylen - (urv->name_len+2), &vallen);
96 }
97 else {
98 value = uwsgi_get_var(wsgi_req, key, keylen, &vallen);
99 }
100 }
101 else {
102 value = uwsgi_get_var(wsgi_req, key, keylen, &vallen);
103 }
104 if (value) {
105 if (uwsgi_buffer_append(ub, value, vallen)) {
106 if (need_free) {
107 free(value);
108 }
109 goto error;
110 }
111 if (need_free) {
112 free(value);
113 }
114 }
115 status = 0;
116 key = NULL;
117 keylen = 0;
118 break;
119 }
120 keylen++;
121 break;
122 default:
123 break;
124 }
125 }
126
127 // fix the buffer
128 if (status == 1) {
129 if (uwsgi_buffer_append(ub, "$", 1)) goto error;
130 }
131 else if (status == 2) {
132 if (uwsgi_buffer_append(ub, "${", 2)) goto error;
133 if (keylen > 0) {
134 if (uwsgi_buffer_append(ub, key, keylen)) goto error;
135 }
136 }
137
138 // add the final NULL byte (to simplify plugin work)
139 if (uwsgi_buffer_append(ub, "\0", 1)) goto error;
140 // .. but came back of 1 position to avoid accounting it
141 ub->pos--;
142
143 if (pass1 != data) {
144 free(pass1);
145 }
146 return ub;
147
148 error:
149 uwsgi_buffer_destroy(ub);
150 return NULL;
151 }
152
uwsgi_routing_reset_memory(struct wsgi_request * wsgi_req,struct uwsgi_route * routes)153 static void uwsgi_routing_reset_memory(struct wsgi_request *wsgi_req, struct uwsgi_route *routes) {
154 // free dynamic memory structures
155 if (routes->if_func) {
156 routes->ovn[wsgi_req->async_id] = 0;
157 if (routes->ovector[wsgi_req->async_id]) {
158 free(routes->ovector[wsgi_req->async_id]);
159 routes->ovector[wsgi_req->async_id] = NULL;
160 }
161 if (routes->condition_ub[wsgi_req->async_id]) {
162 uwsgi_buffer_destroy(routes->condition_ub[wsgi_req->async_id]);
163 routes->condition_ub[wsgi_req->async_id] = NULL;
164 }
165 }
166
167 }
168
uwsgi_apply_routes_do(struct uwsgi_route * routes,struct wsgi_request * wsgi_req,char * subject,uint16_t subject_len)169 int uwsgi_apply_routes_do(struct uwsgi_route *routes, struct wsgi_request *wsgi_req, char *subject, uint16_t subject_len) {
170
171 int n = -1;
172
173 char *orig_subject = subject;
174 uint16_t orig_subject_len = subject_len;
175
176 uint32_t *r_goto = &wsgi_req->route_goto;
177 uint32_t *r_pc = &wsgi_req->route_pc;
178
179 if (routes == uwsgi.error_routes) {
180 r_goto = &wsgi_req->error_route_goto;
181 r_pc = &wsgi_req->error_route_pc;
182 }
183 else if (routes == uwsgi.response_routes) {
184 r_goto = &wsgi_req->response_route_goto;
185 r_pc = &wsgi_req->response_route_pc;
186 }
187 else if (routes == uwsgi.final_routes) {
188 r_goto = &wsgi_req->final_route_goto;
189 r_pc = &wsgi_req->final_route_pc;
190 }
191
192 while (routes) {
193
194 if (routes->label) goto next;
195
196 if (*r_goto > 0 && *r_pc < *r_goto) {
197 goto next;
198 }
199
200 *r_goto = 0;
201
202 if (!routes->if_func) {
203 // could be a "run"
204 if (!routes->subject) {
205 n = 0;
206 goto run;
207 }
208 if (!subject) {
209 char **subject2 = (char **) (((char *) (wsgi_req)) + routes->subject);
210 uint16_t *subject_len2 = (uint16_t *) (((char *) (wsgi_req)) + routes->subject_len);
211 subject = *subject2 ;
212 subject_len = *subject_len2;
213 }
214 n = uwsgi_regexp_match_ovec(routes->pattern, routes->pattern_extra, subject, subject_len, routes->ovector[wsgi_req->async_id], routes->ovn[wsgi_req->async_id]);
215 }
216 else {
217 int ret = routes->if_func(wsgi_req, routes);
218 // error
219 if (ret < 0) {
220 uwsgi_routing_reset_memory(wsgi_req, routes);
221 return UWSGI_ROUTE_BREAK;
222 }
223 // true
224 if (!routes->if_negate) {
225 if (ret == 0) {
226 uwsgi_routing_reset_memory(wsgi_req, routes);
227 goto next;
228 }
229 n = ret;
230 }
231 else {
232 if (ret > 0) {
233 uwsgi_routing_reset_memory(wsgi_req, routes);
234 goto next;
235 }
236 n = 1;
237 }
238 }
239
240 run:
241 if (n >= 0) {
242 wsgi_req->is_routing = 1;
243 int ret = routes->func(wsgi_req, routes);
244 uwsgi_routing_reset_memory(wsgi_req, routes);
245 wsgi_req->is_routing = 0;
246 if (ret == UWSGI_ROUTE_BREAK) {
247 uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].routed_requests++;
248 return ret;
249 }
250 if (ret == UWSGI_ROUTE_CONTINUE) {
251 return ret;
252 }
253
254 if (ret == -1) {
255 return UWSGI_ROUTE_BREAK;
256 }
257 }
258 next:
259 subject = orig_subject;
260 subject_len = orig_subject_len;
261 routes = routes->next;
262 if (routes) *r_pc = *r_pc+1;
263 }
264
265 return UWSGI_ROUTE_CONTINUE;
266 }
267
uwsgi_apply_routes(struct wsgi_request * wsgi_req)268 int uwsgi_apply_routes(struct wsgi_request *wsgi_req) {
269
270 if (!uwsgi.routes)
271 return UWSGI_ROUTE_CONTINUE;
272
273 // avoid loops
274 if (wsgi_req->is_routing)
275 return UWSGI_ROUTE_CONTINUE;
276
277 if (uwsgi_parse_vars(wsgi_req)) {
278 return UWSGI_ROUTE_BREAK;
279 }
280
281 // in case of static files serving previous rules could be applied
282 if (wsgi_req->routes_applied) {
283 return UWSGI_ROUTE_CONTINUE;
284 }
285
286 return uwsgi_apply_routes_do(uwsgi.routes, wsgi_req, NULL, 0);
287 }
288
uwsgi_apply_final_routes(struct wsgi_request * wsgi_req)289 void uwsgi_apply_final_routes(struct wsgi_request *wsgi_req) {
290
291 if (!uwsgi.final_routes) return;
292
293 // avoid loops
294 if (wsgi_req->is_routing) return;
295
296 wsgi_req->is_final_routing = 1;
297
298 uwsgi_apply_routes_do(uwsgi.final_routes, wsgi_req, NULL, 0);
299 }
300
uwsgi_apply_error_routes(struct wsgi_request * wsgi_req)301 int uwsgi_apply_error_routes(struct wsgi_request *wsgi_req) {
302
303 if (!uwsgi.error_routes) return 0;
304
305 // do not forget to check it !!!
306 if (wsgi_req->is_error_routing) return 0;
307
308 wsgi_req->is_error_routing = 1;
309
310 return uwsgi_apply_routes_do(uwsgi.error_routes, wsgi_req, NULL, 0);
311 }
312
uwsgi_apply_response_routes(struct wsgi_request * wsgi_req)313 int uwsgi_apply_response_routes(struct wsgi_request *wsgi_req) {
314
315
316 if (!uwsgi.response_routes) return 0;
317 if (wsgi_req->response_routes_applied) return 0;
318
319 // do not forget to check it !!!
320 if (wsgi_req->is_response_routing) return 0;
321
322 wsgi_req->is_response_routing = 1;
323
324 int ret = uwsgi_apply_routes_do(uwsgi.response_routes, wsgi_req, NULL, 0);
325 wsgi_req->response_routes_applied = 1;
326 return ret;
327 }
328
uwsgi_route_get_condition_func(char * name)329 static void *uwsgi_route_get_condition_func(char *name) {
330 struct uwsgi_route_condition *urc = uwsgi.route_conditions;
331 while(urc) {
332 if (!strcmp(urc->name, name)) {
333 return urc->func;
334 }
335 urc = urc->next;
336 }
337 return NULL;
338 }
339
uwsgi_route_condition_status(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)340 static int uwsgi_route_condition_status(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
341 if (wsgi_req->status == ur->if_status) {
342 return 1;
343 }
344 return 0;
345 }
346
347
uwsgi_opt_add_route(char * opt,char * value,void * foobar)348 void uwsgi_opt_add_route(char *opt, char *value, void *foobar) {
349
350 char *space = NULL;
351 char *command = NULL;
352 struct uwsgi_route *old_ur = NULL, *ur = uwsgi.routes;
353 if (!uwsgi_starts_with(opt, strlen(opt), "final", 5)) {
354 ur = uwsgi.final_routes;
355 }
356 else if (!uwsgi_starts_with(opt, strlen(opt), "error", 5)) {
357 ur = uwsgi.error_routes;
358 }
359 else if (!uwsgi_starts_with(opt, strlen(opt), "response", 8)) {
360 ur = uwsgi.response_routes;
361 }
362 uint64_t pos = 0;
363 while(ur) {
364 old_ur = ur;
365 ur = ur->next;
366 pos++;
367 }
368 ur = uwsgi_calloc(sizeof(struct uwsgi_route));
369 if (old_ur) {
370 old_ur->next = ur;
371 }
372 else {
373 if (!uwsgi_starts_with(opt, strlen(opt), "final", 5)) {
374 uwsgi.final_routes = ur;
375 }
376 else if (!uwsgi_starts_with(opt, strlen(opt), "error", 5)) {
377 uwsgi.error_routes = ur;
378 }
379 else if (!uwsgi_starts_with(opt, strlen(opt), "response", 8)) {
380 uwsgi.response_routes = ur;
381 }
382 else {
383 uwsgi.routes = ur;
384 }
385 }
386
387 ur->pos = pos;
388
389 // is it a label ?
390 if (foobar == NULL) {
391 ur->label = value;
392 ur->label_len = strlen(value);
393 return;
394 }
395
396 ur->orig_route = uwsgi_str(value);
397
398 if (!strcmp(foobar, "run")) {
399 command = ur->orig_route;
400 goto done;
401 }
402
403 space = strchr(ur->orig_route, ' ');
404 if (!space) {
405 uwsgi_log("invalid route syntax\n");
406 exit(1);
407 }
408
409 *space = 0;
410
411 if (!strcmp(foobar, "if") || !strcmp(foobar, "if-not")) {
412 char *colon = strchr(ur->orig_route, ':');
413 if (!colon) {
414 uwsgi_log("invalid route condition syntax\n");
415 exit(1);
416 }
417 *colon = 0;
418
419 if (!strcmp(foobar, "if-not")) {
420 ur->if_negate = 1;
421 }
422
423 foobar = colon+1;
424 ur->if_func = uwsgi_route_get_condition_func(ur->orig_route);
425 if (!ur->if_func) {
426 uwsgi_log("unable to find \"%s\" route condition\n", ur->orig_route);
427 exit(1);
428 }
429 }
430 else if (!strcmp(foobar, "status")) {
431 ur->if_status = atoi(ur->orig_route);
432 foobar = ur->orig_route;
433 ur->if_func = uwsgi_route_condition_status;
434 }
435
436 else if (!strcmp(foobar, "http_host")) {
437 ur->subject = offsetof(struct wsgi_request, host);
438 ur->subject_len = offsetof(struct wsgi_request, host_len);
439 }
440 else if (!strcmp(foobar, "request_uri")) {
441 ur->subject = offsetof(struct wsgi_request, uri);
442 ur->subject_len = offsetof(struct wsgi_request, uri_len);
443 }
444 else if (!strcmp(foobar, "query_string")) {
445 ur->subject = offsetof(struct wsgi_request, query_string);
446 ur->subject_len = offsetof(struct wsgi_request, query_string_len);
447 }
448 else if (!strcmp(foobar, "remote_addr")) {
449 ur->subject = offsetof(struct wsgi_request, remote_addr);
450 ur->subject_len = offsetof(struct wsgi_request, remote_addr_len);
451 }
452 else if (!strcmp(foobar, "user_agent")) {
453 ur->subject = offsetof(struct wsgi_request, user_agent);
454 ur->subject_len = offsetof(struct wsgi_request, user_agent_len);
455 }
456 else if (!strcmp(foobar, "referer")) {
457 ur->subject = offsetof(struct wsgi_request, referer);
458 ur->subject_len = offsetof(struct wsgi_request, referer_len);
459 }
460 else if (!strcmp(foobar, "remote_user")) {
461 ur->subject = offsetof(struct wsgi_request, remote_user);
462 ur->subject_len = offsetof(struct wsgi_request, remote_user_len);
463 }
464 else {
465 ur->subject = offsetof(struct wsgi_request, path_info);
466 ur->subject_len = offsetof(struct wsgi_request, path_info_len);
467 }
468
469 ur->subject_str = foobar;
470 ur->subject_str_len = strlen(ur->subject_str);
471 ur->regexp = ur->orig_route;
472
473 command = space + 1;
474 done:
475 ur->action = uwsgi_str(command);
476
477 char *colon = strchr(command, ':');
478 if (!colon) {
479 uwsgi_log("invalid route syntax\n");
480 exit(1);
481 }
482
483 *colon = 0;
484
485 struct uwsgi_router *r = uwsgi.routers;
486 while (r) {
487 if (!strcmp(r->name, command)) {
488 if (r->func(ur, colon + 1) == 0) {
489 return;
490 }
491 break;
492 }
493 r = r->next;
494 }
495
496 uwsgi_log("unable to register route \"%s\"\n", value);
497 exit(1);
498 }
499
uwsgi_fixup_routes(struct uwsgi_route * ur)500 void uwsgi_fixup_routes(struct uwsgi_route *ur) {
501 while(ur) {
502 // prepare the main pointers
503 ur->ovn = uwsgi_calloc(sizeof(int) * uwsgi.cores);
504 ur->ovector = uwsgi_calloc(sizeof(int *) * uwsgi.cores);
505 ur->condition_ub = uwsgi_calloc( sizeof(struct uwsgi_buffer *) * uwsgi.cores);
506
507 // fill them if needed... (this is an optimization for route with a static subject)
508 if (ur->subject && ur->subject_len) {
509 if (uwsgi_regexp_build(ur->orig_route, &ur->pattern, &ur->pattern_extra)) {
510 exit(1);
511 }
512
513 int i;
514 for(i=0;i<uwsgi.cores;i++) {
515 ur->ovn[i] = uwsgi_regexp_ovector(ur->pattern, ur->pattern_extra);
516 if (ur->ovn[i] > 0) {
517 ur->ovector[i] = uwsgi_calloc(sizeof(int) * (3 * (ur->ovn[i] + 1)));
518 }
519 }
520 }
521 ur = ur->next;
522 }
523 }
524
uwsgi_route_api_func(struct wsgi_request * wsgi_req,char * router,char * args)525 int uwsgi_route_api_func(struct wsgi_request *wsgi_req, char *router, char *args) {
526 struct uwsgi_route *ur = NULL;
527 struct uwsgi_router *r = uwsgi.routers;
528 while(r) {
529 if (!strcmp(router, r->name)) {
530 goto found;
531 }
532 r = r->next;
533 }
534 free(args);
535 return -1;
536 found:
537 ur = uwsgi_calloc(sizeof(struct uwsgi_route));
538 // initialize the virtual route
539 if (r->func(ur, args)) {
540 free(ur);
541 free(args);
542 return -1;
543 }
544 // call it
545 int ret = ur->func(wsgi_req, ur);
546 if (ur->free) {
547 ur->free(ur);
548 }
549 free(ur);
550 free(args);
551 return ret;
552 }
553
554 // continue/last route
555
uwsgi_router_continue_func(struct wsgi_request * wsgi_req,struct uwsgi_route * route)556 static int uwsgi_router_continue_func(struct wsgi_request *wsgi_req, struct uwsgi_route *route) {
557 return UWSGI_ROUTE_CONTINUE;
558 }
559
uwsgi_router_continue(struct uwsgi_route * ur,char * arg)560 static int uwsgi_router_continue(struct uwsgi_route *ur, char *arg) {
561 ur->func = uwsgi_router_continue_func;
562 return 0;
563 }
564
565 // break route
566
uwsgi_router_break_func(struct wsgi_request * wsgi_req,struct uwsgi_route * route)567 static int uwsgi_router_break_func(struct wsgi_request *wsgi_req, struct uwsgi_route *route) {
568 if (route->data_len >= 3) {
569 if (uwsgi_response_prepare_headers(wsgi_req, route->data, route->data_len)) goto end;
570 if (uwsgi_response_add_connection_close(wsgi_req)) goto end;
571 if (uwsgi_response_add_content_type(wsgi_req, "text/plain", 10)) goto end;
572 // no need to check for return value
573 uwsgi_response_write_headers_do(wsgi_req);
574 }
575 end:
576 return UWSGI_ROUTE_BREAK;
577 }
578
uwsgi_router_break(struct uwsgi_route * ur,char * arg)579 static int uwsgi_router_break(struct uwsgi_route *ur, char *arg) {
580 ur->func = uwsgi_router_break_func;
581 ur->data = arg;
582 ur->data_len = strlen(arg);
583 return 0;
584 }
585
uwsgi_router_return_func(struct wsgi_request * wsgi_req,struct uwsgi_route * route)586 static int uwsgi_router_return_func(struct wsgi_request *wsgi_req, struct uwsgi_route *route)
587 {
588
589 if (route->data_len < 3)
590 return UWSGI_ROUTE_BREAK;
591 uint16_t status_msg_len = 0;
592 const char *status_msg = uwsgi_http_status_msg(route->data, &status_msg_len);
593
594 if (!status_msg)
595 return UWSGI_ROUTE_BREAK;
596
597 char *buf = uwsgi_concat3n(route->data, route->data_len, " ", 1, (char *) status_msg, status_msg_len);
598 if (uwsgi_response_prepare_headers(wsgi_req, buf, route->data_len + 1 + status_msg_len))
599 goto end;
600 if (uwsgi_response_add_content_type(wsgi_req, "text/plain", 10))
601 goto end;
602 if (uwsgi_response_add_content_length(wsgi_req, status_msg_len))
603 goto end;
604 uwsgi_response_write_body_do(wsgi_req, (char *) status_msg, status_msg_len);
605
606 end:
607 free(buf);
608 return UWSGI_ROUTE_BREAK;
609 }
610
uwsgi_router_return(struct uwsgi_route * ur,char * arg)611 static int uwsgi_router_return(struct uwsgi_route *ur, char *arg)
612 {
613 ur->func = uwsgi_router_return_func;
614 ur->data = arg;
615 ur->data_len = strlen(arg);
616 return 0;
617 }
618
619 // simple math router
uwsgi_router_simple_math_func(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)620 static int uwsgi_router_simple_math_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
621 char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
622 uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
623
624 uint16_t var_vallen = 0;
625 char *var_value = uwsgi_get_var(wsgi_req, ur->data, ur->data_len, &var_vallen);
626 if (!var_value) return UWSGI_ROUTE_BREAK;
627
628 int64_t base_value = uwsgi_str_num(var_value, var_vallen);
629 int64_t value = 1;
630
631 if (ur->data2_len) {
632 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data2, ur->data2_len);
633 if (!ub) return UWSGI_ROUTE_BREAK;
634 value = uwsgi_str_num(ub->buf, ub->pos);
635 uwsgi_buffer_destroy(ub);
636 }
637
638 char out[sizeof(UMAX64_STR)+1];
639 int64_t total = 0;
640
641 switch(ur->custom) {
642 // -
643 case 1:
644 total = base_value - value;
645 break;
646 // *
647 case 2:
648 total = base_value * value;
649 break;
650 // /
651 case 3:
652 if (value == 0) total = 0;
653 else {
654 total = base_value/value;
655 }
656 break;
657 default:
658 total = base_value + value;
659 break;
660 }
661
662 int ret = uwsgi_long2str2n(total, out, sizeof(UMAX64_STR)+1);
663 if (ret <= 0) return UWSGI_ROUTE_BREAK;
664
665 if (!uwsgi_req_append(wsgi_req, ur->data, ur->data_len, out, ret)) {
666 return UWSGI_ROUTE_BREAK;
667 }
668 return UWSGI_ROUTE_NEXT;
669 }
670
uwsgi_router_simple_math_plus(struct uwsgi_route * ur,char * arg)671 static int uwsgi_router_simple_math_plus(struct uwsgi_route *ur, char *arg) {
672 ur->func = uwsgi_router_simple_math_func;
673 char *comma = strchr(arg, ',');
674 if (comma) {
675 ur->data = arg;
676 ur->data_len = comma - arg;
677 ur->data2 = comma+1;
678 ur->data2_len = strlen(ur->data);
679 }
680 else {
681 ur->data = arg;
682 ur->data_len = strlen(arg);
683 }
684 return 0;
685 }
686
uwsgi_router_simple_math_minus(struct uwsgi_route * ur,char * arg)687 static int uwsgi_router_simple_math_minus(struct uwsgi_route *ur, char *arg) {
688 ur->custom = 1;
689 return uwsgi_router_simple_math_plus(ur, arg);
690 }
691
uwsgi_router_simple_math_multiply(struct uwsgi_route * ur,char * arg)692 static int uwsgi_router_simple_math_multiply(struct uwsgi_route *ur, char *arg) {
693 ur->custom = 2;
694 return uwsgi_router_simple_math_plus(ur, arg);
695 }
696
uwsgi_router_simple_math_divide(struct uwsgi_route * ur,char * arg)697 static int uwsgi_router_simple_math_divide(struct uwsgi_route *ur, char *arg) {
698 ur->custom = 2;
699 return uwsgi_router_simple_math_plus(ur, arg);
700 }
701
702 // harakiri router
uwsgi_router_harakiri_func(struct wsgi_request * wsgi_req,struct uwsgi_route * route)703 static int uwsgi_router_harakiri_func(struct wsgi_request *wsgi_req, struct uwsgi_route *route) {
704 if (route->custom > 0) {
705 set_user_harakiri(route->custom);
706 }
707 return UWSGI_ROUTE_NEXT;
708 }
709
uwsgi_router_harakiri(struct uwsgi_route * ur,char * arg)710 static int uwsgi_router_harakiri(struct uwsgi_route *ur, char *arg) {
711 ur->func = uwsgi_router_harakiri_func;
712 ur->custom = atoi(arg);
713 return 0;
714 }
715
716 // flush response
transform_flush(struct wsgi_request * wsgi_req,struct uwsgi_transformation * ut)717 static int transform_flush(struct wsgi_request *wsgi_req, struct uwsgi_transformation *ut) {
718 // avoid loops !!!
719 if (ut->chunk->pos == 0) return 0;
720 wsgi_req->transformed_chunk = ut->chunk->buf;
721 wsgi_req->transformed_chunk_len = ut->chunk->pos;
722 int ret = uwsgi_response_write_body_do(wsgi_req, ut->chunk->buf, ut->chunk->pos);
723 wsgi_req->transformed_chunk = NULL;
724 wsgi_req->transformed_chunk_len = 0;
725 ut->flushed = 1;
726 return ret;
727 }
uwsgi_router_flush_func(struct wsgi_request * wsgi_req,struct uwsgi_route * route)728 static int uwsgi_router_flush_func(struct wsgi_request *wsgi_req, struct uwsgi_route *route) {
729 struct uwsgi_transformation *ut = uwsgi_add_transformation(wsgi_req, transform_flush, NULL);
730 ut->can_stream = 1;
731 return UWSGI_ROUTE_NEXT;
732 }
uwsgi_router_flush(struct uwsgi_route * ur,char * arg)733 static int uwsgi_router_flush(struct uwsgi_route *ur, char *arg) {
734 ur->func = uwsgi_router_flush_func;
735 return 0;
736 }
737
738 // fix content length
transform_fixcl(struct wsgi_request * wsgi_req,struct uwsgi_transformation * ut)739 static int transform_fixcl(struct wsgi_request *wsgi_req, struct uwsgi_transformation *ut) {
740 char buf[sizeof(UMAX64_STR)+1];
741 int ret = snprintf(buf, sizeof(UMAX64_STR)+1, "%llu", (unsigned long long) ut->chunk->pos);
742 if (ret <= 0 || ret >= (int) (sizeof(UMAX64_STR)+1)) {
743 wsgi_req->write_errors++;
744 return -1;
745 }
746 // do not check for errors !!!
747 uwsgi_response_add_header(wsgi_req, "Content-Length", 14, buf, ret);
748 return 0;
749 }
uwsgi_router_fixcl_func(struct wsgi_request * wsgi_req,struct uwsgi_route * route)750 static int uwsgi_router_fixcl_func(struct wsgi_request *wsgi_req, struct uwsgi_route *route) {
751 uwsgi_add_transformation(wsgi_req, transform_fixcl, NULL);
752 return UWSGI_ROUTE_NEXT;
753 }
uwsgi_router_fixcl(struct uwsgi_route * ur,char * arg)754 static int uwsgi_router_fixcl(struct uwsgi_route *ur, char *arg) {
755 ur->func = uwsgi_router_fixcl_func;
756 return 0;
757 }
758
759 // force content length
transform_forcecl(struct wsgi_request * wsgi_req,struct uwsgi_transformation * ut)760 static int transform_forcecl(struct wsgi_request *wsgi_req, struct uwsgi_transformation *ut) {
761 char buf[sizeof(UMAX64_STR)+1];
762 int ret = snprintf(buf, sizeof(UMAX64_STR)+1, "%llu", (unsigned long long) ut->chunk->pos);
763 if (ret <= 0 || ret >= (int) (sizeof(UMAX64_STR)+1)) {
764 wsgi_req->write_errors++;
765 return -1;
766 }
767 // do not check for errors !!!
768 uwsgi_response_add_header_force(wsgi_req, "Content-Length", 14, buf, ret);
769 return 0;
770 }
uwsgi_router_forcecl_func(struct wsgi_request * wsgi_req,struct uwsgi_route * route)771 static int uwsgi_router_forcecl_func(struct wsgi_request *wsgi_req, struct uwsgi_route *route) {
772 uwsgi_add_transformation(wsgi_req, transform_forcecl, NULL);
773 return UWSGI_ROUTE_NEXT;
774 }
uwsgi_router_forcecl(struct uwsgi_route * ur,char * arg)775 static int uwsgi_router_forcecl(struct uwsgi_route *ur, char *arg) {
776 ur->func = uwsgi_router_forcecl_func;
777 return 0;
778 }
779
780 // log route
uwsgi_router_log_func(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)781 static int uwsgi_router_log_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
782
783 char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
784 uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
785
786 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data, ur->data_len);
787 if (!ub) return UWSGI_ROUTE_BREAK;
788
789 uwsgi_log("%.*s\n", ub->pos, ub->buf);
790 uwsgi_buffer_destroy(ub);
791 return UWSGI_ROUTE_NEXT;
792 }
793
uwsgi_router_log(struct uwsgi_route * ur,char * arg)794 static int uwsgi_router_log(struct uwsgi_route *ur, char *arg) {
795 ur->func = uwsgi_router_log_func;
796 ur->data = arg;
797 ur->data_len = strlen(arg);
798 return 0;
799 }
800
801 // do not log !!!
uwsgi_router_donotlog_func(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)802 static int uwsgi_router_donotlog_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
803 wsgi_req->do_not_log = 1;
804 return UWSGI_ROUTE_NEXT;
805 }
uwsgi_router_donotlog(struct uwsgi_route * ur,char * arg)806 static int uwsgi_router_donotlog(struct uwsgi_route *ur, char *arg) {
807 ur->func = uwsgi_router_donotlog_func;
808 return 0;
809 }
810
811 // do not offload !!!
uwsgi_router_donotoffload_func(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)812 static int uwsgi_router_donotoffload_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
813 wsgi_req->socket->can_offload = 0;
814 return UWSGI_ROUTE_NEXT;
815 }
uwsgi_router_donotoffload(struct uwsgi_route * ur,char * arg)816 static int uwsgi_router_donotoffload(struct uwsgi_route *ur, char *arg) {
817 ur->func = uwsgi_router_donotoffload_func;
818 return 0;
819 }
820
821 // logvar route
uwsgi_router_logvar_func(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)822 static int uwsgi_router_logvar_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
823
824 char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
825 uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
826
827 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data2, ur->data2_len);
828 if (!ub) return UWSGI_ROUTE_BREAK;
829 uwsgi_logvar_add(wsgi_req, ur->data, ur->data_len, ub->buf, ub->pos);
830 uwsgi_buffer_destroy(ub);
831
832 return UWSGI_ROUTE_NEXT;
833 }
834
uwsgi_router_logvar(struct uwsgi_route * ur,char * arg)835 static int uwsgi_router_logvar(struct uwsgi_route *ur, char *arg) {
836 ur->func = uwsgi_router_logvar_func;
837 char *equal = strchr(arg, '=');
838 if (!equal) {
839 uwsgi_log("invalid logvar syntax, must be key=value\n");
840 exit(1);
841 }
842 ur->data = arg;
843 ur->data_len = equal-arg;
844 ur->data2 = equal+1;
845 ur->data2_len = strlen(ur->data2);
846 return 0;
847 }
848
849
850 // goto route
851
uwsgi_router_goto_func(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)852 static int uwsgi_router_goto_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
853 // build the label (if needed)
854 char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
855 uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
856
857 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data, ur->data_len);
858 if (!ub) return UWSGI_ROUTE_BREAK;
859 uint32_t *r_goto = &wsgi_req->route_goto;
860 uint32_t *r_pc = &wsgi_req->route_pc;
861
862 // find the label
863 struct uwsgi_route *routes = uwsgi.routes;
864 if (wsgi_req->is_error_routing) {
865 routes = uwsgi.error_routes;
866 r_goto = &wsgi_req->error_route_goto;
867 r_pc = &wsgi_req->error_route_pc;
868 }
869 else if (wsgi_req->is_final_routing) {
870 routes = uwsgi.final_routes;
871 r_goto = &wsgi_req->final_route_goto;
872 r_pc = &wsgi_req->final_route_pc;
873 }
874 else if (wsgi_req->is_response_routing) {
875 routes = uwsgi.response_routes;
876 r_goto = &wsgi_req->response_route_goto;
877 r_pc = &wsgi_req->response_route_pc;
878 }
879 while(routes) {
880 if (!routes->label) goto next;
881 if (!uwsgi_strncmp(routes->label, routes->label_len, ub->buf, ub->pos)) {
882 *r_goto = routes->pos;
883 goto found;
884 }
885 next:
886 routes = routes->next;
887 }
888
889 *r_goto = ur->custom;
890
891 found:
892 uwsgi_buffer_destroy(ub);
893 if (*r_goto <= *r_pc) {
894 *r_goto = 0;
895 uwsgi_log("[uwsgi-route] ERROR \"goto\" instruction can only jump forward (check your label !!!)\n");
896 return UWSGI_ROUTE_BREAK;
897 }
898 return UWSGI_ROUTE_NEXT;
899 }
900
uwsgi_router_goto(struct uwsgi_route * ur,char * arg)901 static int uwsgi_router_goto(struct uwsgi_route *ur, char *arg) {
902 ur->func = uwsgi_router_goto_func;
903 ur->data = arg;
904 ur->data_len = strlen(arg);
905 ur->custom = atoi(arg);
906 return 0;
907 }
908
909 // addvar route
uwsgi_router_addvar_func(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)910 static int uwsgi_router_addvar_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
911
912 char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
913 uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
914
915 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data2, ur->data2_len);
916 if (!ub) return UWSGI_ROUTE_BREAK;
917
918 if (!uwsgi_req_append(wsgi_req, ur->data, ur->data_len, ub->buf, ub->pos)) {
919 uwsgi_buffer_destroy(ub);
920 return UWSGI_ROUTE_BREAK;
921 }
922 uwsgi_buffer_destroy(ub);
923 return UWSGI_ROUTE_NEXT;
924 }
925
926
uwsgi_router_addvar(struct uwsgi_route * ur,char * arg)927 static int uwsgi_router_addvar(struct uwsgi_route *ur, char *arg) {
928 ur->func = uwsgi_router_addvar_func;
929 char *equal = strchr(arg, '=');
930 if (!equal) {
931 uwsgi_log("[uwsgi-route] invalid addvar syntax, must be KEY=VAL\n");
932 exit(1);
933 }
934 ur->data = arg;
935 ur->data_len = equal-arg;
936 ur->data2 = equal+1;
937 ur->data2_len = strlen(ur->data2);
938 return 0;
939 }
940
941
942 // addheader route
uwsgi_router_addheader_func(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)943 static int uwsgi_router_addheader_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
944
945 char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
946 uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
947
948 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data, ur->data_len);
949 if (!ub) return UWSGI_ROUTE_BREAK;
950 uwsgi_additional_header_add(wsgi_req, ub->buf, ub->pos);
951 uwsgi_buffer_destroy(ub);
952 return UWSGI_ROUTE_NEXT;
953 }
954
955
uwsgi_router_addheader(struct uwsgi_route * ur,char * arg)956 static int uwsgi_router_addheader(struct uwsgi_route *ur, char *arg) {
957 ur->func = uwsgi_router_addheader_func;
958 ur->data = arg;
959 ur->data_len = strlen(arg);
960 return 0;
961 }
962
963 // remheader route
uwsgi_router_remheader_func(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)964 static int uwsgi_router_remheader_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
965
966 char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
967 uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
968
969 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data, ur->data_len);
970 if (!ub) return UWSGI_ROUTE_BREAK;
971 uwsgi_remove_header(wsgi_req, ub->buf, ub->pos);
972 uwsgi_buffer_destroy(ub);
973 return UWSGI_ROUTE_NEXT;
974 }
975
976
uwsgi_router_remheader(struct uwsgi_route * ur,char * arg)977 static int uwsgi_router_remheader(struct uwsgi_route *ur, char *arg) {
978 ur->func = uwsgi_router_remheader_func;
979 ur->data = arg;
980 ur->data_len = strlen(arg);
981 return 0;
982 }
983
984 // clearheaders route
uwsgi_router_clearheaders_func(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)985 static int uwsgi_router_clearheaders_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
986
987 char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
988 uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
989
990 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data, ur->data_len);
991 if (!ub) return UWSGI_ROUTE_BREAK;
992
993 if (uwsgi_response_prepare_headers(wsgi_req, ub->buf, ub->pos)) {
994 uwsgi_buffer_destroy(ub);
995 return UWSGI_ROUTE_BREAK;
996 }
997
998 uwsgi_buffer_destroy(ub);
999 return UWSGI_ROUTE_NEXT;
1000 }
1001
1002
uwsgi_router_clearheaders(struct uwsgi_route * ur,char * arg)1003 static int uwsgi_router_clearheaders(struct uwsgi_route *ur, char *arg) {
1004 ur->func = uwsgi_router_clearheaders_func;
1005 ur->data = arg;
1006 ur->data_len = strlen(arg);
1007 return 0;
1008 }
1009
1010 // disable headers
uwsgi_router_disableheaders_func(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1011 static int uwsgi_router_disableheaders_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1012 wsgi_req->headers_sent = 1;
1013 return UWSGI_ROUTE_NEXT;
1014 }
1015
uwsgi_router_disableheaders(struct uwsgi_route * ur,char * arg)1016 static int uwsgi_router_disableheaders(struct uwsgi_route *ur, char *arg) {
1017 ur->func = uwsgi_router_disableheaders_func;
1018 ur->data = arg;
1019 ur->data_len = strlen(arg);
1020 return 0;
1021 }
1022
1023
1024
1025 // signal route
uwsgi_router_signal_func(struct wsgi_request * wsgi_req,struct uwsgi_route * route)1026 static int uwsgi_router_signal_func(struct wsgi_request *wsgi_req, struct uwsgi_route *route) {
1027 uwsgi_signal_send(uwsgi.signal_socket, route->custom);
1028 return UWSGI_ROUTE_NEXT;
1029 }
uwsgi_router_signal(struct uwsgi_route * ur,char * arg)1030 static int uwsgi_router_signal(struct uwsgi_route *ur, char *arg) {
1031 ur->func = uwsgi_router_signal_func;
1032 ur->custom = atoi(arg);
1033 return 0;
1034 }
1035
1036 // chdir route
uwsgi_router_chdir_func(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1037 static int uwsgi_router_chdir_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1038 char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
1039 uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
1040
1041 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data, ur->data_len);
1042 if (!ub) return UWSGI_ROUTE_BREAK;
1043 if (chdir(ub->buf)) {
1044 uwsgi_req_error("uwsgi_router_chdir_func()/chdir()");
1045 uwsgi_buffer_destroy(ub);
1046 return UWSGI_ROUTE_BREAK;
1047 }
1048 uwsgi_buffer_destroy(ub);
1049 return UWSGI_ROUTE_NEXT;
1050 }
uwsgi_router_chdir(struct uwsgi_route * ur,char * arg)1051 static int uwsgi_router_chdir(struct uwsgi_route *ur, char *arg) {
1052 ur->func = uwsgi_router_chdir_func;
1053 ur->data = arg;
1054 ur->data_len = strlen(arg);
1055 return 0;
1056 }
1057
1058 // setapp route
uwsgi_router_setapp_func(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1059 static int uwsgi_router_setapp_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1060 char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
1061 uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
1062
1063 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data, ur->data_len);
1064 if (!ub) return UWSGI_ROUTE_BREAK;
1065 char *ptr = uwsgi_req_append(wsgi_req, "UWSGI_APPID", 11, ub->buf, ub->pos);
1066 if (!ptr) {
1067 uwsgi_buffer_destroy(ub);
1068 return UWSGI_ROUTE_BREAK;
1069 }
1070 wsgi_req->appid = ptr;
1071 wsgi_req->appid_len = ub->pos;
1072 uwsgi_buffer_destroy(ub);
1073 return UWSGI_ROUTE_NEXT;
1074 }
uwsgi_router_setapp(struct uwsgi_route * ur,char * arg)1075 static int uwsgi_router_setapp(struct uwsgi_route *ur, char *arg) {
1076 ur->func = uwsgi_router_setapp_func;
1077 ur->data = arg;
1078 ur->data_len = strlen(arg);
1079 return 0;
1080 }
1081
1082 // setscriptname route
uwsgi_router_setscriptname_func(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1083 static int uwsgi_router_setscriptname_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1084 char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
1085 uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
1086
1087 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data, ur->data_len);
1088 if (!ub) return UWSGI_ROUTE_BREAK;
1089 char *ptr = uwsgi_req_append(wsgi_req, "SCRIPT_NAME", 11, ub->buf, ub->pos);
1090 if (!ptr) {
1091 uwsgi_buffer_destroy(ub);
1092 return UWSGI_ROUTE_BREAK;
1093 }
1094 wsgi_req->script_name = ptr;
1095 wsgi_req->script_name_len = ub->pos;
1096 uwsgi_buffer_destroy(ub);
1097 return UWSGI_ROUTE_NEXT;
1098 }
uwsgi_router_setscriptname(struct uwsgi_route * ur,char * arg)1099 static int uwsgi_router_setscriptname(struct uwsgi_route *ur, char *arg) {
1100 ur->func = uwsgi_router_setscriptname_func;
1101 ur->data = arg;
1102 ur->data_len = strlen(arg);
1103 return 0;
1104 }
1105
1106 // setmethod route
uwsgi_router_setmethod_func(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1107 static int uwsgi_router_setmethod_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1108 char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
1109 uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
1110
1111 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data, ur->data_len);
1112 if (!ub) return UWSGI_ROUTE_BREAK;
1113 char *ptr = uwsgi_req_append(wsgi_req, "REQUEST_METHOD", 14, ub->buf, ub->pos);
1114 if (!ptr) {
1115 uwsgi_buffer_destroy(ub);
1116 return UWSGI_ROUTE_BREAK;
1117 }
1118 wsgi_req->method = ptr;
1119 wsgi_req->method_len = ub->pos;
1120 uwsgi_buffer_destroy(ub);
1121 return UWSGI_ROUTE_NEXT;
1122 }
uwsgi_router_setmethod(struct uwsgi_route * ur,char * arg)1123 static int uwsgi_router_setmethod(struct uwsgi_route *ur, char *arg) {
1124 ur->func = uwsgi_router_setmethod_func;
1125 ur->data = arg;
1126 ur->data_len = strlen(arg);
1127 return 0;
1128 }
1129
1130 // seturi route
uwsgi_router_seturi_func(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1131 static int uwsgi_router_seturi_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1132 char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
1133 uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
1134
1135 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data, ur->data_len);
1136 if (!ub) return UWSGI_ROUTE_BREAK;
1137 char *ptr = uwsgi_req_append(wsgi_req, "REQUEST_URI", 11, ub->buf, ub->pos);
1138 if (!ptr) {
1139 uwsgi_buffer_destroy(ub);
1140 return UWSGI_ROUTE_BREAK;
1141 }
1142 wsgi_req->uri = ptr;
1143 wsgi_req->uri_len = ub->pos;
1144 uwsgi_buffer_destroy(ub);
1145 return UWSGI_ROUTE_NEXT;
1146 }
uwsgi_router_seturi(struct uwsgi_route * ur,char * arg)1147 static int uwsgi_router_seturi(struct uwsgi_route *ur, char *arg) {
1148 ur->func = uwsgi_router_seturi_func;
1149 ur->data = arg;
1150 ur->data_len = strlen(arg);
1151 return 0;
1152 }
1153
1154 // setremoteaddr route
uwsgi_router_setremoteaddr_func(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1155 static int uwsgi_router_setremoteaddr_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1156 char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
1157 uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
1158
1159 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data, ur->data_len);
1160 if (!ub) return UWSGI_ROUTE_BREAK;
1161 char *ptr = uwsgi_req_append(wsgi_req, "REMOTE_ADDR", 11, ub->buf, ub->pos);
1162 if (!ptr) {
1163 uwsgi_buffer_destroy(ub);
1164 return UWSGI_ROUTE_BREAK;
1165 }
1166 wsgi_req->remote_addr = ptr;
1167 wsgi_req->remote_addr_len = ub->pos;
1168 uwsgi_buffer_destroy(ub);
1169 return UWSGI_ROUTE_NEXT;
1170 }
uwsgi_router_setremoteaddr(struct uwsgi_route * ur,char * arg)1171 static int uwsgi_router_setremoteaddr(struct uwsgi_route *ur, char *arg) {
1172 ur->func = uwsgi_router_setremoteaddr_func;
1173 ur->data = arg;
1174 ur->data_len = strlen(arg);
1175 return 0;
1176 }
1177
1178
1179 // setdocroot route
uwsgi_router_setdocroot_func(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1180 static int uwsgi_router_setdocroot_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1181 char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
1182 uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
1183
1184 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data, ur->data_len);
1185 if (!ub) return UWSGI_ROUTE_BREAK;
1186 char *ptr = uwsgi_req_append(wsgi_req, "DOCUMENT_ROOT", 13, ub->buf, ub->pos);
1187 if (!ptr) {
1188 uwsgi_buffer_destroy(ub);
1189 return UWSGI_ROUTE_BREAK;
1190 }
1191 wsgi_req->document_root = ptr;
1192 wsgi_req->document_root_len = ub->pos;
1193 uwsgi_buffer_destroy(ub);
1194 return UWSGI_ROUTE_NEXT;
1195 }
uwsgi_router_setdocroot(struct uwsgi_route * ur,char * arg)1196 static int uwsgi_router_setdocroot(struct uwsgi_route *ur, char *arg) {
1197 ur->func = uwsgi_router_setdocroot_func;
1198 ur->data = arg;
1199 ur->data_len = strlen(arg);
1200 return 0;
1201 }
1202
1203
1204 // setpathinfo route
uwsgi_router_setpathinfo_func(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1205 static int uwsgi_router_setpathinfo_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1206 char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
1207 uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
1208
1209 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data, ur->data_len);
1210 if (!ub) return UWSGI_ROUTE_BREAK;
1211 char *ptr = uwsgi_req_append(wsgi_req, "PATH_INFO", 9, ub->buf, ub->pos);
1212 if (!ptr) {
1213 uwsgi_buffer_destroy(ub);
1214 return UWSGI_ROUTE_BREAK;
1215 }
1216 wsgi_req->path_info = ptr;
1217 wsgi_req->path_info_len = ub->pos;
1218 uwsgi_buffer_destroy(ub);
1219 return UWSGI_ROUTE_NEXT;
1220 }
uwsgi_router_setpathinfo(struct uwsgi_route * ur,char * arg)1221 static int uwsgi_router_setpathinfo(struct uwsgi_route *ur, char *arg) {
1222 ur->func = uwsgi_router_setpathinfo_func;
1223 ur->data = arg;
1224 ur->data_len = strlen(arg);
1225 return 0;
1226 }
1227
1228 // fixpathinfo route
uwsgi_router_fixpathinfo_func(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1229 static int uwsgi_router_fixpathinfo_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1230 if (wsgi_req->script_name_len == 0)
1231 return UWSGI_ROUTE_NEXT;
1232
1233 char *ptr = uwsgi_req_append(wsgi_req, "PATH_INFO", 9, wsgi_req->path_info+wsgi_req->script_name_len, wsgi_req->path_info_len - wsgi_req->script_name_len);
1234 if (!ptr) {
1235 return UWSGI_ROUTE_BREAK;
1236 }
1237 wsgi_req->path_info = wsgi_req->path_info+wsgi_req->script_name_len;
1238 wsgi_req->path_info_len = wsgi_req->path_info_len - wsgi_req->script_name_len;
1239 return UWSGI_ROUTE_NEXT;
1240 }
uwsgi_router_fixpathinfo(struct uwsgi_route * ur,char * arg)1241 static int uwsgi_router_fixpathinfo(struct uwsgi_route *ur, char *arg) {
1242 ur->func = uwsgi_router_fixpathinfo_func;
1243 ur->data = arg;
1244 ur->data_len = strlen(arg);
1245 return 0;
1246 }
1247
1248
1249 // setscheme route
uwsgi_router_setscheme_func(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1250 static int uwsgi_router_setscheme_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1251 char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
1252 uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
1253
1254 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data, ur->data_len);
1255 if (!ub) return UWSGI_ROUTE_BREAK;
1256 char *ptr = uwsgi_req_append(wsgi_req, "UWSGI_SCHEME", 12, ub->buf, ub->pos);
1257 if (!ptr) {
1258 uwsgi_buffer_destroy(ub);
1259 return UWSGI_ROUTE_BREAK;
1260 }
1261 wsgi_req->scheme = ptr;
1262 wsgi_req->scheme_len = ub->pos;
1263 uwsgi_buffer_destroy(ub);
1264 return UWSGI_ROUTE_NEXT;
1265 }
uwsgi_router_setscheme(struct uwsgi_route * ur,char * arg)1266 static int uwsgi_router_setscheme(struct uwsgi_route *ur, char *arg) {
1267 ur->func = uwsgi_router_setscheme_func;
1268 ur->data = arg;
1269 ur->data_len = strlen(arg);
1270 return 0;
1271 }
1272
1273 // setmodifiers
uwsgi_router_setmodifier1_func(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1274 static int uwsgi_router_setmodifier1_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1275 wsgi_req->uh->modifier1 = ur->custom;
1276 return UWSGI_ROUTE_NEXT;
1277 }
uwsgi_router_setmodifier1(struct uwsgi_route * ur,char * arg)1278 static int uwsgi_router_setmodifier1(struct uwsgi_route *ur, char *arg) {
1279 ur->func = uwsgi_router_setmodifier1_func;
1280 ur->custom = atoi(arg);
1281 return 0;
1282 }
uwsgi_router_setmodifier2_func(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1283 static int uwsgi_router_setmodifier2_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1284 wsgi_req->uh->modifier2 = ur->custom;
1285 return UWSGI_ROUTE_NEXT;
1286 }
uwsgi_router_setmodifier2(struct uwsgi_route * ur,char * arg)1287 static int uwsgi_router_setmodifier2(struct uwsgi_route *ur, char *arg) {
1288 ur->func = uwsgi_router_setmodifier2_func;
1289 ur->custom = atoi(arg);
1290 return 0;
1291 }
1292
1293
1294 // setuser route
uwsgi_router_setuser_func(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1295 static int uwsgi_router_setuser_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1296 char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
1297 uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
1298
1299 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data, ur->data_len);
1300 if (!ub) return UWSGI_ROUTE_BREAK;
1301 uint16_t user_len = ub->pos;
1302 // stop at the first colon (useful for various tricks)
1303 char *colon = memchr(ub->buf, ':', ub->pos);
1304 if (colon) {
1305 user_len = colon - ub->buf;
1306 }
1307 char *ptr = uwsgi_req_append(wsgi_req, "REMOTE_USER", 11, ub->buf, user_len);
1308 if (!ptr) {
1309 uwsgi_buffer_destroy(ub);
1310 return UWSGI_ROUTE_BREAK;
1311 }
1312 wsgi_req->remote_user = ptr;
1313 wsgi_req->remote_user_len = ub->pos;
1314 uwsgi_buffer_destroy(ub);
1315 return UWSGI_ROUTE_NEXT;
1316 }
uwsgi_router_setuser(struct uwsgi_route * ur,char * arg)1317 static int uwsgi_router_setuser(struct uwsgi_route *ur, char *arg) {
1318 ur->func = uwsgi_router_setuser_func;
1319 ur->data = arg;
1320 ur->data_len = strlen(arg);
1321 return 0;
1322 }
1323
1324
1325 // sethome route
uwsgi_router_sethome_func(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1326 static int uwsgi_router_sethome_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1327 char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
1328 uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
1329
1330 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data, ur->data_len);
1331 if (!ub) return UWSGI_ROUTE_BREAK;
1332 char *ptr = uwsgi_req_append(wsgi_req, "UWSGI_HOME", 10, ub->buf, ub->pos);
1333 if (!ptr) {
1334 uwsgi_buffer_destroy(ub);
1335 return UWSGI_ROUTE_BREAK;
1336 }
1337 wsgi_req->home = ptr;
1338 wsgi_req->home_len = ub->pos;
1339 uwsgi_buffer_destroy(ub);
1340 return UWSGI_ROUTE_NEXT;
1341 }
uwsgi_router_sethome(struct uwsgi_route * ur,char * arg)1342 static int uwsgi_router_sethome(struct uwsgi_route *ur, char *arg) {
1343 ur->func = uwsgi_router_sethome_func;
1344 ur->data = arg;
1345 ur->data_len = strlen(arg);
1346 return 0;
1347 }
1348
1349 // setfile route
uwsgi_router_setfile_func(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1350 static int uwsgi_router_setfile_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1351 char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
1352 uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
1353
1354 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data, ur->data_len);
1355 if (!ub) return UWSGI_ROUTE_BREAK;
1356 char *ptr = uwsgi_req_append(wsgi_req, "UWSGI_HOME", 10, ub->buf, ub->pos);
1357 if (!ptr) {
1358 uwsgi_buffer_destroy(ub);
1359 return UWSGI_ROUTE_BREAK;
1360 }
1361 wsgi_req->file = ptr;
1362 wsgi_req->file_len = ub->pos;
1363 wsgi_req->dynamic = 1;
1364 uwsgi_buffer_destroy(ub);
1365 return UWSGI_ROUTE_NEXT;
1366 }
uwsgi_router_setfile(struct uwsgi_route * ur,char * arg)1367 static int uwsgi_router_setfile(struct uwsgi_route *ur, char *arg) {
1368 ur->func = uwsgi_router_setfile_func;
1369 ur->data = arg;
1370 ur->data_len = strlen(arg);
1371 return 0;
1372 }
1373
1374
1375 // setprocname route
uwsgi_router_setprocname_func(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1376 static int uwsgi_router_setprocname_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1377 char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
1378 uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
1379
1380 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data, ur->data_len);
1381 if (!ub) return UWSGI_ROUTE_BREAK;
1382 uwsgi_set_processname(ub->buf);
1383 uwsgi_buffer_destroy(ub);
1384 return UWSGI_ROUTE_NEXT;
1385 }
uwsgi_router_setprocname(struct uwsgi_route * ur,char * arg)1386 static int uwsgi_router_setprocname(struct uwsgi_route *ur, char *arg) {
1387 ur->func = uwsgi_router_setprocname_func;
1388 ur->data = arg;
1389 ur->data_len = strlen(arg);
1390 return 0;
1391 }
1392
1393 // alarm route
uwsgi_router_alarm_func(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1394 static int uwsgi_router_alarm_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1395 char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
1396 uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
1397
1398 struct uwsgi_buffer *ub_alarm = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data, ur->data_len);
1399 if (!ub_alarm) return UWSGI_ROUTE_BREAK;
1400
1401 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data2, ur->data2_len);
1402 if (!ub) {
1403 uwsgi_buffer_destroy(ub_alarm);
1404 return UWSGI_ROUTE_BREAK;
1405 }
1406 uwsgi_alarm_trigger(ub_alarm->buf, ub->buf, ub->pos);
1407 uwsgi_buffer_destroy(ub_alarm);
1408 uwsgi_buffer_destroy(ub);
1409 return UWSGI_ROUTE_NEXT;
1410 }
uwsgi_router_alarm(struct uwsgi_route * ur,char * arg)1411 static int uwsgi_router_alarm(struct uwsgi_route *ur, char *arg) {
1412 ur->func = uwsgi_router_alarm_func;
1413 char *space = strchr(arg, ' ');
1414 if (!space) {
1415 return -1;
1416 }
1417 *space = 0;
1418 ur->data = arg;
1419 ur->data_len = strlen(arg);
1420 ur->data2 = space+1;
1421 ur->data2_len = strlen(ur->data2);
1422 return 0;
1423 }
1424
1425
1426
1427 // send route
uwsgi_router_send_func(struct wsgi_request * wsgi_req,struct uwsgi_route * route)1428 static int uwsgi_router_send_func(struct wsgi_request *wsgi_req, struct uwsgi_route *route) {
1429 char **subject = (char **) (((char *)(wsgi_req))+route->subject);
1430 uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+route->subject_len);
1431
1432 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, route, *subject, *subject_len, route->data, route->data_len);
1433 if (!ub) {
1434 return UWSGI_ROUTE_BREAK;
1435 }
1436 if (route->custom) {
1437 if (uwsgi_buffer_append(ub, "\r\n", 2)) {
1438 uwsgi_buffer_destroy(ub);
1439 return UWSGI_ROUTE_BREAK;
1440 }
1441 }
1442 uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos);
1443 uwsgi_buffer_destroy(ub);
1444 return UWSGI_ROUTE_NEXT;
1445 }
uwsgi_router_send(struct uwsgi_route * ur,char * arg)1446 static int uwsgi_router_send(struct uwsgi_route *ur, char *arg) {
1447 ur->func = uwsgi_router_send_func;
1448 ur->data = arg;
1449 ur->data_len = strlen(arg);
1450 return 0;
1451 }
uwsgi_router_send_crnl(struct uwsgi_route * ur,char * arg)1452 static int uwsgi_router_send_crnl(struct uwsgi_route *ur, char *arg) {
1453 uwsgi_router_send(ur, arg);
1454 ur->custom = 1;
1455 return 0;
1456 }
1457
uwsgi_route_condition_exists(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1458 static int uwsgi_route_condition_exists(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1459 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, NULL, 0, ur->subject_str, ur->subject_str_len);
1460 if (!ub) return -1;
1461 if (uwsgi_file_exists(ub->buf)) {
1462 uwsgi_buffer_destroy(ub);
1463 return 1;
1464 }
1465 uwsgi_buffer_destroy(ub);
1466 return 0;
1467 }
1468
uwsgi_route_condition_isfile(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1469 static int uwsgi_route_condition_isfile(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1470 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, NULL, 0, ur->subject_str, ur->subject_str_len);
1471 if (!ub) return -1;
1472 if (uwsgi_is_file(ub->buf)) {
1473 uwsgi_buffer_destroy(ub);
1474 return 1;
1475 }
1476 uwsgi_buffer_destroy(ub);
1477 return 0;
1478 }
1479
uwsgi_route_condition_regexp(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1480 static int uwsgi_route_condition_regexp(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1481 char *semicolon = memchr(ur->subject_str, ';', ur->subject_str_len);
1482 if (!semicolon) return 0;
1483
1484 ur->condition_ub[wsgi_req->async_id] = uwsgi_routing_translate(wsgi_req, ur, NULL, 0, ur->subject_str, semicolon - ur->subject_str);
1485 if (!ur->condition_ub[wsgi_req->async_id]) return -1;
1486
1487 pcre *pattern;
1488 pcre_extra *pattern_extra;
1489 char *re = uwsgi_concat2n(semicolon+1, ur->subject_str_len - ((semicolon+1) - ur->subject_str), "", 0);
1490 if (uwsgi_regexp_build(re, &pattern, &pattern_extra)) {
1491 free(re);
1492 return -1;
1493 }
1494 free(re);
1495
1496 // a condition has no initialized vectors, let's create them
1497 ur->ovn[wsgi_req->async_id] = uwsgi_regexp_ovector(pattern, pattern_extra);
1498 if (ur->ovn[wsgi_req->async_id] > 0) {
1499 ur->ovector[wsgi_req->async_id] = uwsgi_calloc(sizeof(int) * (3 * (ur->ovn[wsgi_req->async_id] + 1)));
1500 }
1501
1502 if (uwsgi_regexp_match_ovec(pattern, pattern_extra, ur->condition_ub[wsgi_req->async_id]->buf, ur->condition_ub[wsgi_req->async_id]->pos, ur->ovector[wsgi_req->async_id], ur->ovn[wsgi_req->async_id] ) >= 0) {
1503 pcre_free(pattern);
1504 #ifdef PCRE_STUDY_JIT_COMPILE
1505 pcre_free_study(pattern_extra);
1506 #else
1507 pcre_free(pattern_extra);
1508 #endif
1509 return 1;
1510 }
1511
1512 pcre_free(pattern);
1513 #ifdef PCRE_STUDY_JIT_COMPILE
1514 pcre_free_study(pattern_extra);
1515 #else
1516 pcre_free(pattern_extra);
1517 #endif
1518 return 0;
1519 }
1520
uwsgi_route_condition_empty(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1521 static int uwsgi_route_condition_empty(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1522
1523 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, NULL, 0, ur->subject_str, ur->subject_str_len);
1524 if (!ub) return -1;
1525
1526 if (ub->pos == 0) {
1527 uwsgi_buffer_destroy(ub);
1528 return 1;
1529 }
1530
1531 uwsgi_buffer_destroy(ub);
1532 return 0;
1533 }
1534
1535
uwsgi_route_condition_equal(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1536 static int uwsgi_route_condition_equal(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1537 char *semicolon = memchr(ur->subject_str, ';', ur->subject_str_len);
1538 if (!semicolon) return 0;
1539
1540 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, NULL, 0, ur->subject_str, semicolon - ur->subject_str);
1541 if (!ub) return -1;
1542
1543 struct uwsgi_buffer *ub2 = uwsgi_routing_translate(wsgi_req, ur, NULL, 0, semicolon+1, ur->subject_str_len - ((semicolon+1) - ur->subject_str));
1544 if (!ub2) {
1545 uwsgi_buffer_destroy(ub);
1546 return -1;
1547 }
1548
1549 if(!uwsgi_strncmp(ub->buf, ub->pos, ub2->buf, ub2->pos)) {
1550 uwsgi_buffer_destroy(ub);
1551 uwsgi_buffer_destroy(ub2);
1552 return 1;
1553 }
1554 uwsgi_buffer_destroy(ub);
1555 uwsgi_buffer_destroy(ub2);
1556 return 0;
1557 }
1558
uwsgi_route_condition_higher(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1559 static int uwsgi_route_condition_higher(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1560 char *semicolon = memchr(ur->subject_str, ';', ur->subject_str_len);
1561 if (!semicolon) return 0;
1562
1563 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, NULL, 0, ur->subject_str, semicolon - ur->subject_str);
1564 if (!ub) return -1;
1565
1566 struct uwsgi_buffer *ub2 = uwsgi_routing_translate(wsgi_req, ur, NULL, 0, semicolon+1, ur->subject_str_len - ((semicolon+1) - ur->subject_str));
1567 if (!ub2) {
1568 uwsgi_buffer_destroy(ub);
1569 return -1;
1570 }
1571
1572 long num1 = strtol(ub->buf, NULL, 10);
1573 long num2 = strtol(ub2->buf, NULL, 10);
1574 if(num1 > num2) {
1575 uwsgi_buffer_destroy(ub);
1576 uwsgi_buffer_destroy(ub2);
1577 return 1;
1578 }
1579 uwsgi_buffer_destroy(ub);
1580 uwsgi_buffer_destroy(ub2);
1581 return 0;
1582 }
1583
uwsgi_route_condition_higherequal(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1584 static int uwsgi_route_condition_higherequal(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1585 char *semicolon = memchr(ur->subject_str, ';', ur->subject_str_len);
1586 if (!semicolon) return 0;
1587
1588 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, NULL, 0, ur->subject_str, semicolon - ur->subject_str);
1589 if (!ub) return -1;
1590
1591 struct uwsgi_buffer *ub2 = uwsgi_routing_translate(wsgi_req, ur, NULL, 0, semicolon+1, ur->subject_str_len - ((semicolon+1) - ur->subject_str));
1592 if (!ub2) {
1593 uwsgi_buffer_destroy(ub);
1594 return -1;
1595 }
1596
1597 long num1 = strtol(ub->buf, NULL, 10);
1598 long num2 = strtol(ub2->buf, NULL, 10);
1599 if(num1 >= num2) {
1600 uwsgi_buffer_destroy(ub);
1601 uwsgi_buffer_destroy(ub2);
1602 return 1;
1603 }
1604 uwsgi_buffer_destroy(ub);
1605 uwsgi_buffer_destroy(ub2);
1606 return 0;
1607 }
1608
1609
uwsgi_route_condition_lower(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1610 static int uwsgi_route_condition_lower(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1611 char *semicolon = memchr(ur->subject_str, ';', ur->subject_str_len);
1612 if (!semicolon) return 0;
1613
1614 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, NULL, 0, ur->subject_str, semicolon - ur->subject_str);
1615 if (!ub) return -1;
1616
1617 struct uwsgi_buffer *ub2 = uwsgi_routing_translate(wsgi_req, ur, NULL, 0, semicolon+1, ur->subject_str_len - ((semicolon+1) - ur->subject_str));
1618 if (!ub2) {
1619 uwsgi_buffer_destroy(ub);
1620 return -1;
1621 }
1622
1623 long num1 = strtol(ub->buf, NULL, 10);
1624 long num2 = strtol(ub2->buf, NULL, 10);
1625 if(num1 < num2) {
1626 uwsgi_buffer_destroy(ub);
1627 uwsgi_buffer_destroy(ub2);
1628 return 1;
1629 }
1630 uwsgi_buffer_destroy(ub);
1631 uwsgi_buffer_destroy(ub2);
1632 return 0;
1633 }
1634
uwsgi_route_condition_lowerequal(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1635 static int uwsgi_route_condition_lowerequal(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1636 char *semicolon = memchr(ur->subject_str, ';', ur->subject_str_len);
1637 if (!semicolon) return 0;
1638
1639 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, NULL, 0, ur->subject_str, semicolon - ur->subject_str);
1640 if (!ub) return -1;
1641
1642 struct uwsgi_buffer *ub2 = uwsgi_routing_translate(wsgi_req, ur, NULL, 0, semicolon+1, ur->subject_str_len - ((semicolon+1) - ur->subject_str));
1643 if (!ub2) {
1644 uwsgi_buffer_destroy(ub);
1645 return -1;
1646 }
1647
1648 long num1 = strtol(ub->buf, NULL, 10);
1649 long num2 = strtol(ub2->buf, NULL, 10);
1650 if(num1 <= num2) {
1651 uwsgi_buffer_destroy(ub);
1652 uwsgi_buffer_destroy(ub2);
1653 return 1;
1654 }
1655 uwsgi_buffer_destroy(ub);
1656 uwsgi_buffer_destroy(ub2);
1657 return 0;
1658 }
1659
1660 #ifdef UWSGI_SSL
uwsgi_route_condition_lord(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1661 static int uwsgi_route_condition_lord(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1662 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, NULL, 0, ur->subject_str, ur->subject_str_len);
1663 if (!ub) return -1;
1664 int ret = uwsgi_legion_i_am_the_lord(ub->buf);
1665 uwsgi_buffer_destroy(ub);
1666 return ret;
1667 }
1668 #endif
1669
1670
1671
uwsgi_route_condition_startswith(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1672 static int uwsgi_route_condition_startswith(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1673 char *semicolon = memchr(ur->subject_str, ';', ur->subject_str_len);
1674 if (!semicolon) return 0;
1675
1676 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, NULL, 0, ur->subject_str, semicolon - ur->subject_str);
1677 if (!ub) return -1;
1678
1679 struct uwsgi_buffer *ub2 = uwsgi_routing_translate(wsgi_req, ur, NULL, 0, semicolon+1, ur->subject_str_len - ((semicolon+1) - ur->subject_str));
1680 if (!ub2) {
1681 uwsgi_buffer_destroy(ub);
1682 return -1;
1683 }
1684
1685 if(!uwsgi_starts_with(ub->buf, ub->pos, ub2->buf, ub2->pos)) {
1686 uwsgi_buffer_destroy(ub);
1687 uwsgi_buffer_destroy(ub2);
1688 return 1;
1689 }
1690 uwsgi_buffer_destroy(ub);
1691 uwsgi_buffer_destroy(ub2);
1692 return 0;
1693 }
1694
uwsgi_route_condition_ipv4in(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1695 static int uwsgi_route_condition_ipv4in(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1696 #define IP4_LEN (sizeof("255.255.255.255")-1)
1697 #define IP4PFX_LEN (sizeof("255.255.255.255/32")-1)
1698 char ipbuf[IP4_LEN+1] = {}, maskbuf[IP4PFX_LEN+1] = {};
1699 char *slash;
1700 int pfxlen = 32;
1701 in_addr_t ip, net, mask;
1702
1703 char *semicolon = memchr(ur->subject_str, ';', ur->subject_str_len);
1704 if (!semicolon) return 0;
1705
1706 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, NULL, 0, ur->subject_str, semicolon - ur->subject_str);
1707 if (!ub) return -1;
1708
1709 struct uwsgi_buffer *ub2 = uwsgi_routing_translate(wsgi_req, ur, NULL, 0, semicolon+1, ur->subject_str_len - ((semicolon+1) - ur->subject_str));
1710 if (!ub2) {
1711 uwsgi_buffer_destroy(ub);
1712 return -1;
1713 }
1714
1715 if (ub->pos > IP4_LEN || ub2->pos >= IP4PFX_LEN) {
1716 uwsgi_buffer_destroy(ub);
1717 uwsgi_buffer_destroy(ub2);
1718 return -1;
1719 }
1720
1721 memcpy(ipbuf, ub->buf, ub->pos);
1722 memcpy(maskbuf, ub2->buf, ub2->pos);
1723
1724 if ((slash = strchr(maskbuf, '/')) != NULL) {
1725 *slash++ = 0;
1726 pfxlen = atoi(slash);
1727 }
1728
1729 uwsgi_buffer_destroy(ub);
1730 uwsgi_buffer_destroy(ub2);
1731
1732 if ((ip = htonl(inet_addr(ipbuf))) == ~(in_addr_t)0)
1733 return 0;
1734 if ((net = htonl(inet_addr(maskbuf))) == ~(in_addr_t)0)
1735 return 0;
1736 if (pfxlen < 0 || pfxlen > 32)
1737 return 0;
1738
1739 mask = (~0UL << (32 - pfxlen)) & ~0U;
1740
1741 return ((ip & mask) == (net & mask));
1742 #undef IP4_LEN
1743 #undef IP4PFX_LEN
1744 }
1745
uwsgi_route_condition_ipv6in(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1746 static int uwsgi_route_condition_ipv6in(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1747 #define IP6_LEN (sizeof("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")-1)
1748 #define IP6PFX_LEN (sizeof("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128")-1)
1749 #define IP6_U32LEN (128 / 8 / 4)
1750 char ipbuf[IP6_LEN+1] = {}, maskbuf[IP6PFX_LEN+1] = {};
1751 char *slash;
1752 int pfxlen = 128;
1753 uint32_t ip[IP6_U32LEN], net[IP6_U32LEN], mask[IP6_U32LEN] = {};
1754
1755 char *semicolon = memchr(ur->subject_str, ';', ur->subject_str_len);
1756 if (!semicolon) return 0;
1757
1758 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, NULL, 0, ur->subject_str, semicolon - ur->subject_str);
1759 if (!ub) return -1;
1760
1761 struct uwsgi_buffer *ub2 = uwsgi_routing_translate(wsgi_req, ur, NULL, 0, semicolon+1, ur->subject_str_len - ((semicolon+1) - ur->subject_str));
1762 if (!ub2) {
1763 uwsgi_buffer_destroy(ub);
1764 return -1;
1765 }
1766
1767 if (ub->pos > IP6_LEN || ub2->pos >= IP6PFX_LEN) {
1768 uwsgi_buffer_destroy(ub);
1769 uwsgi_buffer_destroy(ub2);
1770 return -1;
1771 }
1772
1773 memcpy(ipbuf, ub->buf, ub->pos);
1774 memcpy(maskbuf, ub2->buf, ub2->pos);
1775
1776 if ((slash = strchr(maskbuf, '/')) != NULL) {
1777 *slash++ = 0;
1778 pfxlen = atoi(slash);
1779 }
1780
1781 uwsgi_buffer_destroy(ub);
1782 uwsgi_buffer_destroy(ub2);
1783
1784 if (inet_pton(AF_INET6, ipbuf, ip) != 1)
1785 return 0;
1786 if (inet_pton(AF_INET6, maskbuf, net) != 1)
1787 return 0;
1788 if (pfxlen < 0 || pfxlen > 128)
1789 return 0;
1790
1791 memset(mask, 0xFF, sizeof(mask));
1792
1793 int i = (pfxlen / 32);
1794 switch (i) {
1795 case 0: mask[0] = 0; /* fallthrough */
1796 case 1: mask[1] = 0; /* fallthrough */
1797 case 2: mask[2] = 0; /* fallthrough */
1798 case 3: mask[3] = 0; /* fallthrough */
1799 }
1800
1801 if (pfxlen % 32)
1802 mask[i] = htonl(~(uint32_t)0 << (32 - (pfxlen % 32)));
1803
1804 for (i = 0; i < 4; i++)
1805 if ((ip[i] & mask[i]) != (net[i] & mask[i]))
1806 return 0;
1807
1808 return 1;
1809 #undef IP6_LEN
1810 #undef IP6PFX_LEN
1811 #undef IP6_U32LEN
1812 }
1813
uwsgi_route_condition_contains(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1814 static int uwsgi_route_condition_contains(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1815 char *semicolon = memchr(ur->subject_str, ';', ur->subject_str_len);
1816 if (!semicolon) return 0;
1817
1818 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, NULL, 0, ur->subject_str, semicolon - ur->subject_str);
1819 if (!ub) return -1;
1820
1821 struct uwsgi_buffer *ub2 = uwsgi_routing_translate(wsgi_req, ur, NULL, 0, semicolon+1, ur->subject_str_len - ((semicolon+1) - ur->subject_str));
1822 if (!ub2) {
1823 uwsgi_buffer_destroy(ub);
1824 return -1;
1825 }
1826
1827 if(uwsgi_contains_n(ub->buf, ub->pos, ub2->buf, ub2->pos)) {
1828 uwsgi_buffer_destroy(ub);
1829 uwsgi_buffer_destroy(ub2);
1830 return 1;
1831 }
1832 uwsgi_buffer_destroy(ub);
1833 uwsgi_buffer_destroy(ub2);
1834 return 0;
1835 }
1836
uwsgi_route_condition_endswith(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1837 static int uwsgi_route_condition_endswith(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1838 char *semicolon = memchr(ur->subject_str, ';', ur->subject_str_len);
1839 if (!semicolon) return 0;
1840
1841 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, NULL, 0, ur->subject_str, semicolon - ur->subject_str);
1842 if (!ub) return -1;
1843
1844 struct uwsgi_buffer *ub2 = uwsgi_routing_translate(wsgi_req, ur, NULL, 0, semicolon+1, ur->subject_str_len - ((semicolon+1) - ur->subject_str));
1845 if (!ub2) {
1846 uwsgi_buffer_destroy(ub);
1847 return -1;
1848 }
1849
1850 if (ub2->pos > ub->pos) goto zero;
1851 if(!uwsgi_strncmp(ub->buf + (ub->pos - ub2->pos), ub2->pos, ub2->buf, ub2->pos)) {
1852 uwsgi_buffer_destroy(ub);
1853 uwsgi_buffer_destroy(ub2);
1854 return 1;
1855 }
1856
1857 zero:
1858 uwsgi_buffer_destroy(ub);
1859 uwsgi_buffer_destroy(ub2);
1860 return 0;
1861 }
1862
1863
1864
uwsgi_route_condition_isdir(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1865 static int uwsgi_route_condition_isdir(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1866 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, NULL, 0, ur->subject_str, ur->subject_str_len);
1867 if (!ub) return -1;
1868 if (uwsgi_is_dir(ub->buf)) {
1869 uwsgi_buffer_destroy(ub);
1870 return 1;
1871 }
1872 uwsgi_buffer_destroy(ub);
1873 return 0;
1874 }
1875
uwsgi_route_condition_islink(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1876 static int uwsgi_route_condition_islink(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1877 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, NULL, 0, ur->subject_str, ur->subject_str_len);
1878 if (!ub) return -1;
1879 if (uwsgi_is_link(ub->buf)) {
1880 uwsgi_buffer_destroy(ub);
1881 return 1;
1882 }
1883 uwsgi_buffer_destroy(ub);
1884 return 0;
1885 }
1886
1887
uwsgi_route_condition_isexec(struct wsgi_request * wsgi_req,struct uwsgi_route * ur)1888 static int uwsgi_route_condition_isexec(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
1889 struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, NULL, 0, ur->subject_str, ur->subject_str_len);
1890 if (!ub) return -1;
1891 if (!access(ub->buf, X_OK)) {
1892 uwsgi_buffer_destroy(ub);
1893 return 1;
1894 }
1895 uwsgi_buffer_destroy(ub);
1896 return 0;
1897 }
1898
uwsgi_route_var_uwsgi(struct wsgi_request * wsgi_req,char * key,uint16_t keylen,uint16_t * vallen)1899 static char *uwsgi_route_var_uwsgi(struct wsgi_request *wsgi_req, char *key, uint16_t keylen, uint16_t *vallen) {
1900 char *ret = NULL;
1901 if (!uwsgi_strncmp(key, keylen, "wid", 3)) {
1902 ret = uwsgi_num2str(uwsgi.mywid);
1903 *vallen = strlen(ret);
1904 }
1905 else if (!uwsgi_strncmp(key, keylen, "pid", 3)) {
1906 ret = uwsgi_num2str(uwsgi.mypid);
1907 *vallen = strlen(ret);
1908 }
1909 else if (!uwsgi_strncmp(key, keylen, "uuid", 4)) {
1910 ret = uwsgi_malloc(37);
1911 uwsgi_uuid(ret);
1912 *vallen = 36;
1913 }
1914 else if (!uwsgi_strncmp(key, keylen, "status", 6)) {
1915 ret = uwsgi_num2str(wsgi_req->status);
1916 *vallen = strlen(ret);
1917 }
1918 else if (!uwsgi_strncmp(key, keylen, "rtime", 5)) {
1919 ret = uwsgi_num2str(wsgi_req->end_of_request - wsgi_req->start_of_request);
1920 *vallen = strlen(ret);
1921 }
1922
1923 else if (!uwsgi_strncmp(key, keylen, "lq", 2)) {
1924 ret = uwsgi_num2str(uwsgi.shared->backlog);
1925 *vallen = strlen(ret);
1926 }
1927 else if (!uwsgi_strncmp(key, keylen, "rsize", 5)) {
1928 ret = uwsgi_64bit2str(wsgi_req->response_size);
1929 *vallen = strlen(ret);
1930 }
1931 else if (!uwsgi_strncmp(key, keylen, "sor", 3)) {
1932 ret = uwsgi_64bit2str(wsgi_req->start_of_request);
1933 *vallen = strlen(ret);
1934 }
1935
1936 return ret;
1937 }
1938
uwsgi_route_var_mime(struct wsgi_request * wsgi_req,char * key,uint16_t keylen,uint16_t * vallen)1939 static char *uwsgi_route_var_mime(struct wsgi_request *wsgi_req, char *key, uint16_t keylen, uint16_t *vallen) {
1940 char *ret = NULL;
1941 uint16_t var_vallen = 0;
1942 char *var_value = uwsgi_get_var(wsgi_req, key, keylen, &var_vallen);
1943 if (var_value) {
1944 size_t mime_type_len = 0;
1945 ret = uwsgi_get_mime_type(var_value, var_vallen, &mime_type_len);
1946 if (ret) *vallen = mime_type_len;
1947 }
1948 return ret;
1949 }
1950
uwsgi_route_var_httptime(struct wsgi_request * wsgi_req,char * key,uint16_t keylen,uint16_t * vallen)1951 static char *uwsgi_route_var_httptime(struct wsgi_request *wsgi_req, char *key, uint16_t keylen, uint16_t *vallen) {
1952 // 30+1
1953 char *ht = uwsgi_calloc(31);
1954 size_t t = uwsgi_str_num(key, keylen);
1955 int len = uwsgi_http_date(uwsgi_now() + t, ht);
1956 if (len == 0) {
1957 free(ht);
1958 return NULL;
1959 }
1960 *vallen = len;
1961 return ht;
1962 }
1963
1964
uwsgi_route_var_time(struct wsgi_request * wsgi_req,char * key,uint16_t keylen,uint16_t * vallen)1965 static char *uwsgi_route_var_time(struct wsgi_request *wsgi_req, char *key, uint16_t keylen, uint16_t *vallen) {
1966 char *ret = NULL;
1967 if (!uwsgi_strncmp(key, keylen, "unix", 4)) {
1968 ret = uwsgi_num2str(uwsgi_now());
1969 *vallen = strlen(ret);
1970 }
1971 else if (!uwsgi_strncmp(key, keylen, "micros", 6)) {
1972 ret = uwsgi_64bit2str(uwsgi_micros());
1973 *vallen = strlen(ret);
1974 }
1975 return ret;
1976 }
1977
uwsgi_route_var_base64(struct wsgi_request * wsgi_req,char * key,uint16_t keylen,uint16_t * vallen)1978 static char *uwsgi_route_var_base64(struct wsgi_request *wsgi_req, char *key, uint16_t keylen, uint16_t *vallen) {
1979 char *ret = NULL;
1980 uint16_t var_vallen = 0;
1981 char *var_value = uwsgi_get_var(wsgi_req, key, keylen, &var_vallen);
1982 if (var_value) {
1983 size_t b64_len = 0;
1984 ret = uwsgi_base64_encode(var_value, var_vallen, &b64_len);
1985 *vallen = b64_len;
1986 }
1987 return ret;
1988 }
1989
uwsgi_route_var_hex(struct wsgi_request * wsgi_req,char * key,uint16_t keylen,uint16_t * vallen)1990 static char *uwsgi_route_var_hex(struct wsgi_request *wsgi_req, char *key, uint16_t keylen, uint16_t *vallen) {
1991 char *ret = NULL;
1992 uint16_t var_vallen = 0;
1993 char *var_value = uwsgi_get_var(wsgi_req, key, keylen, &var_vallen);
1994 if (var_value) {
1995 ret = uwsgi_str_to_hex(var_value, var_vallen);
1996 *vallen = var_vallen*2;
1997 }
1998 return ret;
1999 }
2000
2001 // register embedded routers
uwsgi_register_embedded_routers()2002 void uwsgi_register_embedded_routers() {
2003 uwsgi_register_router("continue", uwsgi_router_continue);
2004 uwsgi_register_router("last", uwsgi_router_continue);
2005 uwsgi_register_router("break", uwsgi_router_break);
2006 uwsgi_register_router("return", uwsgi_router_return);
2007 uwsgi_register_router("break-with-status", uwsgi_router_return);
2008 uwsgi_register_router("log", uwsgi_router_log);
2009 uwsgi_register_router("donotlog", uwsgi_router_donotlog);
2010 uwsgi_register_router("donotoffload", uwsgi_router_donotoffload);
2011 uwsgi_register_router("logvar", uwsgi_router_logvar);
2012 uwsgi_register_router("goto", uwsgi_router_goto);
2013 uwsgi_register_router("addvar", uwsgi_router_addvar);
2014 uwsgi_register_router("addheader", uwsgi_router_addheader);
2015 uwsgi_register_router("delheader", uwsgi_router_remheader);
2016 uwsgi_register_router("remheader", uwsgi_router_remheader);
2017 uwsgi_register_router("clearheaders", uwsgi_router_clearheaders);
2018 uwsgi_register_router("resetheaders", uwsgi_router_clearheaders);
2019 uwsgi_register_router("disableheaders", uwsgi_router_disableheaders);
2020 uwsgi_register_router("signal", uwsgi_router_signal);
2021 uwsgi_register_router("send", uwsgi_router_send);
2022 uwsgi_register_router("send-crnl", uwsgi_router_send_crnl);
2023 uwsgi_register_router("chdir", uwsgi_router_chdir);
2024 uwsgi_register_router("setapp", uwsgi_router_setapp);
2025 uwsgi_register_router("setuser", uwsgi_router_setuser);
2026 uwsgi_register_router("sethome", uwsgi_router_sethome);
2027 uwsgi_register_router("setfile", uwsgi_router_setfile);
2028 uwsgi_register_router("setscriptname", uwsgi_router_setscriptname);
2029 uwsgi_register_router("setmethod", uwsgi_router_setmethod);
2030 uwsgi_register_router("seturi", uwsgi_router_seturi);
2031 uwsgi_register_router("setremoteaddr", uwsgi_router_setremoteaddr);
2032 uwsgi_register_router("setpathinfo", uwsgi_router_setpathinfo);
2033 uwsgi_register_router("fixpathinfo", uwsgi_router_fixpathinfo);
2034 uwsgi_register_router("setdocroot", uwsgi_router_setdocroot);
2035 uwsgi_register_router("setscheme", uwsgi_router_setscheme);
2036 uwsgi_register_router("setprocname", uwsgi_router_setprocname);
2037 uwsgi_register_router("alarm", uwsgi_router_alarm);
2038
2039 uwsgi_register_router("setmodifier1", uwsgi_router_setmodifier1);
2040 uwsgi_register_router("setmodifier2", uwsgi_router_setmodifier2);
2041
2042 uwsgi_register_router("+", uwsgi_router_simple_math_plus);
2043 uwsgi_register_router("-", uwsgi_router_simple_math_minus);
2044 uwsgi_register_router("*", uwsgi_router_simple_math_multiply);
2045 uwsgi_register_router("/", uwsgi_router_simple_math_divide);
2046
2047 uwsgi_register_router("flush", uwsgi_router_flush);
2048 uwsgi_register_router("fixcl", uwsgi_router_fixcl);
2049 uwsgi_register_router("forcecl", uwsgi_router_forcecl);
2050
2051 uwsgi_register_router("harakiri", uwsgi_router_harakiri);
2052
2053 uwsgi_register_route_condition("exists", uwsgi_route_condition_exists);
2054 uwsgi_register_route_condition("isfile", uwsgi_route_condition_isfile);
2055 uwsgi_register_route_condition("isdir", uwsgi_route_condition_isdir);
2056 uwsgi_register_route_condition("islink", uwsgi_route_condition_islink);
2057 uwsgi_register_route_condition("isexec", uwsgi_route_condition_isexec);
2058 uwsgi_register_route_condition("equal", uwsgi_route_condition_equal);
2059 uwsgi_register_route_condition("isequal", uwsgi_route_condition_equal);
2060 uwsgi_register_route_condition("eq", uwsgi_route_condition_equal);
2061 uwsgi_register_route_condition("==", uwsgi_route_condition_equal);
2062 uwsgi_register_route_condition("startswith", uwsgi_route_condition_startswith);
2063 uwsgi_register_route_condition("endswith", uwsgi_route_condition_endswith);
2064 uwsgi_register_route_condition("regexp", uwsgi_route_condition_regexp);
2065 uwsgi_register_route_condition("re", uwsgi_route_condition_regexp);
2066 uwsgi_register_route_condition("ishigher", uwsgi_route_condition_higher);
2067 uwsgi_register_route_condition(">", uwsgi_route_condition_higher);
2068 uwsgi_register_route_condition("islower", uwsgi_route_condition_lower);
2069 uwsgi_register_route_condition("<", uwsgi_route_condition_lower);
2070 uwsgi_register_route_condition("ishigherequal", uwsgi_route_condition_higherequal);
2071 uwsgi_register_route_condition(">=", uwsgi_route_condition_higherequal);
2072 uwsgi_register_route_condition("islowerequal", uwsgi_route_condition_lowerequal);
2073 uwsgi_register_route_condition("<=", uwsgi_route_condition_lowerequal);
2074 uwsgi_register_route_condition("contains", uwsgi_route_condition_contains);
2075 uwsgi_register_route_condition("contain", uwsgi_route_condition_contains);
2076 uwsgi_register_route_condition("ipv4in", uwsgi_route_condition_ipv4in);
2077 uwsgi_register_route_condition("ipv6in", uwsgi_route_condition_ipv6in);
2078 #ifdef UWSGI_SSL
2079 uwsgi_register_route_condition("lord", uwsgi_route_condition_lord);
2080 #endif
2081
2082 uwsgi_register_route_condition("empty", uwsgi_route_condition_empty);
2083
2084 uwsgi_register_route_var("cookie", uwsgi_get_cookie);
2085 uwsgi_register_route_var("qs", uwsgi_get_qs);
2086 uwsgi_register_route_var("mime", uwsgi_route_var_mime);
2087 struct uwsgi_route_var *urv = uwsgi_register_route_var("uwsgi", uwsgi_route_var_uwsgi);
2088 urv->need_free = 1;
2089 urv = uwsgi_register_route_var("time", uwsgi_route_var_time);
2090 urv->need_free = 1;
2091 urv = uwsgi_register_route_var("httptime", uwsgi_route_var_httptime);
2092 urv->need_free = 1;
2093 urv = uwsgi_register_route_var("base64", uwsgi_route_var_base64);
2094 urv->need_free = 1;
2095
2096 urv = uwsgi_register_route_var("hex", uwsgi_route_var_hex);
2097 urv->need_free = 1;
2098 }
2099
uwsgi_register_router(char * name,int (* func)(struct uwsgi_route *,char *))2100 struct uwsgi_router *uwsgi_register_router(char *name, int (*func) (struct uwsgi_route *, char *)) {
2101
2102 struct uwsgi_router *ur = uwsgi.routers;
2103 if (!ur) {
2104 uwsgi.routers = uwsgi_calloc(sizeof(struct uwsgi_router));
2105 uwsgi.routers->name = name;
2106 uwsgi.routers->func = func;
2107 return uwsgi.routers;
2108 }
2109
2110 while (ur) {
2111 if (!ur->next) {
2112 ur->next = uwsgi_calloc(sizeof(struct uwsgi_router));
2113 ur->next->name = name;
2114 ur->next->func = func;
2115 return ur->next;
2116 }
2117 ur = ur->next;
2118 }
2119
2120 return NULL;
2121
2122 }
2123
uwsgi_register_route_condition(char * name,int (* func)(struct wsgi_request *,struct uwsgi_route *))2124 struct uwsgi_route_condition *uwsgi_register_route_condition(char *name, int (*func) (struct wsgi_request *, struct uwsgi_route *)) {
2125 struct uwsgi_route_condition *old_urc = NULL,*urc = uwsgi.route_conditions;
2126 while(urc) {
2127 if (!strcmp(urc->name, name)) {
2128 return urc;
2129 }
2130 old_urc = urc;
2131 urc = urc->next;
2132 }
2133
2134 urc = uwsgi_calloc(sizeof(struct uwsgi_route_condition));
2135 urc->name = name;
2136 urc->func = func;
2137
2138 if (old_urc) {
2139 old_urc->next = urc;
2140 }
2141 else {
2142 uwsgi.route_conditions = urc;
2143 }
2144
2145 return urc;
2146 }
2147
uwsgi_routing_dump()2148 void uwsgi_routing_dump() {
2149 struct uwsgi_string_list *usl = NULL;
2150 struct uwsgi_route *routes = uwsgi.routes;
2151 if (!routes) goto next;
2152 uwsgi_log("*** dumping internal routing table ***\n");
2153 while(routes) {
2154 if (routes->label) {
2155 uwsgi_log("[rule: %llu] label: %s\n", (unsigned long long ) routes->pos, routes->label);
2156 }
2157 else if (!routes->subject_str && !routes->if_func) {
2158 uwsgi_log("[rule: %llu] action: %s\n", (unsigned long long ) routes->pos, routes->action);
2159 }
2160 else {
2161 uwsgi_log("[rule: %llu] subject: %s %s: %s%s action: %s\n", (unsigned long long ) routes->pos, routes->subject_str, routes->if_func ? "func" : "regexp", routes->if_negate ? "!" : "", routes->regexp, routes->action);
2162 }
2163 routes = routes->next;
2164 }
2165 uwsgi_log("*** end of the internal routing table ***\n");
2166 next:
2167 routes = uwsgi.error_routes;
2168 if (!routes) goto next2;
2169 uwsgi_log("*** dumping internal error routing table ***\n");
2170 while(routes) {
2171 if (routes->label) {
2172 uwsgi_log("[rule: %llu] label: %s\n", (unsigned long long ) routes->pos, routes->label);
2173 }
2174 else if (!routes->subject_str && !routes->if_func) {
2175 uwsgi_log("[rule: %llu] action: %s\n", (unsigned long long ) routes->pos, routes->action);
2176 }
2177 else {
2178 uwsgi_log("[rule: %llu] subject: %s %s: %s%s action: %s\n", (unsigned long long ) routes->pos, routes->subject_str, routes->if_func ? "func" : "regexp", routes->if_negate ? "!" : "", routes->regexp, routes->action);
2179 }
2180 routes = routes->next;
2181 }
2182 uwsgi_log("*** end of the internal error routing table ***\n");
2183 next2:
2184 routes = uwsgi.response_routes;
2185 if (!routes) goto next3;
2186 uwsgi_log("*** dumping internal response routing table ***\n");
2187 while(routes) {
2188 if (routes->label) {
2189 uwsgi_log("[rule: %llu] label: %s\n", (unsigned long long ) routes->pos, routes->label);
2190 }
2191 else if (!routes->subject_str && !routes->if_func) {
2192 uwsgi_log("[rule: %llu] action: %s\n", (unsigned long long ) routes->pos, routes->action);
2193 }
2194 else {
2195 uwsgi_log("[rule: %llu] subject: %s %s: %s%s action: %s\n", (unsigned long long ) routes->pos, routes->subject_str, routes->if_func ? "func" : "regexp", routes->if_negate ? "!" : "", routes->regexp, routes->action);
2196 }
2197 routes = routes->next;
2198 }
2199 uwsgi_log("*** end of the internal response routing table ***\n");
2200 next3:
2201 routes = uwsgi.final_routes;
2202 if (!routes) goto next4;
2203 uwsgi_log("*** dumping internal final routing table ***\n");
2204 while(routes) {
2205 if (routes->label) {
2206 uwsgi_log("[rule: %llu] label: %s\n", (unsigned long long ) routes->pos, routes->label);
2207 }
2208 else if (!routes->subject_str && !routes->if_func) {
2209 uwsgi_log("[rule: %llu] action: %s\n", (unsigned long long ) routes->pos, routes->action);
2210 }
2211 else {
2212 uwsgi_log("[rule: %llu] subject: %s %s: %s%s action: %s\n", (unsigned long long ) routes->pos, routes->subject_str, routes->if_func ? "func" : "regexp", routes->if_negate ? "!" : "", routes->regexp, routes->action);
2213 }
2214 routes = routes->next;
2215 }
2216 uwsgi_log("*** end of the internal final routing table ***\n");
2217
2218 next4:
2219 uwsgi_foreach(usl, uwsgi.collect_headers) {
2220 char *space = strchr(usl->value, ' ');
2221 if (!space) {
2222 uwsgi_log("invalid collect header syntax, must be <header> <var>\n");
2223 exit(1);
2224 }
2225 *space = 0;
2226 usl->custom = strlen(usl->value);
2227 *space = ' ';
2228 usl->custom_ptr = space+1;
2229 usl->custom2 = strlen(space+1);
2230 uwsgi_log("collecting header %.*s to var %s\n", usl->custom, usl->value, usl->custom_ptr);
2231 }
2232
2233 uwsgi_foreach(usl, uwsgi.pull_headers) {
2234 char *space = strchr(usl->value, ' ');
2235 if (!space) {
2236 uwsgi_log("invalid pull header syntax, must be <header> <var>\n");
2237 exit(1);
2238 }
2239 *space = 0;
2240 usl->custom = strlen(usl->value);
2241 *space = ' ';
2242 usl->custom_ptr = space+1;
2243 usl->custom2 = strlen(space+1);
2244 uwsgi_log("pulling header %.*s to var %s\n", usl->custom, usl->value, usl->custom_ptr);
2245 }
2246 }
2247 #endif
2248