mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-09-08 06:31:58 +00:00
updated web3 handler
This commit is contained in:
+15
-41
@@ -22,9 +22,8 @@ PyMethodDef uwsgi_eventfd_read_method[] = { {"uwsgi_eventfd_read", py_eventfd_re
|
||||
PyMethodDef uwsgi_eventfd_write_method[] = { {"uwsgi_eventfd_write", py_eventfd_write, METH_VARARGS, ""}};
|
||||
#endif
|
||||
|
||||
int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThreadState *interpreter) {
|
||||
int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThreadState *interpreter, int app_type) {
|
||||
|
||||
PyObject *zero;
|
||||
PyObject *app_list = NULL, *applications = NULL;
|
||||
|
||||
int id = uwsgi.apps_cnt;
|
||||
@@ -212,48 +211,23 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
|
||||
}
|
||||
#endif
|
||||
|
||||
// check function args
|
||||
// by defaut it is a WSGI app
|
||||
wi->argc = 2;
|
||||
zero = PyObject_GetAttrString(wi->callable, "__code__");
|
||||
if (!zero) {
|
||||
zero = PyObject_GetAttrString(wi->callable, "__call__");
|
||||
if (zero) {
|
||||
zero = PyObject_GetAttrString(wi->callable, "__code__");
|
||||
}
|
||||
else {
|
||||
uwsgi_log("WARNING: unable to get the number of callable args. Fallback to WSGI\n");
|
||||
}
|
||||
}
|
||||
wi->argc = 1;
|
||||
|
||||
// avoid __code__ attr error propagation
|
||||
PyErr_Clear();
|
||||
|
||||
if (zero) {
|
||||
zero = PyObject_GetAttrString(zero, "co_argcount");
|
||||
wi->argc = (int) PyInt_AsLong(zero);
|
||||
}
|
||||
|
||||
if (wi->argc == 2) {
|
||||
if (app_type == PYTHON_APP_TYPE_WSGI) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("-- WSGI callable detected --\n");
|
||||
uwsgi_log("-- WSGI callable selected --\n");
|
||||
#endif
|
||||
wi->request_subhandler = uwsgi_request_subhandler_wsgi;
|
||||
wi->response_subhandler = uwsgi_response_subhandler_wsgi;
|
||||
wi->argc = 2;
|
||||
}
|
||||
#ifdef UWSGI_WEB3
|
||||
else if (wi->argc == 1) {
|
||||
else if (app_type == PYTHON_APP_TYPE_WEB3) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("-- Web3 callable detected --\n");
|
||||
uwsgi_log("-- Web3 callable selected --\n");
|
||||
#endif
|
||||
wi->request_subhandler = uwsgi_request_subhandler_web3;
|
||||
wi->response_subhandler = uwsgi_response_subhandler_web3;
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
uwsgi_log("-- INVALID callable detected --\n");
|
||||
goto doh;
|
||||
}
|
||||
|
||||
#ifdef UWSGI_ASYNC
|
||||
wi->args = malloc(sizeof(PyObject*)*uwsgi.cores);
|
||||
@@ -270,7 +244,7 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
|
||||
}
|
||||
|
||||
// add start_response on WSGI app
|
||||
if (wi->argc == 2) {
|
||||
if (app_type == PYTHON_APP_TYPE_WSGI) {
|
||||
if (PyTuple_SetItem(wi->args[i], 1, up.wsgi_spitout)) {
|
||||
uwsgi_log("unable to set start_response in args tuple\n");
|
||||
exit(1);
|
||||
@@ -280,7 +254,7 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
|
||||
#else
|
||||
|
||||
wi->wsgi_args = PyTuple_New(wi->argc);
|
||||
if (wi->argc == 2) {
|
||||
if (app_type == PYTHON_APP_TYPE_WSGI) {
|
||||
if (PyTuple_SetItem(wi->wsgi_args, 1, up.wsgi_spitout)) {
|
||||
uwsgi_log("unable to set start_response in args tuple\n");
|
||||
exit(1);
|
||||
@@ -288,7 +262,7 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
|
||||
}
|
||||
#endif
|
||||
|
||||
if (wi->argc == 2) {
|
||||
if (app_type == PYTHON_APP_TYPE_WSGI) {
|
||||
#ifdef UWSGI_SENDFILE
|
||||
// prepare sendfile() for WSGI app
|
||||
wi->sendfile = PyCFunction_New(uwsgi_sendfile_method, NULL);
|
||||
@@ -329,12 +303,12 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
|
||||
PyThreadState_Swap(up.main_thread);
|
||||
}
|
||||
|
||||
if (wi->argc == 1) {
|
||||
uwsgi_log( "Web3 application %d (SCRIPT_NAME=%.*s) ready on interpreter %p", id, wi->mountpoint_len, wi->mountpoint, wi->interpreter);
|
||||
}
|
||||
else {
|
||||
if (app_type == PYTHON_APP_TYPE_WSGI) {
|
||||
uwsgi_log( "WSGI application %d (SCRIPT_NAME=%.*s) ready on interpreter %p pid: %d", id, wi->mountpoint_len, wi->mountpoint, wi->interpreter, (int) getpid());
|
||||
}
|
||||
else if (app_type == PYTHON_APP_TYPE_WEB3) {
|
||||
uwsgi_log( "Web3 application %d (SCRIPT_NAME=%.*s) ready on interpreter %p pid: %d", id, wi->mountpoint_len, wi->mountpoint, wi->interpreter, (int) getpid());
|
||||
}
|
||||
|
||||
if (!wsgi_req->script_name_len) {
|
||||
uwsgi_rawlog(" (default app)");
|
||||
@@ -355,7 +329,7 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
|
||||
|
||||
wsgi_req->script_name = PyString_AsString(app_mnt);
|
||||
wsgi_req->script_name_len = strlen(wsgi_req->script_name);
|
||||
init_uwsgi_app(LOADER_CALLABLE, PyDict_GetItem(applications, app_mnt), wsgi_req, wi->interpreter);
|
||||
init_uwsgi_app(LOADER_CALLABLE, PyDict_GetItem(applications, app_mnt), wsgi_req, wi->interpreter, app_type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,9 @@ struct option uwsgi_python_options[] = {
|
||||
{"pyargv", required_argument, 0, LONG_ARGS_PYARGV},
|
||||
{"optimize", required_argument, 0, 'O'},
|
||||
{"paste", required_argument, 0, LONG_ARGS_PASTE},
|
||||
{"web3", required_argument, 0, LONG_ARGS_WEB3},
|
||||
{"pump", required_argument, 0, LONG_ARGS_PUMP},
|
||||
{"wsgi-lite", required_argument, 0, LONG_ARGS_WSGI_LITE},
|
||||
#ifdef UWSGI_INI
|
||||
{"ini-paste", required_argument, 0, LONG_ARGS_INI_PASTE},
|
||||
#endif
|
||||
@@ -742,6 +745,15 @@ int uwsgi_python_manage_options(int i, char *optarg) {
|
||||
}
|
||||
return 1;
|
||||
#endif
|
||||
case LONG_ARGS_WEB3:
|
||||
up.web3 = optarg;
|
||||
return 1;
|
||||
case LONG_ARGS_PUMP:
|
||||
up.pump = optarg;
|
||||
return 1;
|
||||
case LONG_ARGS_WSGI_LITE:
|
||||
up.wsgi_lite = optarg;
|
||||
return 1;
|
||||
case LONG_ARGS_PASTE:
|
||||
up.paste = optarg;
|
||||
return 1;
|
||||
@@ -758,9 +770,9 @@ int uwsgi_python_mount_app(char *mountpoint, char *app) {
|
||||
uwsgi.wsgi_req->script_name = mountpoint;
|
||||
uwsgi.wsgi_req->script_name_len = strlen(mountpoint);
|
||||
if (uwsgi.single_interpreter) {
|
||||
return init_uwsgi_app(LOADER_MOUNT, app, uwsgi.wsgi_req, up.main_thread);
|
||||
return 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);
|
||||
return init_uwsgi_app(LOADER_MOUNT, app, uwsgi.wsgi_req, NULL, PYTHON_APP_TYPE_WSGI);
|
||||
|
||||
}
|
||||
|
||||
@@ -889,17 +901,26 @@ void uwsgi_python_init_apps() {
|
||||
|
||||
|
||||
if (up.wsgi_config != NULL) {
|
||||
init_uwsgi_app(LOADER_UWSGI, up.wsgi_config, uwsgi.wsgi_req, up.main_thread);
|
||||
init_uwsgi_app(LOADER_UWSGI, up.wsgi_config, uwsgi.wsgi_req, up.main_thread, PYTHON_APP_TYPE_WSGI);
|
||||
}
|
||||
|
||||
if (up.file_config != NULL) {
|
||||
init_uwsgi_app(LOADER_FILE, up.file_config, uwsgi.wsgi_req, up.main_thread);
|
||||
init_uwsgi_app(LOADER_FILE, up.file_config, uwsgi.wsgi_req, up.main_thread, PYTHON_APP_TYPE_WSGI);
|
||||
}
|
||||
if (up.paste != NULL) {
|
||||
init_uwsgi_app(LOADER_PASTE, up.paste, uwsgi.wsgi_req, up.main_thread);
|
||||
init_uwsgi_app(LOADER_PASTE, up.paste, uwsgi.wsgi_req, up.main_thread, PYTHON_APP_TYPE_WSGI);
|
||||
}
|
||||
if (up.eval != NULL) {
|
||||
init_uwsgi_app(LOADER_EVAL, up.eval, uwsgi.wsgi_req, up.main_thread);
|
||||
init_uwsgi_app(LOADER_EVAL, up.eval, uwsgi.wsgi_req, up.main_thread, PYTHON_APP_TYPE_WSGI);
|
||||
}
|
||||
if (up.web3 != NULL) {
|
||||
init_uwsgi_app(LOADER_UWSGI, up.web3, uwsgi.wsgi_req, up.main_thread, PYTHON_APP_TYPE_WEB3);
|
||||
}
|
||||
if (up.pump != NULL) {
|
||||
init_uwsgi_app(LOADER_UWSGI, up.pump, uwsgi.wsgi_req, up.main_thread, PYTHON_APP_TYPE_PUMP);
|
||||
}
|
||||
if (up.wsgi_lite != NULL) {
|
||||
init_uwsgi_app(LOADER_UWSGI, up.wsgi_lite, uwsgi.wsgi_req, up.main_thread, PYTHON_APP_TYPE_WSGI_LITE);
|
||||
}
|
||||
|
||||
if (uwsgi.profiler) {
|
||||
@@ -979,16 +1000,16 @@ int uwsgi_python_xml(char *node, char *content) {
|
||||
}
|
||||
|
||||
if (!strcmp("script", node)) {
|
||||
return init_uwsgi_app(LOADER_UWSGI, content, uwsgi.wsgi_req, interpreter);
|
||||
return init_uwsgi_app(LOADER_UWSGI, content, uwsgi.wsgi_req, interpreter, PYTHON_APP_TYPE_WSGI);
|
||||
}
|
||||
else if (!strcmp("file", node)) {
|
||||
return init_uwsgi_app(LOADER_FILE, content, uwsgi.wsgi_req, interpreter);
|
||||
return init_uwsgi_app(LOADER_FILE, content, uwsgi.wsgi_req, interpreter, PYTHON_APP_TYPE_WSGI);
|
||||
}
|
||||
else if (!strcmp("eval", node)) {
|
||||
return init_uwsgi_app(LOADER_EVAL, content, uwsgi.wsgi_req, interpreter);
|
||||
return init_uwsgi_app(LOADER_EVAL, content, uwsgi.wsgi_req, interpreter, PYTHON_APP_TYPE_WSGI);
|
||||
}
|
||||
else if (!strcmp("wsgi", node)) {
|
||||
return init_uwsgi_app(LOADER_EVAL, content, uwsgi.wsgi_req, interpreter);
|
||||
return init_uwsgi_app(LOADER_EVAL, content, uwsgi.wsgi_req, interpreter, PYTHON_APP_TYPE_WSGI);
|
||||
}
|
||||
else if (!strcmp("module", node)) {
|
||||
uwsgi.wsgi_req->module = content;
|
||||
@@ -999,10 +1020,10 @@ int uwsgi_python_xml(char *node, char *content) {
|
||||
uwsgi.wsgi_req->callable++;
|
||||
uwsgi.wsgi_req->callable_len = strlen(uwsgi.wsgi_req->callable);
|
||||
uwsgi.wsgi_req->module_len = strlen(uwsgi.wsgi_req->module);
|
||||
return init_uwsgi_app(LOADER_DYN, uwsgi.wsgi_req, uwsgi.wsgi_req, interpreter);
|
||||
return init_uwsgi_app(LOADER_DYN, uwsgi.wsgi_req, uwsgi.wsgi_req, interpreter, PYTHON_APP_TYPE_WSGI);
|
||||
}
|
||||
else {
|
||||
return init_uwsgi_app(LOADER_UWSGI, content, uwsgi.wsgi_req, interpreter);
|
||||
return init_uwsgi_app(LOADER_UWSGI, content, uwsgi.wsgi_req, interpreter, PYTHON_APP_TYPE_WSGI);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -1014,7 +1035,7 @@ int uwsgi_python_xml(char *node, char *content) {
|
||||
else if (!strcmp("callable", node)) {
|
||||
uwsgi.wsgi_req->callable = content;
|
||||
uwsgi.wsgi_req->callable_len = strlen(content);
|
||||
return init_uwsgi_app(LOADER_DYN, uwsgi.wsgi_req, uwsgi.wsgi_req, interpreter);
|
||||
return init_uwsgi_app(LOADER_DYN, uwsgi.wsgi_req, uwsgi.wsgi_req, interpreter, PYTHON_APP_TYPE_WSGI);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -15,6 +15,15 @@
|
||||
#define LONG_ARGS_RELOAD_OS_ENV LONG_ARGS_PYTHON_BASE + 5
|
||||
#define LONG_ARGS_PYIMPORT LONG_ARGS_PYTHON_BASE + 6
|
||||
#define LONG_ARGS_POST_PYMODULE_ALIAS LONG_ARGS_PYTHON_BASE + 7
|
||||
#define LONG_ARGS_WEB3 LONG_ARGS_PYTHON_BASE + 8
|
||||
#define LONG_ARGS_PUMP LONG_ARGS_PYTHON_BASE + 9
|
||||
#define LONG_ARGS_WSGI_LITE LONG_ARGS_PYTHON_BASE + 10
|
||||
|
||||
#define PYTHON_APP_TYPE_WSGI 0
|
||||
#define PYTHON_APP_TYPE_WEB3 1
|
||||
#define PYTHON_APP_TYPE_WSGI2 2
|
||||
#define PYTHON_APP_TYPE_PUMP 3
|
||||
#define PYTHON_APP_TYPE_WSGI_LITE 4
|
||||
|
||||
#if PY_MINOR_VERSION == 4 && PY_MAJOR_VERSION == 2
|
||||
#define Py_ssize_t ssize_t
|
||||
@@ -83,6 +92,16 @@ PyAPI_FUNC(PyObject *) PyMarshal_ReadObjectFromString(char *, Py_ssize_t);
|
||||
|
||||
#define LOADER_MAX 8
|
||||
|
||||
typedef struct uwsgi_Input {
|
||||
PyObject_HEAD
|
||||
char readline[1024];
|
||||
size_t readline_size;
|
||||
size_t readline_max_size;
|
||||
size_t readline_pos;
|
||||
size_t pos;
|
||||
struct wsgi_request *wsgi_req;
|
||||
} uwsgi_Input;
|
||||
|
||||
struct uwsgi_python {
|
||||
|
||||
char *home;
|
||||
@@ -116,6 +135,9 @@ struct uwsgi_python {
|
||||
char *paste;
|
||||
char *eval;
|
||||
|
||||
char *web3;
|
||||
char *pump;
|
||||
char *wsgi_lite;
|
||||
|
||||
char *callable;
|
||||
|
||||
@@ -166,7 +188,7 @@ void uwsgi_paste_config(char *);
|
||||
void uwsgi_file_config(char *);
|
||||
void uwsgi_eval_config(char *);
|
||||
|
||||
int init_uwsgi_app(int, void *, struct wsgi_request *wsgi_req, PyThreadState *);
|
||||
int init_uwsgi_app(int, void *, struct wsgi_request *, PyThreadState *, int);
|
||||
|
||||
|
||||
PyObject *py_eventfd_read(PyObject *, PyObject *);
|
||||
@@ -188,10 +210,8 @@ PyObject *py_uwsgi_spit(PyObject *, PyObject *);
|
||||
|
||||
void init_pyargv(void);
|
||||
|
||||
#ifdef UWSGI_WEB3
|
||||
void *uwsgi_request_subhandler_web3(struct wsgi_request *, struct uwsgi_app *);
|
||||
int uwsgi_response_subhandler_web3(struct wsgi_request *);
|
||||
#endif
|
||||
|
||||
PyObject *uwsgi_uwsgi_loader(void *);
|
||||
PyObject *uwsgi_dyn_loader(void *);
|
||||
|
||||
@@ -3,7 +3,7 @@ import os,sys
|
||||
from distutils import sysconfig
|
||||
|
||||
NAME='python'
|
||||
GCC_LIST = ['python_plugin', 'pyutils', 'pyloader', 'wsgi_handlers', 'wsgi_headers', 'wsgi_subhandler', 'gil', 'uwsgi_pymodule', 'profiler', 'symimporter']
|
||||
GCC_LIST = ['python_plugin', 'pyutils', 'pyloader', 'wsgi_handlers', 'wsgi_headers', 'wsgi_subhandler', 'web3_subhandler', 'gil', 'uwsgi_pymodule', 'profiler', 'symimporter']
|
||||
|
||||
CFLAGS = ['-I' + sysconfig.get_python_inc(), '-I' + sysconfig.get_python_inc(plat_specific=True) ]
|
||||
LDFLAGS = []
|
||||
|
||||
@@ -1,20 +1,70 @@
|
||||
#include "uwsgi.h"
|
||||
#include "uwsgi_python.h"
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
extern struct uwsgi_python up;
|
||||
extern PyTypeObject uwsgi_InputType;
|
||||
|
||||
void *uwsgi_request_subhandler_web3(struct wsgi_request *wsgi_req, struct uwsgi_app *wi) {
|
||||
|
||||
PyObject *zero, *wsgi_socket;
|
||||
PyObject *zero;
|
||||
|
||||
wsgi_socket = PyFile_FromFile(wsgi_req->async_post, "web3_input", "r", NULL);
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "web3.input", wsgi_socket);
|
||||
Py_DECREF(wsgi_socket);
|
||||
int i;
|
||||
PyObject *pydictkey, *pydictvalue;
|
||||
char *path_info;
|
||||
|
||||
zero = PyTuple_New(2);
|
||||
PyTuple_SetItem(zero, 0, PyInt_FromLong(1));
|
||||
PyTuple_SetItem(zero, 1, PyInt_FromLong(0));
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "web3.version", zero);
|
||||
Py_DECREF(zero);
|
||||
for (i = 0; i < wsgi_req->var_cnt; i += 2) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_debug("%.*s: %.*s\n", wsgi_req->hvec[i].iov_len, wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i+1].iov_len, wsgi_req->hvec[i+1].iov_base);
|
||||
#endif
|
||||
#ifdef PYTHREE
|
||||
pydictkey = PyUnicode_DecodeLatin1(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len, NULL);
|
||||
pydictvalue = PyUnicode_DecodeLatin1(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len, NULL);
|
||||
#else
|
||||
pydictkey = PyString_FromStringAndSize(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len);
|
||||
pydictvalue = PyString_FromStringAndSize(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len);
|
||||
#endif
|
||||
PyDict_SetItem(wsgi_req->async_environ, pydictkey, pydictvalue);
|
||||
Py_DECREF(pydictkey);
|
||||
Py_DECREF(pydictvalue);
|
||||
}
|
||||
|
||||
if (wsgi_req->uh.modifier1 == UWSGI_MODIFIER_MANAGE_PATH_INFO) {
|
||||
wsgi_req->uh.modifier1 = 0;
|
||||
pydictkey = PyDict_GetItemString(wsgi_req->async_environ, "SCRIPT_NAME");
|
||||
if (pydictkey) {
|
||||
if (PyString_Check(pydictkey)) {
|
||||
pydictvalue = PyDict_GetItemString(wsgi_req->async_environ, "PATH_INFO");
|
||||
if (pydictvalue) {
|
||||
if (PyString_Check(pydictvalue)) {
|
||||
path_info = PyString_AsString(pydictvalue);
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "PATH_INFO", PyString_FromString(path_info + PyString_Size(pydictkey)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if async_post is mapped as a file, directly use it as wsgi.input
|
||||
if (wsgi_req->async_post) {
|
||||
#ifdef PYTHREE
|
||||
wsgi_req->async_input = PyFile_FromFd(fileno(wsgi_req->async_post), "web3_input", "rb", 0, NULL, NULL, NULL, 0);
|
||||
#else
|
||||
wsgi_req->async_input = PyFile_FromFile(wsgi_req->async_post, "web3_input", "r", NULL);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
// create wsgi.input custom object
|
||||
wsgi_req->async_input = (PyObject *) PyObject_New(uwsgi_Input, &uwsgi_InputType);
|
||||
((uwsgi_Input*)wsgi_req->async_input)->wsgi_req = wsgi_req;
|
||||
((uwsgi_Input*)wsgi_req->async_input)->pos = 0;
|
||||
((uwsgi_Input*)wsgi_req->async_input)->readline_pos = 0;
|
||||
((uwsgi_Input*)wsgi_req->async_input)->readline_max_size = 0;
|
||||
|
||||
}
|
||||
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "web3.input", wsgi_req->async_input);
|
||||
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "web3.version", wi->uwsgi_version);
|
||||
|
||||
zero = PyFile_FromFile(stderr, "web3_input", "w", NULL);
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "web3.errors", zero);
|
||||
@@ -48,12 +98,30 @@ void *uwsgi_request_subhandler_web3(struct wsgi_request *wsgi_req, struct uwsgi_
|
||||
Py_DECREF(zero);
|
||||
|
||||
|
||||
wsgi_req->async_app = wi->wsgi_callable;
|
||||
wsgi_req->async_app = wi->callable;
|
||||
|
||||
PyDict_SetItemString(uwsgi.embedded_dict, "env", wsgi_req->async_environ);
|
||||
// export .env only in non-threaded mode
|
||||
if (uwsgi.threads < 2) {
|
||||
PyDict_SetItemString(up.embedded_dict, "env", wsgi_req->async_environ);
|
||||
}
|
||||
|
||||
// TODO: fix this
|
||||
//PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.version", uwsgi_version);
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.version", wi->uwsgi_version);
|
||||
|
||||
if (uwsgi.cores > 1) {
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.core", PyInt_FromLong(wsgi_req->async_id));
|
||||
}
|
||||
|
||||
// cache this ?
|
||||
if (uwsgi.cluster_fd >= 0) {
|
||||
zero = PyString_FromString(uwsgi.cluster);
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.cluster", zero);
|
||||
Py_DECREF(zero);
|
||||
zero = PyString_FromString(uwsgi.hostname);
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.cluster_node", zero);
|
||||
Py_DECREF(zero);
|
||||
}
|
||||
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.node", wi->uwsgi_node);
|
||||
|
||||
|
||||
// call
|
||||
@@ -68,16 +136,7 @@ int uwsgi_response_subhandler_web3(struct wsgi_request *wsgi_req) {
|
||||
PyObject *pychunk;
|
||||
ssize_t wsize;
|
||||
|
||||
// return or yield ? (PyString on python2 PyBytes on python3)
|
||||
if (PyString_Check((PyObject *)wsgi_req->async_result)) {
|
||||
if ((wsize = write(wsgi_req->poll.fd, PyString_AsString(wsgi_req->async_result), PyString_Size(wsgi_req->async_result))) < 0) {
|
||||
uwsgi_error("write()");
|
||||
goto clear;
|
||||
}
|
||||
wsgi_req->response_size += wsize;
|
||||
goto clear;
|
||||
}
|
||||
|
||||
UWSGI_GET_GIL
|
||||
|
||||
// ok its a yield
|
||||
if (!wsgi_req->async_placeholder) {
|
||||
@@ -86,19 +145,36 @@ int uwsgi_response_subhandler_web3(struct wsgi_request *wsgi_req) {
|
||||
uwsgi_log("invalid Web3 response.\n");
|
||||
goto clear;
|
||||
}
|
||||
if (py_uwsgi_spit(NULL, (PyObject *)wsgi_req->async_result) == Py_None) {
|
||||
PyObject *spit_args = PyTuple_New(2);
|
||||
PyTuple_SetItem(spit_args, 0, PyTuple_GetItem((PyObject *)wsgi_req->async_result, 1));
|
||||
PyTuple_SetItem(spit_args, 1, PyTuple_GetItem((PyObject *)wsgi_req->async_result, 2));
|
||||
Py_INCREF((PyObject *)wsgi_req->async_result);
|
||||
|
||||
if (py_uwsgi_spit(NULL, spit_args) == Py_None) {
|
||||
Py_DECREF(spit_args);
|
||||
goto clear;
|
||||
}
|
||||
Py_DECREF(spit_args);
|
||||
|
||||
wsgi_req->async_result = PyTuple_GetItem((PyObject *)wsgi_req->async_result, 0);
|
||||
wsgi_req->async_placeholder = PyTuple_GetItem((PyObject *)wsgi_req->async_result, 0);
|
||||
|
||||
wsgi_req->async_placeholder = PyObject_GetIter( (PyObject *)wsgi_req->async_result );
|
||||
if (PyString_Check((PyObject *)wsgi_req->async_placeholder)) {
|
||||
if ((wsize = wsgi_req->socket->proto_write(wsgi_req, PyString_AsString(wsgi_req->async_placeholder), PyString_Size(wsgi_req->async_placeholder))) < 0) {
|
||||
uwsgi_error("write()");
|
||||
goto clear;
|
||||
}
|
||||
wsgi_req->response_size += wsize;
|
||||
goto clear;
|
||||
}
|
||||
|
||||
wsgi_req->async_placeholder = PyObject_GetIter( (PyObject *)wsgi_req->async_placeholder );
|
||||
|
||||
if (!wsgi_req->async_placeholder) {
|
||||
goto clear2;
|
||||
goto clear;
|
||||
}
|
||||
#ifdef UWSGI_ASYNC
|
||||
if (uwsgi.async > 1) {
|
||||
UWSGI_RELEASE_GIL
|
||||
return UWSGI_AGAIN;
|
||||
}
|
||||
}
|
||||
@@ -121,7 +197,7 @@ int uwsgi_response_subhandler_web3(struct wsgi_request *wsgi_req) {
|
||||
|
||||
|
||||
if (PyString_Check(pychunk)) {
|
||||
if ((wsize = write(wsgi_req->poll.fd, PyString_AsString(pychunk), PyString_Size(pychunk))) < 0) {
|
||||
if ((wsize = wsgi_req->socket->proto_write(wsgi_req, PyString_AsString(pychunk), PyString_Size(pychunk))) < 0) {
|
||||
uwsgi_error("write()");
|
||||
Py_DECREF(pychunk);
|
||||
goto clear;
|
||||
@@ -131,34 +207,22 @@ int uwsgi_response_subhandler_web3(struct wsgi_request *wsgi_req) {
|
||||
|
||||
|
||||
Py_DECREF(pychunk);
|
||||
UWSGI_RELEASE_GIL
|
||||
return UWSGI_AGAIN;
|
||||
|
||||
clear:
|
||||
if (wsgi_req->async_input) {
|
||||
Py_DECREF((PyObject *)wsgi_req->async_input);
|
||||
}
|
||||
if (wsgi_req->async_environ) {
|
||||
PyDict_Clear(wsgi_req->async_environ);
|
||||
}
|
||||
if (wsgi_req->async_post && !wsgi_req->fd_closed) {
|
||||
fclose(wsgi_req->async_post);
|
||||
if (!uwsgi.post_buffering || wsgi_req->post_cl <= (size_t) uwsgi.post_buffering) {
|
||||
wsgi_req->fd_closed = 1;
|
||||
}
|
||||
}
|
||||
Py_XDECREF((PyObject *)wsgi_req->async_placeholder);
|
||||
clear2:
|
||||
|
||||
Py_DECREF((PyObject *)wsgi_req->async_result);
|
||||
PyErr_Clear();
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
if (wsgi_req->async_placeholder) {
|
||||
uwsgi_debug("wsgi_req->async_placeholder: %d\n", ((PyObject *)wsgi_req->async_placeholder)->ob_refcnt);
|
||||
}
|
||||
if (wsgi_req->async_result) {
|
||||
uwsgi_debug("wsgi_req->async_result: %d\n", ((PyObject *)wsgi_req->async_result)->ob_refcnt);
|
||||
}
|
||||
if (wsgi_req->async_app) {
|
||||
uwsgi_debug("wsgi_req->async_app: %d\n", ((PyObject *)wsgi_req->async_app)->ob_refcnt);
|
||||
}
|
||||
#endif
|
||||
UWSGI_RELEASE_GIL
|
||||
return UWSGI_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,16 +4,6 @@ extern struct uwsgi_server uwsgi;
|
||||
extern struct uwsgi_python up;
|
||||
|
||||
|
||||
typedef struct uwsgi_Input {
|
||||
PyObject_HEAD
|
||||
char readline[1024];
|
||||
size_t readline_size;
|
||||
size_t readline_max_size;
|
||||
size_t readline_pos;
|
||||
size_t pos;
|
||||
struct wsgi_request *wsgi_req;
|
||||
} uwsgi_Input;
|
||||
|
||||
PyObject *uwsgi_Input_iter(PyObject *self) {
|
||||
Py_INCREF(self);
|
||||
return self;
|
||||
@@ -62,7 +52,7 @@ PyObject *uwsgi_Input_getline(uwsgi_Input *self) {
|
||||
else {
|
||||
rlen = read(wsgi_req->poll.fd, self->readline, 1024);
|
||||
}
|
||||
if (rlen < 0) {
|
||||
if (rlen <= 0) {
|
||||
UWSGI_GET_GIL
|
||||
return PyErr_Format(PyExc_IOError, "error reading wsgi.input data");
|
||||
}
|
||||
@@ -166,7 +156,7 @@ static PyObject *uwsgi_Input_read(uwsgi_Input *self, PyObject *args) {
|
||||
}
|
||||
|
||||
rlen = read(self->wsgi_req->poll.fd, tmp_buf+tmp_pos, remains);
|
||||
if (rlen < 0) {
|
||||
if (rlen <= 0) {
|
||||
free(tmp_buf);
|
||||
UWSGI_GET_GIL
|
||||
return PyErr_Format(PyExc_IOError, "error reading wsgi.input data");
|
||||
@@ -327,11 +317,6 @@ PyObject *py_eventfd_write(PyObject * self, PyObject * args) {
|
||||
|
||||
int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) {
|
||||
|
||||
int i;
|
||||
|
||||
PyObject *pydictkey, *pydictvalue;
|
||||
|
||||
char *path_info;
|
||||
struct uwsgi_app *wi;
|
||||
|
||||
int tmp_stderr;
|
||||
@@ -406,10 +391,10 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) {
|
||||
|
||||
UWSGI_GET_GIL
|
||||
if (uwsgi.single_interpreter) {
|
||||
wsgi_req->app_id = init_uwsgi_app(LOADER_DYN, (void *) wsgi_req, wsgi_req, up.main_thread);
|
||||
wsgi_req->app_id = init_uwsgi_app(LOADER_DYN, (void *) wsgi_req, wsgi_req, up.main_thread, PYTHON_APP_TYPE_WSGI);
|
||||
}
|
||||
else {
|
||||
wsgi_req->app_id = init_uwsgi_app(LOADER_DYN, (void *) wsgi_req, wsgi_req, NULL);
|
||||
wsgi_req->app_id = init_uwsgi_app(LOADER_DYN, (void *) wsgi_req, wsgi_req, NULL, PYTHON_APP_TYPE_WSGI);
|
||||
}
|
||||
UWSGI_RELEASE_GIL
|
||||
if (uwsgi.threads > 1) {
|
||||
@@ -485,60 +470,6 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) {
|
||||
|
||||
Py_INCREF((PyObject *)wsgi_req->async_environ);
|
||||
|
||||
for (i = 0; i < wsgi_req->var_cnt; i += 2) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_debug("%.*s: %.*s\n", wsgi_req->hvec[i].iov_len, wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i+1].iov_len, wsgi_req->hvec[i+1].iov_base);
|
||||
#endif
|
||||
#ifdef PYTHREE
|
||||
pydictkey = PyUnicode_DecodeLatin1(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len, NULL);
|
||||
pydictvalue = PyUnicode_DecodeLatin1(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len, NULL);
|
||||
#else
|
||||
pydictkey = PyString_FromStringAndSize(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len);
|
||||
pydictvalue = PyString_FromStringAndSize(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len);
|
||||
#endif
|
||||
PyDict_SetItem(wsgi_req->async_environ, pydictkey, pydictvalue);
|
||||
Py_DECREF(pydictkey);
|
||||
Py_DECREF(pydictvalue);
|
||||
}
|
||||
|
||||
if (wsgi_req->uh.modifier1 == UWSGI_MODIFIER_MANAGE_PATH_INFO) {
|
||||
wsgi_req->uh.modifier1 = 0;
|
||||
pydictkey = PyDict_GetItemString(wsgi_req->async_environ, "SCRIPT_NAME");
|
||||
if (pydictkey) {
|
||||
if (PyString_Check(pydictkey)) {
|
||||
pydictvalue = PyDict_GetItemString(wsgi_req->async_environ, "PATH_INFO");
|
||||
if (pydictvalue) {
|
||||
if (PyString_Check(pydictvalue)) {
|
||||
path_info = PyString_AsString(pydictvalue);
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "PATH_INFO", PyString_FromString(path_info + PyString_Size(pydictkey)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// if async_post is mapped as a file, directly use it as wsgi.input
|
||||
if (wsgi_req->async_post) {
|
||||
#ifdef PYTHREE
|
||||
wsgi_req->async_input = PyFile_FromFd(fileno(wsgi_req->async_post), "wsgi_input", "rb", 0, NULL, NULL, NULL, 0);
|
||||
#else
|
||||
wsgi_req->async_input = PyFile_FromFile(wsgi_req->async_post, "wsgi_input", "r", NULL);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
// create wsgi.input custom object
|
||||
wsgi_req->async_input = (PyObject *) PyObject_New(uwsgi_Input, &uwsgi_InputType);
|
||||
((uwsgi_Input*)wsgi_req->async_input)->wsgi_req = wsgi_req;
|
||||
((uwsgi_Input*)wsgi_req->async_input)->pos = 0;
|
||||
((uwsgi_Input*)wsgi_req->async_input)->readline_pos = 0;
|
||||
((uwsgi_Input*)wsgi_req->async_input)->readline_max_size = 0;
|
||||
|
||||
}
|
||||
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "wsgi.input", wsgi_req->async_input);
|
||||
|
||||
wsgi_req->async_result = wi->request_subhandler(wsgi_req, wi);
|
||||
|
||||
UWSGI_RELEASE_GIL
|
||||
|
||||
@@ -2,10 +2,66 @@
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
extern struct uwsgi_python up;
|
||||
extern PyTypeObject uwsgi_InputType;
|
||||
|
||||
void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_app *wi) {
|
||||
|
||||
PyObject *zero;
|
||||
int i;
|
||||
PyObject *pydictkey, *pydictvalue;
|
||||
char *path_info;
|
||||
|
||||
for (i = 0; i < wsgi_req->var_cnt; i += 2) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_debug("%.*s: %.*s\n", wsgi_req->hvec[i].iov_len, wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i+1].iov_len, wsgi_req->hvec[i+1].iov_base);
|
||||
#endif
|
||||
#ifdef PYTHREE
|
||||
pydictkey = PyUnicode_DecodeLatin1(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len, NULL);
|
||||
pydictvalue = PyUnicode_DecodeLatin1(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len, NULL);
|
||||
#else
|
||||
pydictkey = PyString_FromStringAndSize(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len);
|
||||
pydictvalue = PyString_FromStringAndSize(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len);
|
||||
#endif
|
||||
PyDict_SetItem(wsgi_req->async_environ, pydictkey, pydictvalue);
|
||||
Py_DECREF(pydictkey);
|
||||
Py_DECREF(pydictvalue);
|
||||
}
|
||||
|
||||
if (wsgi_req->uh.modifier1 == UWSGI_MODIFIER_MANAGE_PATH_INFO) {
|
||||
wsgi_req->uh.modifier1 = 0;
|
||||
pydictkey = PyDict_GetItemString(wsgi_req->async_environ, "SCRIPT_NAME");
|
||||
if (pydictkey) {
|
||||
if (PyString_Check(pydictkey)) {
|
||||
pydictvalue = PyDict_GetItemString(wsgi_req->async_environ, "PATH_INFO");
|
||||
if (pydictvalue) {
|
||||
if (PyString_Check(pydictvalue)) {
|
||||
path_info = PyString_AsString(pydictvalue);
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "PATH_INFO", PyString_FromString(path_info + PyString_Size(pydictkey)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if async_post is mapped as a file, directly use it as wsgi.input
|
||||
if (wsgi_req->async_post) {
|
||||
#ifdef PYTHREE
|
||||
wsgi_req->async_input = PyFile_FromFd(fileno(wsgi_req->async_post), "wsgi_input", "rb", 0, NULL, NULL, NULL, 0);
|
||||
#else
|
||||
wsgi_req->async_input = PyFile_FromFile(wsgi_req->async_post, "wsgi_input", "r", NULL);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
// create wsgi.input custom object
|
||||
wsgi_req->async_input = (PyObject *) PyObject_New(uwsgi_Input, &uwsgi_InputType);
|
||||
((uwsgi_Input*)wsgi_req->async_input)->wsgi_req = wsgi_req;
|
||||
((uwsgi_Input*)wsgi_req->async_input)->pos = 0;
|
||||
((uwsgi_Input*)wsgi_req->async_input)->readline_pos = 0;
|
||||
((uwsgi_Input*)wsgi_req->async_input)->readline_max_size = 0;
|
||||
|
||||
}
|
||||
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "wsgi.input", wsgi_req->async_input);
|
||||
|
||||
#ifdef UWSGI_SENDFILE
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "wsgi.file_wrapper", wi->sendfile);
|
||||
|
||||
Reference in New Issue
Block a user