diff --git a/mojoapp.pl b/mojoapp.pl
new file mode 100644
index 00000000..221fca23
--- /dev/null
+++ b/mojoapp.pl
@@ -0,0 +1,23 @@
+use Mojolicious::Lite;
+
+# /
+get '/' => 'index';
+
+# /*
+get '/:groovy' => sub {
+ my $self = shift;
+ $self->render_text($self->param('groovy'), layout => 'funky');
+};
+
+app->start('psgi');
+__DATA__
+
+@@ index.html.ep
+% layout 'funky';
+Yea baby!
+
+@@ layouts/funky.html.ep
+
+
Funky!
+ <%= content %>
+
diff --git a/plugins.c b/plugins.c
new file mode 100644
index 00000000..7900f1a2
--- /dev/null
+++ b/plugins.c
@@ -0,0 +1,83 @@
+#include "uwsgi.h"
+
+void embed_plugins(struct uwsgi_server *uwsgi) {
+
+ int ret ;
+
+#ifdef UWSGI_EMBED_PLUGIN_PSGI
+ if (uwsgi->plugin_arg_psgi)
+ ret = uwsgi_load_plugin(uwsgi, 5, "psgi_plugin.so", uwsgi->plugin_arg_psgi, 0);
+#endif
+
+#ifdef UWSGI_EMBED_PLUGIN_LUA
+ if (uwsgi->plugin_arg_lua)
+ ret = uwsgi_load_plugin(uwsgi, 6, "lua_plugin.so", uwsgi->plugin_arg_lua, 0);
+#endif
+
+#ifdef UWSGI_EMBED_PLUGIN_RACK
+ if (uwsgi->plugin_arg_rack)
+ ret = uwsgi_load_plugin(uwsgi, 7, "rack_plugin.so", uwsgi->plugin_arg_rack, 0);
+#endif
+
+}
+
+int uwsgi_load_plugin(struct uwsgi_server *uwsgi, int modifier, char *plugin, char *pargs, int absolute) {
+
+ char *plugin_name ;
+
+ void *plugin_handle;
+ int (*plugin_init) (struct uwsgi_server *, char *);
+ int (*plugin_request) (struct uwsgi_server *, struct wsgi_request *);
+ void (*plugin_after_request) (struct uwsgi_server *, struct wsgi_request *);
+
+ if (absolute) {
+ plugin_name = malloc(strlen(plugin) + 1);
+ strcpy(plugin_name, plugin);
+ }
+ else {
+ plugin_name = malloc(strlen(UWSGI_PLUGIN_DIR) + 1 + strlen(plugin) + 1);
+ if (!plugin_name) {
+ uwsgi_error("malloc()");
+ return -1 ;
+ }
+ strcpy(plugin_name, UWSGI_PLUGIN_DIR);
+ strcat(plugin_name, "/");
+ strcat(plugin_name, plugin);
+ }
+ plugin_handle = dlopen(plugin_name, RTLD_NOW | RTLD_GLOBAL);
+ free(plugin_name);
+
+ if (!plugin_handle) {
+ uwsgi_log( "%s\n", dlerror());
+ }
+ else {
+ plugin_init = dlsym(plugin_handle, "uwsgi_init");
+ if (plugin_init) {
+ if ((*plugin_init) (uwsgi, pargs)) {
+ uwsgi_log( "plugin initialization returned error\n");
+ if (dlclose(plugin_handle)) {
+ uwsgi_log( "unable to unload plugin\n");
+ }
+
+ return -1;
+ }
+ }
+
+ plugin_request = dlsym(plugin_handle, "uwsgi_request");
+ if (plugin_request) {
+ uwsgi->shared->hooks[modifier] = plugin_request;
+ plugin_after_request = dlsym(plugin_handle, "uwsgi_after_request");
+ if (plugin_after_request) {
+ uwsgi->shared->after_hooks[modifier] = plugin_after_request;
+ }
+ return 0;
+
+ }
+ else {
+ uwsgi_log( "%s\n", dlerror());
+ }
+ }
+
+
+ return -1;
+}
diff --git a/plugins/example/example_plugin.c b/plugins/example/example_plugin.c
index a3140e8d..3bf1de34 100644
--- a/plugins/example/example_plugin.c
+++ b/plugins/example/example_plugin.c
@@ -1,7 +1,7 @@
#include "../../uwsgi.h"
int uwsgi_init(struct uwsgi_server *uwsgi, char *args){
- fprintf(stderr,"i am the example plugin initialization function with arg: %s\n", args);
+ uwsgi_log("i am the example plugin initialization function with arg: %s\n", args);
return 0;
}
@@ -16,5 +16,5 @@ int uwsgi_request(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req) {
void uwsgi_after_request(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req) {
- fprintf(stderr,"i am the example plugin after request function\n");
+ uwsgi_log("i am the example plugin after request function\n");
}
diff --git a/plugins/psgi/psgi_plugin.c b/plugins/psgi/psgi_plugin.c
index 42e0c427..2ec9f016 100644
--- a/plugins/psgi/psgi_plugin.c
+++ b/plugins/psgi/psgi_plugin.c
@@ -6,6 +6,8 @@
static PerlInterpreter *my_perl;
static SV *psgi_func ;
+extern char **environ;
+
/* statistically ordered */
static struct http_status_codes hsc[] = {
@@ -76,7 +78,6 @@ xs_init(pTHX)
int uwsgi_init(struct uwsgi_server *uwsgi, char *args){
- char *pargs[2] ;
char *psgibuffer ;
int fd ;
@@ -84,20 +85,20 @@ int uwsgi_init(struct uwsgi_server *uwsgi, char *args){
struct http_status_codes *http_sc ;
- char *embedding[] = { "", "-e", "0" };
+ int argc = 4 ;
+ char *embedding[] = { "", args, "-e", "0" };
+ char **argv = embedding ;
+ uwsgi_log("initializing Perl environment: %s\n", args);
- fprintf(stderr,"initializing Perl environment: %s\n", args);
-
+ PERL_SYS_INIT3(&argc, &argv, &environ);
my_perl = perl_alloc();
if (!my_perl) {
- fprintf(stderr,"unable to allocate perl interpreter\n");
+ uwsgi_log("unable to allocate perl interpreter\n");
return -1;
}
- pargs[0] = "" ;
- pargs[1] = args ;
-
+ PL_perl_destruct_level = 1;
perl_construct(my_perl);
// filling http status codes
@@ -106,31 +107,32 @@ int uwsgi_init(struct uwsgi_server *uwsgi, char *args){
}
- perl_parse(my_perl, xs_init, 3, embedding, NULL);
+ PL_origalen = 1;
+ perl_parse(my_perl, xs_init, 4, embedding, NULL);
perl_eval_pv("use IO::Handle;", 0);
fd = open(args, O_RDONLY);
if (fd < 0) {
- perror("open()");
+ uwsgi_error("open()");
goto clear ;
}
if (fstat(fd, &stat_psgi)) {
- perror("fstat()");
+ uwsgi_error("fstat()");
close(fd);
goto clear;
}
psgibuffer = malloc(stat_psgi.st_size);
if (!psgibuffer) {
- perror("malloc()");
+ uwsgi_error("malloc()");
close(fd);
goto clear;
}
if (read(fd, psgibuffer, stat_psgi.st_size) != stat_psgi.st_size) {
- perror("read()");
+ uwsgi_error("read()");
close(fd);
free(psgibuffer);
goto clear;
@@ -139,8 +141,9 @@ int uwsgi_init(struct uwsgi_server *uwsgi, char *args){
psgibuffer[stat_psgi.st_size] = 0 ;
psgi_func = perl_eval_pv(psgibuffer, 0);
+
if (!psgi_func) {
- fprintf(stderr,"unable to find PSGI function entry point.\n");
+ uwsgi_log("unable to find PSGI function entry point.\n");
close(fd);
free(psgibuffer);
goto clear;
@@ -175,13 +178,13 @@ int uwsgi_request(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req) {
/* Standard PSGI request */
if (!wsgi_req->uh.pktsize) {
- fprintf (stderr, "Invalid PSGI request. skip.\n");
+ uwsgi_log("Invalid PSGI request. skip.\n");
return -1;
}
if (uwsgi_parse_vars(uwsgi, wsgi_req)) {
- fprintf(stderr,"Invalid PSGI request. skip.\n");
+ uwsgi_log("Invalid PSGI request. skip.\n");
return -1;
}
@@ -259,7 +262,6 @@ int uwsgi_request(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req) {
// dereference output
response = (AV *) SvRV( sv_2mortal(newSVsv(POPs)) ) ;
-
status_code = av_fetch(response, 0, 0);
wsgi_req->hvec[0].iov_base = "HTTP/1.1 ";
@@ -320,7 +322,7 @@ int uwsgi_request(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req) {
if ( (wsgi_req->response_size = writev(wsgi_req->poll.fd, wsgi_req->hvec, vi+1)) < 0) {
- perror("writev()");
+ uwsgi_error("writev()");
}
@@ -328,8 +330,7 @@ int uwsgi_request(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req) {
io = *hitem;
-
- if (SvTYPE(SvRV(io)) == SVt_PVGV) {
+ if (SvTYPE(SvRV(io)) == SVt_PVGV || SvTYPE(SvRV(io)) == SVt_PVHV) {
for(;;) {
@@ -360,6 +361,9 @@ int uwsgi_request(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req) {
}
}
+ else {
+ uwsgi_log("unsupported response body type: %d\n", SvTYPE(SvRV(io)));
+ }
FREETMPS;
LEAVE;
diff --git a/psgi.py b/psgi.py
index aa249b4b..dd221e60 100644
--- a/psgi.py
+++ b/psgi.py
@@ -1,3 +1,8 @@
import uwsgi
+import sys
-uwsgi.load_plugin(0, "plugins/psgi/psgi_plugin.so", "test.psgi")
+if uwsgi.load_plugin(0, "plugins/psgi/psgi_plugin.so", "mojoapp.pl"):
+ print "PSGI plugin loaded"
+else:
+ print "unable to load PSGI plugin"
+ sys.exit(1)
diff --git a/simple_app.py b/simple_app.py
index ca4cd095..cdab876f 100644
--- a/simple_app.py
+++ b/simple_app.py
@@ -8,6 +8,11 @@ def ciao():
def ciao2():
print "nuovo uwsgi_server"
+#if uwsgi.load_plugin(0, 'plugins/example/example_plugin.so', 'ciao'):
+# print "example plugin loaded"
+#else:
+# print "unable to load example plugin"
+
#uwsgi.event_add(uwsgi.EVENT_FILE, "/tmp", ciao)
#uwsgi.event_add(uwsgi.EVENT_DNSSD, "_uwsgi._tcp", ciao2)
#uwsgi.event_add(uwsgi.EVENT_TIMER, 1000, ciao2)
diff --git a/test.psgi b/test.psgi
index 9698f23d..b5b42d3b 100644
--- a/test.psgi
+++ b/test.psgi
@@ -9,4 +9,3 @@ my $app = sub {
[ "Hello World\r\n", $env->{'REQUEST_URI'} ],
];
};
-
diff --git a/uwsgi.c b/uwsgi.c
index bf470ad6..6c3eddff 100644
--- a/uwsgi.c
+++ b/uwsgi.c
@@ -378,6 +378,9 @@ int main(int argc, char *argv[], char *envp[]) {
{"ugreen", no_argument, &uwsgi.ugreen, 1},
{"ugreen-stacksize", required_argument, 0, LONG_ARGS_UGREEN_PAGES},
#endif
+ UWSGI_PLUGIN_LONGOPT_PSGI
+ UWSGI_PLUGIN_LONGOPT_LUA
+ UWSGI_PLUGIN_LONGOPT_RACK
{"logto", required_argument, 0, LONG_ARGS_LOGTO},
{"grunt", no_argument, &uwsgi.grunt, 1},
{"no-site", no_argument, &Py_NoSiteFlag, 1},
@@ -481,6 +484,10 @@ int main(int argc, char *argv[], char *envp[]) {
}
#endif
+#ifdef UWSGI_DEBUG
+ uwsgi_log("***\n*** You are running a DEBUG version of uWSGI, plese disable DEBUG in uwsgiconfig.py and recompile it ***\n***\n");
+#endif
+
uwsgi_log("compiled with version: %s\n", __VERSION__);
#ifdef __BIG_ENDIAN__
@@ -909,6 +916,10 @@ int main(int argc, char *argv[], char *envp[]) {
uwsgi_log( "done.\n");
+#ifdef UWSGI_EMBED_PLUGINS
+ embed_plugins(&uwsgi);
+#endif
+
#ifdef UWSGI_ERLANG
if (uwsgi.erlang_node) {
uwsgi.erlang_nodes = 1;
@@ -951,7 +962,6 @@ int main(int argc, char *argv[], char *envp[]) {
}
-
#ifndef UNBIT
if (no_server) {
uwsgi_log( "no-server mode requested. Goodbye.\n");
@@ -2214,7 +2224,6 @@ void uwsgi_wsgi_config(char *filename) {
}
}
-
wsgi_dict = PyModule_GetDict(wsgi_module);
if (!wsgi_dict) {
PyErr_Print();
@@ -2783,6 +2792,9 @@ void manage_opt(int i, char *optarg) {
case 'i':
uwsgi.single_interpreter = 1;
break;
+ LONG_ARGS_PLUGIN_EMBED_PSGI
+ LONG_ARGS_PLUGIN_EMBED_LUA
+ LONG_ARGS_PLUGIN_EMBED_RACK
#ifndef UNBIT
case 'h':
fprintf(stdout, "Usage: %s [options...]\n\
diff --git a/uwsgi.h b/uwsgi.h
index f2a243d1..f55474b5 100644
--- a/uwsgi.h
+++ b/uwsgi.h
@@ -33,6 +33,10 @@
#include
#endif
+#ifndef UWSGI_PLUGIN_BASE
+#define UWSGI_PLUGIN_BASE ""
+#endif
+
#include
#include
#include
@@ -556,6 +560,22 @@ struct uwsgi_server {
#endif
int no_orphans;
+
+#ifdef UWSGI_EMBED_PLUGINS
+
+#ifdef UWSGI_EMBED_PLUGIN_PSGI
+ char *plugin_arg_psgi;
+#endif
+
+#ifdef UWSGI_EMBED_PLUGIN_LUA
+ char *plugin_arg_lua;
+#endif
+
+#ifdef UWSGI_EMBED_PLUGIN_RACK
+ char *plugin_arg_rack;
+#endif
+
+#endif
};
struct uwsgi_cluster_node {
@@ -880,3 +900,57 @@ void uwsgi_log(const char *, ...);
#define EVDIS_TYPE_FILE
#define EVDIS_TYPE_DNSSD
#endif
+
+int uwsgi_load_plugin(struct uwsgi_server *, int, char *, char *, int);
+void embed_plugins(struct uwsgi_server *);
+
+
+// PLUGINS
+
+#define UWSGI_PLUGIN_LONGOPT_PSGI
+#define UWSGI_PLUGIN_LONGOPT_LUA
+#define UWSGI_PLUGIN_LONGOPT_RACK
+#define LONG_ARGS_PLUGIN_EMBED_PSGI
+#define LONG_ARGS_PLUGIN_EMBED_LUA
+#define LONG_ARGS_PLUGIN_EMBED_RACK
+
+
+
+#ifdef UWSGI_EMBED_PLUGINS
+
+
+#ifdef UWSGI_EMBED_PLUGIN_PSGI
+
+#undef UWSGI_PLUGIN_LONGOPT_PSGI
+#define UWSGI_PLUGIN_LONGOPT_PSGI {"psgi", required_argument, 0, 30005},
+
+#undef LONG_ARGS_PLUGIN_EMBED_PSGI
+#define LONG_ARGS_PLUGIN_EMBED_PSGI case 30005:\
+ uwsgi.plugin_arg_psgi = optarg;\
+ break;
+#endif
+
+#ifdef UWSGI_EMBED_PLUGIN_LUA
+
+#undef UWSGI_PLUGIN_LONGOPT_LUA
+#define UWSGI_PLUGIN_LONGOPT_LUA {"lua", required_argument, 0, 30006},
+
+#undef LONG_ARGS_PLUGIN_EMBED_LUA
+#define LONG_ARGS_PLUGIN_EMBED_LUA case 30006:\
+ uwsgi.plugin_arg_lua = optarg;\
+ break;
+#endif
+
+#ifdef UWSGI_EMBED_PLUGIN_RACK
+
+#undef UWSGI_PLUGIN_LONGOPT_RACK
+#define UWSGI_PLUGIN_LONGOPT_RACK {"rack", required_argument, 0, 30007},
+
+#undef LONG_ARGS_PLUGIN_EMBED_RACK
+#define LONG_ARGS_PLUGIN_EMBED_RACK case 30007:\
+ uwsgi.plugin_arg_rack = optarg;\
+ break;
+#endif
+
+
+#endif
diff --git a/uwsgi_pymodule.c b/uwsgi_pymodule.c
index 43af9b05..40c01a69 100644
--- a/uwsgi_pymodule.c
+++ b/uwsgi_pymodule.c
@@ -583,55 +583,21 @@ PyObject *py_uwsgi_set_option(PyObject * self, PyObject * args) {
}
PyObject *py_uwsgi_load_plugin(PyObject * self, PyObject * args) {
- uint8_t modifier;
+ int modifier;
char *plugin_name = NULL;
char *pargs = NULL;
- void *plugin_handle;
- int (*plugin_init) (struct uwsgi_server *, char *);
- int (*plugin_request) (struct uwsgi_server *, struct wsgi_request *);
- void (*plugin_after_request) (struct uwsgi_server *, struct wsgi_request *);
-
if (!PyArg_ParseTuple(args, "is|s:load_plugin", &modifier, &plugin_name, &pargs)) {
return NULL;
}
- plugin_handle = dlopen(plugin_name, RTLD_NOW | RTLD_GLOBAL);
- if (!plugin_handle) {
- uwsgi_log( "%s\n", dlerror());
- }
- else {
- plugin_init = dlsym(plugin_handle, "uwsgi_init");
- if (plugin_init) {
- if ((*plugin_init) (&uwsgi, pargs)) {
- uwsgi_log( "plugin initialization returned error\n");
- if (dlclose(plugin_handle)) {
- uwsgi_log( "unable to unload plugin\n");
- }
-
- Py_INCREF(Py_None);
- return Py_None;
- }
- }
-
- plugin_request = dlsym(plugin_handle, "uwsgi_request");
- if (plugin_request) {
- uwsgi.shared->hooks[modifier] = plugin_request;
- plugin_after_request = dlsym(plugin_handle, "uwsgi_after_request");
- if (plugin_after_request) {
- uwsgi.shared->after_hooks[modifier] = plugin_after_request;
- }
- Py_INCREF(Py_True);
- return Py_True;
-
- }
- else {
- uwsgi_log( "%s\n", dlerror());
- }
+ if (uwsgi_load_plugin(&uwsgi, modifier, plugin_name, pargs, 1)) {
+ Py_INCREF(Py_None);
+ return Py_None;
}
- Py_INCREF(Py_None);
- return Py_None;
+ Py_INCREF(Py_True);
+ return Py_True;
}
#ifdef UWSGI_MULTICAST
diff --git a/uwsgiconfig.py b/uwsgiconfig.py
index 26f4c8c9..28368477 100644
--- a/uwsgiconfig.py
+++ b/uwsgiconfig.py
@@ -20,11 +20,15 @@ UGREEN=True
EVDIS=True
WSGI2=True
STACKLESS=False
+#PLUGINS = ['psgi']
PLUGINS = []
USWALLOW=False
UNBIT=False
DEBUG=True
+EMBED_PLUGINS=True
UWSGI_BIN_NAME = 'uwsgi'
+UWSGI_PLUGIN_DIR = '.'
+
# specific compilation flags
# libxml2 or expat
@@ -55,7 +59,7 @@ GCC = os.environ.get('CC', sysconfig.get_config_var('CC'))
if not GCC:
GCC = 'gcc'
-gcc_list = ['utils', 'pyutils', 'protocol', 'socket', 'logging', 'wsgi_handlers', 'wsgi_headers', 'uwsgi_handlers', 'uwsgi']
+gcc_list = ['utils', 'pyutils', 'protocol', 'socket', 'logging', 'wsgi_handlers', 'wsgi_headers', 'uwsgi_handlers', 'plugins', 'uwsgi']
# large file support
try:
@@ -107,9 +111,10 @@ def build_uwsgi(bin_name):
sys.exit(1)
if len(PLUGINS) > 0:
- print("*** uWSGI embedding plugin ***")
+ print("*** uWSGI building plugins ***")
for plugin in PLUGINS:
- print(plugin)
+ print("*** building plugin: %s ***" % plugin)
+ build_plugin("plugins/%s" % plugin)
print("*** uWSGI linking ***")
ldline = "%s -o %s %s %s %s" % (GCC, bin_name, ' '.join(ldflags), ' '.join(map(add_o, gcc_list)), ' '.join(libs))
@@ -267,6 +272,14 @@ def parse_vars():
cflags.append(ERLANG_CFLAGS)
gcc_list.append('erlang')
+ if UWSGI_PLUGIN_DIR is not None:
+ cflags.append("-DUWSGI_PLUGIN_DIR=\\\"%s\\\"" % UWSGI_PLUGIN_DIR)
+
+ if len(PLUGINS) > 0 and EMBED_PLUGINS:
+ cflags.append("-DUWSGI_EMBED_PLUGINS")
+ for plugin in PLUGINS:
+ cflags.append("-DUWSGI_EMBED_PLUGIN_%s" % plugin.upper())
+
if SCTP:
libs.append("-lsctp")
cflags.append("-DUWSGI_SCTP")
@@ -281,6 +294,7 @@ def parse_vars():
if DEBUG:
cflags.append("-DUWSGI_DEBUG")
+ cflags.append("-g")
if UNBIT:
cflags.append("-DUWSGI_UNBIT")
@@ -291,14 +305,24 @@ def build_plugin(path):
sys.path.insert(0, path)
import uwsgiplugin as up
- cflags.append(up.CFLAGS)
- libs.append(up.LDFLAGS)
+ p_cflags = cflags[:]
+ p_libs = libs[:]
+ p_ldflags = ldflags[:]
- cflags.insert(0, '-I.')
+ p_cflags.append(up.CFLAGS)
+ p_libs.append(up.LDFLAGS)
+
+ p_cflags.insert(0, '-I.')
plugin_base = path + '/' + up.NAME + '_plugin'
+ plugin_dest = UWSGI_PLUGIN_DIR + '/' + up.NAME + '_plugin'
- gccline = "%s -fPIC -shared -o %s.so %s %s %s.c %s" % (GCC, plugin_base, ' '.join(cflags), ' '.join(ldflags), plugin_base, ' '.join(libs))
+ shared_flag = '-shared'
+
+ if uwsgi_os == 'Darwin':
+ shared_flag = '-dynamiclib -undefined dynamic_lookup'
+
+ gccline = "%s -fPIC %s -o %s.so %s %s %s.c %s" % (GCC, shared_flag, plugin_dest, ' '.join(p_cflags), ' '.join(p_ldflags), plugin_base, ' '.join(p_libs))
print(gccline)
ret = os.system(gccline)
@@ -306,7 +330,7 @@ def build_plugin(path):
print("*** unable to build %s plugin ***" % up.NAME)
sys.exit(1)
- print("*** %s plugin built and available in %s ***" % (up.NAME, plugin_base + '.so'))
+ print("*** %s plugin built and available in %s ***" % (up.NAME, plugin_dest + '.so'))