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