From 0ab55fef4660007df66f0ab14668eb0af3aafee6 Mon Sep 17 00:00:00 2001 From: "roberto@debian32" Date: Sun, 4 Sep 2011 21:33:30 +0200 Subject: [PATCH] added support for regexp in UWSGI_APPID --- master_utils.c | 4 ++-- plugins/python/python_plugin.c | 20 +++++++++++++++++--- regexp.c | 26 ++++++++++++++++++++++++-- utils.c | 16 ++++++++++++++++ uwsgi.c | 24 ++++++++++++++++++++++-- uwsgi.h | 16 +++++++++++++++- uwsgiconfig.py | 2 +- 7 files changed, 97 insertions(+), 11 deletions(-) diff --git a/master_utils.c b/master_utils.c index 4ec6d045..81462d63 100644 --- a/master_utils.c +++ b/master_utils.c @@ -60,8 +60,8 @@ int uwsgi_respawn_worker(int wid) { uwsgi.workers[uwsgi.mywid].last_spawn = uwsgi.current_time; uwsgi.workers[uwsgi.mywid].manage_next_request = 1; - // reset the apps count - uwsgi.workers[uwsgi.mywid].apps_cnt = 0; + // reset the apps count with a copy from the master + uwsgi.workers[uwsgi.mywid].apps_cnt = uwsgi.workers[0].apps_cnt; // close the cache server if (uwsgi.cache_server_fd != -1) { diff --git a/plugins/python/python_plugin.c b/plugins/python/python_plugin.c index 5dc98962..87496d68 100644 --- a/plugins/python/python_plugin.c +++ b/plugins/python/python_plugin.c @@ -800,14 +800,28 @@ int uwsgi_python_manage_options(int i, char *optarg) { return 0; } -int uwsgi_python_mount_app(char *mountpoint, char *app) { +int uwsgi_python_mount_app(char *mountpoint, char *app, int regexp) { + int id, i; uwsgi.wsgi_req->appid = mountpoint; uwsgi.wsgi_req->appid_len = strlen(mountpoint); if (uwsgi.single_interpreter) { - return init_uwsgi_app(LOADER_MOUNT, app, uwsgi.wsgi_req, up.main_thread, PYTHON_APP_TYPE_WSGI); + id = init_uwsgi_app(LOADER_MOUNT, app, uwsgi.wsgi_req, up.main_thread, PYTHON_APP_TYPE_WSGI); } - return init_uwsgi_app(LOADER_MOUNT, app, uwsgi.wsgi_req, NULL, PYTHON_APP_TYPE_WSGI); + id = init_uwsgi_app(LOADER_MOUNT, app, uwsgi.wsgi_req, NULL, PYTHON_APP_TYPE_WSGI); + + if (regexp && id != -1) { + struct uwsgi_app *ua = &uwsgi_apps[id]; + uwsgi_regexp_build(mountpoint, &ua->pattern, &ua->pattern_extra); + if (uwsgi.mywid == 0) { + for(i=1;i<=uwsgi.numproc;i++) { + uwsgi.workers[i].apps[id].pattern = ua->pattern; + uwsgi.workers[i].apps[id].pattern_extra = ua->pattern_extra; + } + } + } + + return id; } diff --git a/regexp.c b/regexp.c index 228fbd2f..8d10c111 100644 --- a/regexp.c +++ b/regexp.c @@ -1,8 +1,30 @@ #ifdef UWSGI_PCRE - #include "uwsgi.h" -#include +void uwsgi_regexp_build(char *re, pcre **pattern, pcre_extra **pattern_extra) { + + const char *errstr; + int erroff; + + *pattern = pcre_compile( (const char *)re, 0, &errstr, &erroff, NULL); + if (!*pattern) { + uwsgi_log("pcre error: %s at offset %d\n", errstr, erroff); + exit(1); + } + + *pattern_extra = (pcre_extra *) pcre_study((const pcre*)*pattern, 0, &errstr); + if (!*pattern_extra) { + uwsgi_log("pcre (study) error: %s\n", errstr); + exit(1); + } + + +} + +int uwsgi_regexp_match(pcre *pattern, pcre_extra *pattern_extra, char *subject, int length) { + + return pcre_exec((const pcre*)pattern, (const pcre_extra *)pattern_extra, subject, length, 0, 0, NULL, 0 ); +} /* diff --git a/utils.c b/utils.c index a94bd72c..744424bb 100644 --- a/utils.c +++ b/utils.c @@ -1348,15 +1348,31 @@ int uwsgi_get_app_id(char *app_name, int app_name_len, int modifier1) { int i; struct stat st; + int found; for (i = 0; i < uwsgi_apps_cnt; i++) { + // reset check + found = 0; #ifdef UWSGI_DEBUG uwsgi_log("searching for %.*s in %.*s %p\n", app_name_len, app_name, uwsgi_apps[i].mountpoint_len, uwsgi_apps[i].mountpoint, uwsgi_apps[i].callable); #endif if (!uwsgi_apps[i].callable) { continue; } + +#ifdef UWSGI_PCRE + if (uwsgi_apps[i].pattern) { + if (uwsgi_regexp_match(uwsgi_apps[i].pattern, uwsgi_apps[i].pattern_extra, app_name, app_name_len) >= 0) { + found = 1; + } + } + else +#endif if (!uwsgi_strncmp(uwsgi_apps[i].mountpoint, uwsgi_apps[i].mountpoint_len, app_name, app_name_len)) { + found = 1; + } + + if (found) { if (uwsgi_apps[i].touch_reload) { if (!stat(uwsgi_apps[i].touch_reload, &st)) { if (st.st_mtime != uwsgi_apps[i].touch_reload_mtime) { diff --git a/uwsgi.c b/uwsgi.c index 0ea752ef..0d6bc448 100644 --- a/uwsgi.c +++ b/uwsgi.c @@ -209,6 +209,9 @@ static struct option long_base_options[] = { {"idle", required_argument, 0, LONG_ARGS_IDLE}, {"die-on-idle", no_argument, &uwsgi.die_on_idle, 1}, {"mount", required_argument, 0, LONG_ARGS_MOUNT}, +#ifdef UWSGI_PCRE + {"regexp-mount", required_argument, 0, LONG_ARGS_REGEXP_MOUNT}, +#endif {"grunt", no_argument, &uwsgi.grunt, 1}, {"threads", required_argument, 0, LONG_ARGS_THREADS}, {"threads-stacksize", required_argument, 0, LONG_ARGS_THREADS_STACKSIZE}, @@ -3236,6 +3239,17 @@ static int manage_base_opt(int i, char *optarg) { uwsgi_log("you can specify at most %d --mount options\n", MAX_APPS); } return 1; +#ifdef UWSGI_PCRE + case LONG_ARGS_REGEXP_MOUNT: + if (uwsgi.mounts_cnt < MAX_APPS) { + uwsgi.mounts[uwsgi.mounts_cnt] = uwsgi_concat2("regexp://", optarg); + uwsgi.mounts_cnt++; + } + else { + uwsgi_log("you can specify at most %d --regexp-mount options\n", MAX_APPS); + } + return 1; +#endif #ifdef UWSGI_SPOOLER case 'Q': uwsgi.spool_dir = uwsgi_malloc(PATH_MAX); @@ -4187,8 +4201,14 @@ void uwsgi_init_all_apps() { uwsgi_log("mounting %s on %s\n", what, uwsgi.mounts[i]); for (j = 0; j < 0xFF; j++) { if (uwsgi.p[j]->mount_app) { - if (uwsgi.p[j]->mount_app(uwsgi.mounts[i], what) != -1) - break; + if (!uwsgi_startswith(uwsgi.mounts[i], "regexp://", 9)) { + if (uwsgi.p[j]->mount_app(uwsgi.mounts[i]+9, what, 1) != -1) + break; + } + else { + if (uwsgi.p[j]->mount_app(uwsgi.mounts[i], what, 0) != -1) + break; + } } } what--; diff --git a/uwsgi.h b/uwsgi.h index 522103af..3148285f 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -490,6 +490,7 @@ struct uwsgi_opt { #define LONG_ARGS_EMPEROR_THROTTLE 17135 #define LONG_ARGS_STOP 17136 #define LONG_ARGS_RELOAD 17137 +#define LONG_ARGS_REGEXP_MOUNT 17138 #define UWSGI_OK 0 @@ -609,7 +610,7 @@ struct uwsgi_plugin { void (*init_apps) (void); void (*fixup) (void); void (*master_fixup) (int); - int (*mount_app) (char *, char *); + int (*mount_app) (char *, char *, int); int (*manage_udp) (char *, int, char *, int); int (*manage_xml) (char *, char *); void (*suspend) (struct wsgi_request *); @@ -635,6 +636,13 @@ struct uwsgi_plugin { }; +#ifdef UWSGI_PCRE +#include +void uwsgi_regexp_build(char *re, pcre **pattern, pcre_extra **pattern_extra); +int uwsgi_regexp_match(pcre *pattern, pcre_extra *pattern_extra, char *subject, int length); +#endif + + struct uwsgi_app { @@ -643,6 +651,11 @@ struct uwsgi_app { char *mountpoint; int mountpoint_len; +#ifdef UWSGI_PCRE + pcre *pattern; + pcre_extra *pattern_extra; +#endif + void *interpreter; void *callable; @@ -2161,6 +2174,7 @@ char *uwsgi_str_contains(char *, int, char); int uwsgi_simple_parse_vars(struct wsgi_request *, char *, char *); + #ifdef UWSGI_AS_SHARED_LIBRARY int uwsgi_init(int, char **, char **); #endif diff --git a/uwsgiconfig.py b/uwsgiconfig.py index a06252cc..1d37682f 100644 --- a/uwsgiconfig.py +++ b/uwsgiconfig.py @@ -463,7 +463,7 @@ class uConf(object): self.cflags.append("-DUWSGI_UDP") # re-enable after pcre fix - if self.get('pcreOFF'): + if self.get('pcre'): if self.get('pcre') == 'auto': pcreconf = spcall('pcre-config --libs') if pcreconf: