From a92c2003ee04f37909d59afaa3fb4ecc5bf0ac08 Mon Sep 17 00:00:00 2001 From: "roberto@goyle" Date: Thu, 2 Feb 2012 18:20:10 +0100 Subject: [PATCH] prepare for new routing system --- buildconf/default.ini | 1 + plugins/python/wsgi_subhandler.c | 10 --- routing.c | 145 +------------------------------ utils.c | 8 +- uwsgi.c | 4 - uwsgi.h | 33 ++----- uwsgiconfig.py | 4 + xmlconf.c | 79 ----------------- 8 files changed, 17 insertions(+), 267 deletions(-) diff --git a/buildconf/default.ini b/buildconf/default.ini index 4f646c63..93734498 100644 --- a/buildconf/default.ini +++ b/buildconf/default.ini @@ -18,6 +18,7 @@ async = true evdis = false ldap = auto pcre = auto +routing = true debug = false unbit = false xml_implementation = libxml2 diff --git a/plugins/python/wsgi_subhandler.c b/plugins/python/wsgi_subhandler.c index a9475260..ff27824d 100644 --- a/plugins/python/wsgi_subhandler.c +++ b/plugins/python/wsgi_subhandler.c @@ -156,18 +156,8 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_ PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.node", wi->uwsgi_node); - -#ifdef UWSGI_ROUTING - uwsgi_log("routing %d routes %d\n", uwsgi.routing, uwsgi.nroutes); - if (uwsgi.routing && uwsgi.nroutes > 0) { - check_route(uwsgi, wsgi_req); - } -#endif - - // call - PyTuple_SetItem(wsgi_req->async_args, 0, wsgi_req->async_environ); return python_call(wsgi_req->async_app, wsgi_req->async_args, up.catch_exceptions, wsgi_req); } diff --git a/routing.c b/routing.c index bfcb57ca..e5338f8c 100644 --- a/routing.c +++ b/routing.c @@ -1,148 +1,7 @@ #ifdef UWSGI_ROUTING #include "uwsgi.h" -void routing_setup(struct uwsgi_server *uwsgi) { - - int i; - struct uwsgi_route *ur; - int max_ovec = 0; - - for(i=0;inroutes;i++) { - uwsgi_log("%d = %p\n", i, uwsgi->routes[i].pattern); - ur = &uwsgi->routes[i]; - if (ur->args > max_ovec) { - max_ovec = ur->args; - } - } - - uwsgi->async_ovector = malloc( sizeof(int *) * uwsgi->async); - if (!uwsgi->async_ovector) { - uwsgi_error("malloc()"); - exit(1); - } - - uwsgi_log("max_ovec = %d\n", max_ovec); - for(i=0;iasync;i++) { - uwsgi->async_ovector[i] = malloc(sizeof(int) * ((max_ovec+1)*3)); - if (!uwsgi->async_ovector[i]) { - uwsgi_error("malloc()"); - exit(1); - } - } +int uwsgi_apply_routes(struct wsgi_request *wsgi_req) { + return 0; } - -void check_route(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req) { - - int ret,i; - struct uwsgi_route *ur; - - for(i=0;inroutes;i++) { - - //uwsgi_log("checking route %d\n", i); - ur = &uwsgi->routes[i]; - ret = pcre_exec(ur->pattern, ur->pattern_extra, wsgi_req->path_info, wsgi_req->path_info_len, 0, 0, wsgi_req->ovector, (ur->args+1)*3 ); - - if (ret >= 0) { - uwsgi_log("found route %d for PATH_INFO=%.*s\n", i, wsgi_req->path_info_len, wsgi_req->path_info); - if (ur->action) { - ur->action(uwsgi, wsgi_req, ur); - } - else { - uwsgi_route_action_wsgi(uwsgi, wsgi_req, ur); - } - } - - /* TODO check for errors if < 0 && != NO_MATCH */ - } - - return; -} - -void uwsgi_route_action_wsgi(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req, struct uwsgi_route *ur) { - - int i; - PyObject *route_py_callbase, *route_py_dict = NULL; - - uwsgi_log("managing WSGI route...\n"); - if (ur->callable == NULL) { - if (ur->callbase) { - route_py_callbase = PyImport_ImportModule(ur->callbase); - if (route_py_callbase == NULL) { - PyErr_Print(); - } - else { - uwsgi_log("callbase dict ok for %s\n", ur->call); - route_py_dict = PyModule_GetDict(route_py_callbase); - } - } - - ur->callable = PyDict_GetItemString(route_py_dict, ur->call); - if (ur->callable == NULL) { - uwsgi_log("route_py_dict: %p call: %s\n", route_py_dict, ur->call); - PyErr_Print(); - } - } - - // TODO put regex captured groups in WSGI env - - PyObject *ra = PyTuple_New(ur->args); - for (i=1;i<=ur->args;i++) { - PyTuple_SetItem(ra, i-1, PyString_FromStringAndSize( - wsgi_req->path_info + wsgi_req->ovector[i*2], - wsgi_req->ovector[(i*2)+1] - wsgi_req->ovector[i*2] - )); - } - - PyDict_SetItemString(wsgi_req->async_environ, "x-wsgiorg.uwsgi.route_args", ra); - - if (ur->callable) { - wsgi_req->async_app = ur->callable; - } -} - -void uwsgi_route_action_uwsgi(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req, struct uwsgi_route *ur) { - PyObject *route_py_callbase, *route_py_dict = NULL; - int i; - - uwsgi_log("managing uwsgi route...\n"); - if (ur->callable == NULL) { - if (ur->callbase) { - route_py_callbase = PyImport_ImportModule(ur->callbase); - if (route_py_callbase == NULL) { - PyErr_Print(); - } - else { - uwsgi_log("callbase dict ok for %s\n", ur->call); - route_py_dict = PyModule_GetDict(route_py_callbase); - } - } - - ur->callable = PyDict_GetItemString(route_py_dict, ur->call); - if (ur->callable == NULL) { - uwsgi_log("route_py_dict: %p call: %s\n", route_py_dict, ur->call); - PyErr_Print(); - } - - ur->callable_args = PyTuple_New(ur->args+1); - } - - if (ur->callable) { - uwsgi_log("route callable dict ok: %d\n", ur->args); - wsgi_req->async_app = ur->callable; - wsgi_req->async_args = ur->callable_args; - - for (i=1;i<=ur->args;i++) { - uwsgi_log("%d\n", i); - uwsgi_log("%d / %d\n", wsgi_req->ovector[i*2], wsgi_req->ovector[(i*2)+1]); - uwsgi_log("%d = %.*s\n", i,wsgi_req->ovector[(i*2)+1] - wsgi_req->ovector[i*2], - wsgi_req->path_info + wsgi_req->ovector[i*2]); - PyTuple_SetItem(wsgi_req->async_args, i, PyString_FromStringAndSize( - wsgi_req->path_info + wsgi_req->ovector[i*2], - wsgi_req->ovector[(i*2)+1] - wsgi_req->ovector[i*2] - )); - } - uwsgi_log("route callable built\n"); - } -} - #endif diff --git a/utils.c b/utils.c index b2598542..68b7e066 100644 --- a/utils.c +++ b/utils.c @@ -852,10 +852,6 @@ void wsgi_req_setup(struct wsgi_request *wsgi_req, int async_id, struct uwsgi_so wsgi_req->hvec = uwsgi.async_hvec[wsgi_req->async_id]; wsgi_req->buffer = uwsgi.async_buf[wsgi_req->async_id]; -#ifdef UWSGI_ROUTING - wsgi_req->ovector = uwsgi.async_ovector[wsgi_req->async_id]; -#endif - if (uwsgi.post_buffering > 0) { wsgi_req->post_buffering_buf = uwsgi.async_post_buf[wsgi_req->async_id]; } @@ -923,6 +919,10 @@ int wsgi_req_recv(struct wsgi_request *wsgi_req) { set_harakiri(uwsgi.shared->options[UWSGI_OPTION_HARAKIRI]); } +#ifdef UWSGI_ROUTING + if (uwsgi_apply_routes(wsgi_req)) return 0; +#endif + wsgi_req->async_status = uwsgi.p[wsgi_req->uh.modifier1]->request(wsgi_req); return 0; diff --git a/uwsgi.c b/uwsgi.c index 78024c52..33332a05 100644 --- a/uwsgi.c +++ b/uwsgi.c @@ -2479,10 +2479,6 @@ skipzero: } #endif -#ifdef UWSGI_ROUTING - routing_setup(); -#endif - if (!uwsgi.master_process) { if (uwsgi.numproc == 1) { uwsgi_log("spawned uWSGI worker 1 (and the only) (pid: %d, cores: %d)\n", masterpid, uwsgi.cores); diff --git a/uwsgi.h b/uwsgi.h index 8197bc71..03174d37 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -669,24 +669,9 @@ struct uwsgi_spooler { #ifdef UWSGI_ROUTING struct uwsgi_route { - const char *mountpoint; - const char *callbase; + uint8_t modifier1; + uint8_t modifier2; - pcre *pattern; - pcre_extra *pattern_extra; - pcre *method; - pcre_extra *method_extra; - - const char *call; - - int modifier1; - int modifier2; - - void *callable; - void *callable_args; - int args; - - void (*action) (struct wsgi_request *, struct uwsgi_route *); }; #endif @@ -1162,10 +1147,6 @@ struct uwsgi_server { struct wsgi_request **async_queue_unused; -#ifdef UWSGI_ROUTING - int **async_ovector; -#endif - // store rlimit struct rlimit rl; size_t limit_post; @@ -1308,12 +1289,7 @@ struct uwsgi_server { #ifdef UWSGI_ROUTING -#ifndef MAX_UWSGI_ROUTES -#define MAX_UWSGI_ROUTES 64 -#endif - int routing; - int nroutes; - struct uwsgi_route routes[MAX_UWSGI_ROUTES]; + struct uwsgi_route *routes; #endif int single_interpreter; @@ -2556,6 +2532,9 @@ void uwsgi_opt_set_unshare(char *, char *, void *); char *uwsgi_tmpname(char *, char *); +#ifdef UWSGI_ROUTING +int uwsgi_apply_routes(struct wsgi_request *); +#endif #ifdef UWSGI_AS_SHARED_LIBRARY int uwsgi_init(int, char **, char **); diff --git a/uwsgiconfig.py b/uwsgiconfig.py index efde5bd5..a3cfea1e 100644 --- a/uwsgiconfig.py +++ b/uwsgiconfig.py @@ -513,6 +513,10 @@ class uConf(object): if self.get('udp'): self.cflags.append("-DUWSGI_UDP") + if self.get('routing'): + self.gcc_list.append('routing') + self.cflags.append("-DUWSGI_ROUTING") + # re-enable after pcre fix if self.get('pcre'): if self.get('pcre') == 'auto': diff --git a/xmlconf.c b/xmlconf.c index d087efb7..6e4000e1 100644 --- a/xmlconf.c +++ b/xmlconf.c @@ -100,17 +100,6 @@ void uwsgi_xml_config(char *filename, struct wsgi_request *wsgi_req, int app_tag continue; } -#ifdef UWSGI_ROUTING - if (!strcmp((char *) node->name, "route")) { - uwsgi.xml_round2 = 1; - continue; - } - if (!strcmp((char *) node->name, "routing")) { - uwsgi.xml_round2 = 1; - continue; - } -#endif - node_mode = xmlGetProp(node, (const xmlChar *) "mode"); if (uwsgi.mode && node_mode) { if (strcmp(uwsgi.mode, (char *) node_mode)) { @@ -170,81 +159,13 @@ void uwsgi_xml_config(char *filename, struct wsgi_request *wsgi_req, int app_tag } } } -#ifdef UWSGI_ROUTING - else if (!strcmp((char *) node->name, "routing")) { - unsigned char *default_route_mountpoint = NULL; - unsigned char *default_route_callbase = NULL; - xmlChar *tmp_val; - int default_route_modifier1 = 0; - int default_route_modifier2 = 0; - const char *errstr; - int erroff; - - default_route_mountpoint = xmlGetProp(node, (const xmlChar *) "mountpoint"); - default_route_callbase = xmlGetProp(node, (const xmlChar *) "base"); - - tmp_val = xmlGetProp(node, (const xmlChar *) "modifier1"); - if (tmp_val) { - default_route_modifier1 = atoi( (char *)tmp_val); - } - - tmp_val = xmlGetProp(node, (const xmlChar *) "modifier2"); - if (tmp_val) { - default_route_modifier2 = atoi( (char *) tmp_val); - } - - - for (node2 = node->children; node2; node2 = node2->next) { - if (node2->type == XML_ELEMENT_NODE) { - if (!strcmp((char *) node2->name, "route") && uwsgi.nroutes < MAX_UWSGI_ROUTES) { - if (!node2->children) { - uwsgi_log( "no route callable defined. skip.\n"); - continue; - } - uwsgi.routes[uwsgi.nroutes].mountpoint = (char *) default_route_mountpoint; - uwsgi.routes[uwsgi.nroutes].callbase = (char *) default_route_callbase; - uwsgi.routes[uwsgi.nroutes].modifier1 = default_route_modifier1; - uwsgi.routes[uwsgi.nroutes].modifier2 = default_route_modifier2; - // TODO check for action - uwsgi.routes[uwsgi.nroutes].action = NULL; - uwsgi.routes[uwsgi.nroutes].call = (char *) node2->children->content; - if (uwsgi.routes[uwsgi.nroutes].call == NULL) { - uwsgi_log( "no route callable defined. skip.\n"); - continue; - } - - tmp_val = xmlGetProp(node2, (const xmlChar *) "pattern"); - if (!tmp_val) { - uwsgi_log( "no route pattern defined. skip.\n"); - continue; - } - - uwsgi.routes[uwsgi.nroutes].pattern = pcre_compile( (char *) tmp_val, 0, &errstr, &erroff, NULL); - uwsgi.routes[uwsgi.nroutes].pattern_extra = pcre_study(uwsgi.routes[uwsgi.nroutes].pattern, 0, &errstr); - - - pcre_fullinfo(uwsgi.routes[uwsgi.nroutes].pattern, uwsgi.routes[uwsgi.nroutes].pattern_extra, PCRE_INFO_CAPTURECOUNT, &uwsgi.routes[uwsgi.nroutes].args); - - uwsgi_log("route call: %s %d\n", uwsgi.routes[uwsgi.nroutes].call, uwsgi.routes[uwsgi.nroutes].args); - - uwsgi.nroutes++; - } - } - } - - } -#endif } } } /* We cannot free xml resources on the first round (and with routing enabled) as the string pointer must be valid for all the server lifecycle */ -#ifdef UWSGI_ROUTING - if (app_tag && !uwsgi.routing) { -#else if (app_tag) { -#endif xmlFreeDoc (doc); xmlCleanupParser (); }