mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-08-28 17:55:39 +00:00
258 lines
6.8 KiB
C
258 lines
6.8 KiB
C
#include "uwsgi.h"
|
|
|
|
int manage_python_response(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req) {
|
|
|
|
PyObject *pychunk ;
|
|
ssize_t wsize ;
|
|
#ifdef UWSGI_SENDFILE
|
|
ssize_t sf_len = 0 ;
|
|
#endif
|
|
|
|
// return or yield ?
|
|
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;
|
|
}
|
|
|
|
#ifdef PYTHREE
|
|
if (PyBytes_Check((PyObject *)wsgi_req->async_result)) {
|
|
if ((wsize = write(wsgi_req->poll.fd, PyBytes_AsString(wsgi_req->async_result), PyBytes_Size(wsgi_req->async_result))) < 0) {
|
|
uwsgi_error("write()");
|
|
goto clear;
|
|
}
|
|
wsgi_req->response_size += wsize;
|
|
goto clear;
|
|
}
|
|
#endif
|
|
|
|
#ifdef UWSGI_SENDFILE
|
|
if (wsgi_req->sendfile_obj == wsgi_req->async_result && wsgi_req->sendfile_fd != -1) {
|
|
sf_len = uwsgi_sendfile(uwsgi, wsgi_req);
|
|
if (sf_len < 1) goto clear;
|
|
wsgi_req->response_size += sf_len ;
|
|
#ifdef UWSGI_ASYNC
|
|
if (uwsgi->async > 1) {
|
|
if (wsgi_req->response_size < wsgi_req->sendfile_fd_size) {
|
|
return UWSGI_AGAIN;
|
|
}
|
|
}
|
|
#endif
|
|
goto clear;
|
|
}
|
|
#endif
|
|
|
|
#ifdef UWSGI_WSGI2
|
|
// is it a tuple (WSGI2.0) ?
|
|
// move it to another hook !!!
|
|
if (PyTuple_Check((PyObject *)wsgi_req->async_result)) {
|
|
if (PyTuple_Size((PyObject *)wsgi_req->async_result) != 3) {
|
|
uwsgi_log("invalid WSGI2.0 response size: %d.\n", PyTuple_Size((PyObject *)wsgi_req->async_result));
|
|
goto clear;
|
|
}
|
|
#ifdef UWSGI_DEBUG
|
|
uwsgi_debug("wsgi_req->async_result = %d\n", ((PyObject *)wsgi_req->async_result)->ob_refcnt);
|
|
#endif
|
|
if (py_uwsgi_spit(NULL, (PyObject *)wsgi_req->async_result) == Py_None) {
|
|
goto clear;
|
|
}
|
|
#ifdef UWSGI_DEBUG
|
|
uwsgi_debug("wsgi_req->async_result = %d\n", ((PyObject *)wsgi_req->async_result)->ob_refcnt);
|
|
#endif
|
|
wsgi_req->async_orig_result = wsgi_req->async_result ;
|
|
wsgi_req->async_result = PyTuple_GetItem((PyObject *)wsgi_req->async_result, 2);
|
|
#ifdef UWSGI_DEBUG
|
|
uwsgi_debug("wsgi_req->async_orig_result = %d\n", ((PyObject *)wsgi_req->async_orig_result)->ob_refcnt);
|
|
uwsgi_debug("wsgi_req->async_result = %d\n", ((PyObject *)wsgi_req->async_result)->ob_refcnt);
|
|
#endif
|
|
return UWSGI_AGAIN;
|
|
}
|
|
#endif
|
|
|
|
// ok its a yield
|
|
if (!wsgi_req->async_placeholder) {
|
|
wsgi_req->async_placeholder = PyObject_GetIter(wsgi_req->async_result);
|
|
if (!wsgi_req->async_placeholder) {
|
|
goto clear2;
|
|
}
|
|
#ifdef UWSGI_ASYNC
|
|
if (uwsgi->async > 1) {
|
|
return UWSGI_AGAIN;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
pychunk = PyIter_Next(wsgi_req->async_placeholder) ;
|
|
|
|
if (!pychunk) {
|
|
if (PyErr_Occurred()) PyErr_Print();
|
|
goto clear;
|
|
}
|
|
|
|
|
|
|
|
if (PyString_Check(pychunk)) {
|
|
if ((wsize = write(wsgi_req->poll.fd, PyString_AsString(pychunk), PyString_Size(pychunk))) < 0) {
|
|
uwsgi_error("write()");
|
|
Py_DECREF(pychunk);
|
|
goto clear;
|
|
}
|
|
wsgi_req->response_size += wsize;
|
|
}
|
|
|
|
#ifdef PYTHREE
|
|
else if (PyBytes_Check(pychunk)) {
|
|
if ((wsize = write(wsgi_req->poll.fd, PyBytes_AsString(pychunk), PyBytes_Size(pychunk))) < 0) {
|
|
uwsgi_error("write()");
|
|
Py_DECREF(pychunk);
|
|
goto clear;
|
|
}
|
|
wsgi_req->response_size += wsize;
|
|
}
|
|
#endif
|
|
|
|
#ifdef UWSGI_SENDFILE
|
|
else if (wsgi_req->sendfile_obj == pychunk && wsgi_req->sendfile_fd != -1) {
|
|
sf_len = uwsgi_sendfile(uwsgi, wsgi_req);
|
|
if (sf_len < 1) goto clear;
|
|
wsgi_req->response_size += sf_len ;
|
|
}
|
|
#endif
|
|
|
|
Py_DECREF(pychunk);
|
|
return UWSGI_AGAIN ;
|
|
|
|
clear:
|
|
if (wsgi_req->sendfile_fd != -1) {
|
|
Py_DECREF((PyObject *)wsgi_req->async_sendfile);
|
|
}
|
|
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);
|
|
#ifdef UWSGI_WSGI2
|
|
Py_XDECREF((PyObject *)wsgi_req->async_orig_result);
|
|
#endif
|
|
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);
|
|
}
|
|
#ifdef UWSGI_WSGI2
|
|
if (wsgi_req->async_orig_result) {
|
|
uwsgi_debug("wsgi_req->async_orig_result: %d\n", ((PyObject *)wsgi_req->async_orig_result)->ob_refcnt);
|
|
}
|
|
#endif
|
|
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
|
|
return UWSGI_OK;
|
|
}
|
|
|
|
|
|
PyObject *python_call(PyObject *callable, PyObject *args, int catch) {
|
|
|
|
PyObject *pyret;
|
|
|
|
pyret = PyEval_CallObject(callable, args);
|
|
if (PyErr_Occurred()) {
|
|
if (!catch) {
|
|
PyErr_Print();
|
|
}
|
|
}
|
|
|
|
#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 uwsgi_server *uwsgi, struct wsgi_request *wsgi_req, PyObject *callable, PyObject *args) {
|
|
|
|
wsgi_req->async_result = python_call(callable, args, 0);
|
|
|
|
if (wsgi_req->async_result) {
|
|
while ( manage_python_response(uwsgi, wsgi_req) != UWSGI_OK) {
|
|
#ifdef UWSGI_ASYNC
|
|
if (uwsgi->async > 1) {
|
|
return UWSGI_AGAIN;
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
return UWSGI_OK;
|
|
}
|
|
|
|
void init_pyargv(struct uwsgi_server *uwsgi) {
|
|
|
|
char *ap;
|
|
|
|
#ifdef PYTHREE
|
|
wchar_t pname[6];
|
|
mbstowcs(pname, "uwsgi", 6);
|
|
uwsgi->py_argv[0] = pname;
|
|
#else
|
|
uwsgi->py_argv[0] = "uwsgi";
|
|
#endif
|
|
|
|
if (uwsgi->pyargv != NULL && !uwsgi->pyargc) {
|
|
uwsgi->pyargc++;
|
|
#ifdef PYTHREE
|
|
wchar_t *wcargv = malloc( sizeof( wchar_t ) * (strlen(uwsgi->pyargv)+1));
|
|
if (!wcargv) {
|
|
uwsgi_error("malloc()");
|
|
exit(1);
|
|
}
|
|
memset(wcargv, 0, sizeof( wchar_t ) * (strlen(uwsgi->pyargv)+1));
|
|
#endif
|
|
|
|
#ifdef __sun__
|
|
// FIX THIS !!!
|
|
ap = strtok(uwsgi->pyargv, " ");
|
|
while ((ap = strtok(NULL, " ")) != NULL) {
|
|
#else
|
|
while ((ap = strsep(&uwsgi->pyargv, " \t")) != NULL) {
|
|
#endif
|
|
if (*ap != '\0') {
|
|
#ifdef PYTHREE
|
|
mbstowcs( wcargv + strlen(ap), ap, strlen(ap));
|
|
uwsgi->py_argv[uwsgi->pyargc] = wcargv + strlen(ap);
|
|
#else
|
|
uwsgi->py_argv[uwsgi->pyargc] = ap;
|
|
#endif
|
|
uwsgi->pyargc++;
|
|
}
|
|
if (uwsgi->pyargc + 1 > MAX_PYARGV)
|
|
break;
|
|
}
|
|
}
|
|
|
|
PySys_SetArgv(uwsgi->pyargc, uwsgi->py_argv);
|
|
}
|