diff --git a/routing.c b/routing.c index e5338f8c..9e884337 100644 --- a/routing.c +++ b/routing.c @@ -1,7 +1,110 @@ #ifdef UWSGI_ROUTING #include "uwsgi.h" +extern struct uwsgi_server uwsgi; + int uwsgi_apply_routes(struct wsgi_request *wsgi_req) { + + struct uwsgi_route *routes = uwsgi.routes; + + if (!routes) return 0; + + if (uwsgi_parse_vars(wsgi_req)) { + return -1; + } + + while(routes) { + + if (uwsgi_regexp_match(routes->pattern, routes->pattern_extra, wsgi_req->path_info, wsgi_req->path_info_len) >= 0) { + + uwsgi_log("regexp match for %.*s\n", wsgi_req->path_info_len, wsgi_req->path_info); + return routes->func(wsgi_req, routes->data); + } + + routes = routes->next; + } + return 0; } + +int uwsgi_routing_func_uwsgi_simple(struct wsgi_request *wsgi_req, void *data) { + + struct uwsgi_header *uh = (struct uwsgi_header *) data; + + wsgi_req->uh.modifier1 = uh->modifier1; + wsgi_req->uh.modifier2 = uh->modifier2; + + return 0; +} + +void uwsgi_opt_add_route(char *opt, char *value, void *foobar) { + + char *route = uwsgi_str(value); + + char *space = strchr(route, ' '); + if (!space) { + uwsgi_log("invalid route syntax\n"); + exit(1); + } + + *space = 0; + + struct uwsgi_route *ur = uwsgi.routes; + if (!ur) { + uwsgi.routes = uwsgi_calloc(sizeof(struct uwsgi_route)); + ur = uwsgi.routes; + } + else { + while(ur) { + if (!ur->next) { + ur->next = uwsgi_calloc(sizeof(struct uwsgi_route)); + ur = ur->next; + break; + } + ur = ur->next; + } + } + + if (uwsgi_regexp_build(route, &ur->pattern, &ur->pattern_extra)) { + exit(1); + } + + char *command = space+1; + + char *colon = strchr(command, ':'); + if (!colon) { + uwsgi_log("invalid route syntax\n"); + exit(1); + } + + *colon = 0; + + if (!strcmp(command, "uwsgi")) { + char *args = colon+1; + // check for commas + char *comma1 = strchr(args, ','); + if (!comma1) { + uwsgi_log("invalid route syntax\n"); + exit(1); + } + + char *comma2 = strchr(comma1+1, ','); + if (!comma2) { + uwsgi_log("invalid route syntax\n"); + exit(1); + } + + *comma1 = 0; + *comma2 = 0; + // simple modifier remapper + if (*args == 0) { + struct uwsgi_header *uh = uwsgi_calloc(sizeof(struct uwsgi_header)); + ur->func = uwsgi_routing_func_uwsgi_simple; + ur->data = (void *) uh; + + uh->modifier1 = atoi(comma1+1); + uh->modifier2 = atoi(comma2+1); + } + } +} #endif diff --git a/uwsgi.c b/uwsgi.c index 33332a05..45065eff 100644 --- a/uwsgi.c +++ b/uwsgi.c @@ -293,11 +293,9 @@ static struct uwsgi_option uwsgi_base_options[] = { {"vhost", no_argument, 0, "enable virtualhosting mode (based on SERVER_NAME variable)", uwsgi_opt_true, &uwsgi.vhost, 0}, {"vhost-host", no_argument, 0, "enable virtualhosting mode (based on HTTP_HOST variable)", uwsgi_opt_true, &uwsgi.vhost_host, UWSGI_OPT_VHOST}, -/* #ifdef UWSGI_ROUTING - {"routing", no_argument, 0, "enable routing subsystem", uwsgi_opt_set_str, &uwsgi.routing, 0}, + {"route", no_argument, 0, "add a route", uwsgi_opt_add_route, NULL, 0}, #endif -*/ {"add-header", required_argument, 0, "automatically add HTTP headers to response", uwsgi_opt_add_string_list, &uwsgi.additional_headers, 0}, {"check-static", required_argument, 0, "check for static files in the specified directory", uwsgi_opt_check_static, NULL, 0}, {"static-check", required_argument, 0, "check for static files in the specified directory", uwsgi_opt_check_static, NULL, 0}, @@ -324,8 +322,9 @@ static struct uwsgi_option uwsgi_base_options[] = { {"ns-net", required_argument, 0, "add network namespace", uwsgi_opt_set_str, &uwsgi.ns_net, 0}, #endif {"reuse-port", no_argument, 0, "enable REUSE_PORT flag on socket (BSD only)", uwsgi_opt_true, &uwsgi.reuse_port, 0}, - {"zerg", required_argument, 0, "attach to a zerg server", uwsgi_opt_zerg, NULL, 0}, + {"zerg", required_argument, 0, "attach to a zerg server", uwsgi_opt_set_str, &uwsgi.zerg_node, 0}, {"zerg-server", required_argument, 0, "enable the zerg server on the specified UNIX socket", uwsgi_opt_set_str, &uwsgi.zerg_server, UWSGI_OPT_MASTER}, + //{"zerg-pool", required_argument, 0, "create a zerg pool", uwsgi_opt_zerg_pool, NULL, 0}, {"cron", required_argument, 0, "add a cron task", uwsgi_opt_add_cron, NULL, UWSGI_OPT_MASTER}, {"loop", required_argument, 0, "select the uWSGI loop engine", uwsgi_opt_set_str, &uwsgi.loop, 0}, {"worker-exec", required_argument, 0, "run the specified command as worker", uwsgi_opt_set_str, &uwsgi.worker_exec, 0}, @@ -1917,6 +1916,10 @@ int uwsgi_start(void *v_argv) { } } + if (uwsgi.zerg_node) { + if (uwsgi_zerg_attach(uwsgi.zerg_node)) { + } + } //check for inherited sockets if (uwsgi.is_a_reload || uwsgi.zerg) { @@ -3415,18 +3418,21 @@ void uwsgi_opt_static_map(char *opt, char *value, void *foobar) { uwsgi.build_mime_dict = 1; } -void uwsgi_opt_zerg(char *opt, char *value, void *foobar) { + +int uwsgi_zerg_attach(char *value) { + int zerg_fd = uwsgi_connect(value, 30, 0); - if (zerg_fd < 0) { - uwsgi_log("--- unable to connect to zerg server ---\n"); - exit(1); - } - uwsgi.zerg = uwsgi_attach_fd(zerg_fd, 8, "uwsgi-zerg", 11); - if (uwsgi.zerg == NULL) { - uwsgi_log("--- invalid data received from zerg-server ---\n"); - exit(1); - } - close(zerg_fd); + if (zerg_fd < 0) { + uwsgi_log("--- unable to connect to zerg server ---\n"); + return -1; + } + uwsgi.zerg = uwsgi_attach_fd(zerg_fd, 8, "uwsgi-zerg", 11); + if (uwsgi.zerg == NULL) { + uwsgi_log("--- invalid data received from zerg-server ---\n"); + return -1; + } + close(zerg_fd); + return 0; } void uwsgi_opt_signal(char *opt, char *value, void *foobar) { diff --git a/uwsgi.h b/uwsgi.h index 03174d37..fd47c760 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -669,8 +669,14 @@ struct uwsgi_spooler { #ifdef UWSGI_ROUTING struct uwsgi_route { - uint8_t modifier1; - uint8_t modifier2; + pcre *pattern; + pcre_extra *pattern_extra; + + int (*func)(struct wsgi_request *, void *); + + void *data; + + struct uwsgi_route *next; }; #endif @@ -1039,6 +1045,7 @@ struct uwsgi_server { // enable zerg mode int *zerg; char *zerg_server; + char *zerg_node; int zerg_server_fd; // security @@ -2455,6 +2462,8 @@ struct uwsgi_spooler *uwsgi_new_spooler(char *); struct uwsgi_spooler *uwsgi_get_spooler_by_name(char *); +int uwsgi_zerg_attach(char *); + int uwsgi_manage_opt(char *, char *); void uwsgi_opt_print(char *, char *, void *); @@ -2509,8 +2518,6 @@ void uwsgi_opt_add_mule(char *, char *, void *); void uwsgi_opt_add_mules(char *, char *, void *); void uwsgi_opt_add_farm(char *, char *, void *); -void uwsgi_opt_zerg(char *, char *, void *); - void uwsgi_opt_signal(char *, char *, void *); void uwsgi_opt_snmp(char *, char *, void *); @@ -2533,6 +2540,7 @@ void uwsgi_opt_set_unshare(char *, char *, void *); char *uwsgi_tmpname(char *, char *); #ifdef UWSGI_ROUTING +void uwsgi_opt_add_route(char *, char *, void *); int uwsgi_apply_routes(struct wsgi_request *); #endif