mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-05-14 10:43:51 +00:00
preliminary api for language-independent body read another step completed body read language independent implementation ported gevent to the new read/write api ported websockets to the new read/write api removed channels subsystem removed channels subsystem ported lua to the new read/write api fixed post-buffering readline is still broken improved request body readline very difficult test for readline()/read() combo passed other improvements in postbuffering/read/readline ported --http-socket to the new api added X-Forwarded-SSL management removed old api more refactoring ported the RACK plugin to the new api ported psgi plugin to the new api defintely removed clustering simpified ifdel hell simpified ifdef hell removed useless configuration options
238 lines
5.1 KiB
C
238 lines
5.1 KiB
C
#include "uwsgi_python.h"
|
|
|
|
extern struct uwsgi_server uwsgi;
|
|
extern struct uwsgi_python up;
|
|
|
|
int manage_python_response(struct wsgi_request *wsgi_req) {
|
|
// use standard WSGI response parse
|
|
return uwsgi_response_subhandler_wsgi(wsgi_req);
|
|
}
|
|
|
|
char *uwsgi_python_get_exception_type(PyObject *exc) {
|
|
char *class_name = NULL;
|
|
#if !defined(PYTHREE) && !defined(UWSGI_PYPY)
|
|
if (PyClass_Check(exc)) {
|
|
class_name = PyString_AsString( ((PyClassObject*)(exc))->cl_name );
|
|
}
|
|
else {
|
|
#endif
|
|
class_name = (char *) ((PyTypeObject*)exc)->tp_name;
|
|
#if !defined(PYTHREE) && !defined(UWSGI_PYPY)
|
|
}
|
|
#endif
|
|
|
|
if (class_name) {
|
|
char *dot = strrchr(class_name, '.');
|
|
if (dot) class_name = dot+1;
|
|
|
|
PyObject *module_name = PyObject_GetAttrString(exc, "__module__");
|
|
if (module_name) {
|
|
char *mod_name = PyString_AsString(module_name);
|
|
if (mod_name && strcmp(mod_name, "exceptions") ) {
|
|
char *ret = uwsgi_concat3(mod_name, ".", class_name);
|
|
Py_DECREF(module_name);
|
|
return ret;
|
|
}
|
|
Py_DECREF(module_name);
|
|
return uwsgi_str(class_name);
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
char *uwsgi_python_get_exception_value(PyObject *value) {
|
|
return PyString_AsString( PyObject_Str(value) );
|
|
}
|
|
|
|
char *uwsgi_python_get_exception_repr(PyObject *exc, PyObject *value) {
|
|
char *exc_type = uwsgi_python_get_exception_type(exc);
|
|
char *exc_value = uwsgi_python_get_exception_value(value);
|
|
|
|
if (exc_type && exc_value) {
|
|
return uwsgi_concat3(exc_type, ": ", exc_value);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
int uwsgi_python_manage_exceptions(void) {
|
|
PyObject *type = NULL;
|
|
PyObject *value = NULL;
|
|
PyObject *traceback = NULL;
|
|
|
|
char *exc_type = NULL;
|
|
char *exc_value = NULL;
|
|
char *exc_repr = NULL;
|
|
|
|
PyErr_Fetch(&type, &value, &traceback);
|
|
PyErr_NormalizeException(&type, &value, &traceback);
|
|
|
|
if (uwsgi.reload_on_exception_type) {
|
|
exc_type = uwsgi_python_get_exception_type(type);
|
|
}
|
|
|
|
if (uwsgi.reload_on_exception_value) {
|
|
exc_value = uwsgi_python_get_exception_value(value);
|
|
}
|
|
|
|
if (uwsgi.reload_on_exception_repr) {
|
|
exc_repr = uwsgi_python_get_exception_repr(type, value);
|
|
}
|
|
|
|
int ret = uwsgi_manage_exception(exc_type, exc_value, exc_repr);
|
|
|
|
// free memory allocated for strcmp
|
|
if (exc_type) free(exc_type);
|
|
if (exc_repr) free(exc_repr);
|
|
|
|
PyErr_Restore(type, value, traceback);
|
|
|
|
return ret;
|
|
}
|
|
|
|
PyObject *python_call(PyObject *callable, PyObject *args, int catch, struct wsgi_request *wsgi_req) {
|
|
|
|
//uwsgi_log("ready to call %p %p\n", callable, args);
|
|
|
|
PyObject *pyret = PyEval_CallObject(callable, args);
|
|
|
|
//uwsgi_log("called\n");
|
|
|
|
if (PyErr_Occurred()) {
|
|
|
|
|
|
int do_exit = uwsgi_python_manage_exceptions();
|
|
|
|
if (PyErr_ExceptionMatches(PyExc_MemoryError)) {
|
|
uwsgi_log("Memory Error detected !!!\n");
|
|
}
|
|
|
|
// this can be in a spooler or in the master
|
|
if (uwsgi.mywid > 0) {
|
|
uwsgi.workers[uwsgi.mywid].exceptions++;
|
|
if (wsgi_req) {
|
|
uwsgi_apps[wsgi_req->app_id].exceptions++;
|
|
}
|
|
}
|
|
if (!catch) {
|
|
PyErr_Print();
|
|
}
|
|
|
|
if (do_exit) {
|
|
exit(UWSGI_EXCEPTION_CODE);
|
|
}
|
|
}
|
|
|
|
#ifdef UWSGI_DEBUG
|
|
if (pyret) {
|
|
uwsgi_debug("called %p %p %d\n", callable, args, pyret->ob_refcnt);
|
|
}
|
|
#endif
|
|
|
|
return pyret;
|
|
}
|
|
|
|
int uwsgi_python_call(struct wsgi_request *wsgi_req, PyObject *callable, PyObject *args) {
|
|
|
|
wsgi_req->async_result = python_call(callable, args, 0, wsgi_req);
|
|
|
|
if (wsgi_req->async_result) {
|
|
while ( manage_python_response(wsgi_req) != UWSGI_OK) {
|
|
if (uwsgi.async > 1) {
|
|
return UWSGI_AGAIN;
|
|
}
|
|
}
|
|
}
|
|
|
|
return UWSGI_OK;
|
|
}
|
|
|
|
void init_pyargv() {
|
|
|
|
char *ap;
|
|
|
|
char *argv0 = "uwsgi";
|
|
|
|
if (up.pyrun) {
|
|
argv0 = up.pyrun;
|
|
}
|
|
|
|
#ifdef PYTHREE
|
|
wchar_t *pname = uwsgi_calloc(sizeof(wchar_t) * (strlen(argv0)+1));
|
|
mbstowcs(pname, argv0, strlen(argv0)+1);
|
|
#else
|
|
char *pname = argv0;
|
|
#endif
|
|
|
|
up.argc = 1;
|
|
if (up.argv) {
|
|
char *tmp_ptr = uwsgi_str(up.argv);
|
|
#ifdef __sun__
|
|
// FIX THIS !!!
|
|
ap = strtok(tmp_ptr, " ");
|
|
while ((ap = strtok(NULL, " ")) != NULL) {
|
|
#else
|
|
while ((ap = strsep(&tmp_ptr, " \t")) != NULL) {
|
|
#endif
|
|
if (*ap != '\0') {
|
|
up.argc++;
|
|
}
|
|
}
|
|
|
|
free(tmp_ptr);
|
|
}
|
|
|
|
#ifdef PYTHREE
|
|
up.py_argv = uwsgi_calloc(sizeof(wchar_t *) * up.argc+1);
|
|
#else
|
|
up.py_argv = uwsgi_calloc(sizeof(char *) * up.argc+1);
|
|
#endif
|
|
|
|
up.py_argv[0] = pname;
|
|
|
|
|
|
if (up.argv) {
|
|
|
|
char *py_argv_copy = uwsgi_str(up.argv);
|
|
up.argc = 1;
|
|
#ifdef PYTHREE
|
|
wchar_t *wcargv = uwsgi_calloc( sizeof( wchar_t ) * (strlen(py_argv_copy)+1));
|
|
#endif
|
|
|
|
#ifdef __sun__
|
|
// FIX THIS !!!
|
|
ap = strtok(py_argv_copy, " ");
|
|
while ((ap = strtok(NULL, " ")) != NULL) {
|
|
#else
|
|
while ((ap = strsep(&py_argv_copy, " \t")) != NULL) {
|
|
#endif
|
|
if (*ap != '\0') {
|
|
#ifdef PYTHREE
|
|
mbstowcs( wcargv + strlen(ap), ap, strlen(ap));
|
|
up.py_argv[up.argc] = wcargv + strlen(ap);
|
|
#else
|
|
up.py_argv[up.argc] = ap;
|
|
#endif
|
|
up.argc++;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
PySys_SetArgv(up.argc, up.py_argv);
|
|
|
|
PyObject *sys_dict = get_uwsgi_pydict("sys");
|
|
if (!sys_dict) {
|
|
uwsgi_log("unable to load python sys module !!!\n");
|
|
exit(1);
|
|
}
|
|
#ifdef PYTHREE
|
|
PyDict_SetItemString(sys_dict, "executable", PyUnicode_FromString(uwsgi.binary_path));
|
|
#else
|
|
PyDict_SetItemString(sys_dict, "executable", PyString_FromString(uwsgi.binary_path));
|
|
#endif
|
|
|
|
|
|
}
|