diff --git a/ChangeLog b/ChangeLog index 08a6f197..e1a6a50e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +*** february 2010 *** + * Maintenance release * + +- better support for NetBSD +- threading fix for FreeBSD +- sendfile portability fixes +- new makefiles +- example app for testing static file serving +- fixes for ROCK_SOLID mode + *** january 2010 *** - Integrated Spooler diff --git a/Makefile b/Makefile index c4c325b6..93708602 100644 --- a/Makefile +++ b/Makefile @@ -8,6 +8,8 @@ XML_LIBS=`xml2-config --libs` CFLAGS=$(PYTHON_CFLAGS) $(XML_CFLAGS) LD_FLAGS=$(PYTHON_LIBS) $(XML_LIBS) +UWSGI_BASEFLAGS=`python2.5 ucheck.py` + PROGRAM=uwsgi include base.mk diff --git a/Makefile.Py24 b/Makefile.Py24 index 4d79918e..c72a57d9 100644 --- a/Makefile.Py24 +++ b/Makefile.Py24 @@ -8,6 +8,8 @@ XML_LIBS=`xml2-config --libs` CFLAGS=$(PYTHON_CFLAGS) $(XML_CFLAGS) LD_FLAGS=$(PYTHON_LIBS) $(XML_LIBS) +UWSGI_BASEFLAGS=`python2.4 ucheck.py` + PROGRAM=uwsgi24 include base.mk diff --git a/Makefile.Py26 b/Makefile.Py26 index ff1feba0..60f8bc26 100644 --- a/Makefile.Py26 +++ b/Makefile.Py26 @@ -8,6 +8,8 @@ XML_LIBS=`xml2-config --libs` CFLAGS=$(PYTHON_CFLAGS) $(XML_CFLAGS) LD_FLAGS=$(PYTHON_LIBS) $(XML_LIBS) +UWSGI_BASEFLAGS=`python2.6 ucheck.py` + PROGRAM=uwsgi26 include base.mk diff --git a/Makefile.Py30 b/Makefile.Py30 index 88b217a2..70c98a77 100644 --- a/Makefile.Py30 +++ b/Makefile.Py30 @@ -8,6 +8,8 @@ XML_LIBS=`xml2-config --libs` CFLAGS=$(PYTHON_CFLAGS) $(XML_CFLAGS) LD_FLAGS=$(PYTHON_LIBS) $(XML_LIBS) +UWSGI_BASEFLAGS=`python3.0 ucheck.py` + PROGRAM=uwsgi30 include base.mk diff --git a/Makefile.Py31 b/Makefile.Py31 index 5aad3aa3..3028c6b7 100644 --- a/Makefile.Py31 +++ b/Makefile.Py31 @@ -8,6 +8,8 @@ XML_LIBS=`xml2-config --libs` CFLAGS=$(PYTHON_CFLAGS) $(XML_CFLAGS) LD_FLAGS=$(PYTHON_LIBS) $(XML_LIBS) +UWSGI_BASEFLAGS=`python3.1 ucheck.py` + PROGRAM=uwsgi31 include base.mk diff --git a/base.mk b/base.mk index 34ffb89f..dab8d98f 100644 --- a/base.mk +++ b/base.mk @@ -14,7 +14,7 @@ LD_FLAGS := $(LD_FLAGS) $(UWSGI_LD_FLAGS) all: clean uwsgi uwsgi: utils.o protocol.o socket.o pymodule.o spooler.o logging.o snmp.o wsgihandlers.o basehandlers.o main.o - $(CC) $(LD_FLAGS) utils.o protocol.o socket.o spooler.o logging.o snmp.o pymodule.o wsgihandlers.o basehandlers.o main.o -o $(PROGRAM) + $(CC) $(LD_FLAGS) $(UWSGI_BASEFLAGS) -lpthread utils.o protocol.o socket.o spooler.o logging.o snmp.o pymodule.o wsgihandlers.o basehandlers.o main.o -o $(PROGRAM) utils.o: utils.c $(CC) -c $(CFLAGS) utils.c diff --git a/logging.c b/logging.c index cd3555b8..4e3cb7c7 100644 --- a/logging.c +++ b/logging.c @@ -4,7 +4,6 @@ extern struct uwsgi_server uwsgi; void log_request(struct wsgi_request *wsgi_req) { char *time_request ; - struct timeval end_request ; time_t microseconds, microseconds2; @@ -27,20 +26,19 @@ void log_request(struct wsgi_request *wsgi_req) { } } via = msg2 ; + if (wsgi_req->sendfile_fd > -1) { via = msg1 ; } #endif time_request = ctime( (const time_t *) &wsgi_req->start_of_request.tv_sec); - gettimeofday(&end_request, NULL) ; - microseconds = end_request.tv_sec*1000000+end_request.tv_usec ; + microseconds = wsgi_req->end_of_request.tv_sec*1000000+wsgi_req->end_of_request.tv_usec ; microseconds2 = wsgi_req->start_of_request.tv_sec*1000000+wsgi_req->start_of_request.tv_usec ; #ifndef ROCK_SOLID - if (uwsgi.options[UWSGI_OPTION_MEMORY_DEBUG] == 1) { - get_memusage(); + if (uwsgi.options[UWSGI_OPTION_MEMORY_DEBUG] == 1) { #ifndef UNBIT if (uwsgi.synclog) { snprintf(uwsgi.sync_page, uwsgi.page_size, "{address space usage: %lld bytes/%lluMB} {rss usage: %llu bytes/%lluMB} ", uwsgi.workers[uwsgi.mywid].vsz_size, uwsgi.workers[uwsgi.mywid].vsz_size/1024/1024, uwsgi.workers[uwsgi.mywid].rss_size, uwsgi.workers[uwsgi.mywid].rss_size/1024/1024) ; @@ -55,8 +53,6 @@ void log_request(struct wsgi_request *wsgi_req) { } #endif - uwsgi.workers[uwsgi.mywid].running_time += (double) (( (double)microseconds-(double)microseconds2)/ (double)1000.0) ; - #ifdef ROCK_SOLID fprintf(stderr, "[pid: %d|req: %llu] %.*s (%.*s) {%d vars in %d bytes} [%.*s] %.*s %.*s => generated %d bytes in %ld msecs (%.*s %d) %d headers in %d bytes\n", uwsgi.mypid, uwsgi.workers[0].requests, wsgi_req->remote_addr_len, wsgi_req->remote_addr, @@ -81,8 +77,7 @@ void get_memusage() { #ifdef UNBIT uwsgi.workers[uwsgi.mywid].vsz_size = syscall(356); -#else -#ifdef __linux__ +#elif defined(__linux__) FILE *procfile; int i; procfile = fopen("/proc/self/stat","r"); @@ -94,9 +89,8 @@ void get_memusage() { fclose(procfile); } uwsgi.workers[uwsgi.mywid].rss_size = uwsgi.workers[uwsgi.mywid].rss_size*uwsgi.page_size; -#endif -#ifdef __APPLE__ - /* darwin documentation says that the value are in pages, bot they are bytes !!! */ +#elif defined( __APPLE__) + /* darwin documentation says that the value are in pages, but they are bytes !!! */ struct task_basic_info t_info; mach_msg_type_number_t t_size = sizeof(struct task_basic_info); @@ -104,8 +98,8 @@ void get_memusage() { uwsgi.workers[uwsgi.mywid].rss_size = t_info.resident_size; uwsgi.workers[uwsgi.mywid].vsz_size = t_info.virtual_size; } +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) -#endif #endif } #endif diff --git a/logo_uWSGI.png b/logo_uWSGI.png new file mode 100644 index 00000000..1455d2bf Binary files /dev/null and b/logo_uWSGI.png differ diff --git a/plugins/example/example_plugin.c b/plugins/example/example_plugin.c index e43bd4de..e58165a2 100644 --- a/plugins/example/example_plugin.c +++ b/plugins/example/example_plugin.c @@ -1,7 +1,9 @@ #include "../../uwsgi.h" -void uwsgi_init(struct uwsgi_server *uwsgi){ - fprintf(stderr,"i am the example plugin initialization function\n"); +/* gcc `python2.5-config --cflags` -o example_plugin.so -fPIC -shared example_plugin.c */ + +void uwsgi_init(struct uwsgi_server *uwsgi, char *args){ + fprintf(stderr,"i am the example plugin initialization function with arg: %s\n", args); } int uwsgi_request(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req, char *buffer) { diff --git a/plugins/lua/lua_plugin.c b/plugins/lua/lua_plugin.c new file mode 100644 index 00000000..88351d86 --- /dev/null +++ b/plugins/lua/lua_plugin.c @@ -0,0 +1,241 @@ +#include "../../uwsgi.h" + +/* gcc -fPIC -shared -o lua_plugin.so `python2.5-config --cflags` -I /usr/include/lua5.1 -llua5.1 lua_plugin.c */ + +#include +#include + + +static struct uwsgi_lua { + struct lua_State *L ; + struct uwsgi_server *uwsgi; +} ulua; + +static void *uwsgi_lua_alloc(void *ud, void *ptr, size_t osize, size_t nsize) { + if(nsize == 0) { + free(ptr); + return NULL; + } + + return realloc(ptr, nsize); +} + +static const char *uwsgi_read_lua(lua_State *L, void *data, size_t *size) { + + int fd = *(int *)data; + static char buf[4096]; + + *size = read(fd, buf, 4096); + + if (size == 0) { + return NULL; + } + + return buf; +} + +static int uwsgi_lua_input(lua_State *L) { + + int n = lua_gettop(L); + + static char *buf = "" ; + + fprintf(stderr,"richiesti %d bytes\n", n); + + //sum = read(ulua.uwsgi->poll.fd,); + + lua_pushlstring(L, buf, 0); + + return 1; +} + +void uwsgi_init(struct uwsgi_server *uwsgi, char *args){ + + int fd, i; + + fprintf(stderr,"Initializing Lua environment...\n"); + + + + + ulua.L = lua_newstate(uwsgi_lua_alloc, NULL); + + luaL_openlibs(ulua.L); + + + fd = open(args, O_RDONLY) ; + if (fd < 0) { + perror("open()"); + return ; + } + + + i = lua_load(ulua.L, uwsgi_read_lua, &fd, "uwsgi"); + + fprintf(stderr,"lua_load: %d\n" ,i); + + // use a pcall + lua_call(ulua.L, 0, 1); + + fprintf(stderr,"%s\n", lua_typename(ulua.L, lua_type(ulua.L, -1))); + + // ok the lua engine is ready + return ; + + +} + +int uwsgi_request(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req, char *buffer) { + + char *ptrbuf; + char *bufferend; + uint16_t strsize = 0; + int i; + const char *http ; + size_t slen ; + + /* Standard WSAPI request */ + if (!wsgi_req->size) { + fprintf (stderr, "Invalid WSAPI request. skip.\n"); + return -1; + } + + ptrbuf = buffer; + bufferend = ptrbuf + wsgi_req->size; + + /* set an HTTP 500 status as default */ + wsgi_req->status = 500; + + while (ptrbuf < bufferend) { + if (ptrbuf + 2 < bufferend) { + memcpy (&strsize, ptrbuf, 2); +#ifdef __BIG_ENDIAN__ + strsize = uwsgi_swap16 (strsize); +#endif + ptrbuf += 2; + if (ptrbuf + strsize < bufferend) { + // var key + uwsgi->hvec[wsgi_req->var_cnt].iov_base = ptrbuf; + uwsgi->hvec[wsgi_req->var_cnt].iov_len = strsize; + ptrbuf += strsize; + if (ptrbuf + 2 < bufferend) { + memcpy (&strsize, ptrbuf, 2); +#ifdef __BIG_ENDIAN__ + strsize = uwsgi_swap16 (strsize); +#endif + ptrbuf += 2; + if (ptrbuf + strsize <= bufferend) { + if (wsgi_req->var_cnt < uwsgi->vec_size - (4 + 1)) { + wsgi_req->var_cnt++; + } + else { + fprintf (stderr, "max vec size reached. skip this header.\n"); + break; + } + // var value + uwsgi->hvec[wsgi_req->var_cnt].iov_base = ptrbuf; + uwsgi->hvec[wsgi_req->var_cnt].iov_len = strsize; + if (wsgi_req->var_cnt < uwsgi->vec_size - (4 + 1)) { + wsgi_req->var_cnt++; + } + else { + fprintf (stderr, "max vec size reached. skip this header.\n"); + break; + } + ptrbuf += strsize; + } + else { + break; + } + } + else { + break; + } + } + } + else { + break; + } + } + + // put function in the stack + lua_pushvalue(ulua.L, -1); + lua_getfield(ulua.L, -1, "run"); + + // put cgi vars in the stack + lua_newtable(ulua.L); + lua_pushstring(ulua.L, ""); + lua_setfield(ulua.L, -2, "CONTENT_TYPE"); + for(i=0;ivar_cnt;i++) { + lua_pushlstring(ulua.L, (char *)uwsgi->hvec[i+1].iov_base, uwsgi->hvec[i+1].iov_len); + // transform it in a valid c string TODO this is ugly + ptrbuf = uwsgi->hvec[i].iov_base+uwsgi->hvec[i].iov_len ; + *ptrbuf = 0 ; + lua_setfield(ulua.L, -2, (char *)uwsgi->hvec[i].iov_base); + //fprintf(stderr,"%.*s=%.*s\n", uwsgi->hvec[i].iov_len, uwsgi->hvec[i].iov_base, uwsgi->hvec[i+1].iov_len, uwsgi->hvec[i+1].iov_base); + i++; + } + + + // put "input" table + lua_newtable(ulua.L); + lua_pushcfunction(ulua.L, uwsgi_lua_input); + lua_setfield(ulua.L, -2, "read"); + lua_setfield(ulua.L, -2, "input"); + + + // call function + i = lua_pcall(ulua.L, 1, 3, 0); + if (i != 0) { + fprintf(stderr,"%s\n", lua_tostring(ulua.L, -1)); + lua_pop(ulua.L, 1); + return -1 ; + } + + fprintf(stderr,"%d %s %s %s\n",i,lua_typename(ulua.L, lua_type(ulua.L, -3)), lua_typename(ulua.L, lua_type(ulua.L, -2)) , lua_typename(ulua.L, lua_type(ulua.L, -1))); + + // send status + if (lua_type(ulua.L, -3) == LUA_TSTRING || lua_type(ulua.L, -3) == LUA_TNUMBER) { + http = lua_tolstring(ulua.L, -3, &slen); + write(uwsgi->poll.fd, "HTTP/1.1 ", 9); + write(uwsgi->poll.fd, http, slen); + write(uwsgi->poll.fd, "\r\n", 2); + } + + // send headers + + lua_pushnil(ulua.L); + while(lua_next(ulua.L, -3) != 0) { + http = lua_tolstring(ulua.L, -2, &slen); + write(uwsgi->poll.fd, http, slen); + write(uwsgi->poll.fd, ": ", 2); + http = lua_tolstring(ulua.L, -1, &slen); + write(uwsgi->poll.fd, http, slen); + write(uwsgi->poll.fd, "\r\n", 2); + lua_pop(ulua.L, 1); + } + + write(uwsgi->poll.fd, "\r\n", 2); + + // send body with coroutine + lua_pushvalue(ulua.L, -1); + + while ( (i = lua_pcall(ulua.L, 0, 1, 0)) == 0) { + if (lua_type(ulua.L, -1) == LUA_TSTRING) { + http = lua_tolstring(ulua.L, -1, &slen); + write(uwsgi->poll.fd, http, slen); + //fprintf(stderr,"%.*s\n", slen, http); + } + lua_pop(ulua.L, 1); + lua_pushvalue(ulua.L, -1); + } + + lua_pop(ulua.L, 4); + + return 0; + +} + +void uwsgi_after_request(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req, char *buffer) { + return; +} diff --git a/staticfile.py b/staticfile.py new file mode 100644 index 00000000..f8ab2f6f --- /dev/null +++ b/staticfile.py @@ -0,0 +1,4 @@ +def application(environ, start_response): + start_response('200 OK', [('Content-Type', 'image/png')]) + fd = open('logo_uWSGI.png','r') + return environ['wsgi.file_wrapper'](fd, 4096) diff --git a/testapp.py b/testapp.py index bfad7078..1d834065 100644 --- a/testapp.py +++ b/testapp.py @@ -10,7 +10,7 @@ os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings' #import django.core.handlers.wsgi -uwsgi.load_plugin(0, "plugins/rack/rack_plugin.so") +uwsgi.load_plugin(0, "plugins/example/example_plugin.so", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa") from threading import Thread diff --git a/uwsgi.c b/uwsgi.c index 9ca444bc..1b4a9472 100644 --- a/uwsgi.c +++ b/uwsgi.c @@ -207,31 +207,6 @@ void internal_server_error (int fd, char *message) { wsgi_req.response_size += write (fd, message, strlen (message)); } -#ifndef ROCK_SOLID -PyObject *py_uwsgi_sendfile (PyObject * self, PyObject * args) { - - //PyObject *zero ; - - uwsgi.py_sendfile = PyTuple_GetItem (args, 0); - -#ifdef PYTHREE - if ((wsgi_req.sendfile_fd = PyObject_AsFileDescriptor (uwsgi.py_sendfile)) >= 0) { - Py_INCREF (uwsgi.py_sendfile); - } -#else - if (PyFile_Check (uwsgi.py_sendfile)) { - //zero = PyFile_Name(uwsgi.py_sendfile) ; - //fprintf(stderr,"->serving %s as static file...", PyString_AsString(zero)); - wsgi_req.sendfile_fd = PyObject_AsFileDescriptor (uwsgi.py_sendfile); - Py_INCREF (uwsgi.py_sendfile); - } -#endif - - - return PyTuple_New (0); -} -#endif - PyObject *py_uwsgi_write (PyObject * self, PyObject * args) { PyObject *data; char *content; @@ -450,6 +425,30 @@ PyObject *py_uwsgi_spit (PyObject * self, PyObject * args) { return Py_None; } +#ifndef ROCK_SOLID +PyObject *py_uwsgi_sendfile (PyObject * self, PyObject * args) { + + //PyObject *zero ; + + uwsgi.py_sendfile = PyTuple_GetItem (args, 0); + +#ifdef PYTHREE + if ((wsgi_req.sendfile_fd = PyObject_AsFileDescriptor (uwsgi.py_sendfile)) >= 0) { + Py_INCREF (uwsgi.py_sendfile); + } +#else + if (PyFile_Check (uwsgi.py_sendfile)) { + //zero = PyFile_Name(uwsgi.py_sendfile) ; + //fprintf(stderr,"->serving %s as static file...", PyString_AsString(zero)); + wsgi_req.sendfile_fd = PyObject_AsFileDescriptor (uwsgi.py_sendfile); + Py_INCREF (uwsgi.py_sendfile); + } +#endif + + + return PyTuple_New (0); +} +#endif PyMethodDef uwsgi_spit_method[] = { {"uwsgi_spit", py_uwsgi_spit, METH_VARARGS, ""} }; @@ -474,6 +473,15 @@ int single_app_mode = 0; char *spool_dir = NULL; +static int unconfigured_hook(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req, char *buffer) { + fprintf(stderr, "-- unavailable modifier requested: %d --\n", wsgi_req->modifier); + return -1; +} + +static void unconfigured_after_hook(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req, char *buffer) { + return; +} + int main (int argc, char *argv[], char *envp[]) { struct timeval check_interval = {.tv_sec = 1,.tv_usec = 0 }; @@ -549,8 +557,8 @@ int main (int argc, char *argv[], char *envp[]) { signal (SIGTERM, SIG_IGN); for(i=0;i<0xFF;i++) { - uwsgi.hooks[i] = NULL; - uwsgi.after_hooks[i] = NULL; + uwsgi.hooks[i] = unconfigured_hook; + uwsgi.after_hooks[i] = unconfigured_after_hook; } memset (&uwsgi, 0, sizeof (struct uwsgi_server)); @@ -1802,30 +1810,36 @@ int main (int argc, char *argv[], char *envp[]) { } #endif - ret = -1 ; + // enter harakiri mode if (uwsgi.options[UWSGI_OPTION_HARAKIRI] > 0) { set_harakiri(uwsgi.options[UWSGI_OPTION_HARAKIRI]); } - if (uwsgi.hooks[wsgi_req.modifier] != NULL) { - ret = (*uwsgi.hooks[wsgi_req.modifier])(&uwsgi, &wsgi_req, buffer); - if (!ret) { - if (uwsgi.after_hooks[wsgi_req.modifier] != NULL) { - ret = (*uwsgi.after_hooks[wsgi_req.modifier])(&uwsgi, &wsgi_req, buffer); - } - } - } - else { - fprintf(stderr,"unknown uwsgi request type received: %d\n", wsgi_req.modifier); - } + + ret = (*uwsgi.hooks[wsgi_req.modifier])(&uwsgi, &wsgi_req, buffer); + // calculate execution time + gettimeofday(&wsgi_req.end_of_request, NULL) ; + uwsgi.workers[uwsgi.mywid].running_time += (double) (( (double)(wsgi_req.end_of_request.tv_sec*1000000+wsgi_req.end_of_request.tv_usec)-(double)(wsgi_req.start_of_request.tv_sec*1000000+wsgi_req.start_of_request.tv_usec))/ (double)1000.0) ; + +#ifndef ROCK_SOLID + // get memory usage + if (uwsgi.options[UWSGI_OPTION_MEMORY_DEBUG] == 1) + get_memusage(); +#endif + + // close the connection with the webserver + close(uwsgi.poll.fd); + uwsgi.workers[0].requests++; + uwsgi.workers[uwsgi.mywid].requests++; + + if (!ret) + (*uwsgi.after_hooks[wsgi_req.modifier])(&uwsgi, &wsgi_req, buffer); + // leave harakiri mode if (uwsgi.workers[uwsgi.mywid].harakiri > 0) { set_harakiri(0); } - close(uwsgi.poll.fd); - uwsgi.workers[0].requests++; - uwsgi.workers[uwsgi.mywid].requests++; // defunct process reaper if (uwsgi.options[UWSGI_OPTION_REAPER] == 1) { @@ -1839,7 +1853,6 @@ int main (int argc, char *argv[], char *envp[]) { } #endif - if (uwsgi.options[UWSGI_OPTION_MAX_REQUESTS] > 0 && uwsgi.workers[uwsgi.mywid].requests >= uwsgi.options[UWSGI_OPTION_MAX_REQUESTS]) { goodbye_cruel_world (); } @@ -1855,13 +1868,6 @@ int main (int argc, char *argv[], char *envp[]) { } #endif -/* - } - else { - fprintf (stderr, "Unsupported uwsgi modifier requested: %d\n", wsgi_req.modifier); - } -*/ - } if (uwsgi.workers[uwsgi.mywid].manage_next_request == 0) { diff --git a/uwsgi.h b/uwsgi.h index 623e15e0..fdb588c0 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -188,6 +188,7 @@ struct __attribute__ ((packed)) wsgi_request { int app_id; #endif struct timeval start_of_request; + struct timeval end_of_request; char *uri; unsigned short uri_len; char *remote_addr; @@ -240,7 +241,7 @@ struct __attribute__ ((packed)) wsgi_request { #endif int (*hooks[0xFF])(struct uwsgi_server *, struct wsgi_request*, char*) ; - int (*after_hooks[0xFF])(struct uwsgi_server *, struct wsgi_request*, char*) ; + void (*after_hooks[0xFF])(struct uwsgi_server *, struct wsgi_request*, char*) ; // iovec struct iovec *hvec; @@ -428,7 +429,7 @@ struct __attribute__ ((packed)) wsgi_request { /* included HOOKS */ int uwsgi_request_wsgi(struct uwsgi_server*, struct wsgi_request*, char *); -int uwsgi_after_request_wsgi(struct uwsgi_server*, struct wsgi_request*, char *); +void uwsgi_after_request_wsgi(struct uwsgi_server*, struct wsgi_request*, char *); int uwsgi_request_admin(struct uwsgi_server*, struct wsgi_request*, char *); int uwsgi_request_spooler(struct uwsgi_server*, struct wsgi_request*, char *); diff --git a/uwsgi_pymodule.c b/uwsgi_pymodule.c index 328f41f2..2e535bb7 100644 --- a/uwsgi_pymodule.c +++ b/uwsgi_pymodule.c @@ -549,13 +549,14 @@ PyObject *py_uwsgi_set_option(PyObject *self, PyObject *args) { PyObject *py_uwsgi_load_plugin(PyObject *self, PyObject *args) { uint8_t modifier ; char *plugin_name = NULL ; + char *pargs = NULL ; void *plugin_handle; - void (*plugin_init)(struct uwsgi_server *); + void (*plugin_init)(struct uwsgi_server *, char *); int (*plugin_request)(struct uwsgi_server *, struct wsgi_request*, char*) ; - int (*plugin_after_request)(struct uwsgi_server *, struct wsgi_request*, char*) ; + void (*plugin_after_request)(struct uwsgi_server *, struct wsgi_request*, char*) ; - if (!PyArg_ParseTuple(args, "is:load_plugin", &modifier, &plugin_name)) { + if (!PyArg_ParseTuple(args, "is|s:load_plugin", &modifier, &plugin_name, &pargs)) { return NULL ; } @@ -567,7 +568,7 @@ PyObject *py_uwsgi_load_plugin(PyObject *self, PyObject *args) { else { plugin_init = dlsym(plugin_handle, "uwsgi_init"); if (plugin_init) { - (*plugin_init)(&uwsgi); + (*plugin_init)(&uwsgi, pargs); } plugin_request = dlsym(plugin_handle, "uwsgi_request"); diff --git a/wsgi_handlers.c b/wsgi_handlers.c index 1ad72b22..4b33df8e 100644 --- a/wsgi_handlers.c +++ b/wsgi_handlers.c @@ -1,5 +1,7 @@ #include "uwsgi.h" +static int uwsgi_sendfile(struct uwsgi_server *, int , int ) ; + int uwsgi_request_wsgi (struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req, char *buffer) { char *ptrbuf; @@ -18,10 +20,7 @@ int uwsgi_request_wsgi (struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_re PyObject *wsgi_result, *wsgi_chunks, *wchunk; - int rlen; - /* Standard WSGI request */ - if (!wsgi_req->size) { fprintf (stderr, "Invalid WSGI request. skip.\n"); return -1; @@ -231,29 +230,6 @@ int uwsgi_request_wsgi (struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_re } - - /* max 1 minute before harakiri */ - if (uwsgi->options[UWSGI_OPTION_HARAKIRI] > 0) { -#ifdef UNBIT - if (wsgi_req->modifier != 0) { - switch (wsgi_req->modifier) { - case UWSGI_MODIFIER_HT_S: - set_harakiri (wsgi_req->modifier_arg); - case UWSGI_MODIFIER_HT_M: - set_harakiri (wsgi_req->modifier_arg * 60); - case UWSGI_MODIFIER_HT_H: - set_harakiri (wsgi_req->modifier_arg * 3600); - } - } - else { -#endif - set_harakiri (uwsgi->options[UWSGI_OPTION_HARAKIRI]); -#ifdef UNBIT - } -#endif - } - - for (i = 0; i < wsgi_req->var_cnt; i += 2) { /*fprintf(stderr,"%.*s: %.*s\n", uwsgi->hvec[i].iov_len, uwsgi->hvec[i].iov_base, uwsgi->hvec[i+1].iov_len, uwsgi->hvec[i+1].iov_base); */ pydictkey = PyString_FromStringAndSize (uwsgi->hvec[i].iov_base, uwsgi->hvec[i].iov_len); @@ -279,8 +255,6 @@ int uwsgi_request_wsgi (struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_re } - - // set wsgi vars wsgi_socket = PyFile_FromFile (wsgi_file, "wsgi_input", "r", NULL); @@ -324,8 +298,6 @@ int uwsgi_request_wsgi (struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_re #endif - - // call #ifndef ROCK_SOLID if (uwsgi->enable_profiler == 1) { @@ -358,39 +330,7 @@ int uwsgi_request_wsgi (struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_re #ifndef ROCK_SOLID if (wsgi_req->sendfile_fd > -1) { - rlen = lseek (wsgi_req->sendfile_fd, 0, SEEK_END); - if (rlen > 0) { - lseek (wsgi_req->sendfile_fd, 0, SEEK_SET); -#ifndef __linux__ -#if defined(__FreeBSD__) || defined(__DragonFly__) - - wsgi_req->response_size = sendfile (wsgi_req->sendfile_fd, uwsgi->poll.fd, 0, 0, NULL, (off_t *) & rlen, 0); -#elif __OpenBSD__ || __sun__ - char *no_sendfile_buf[4096]; - int jlen = 0; - i = 0; - while (i < rlen) { - jlen = read (wsgi_req->sendfile_fd, no_sendfile_buf, 4096); - if (jlen <= 0) { - perror ("read()"); - break; - } - i += jlen; - jlen = write (uwsgi->poll.fd, no_sendfile_buf, jlen); - if (jlen <= 0) { - perror ("write()"); - break; - } - - } -#else - wsgi_req->response_size = sendfile (wsgi_req->sendfile_fd, uwsgi->poll.fd, 0, (off_t *) & rlen, NULL, 0); -#endif -#else - wsgi_req->response_size = sendfile (uwsgi->poll.fd, wsgi_req->sendfile_fd, NULL, rlen); -#endif - } - Py_DECREF (uwsgi->py_sendfile); + wsgi_req->response_size = uwsgi_sendfile(uwsgi, wsgi_req->sendfile_fd, uwsgi->poll.fd); } else { @@ -474,10 +414,70 @@ int uwsgi_request_wsgi (struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_re } -int uwsgi_after_request_wsgi (struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req, char *buffer) { +void uwsgi_after_request_wsgi (struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req, char *buffer) { if (uwsgi->options[UWSGI_OPTION_LOGGING]) log_request(wsgi_req) ; - - return 0; } + +#ifndef ROCK_SOLID +static int uwsgi_sendfile(struct uwsgi_server *uwsgi, int fd, int sockfd) { + + int rlen,i ; + +#ifdef __sun__ + struct stat stat_buf; + if (fstat(fd, &stat_buf)) { + perror("fstat()"); + return 0; + } + else { + rlen = stat_buf.st_size ; + } +#else + rlen = lseek(fd, 0, SEEK_END) ; +#endif + + if (rlen > 0) { + lseek(fd, 0, SEEK_SET) ; +#if !defined(__linux__) && !defined(__sun__) + #if defined(__FreeBSD__) || defined(__DragonFly__) + + if (sendfile(fd, sockfd, 0, 0, NULL, (off_t *) &rlen, 0)) { + perror("sendfile()"); + } + #elif __APPLE__ + if (sendfile(fd, sockfd, 0, (off_t *) &rlen, NULL, 0)) { + perror("sendfile()"); + } + #else + char *no_sendfile_buf[4096] ; + int jlen = 0 ; + rlen = 0 ; + i = 0 ; + while(i < rlen) { + jlen = read(fd, no_sendfile_buf, 4096); + if (jlen<=0) { + perror("read()"); + break; + } + i += jlen; + jlen = write(sockfd, no_sendfile_buf, jlen); + if (jlen<=0) { + perror("write()"); + break; + } + rlen += jlen; + } + #endif +#else + i = 0 ; + rlen = sendfile(sockfd, fd, (off_t *) &i, rlen) ; +#endif + + } + Py_DECREF(uwsgi->py_sendfile); + + return rlen; +} +#endif