diff --git a/plugins/python/raw.c b/plugins/python/raw.c index b4e077ae..c577bf1a 100644 --- a/plugins/python/raw.c +++ b/plugins/python/raw.c @@ -7,16 +7,41 @@ static int manage_raw_response(struct wsgi_request *wsgi_req) { int ret = 0; if (!wsgi_req->async_force_again) { ret = uwsgi_python_send_body(wsgi_req, (PyObject *) wsgi_req->async_result); - } + if (ret == 0) { + if (PyInt_Check((PyObject *) wsgi_req->async_result) || PyObject_HasAttrString((PyObject *) wsgi_req->async_result, "fileno")) { + // is it a file ? + int fd = PyObject_AsFileDescriptor((PyObject *) wsgi_req->async_result); + if (fd >= 0) { + wsgi_req->sendfile_fd = fd; + uwsgi_response_sendfile_do(wsgi_req, fd, 0, 0); + wsgi_req->sendfile_fd = -1; + return UWSGI_OK; + } + } + } + } if (ret == 0) { if (!wsgi_req->async_placeholder) { - wsgi_req->async_placeholder = PyObject_GetIter((PyObject *)wsgi_req->async_result); - if (!wsgi_req->async_placeholder) return UWSGI_OK; + wsgi_req->async_placeholder = PyObject_GetIter((PyObject *) wsgi_req->async_result); + if (!wsgi_req->async_placeholder) + return UWSGI_OK; } - PyObject *pychunk = PyIter_Next((PyObject *)wsgi_req->async_placeholder); - if (!pychunk) return UWSGI_OK; + PyObject *pychunk = PyIter_Next((PyObject *) wsgi_req->async_placeholder); + if (!pychunk) + return UWSGI_OK; ret = uwsgi_python_send_body(wsgi_req, pychunk); + if (ret == 0) { + if (PyInt_Check(pychunk) || PyObject_HasAttrString(pychunk, "fileno")) { + // is it a file ? + int fd = PyObject_AsFileDescriptor(pychunk); + if (fd >= 0) { + wsgi_req->sendfile_fd = fd; + uwsgi_response_sendfile_do(wsgi_req, fd, 0, 0); + wsgi_req->sendfile_fd = -1; + } + } + } Py_DECREF(pychunk); return UWSGI_AGAIN; } @@ -24,33 +49,30 @@ static int manage_raw_response(struct wsgi_request *wsgi_req) { } int uwsgi_request_python_raw(struct wsgi_request *wsgi_req) { - if (!up.raw_callable) return UWSGI_OK; + if (!up.raw_callable) + return UWSGI_OK; // back from async if (wsgi_req->async_force_again) { - UWSGI_GET_GIL - int ret = manage_raw_response(wsgi_req); + UWSGI_GET_GIL int ret = manage_raw_response(wsgi_req); if (ret == UWSGI_AGAIN) { wsgi_req->async_force_again = 1; - UWSGI_RELEASE_GIL - return UWSGI_AGAIN; + UWSGI_RELEASE_GIL return UWSGI_AGAIN; } goto end; } - UWSGI_GET_GIL - PyObject *args = PyTuple_New(1); + UWSGI_GET_GIL PyObject * args = PyTuple_New(1); PyTuple_SetItem(args, 0, PyInt_FromLong(wsgi_req->fd)); wsgi_req->async_result = PyEval_CallObject(up.raw_callable, args); Py_DECREF(args); if (wsgi_req->async_result) { - for(;;) { + for (;;) { int ret = manage_raw_response(wsgi_req); if (ret == UWSGI_AGAIN) { wsgi_req->async_force_again = 1; if (uwsgi.async > 1) { - UWSGI_RELEASE_GIL - return UWSGI_AGAIN; + UWSGI_RELEASE_GIL return UWSGI_AGAIN; } continue; } @@ -58,7 +80,8 @@ int uwsgi_request_python_raw(struct wsgi_request *wsgi_req) { } } end: - if (PyErr_Occurred()) PyErr_Print(); + if (PyErr_Occurred()) + PyErr_Print(); if (wsgi_req->async_result) { Py_DECREF((PyObject *) wsgi_req->async_result); }