From 8b07fbbedc8acc1603947cb5b5915b94692676c5 Mon Sep 17 00:00:00 2001 From: Roberta Giordano Date: Wed, 22 May 2013 07:16:34 +0200 Subject: [PATCH] honour read() method if original file_wrapper object is not a file --- plugins/python/wsgi_subhandler.c | 67 ++++++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 8 deletions(-) diff --git a/plugins/python/wsgi_subhandler.c b/plugins/python/wsgi_subhandler.c index 303efca1..10da368d 100644 --- a/plugins/python/wsgi_subhandler.c +++ b/plugins/python/wsgi_subhandler.c @@ -143,10 +143,35 @@ int uwsgi_response_subhandler_wsgi(struct wsgi_request *wsgi_req) { } - if (wsgi_req->sendfile_obj == wsgi_req->async_result && wsgi_req->sendfile_fd != -1) { - UWSGI_RELEASE_GIL - uwsgi_response_sendfile_do(wsgi_req, wsgi_req->sendfile_fd, 0, 0); - UWSGI_GET_GIL + if (wsgi_req->sendfile_obj == wsgi_req->async_result) { + if (wsgi_req->sendfile_fd >= 0) { + UWSGI_RELEASE_GIL + uwsgi_response_sendfile_do(wsgi_req, wsgi_req->sendfile_fd, 0, 0); + UWSGI_GET_GIL + } + else { + // we do not have an iterable, check for read() method + if (PyObject_HasAttrString((PyObject *)wsgi_req->async_result, "read")) { + PyObject *read_method = PyObject_GetAttrString((PyObject *)wsgi_req->async_result, "read"); + PyObject *read_method_args = PyTuple_New(0); + PyObject *read_method_output = PyEval_CallObject(read_method, read_method_args); + if (PyErr_Occurred()) { + uwsgi_manage_exception(wsgi_req, 0); + } + if (read_method_output) { + if (PyString_Check(read_method_output)) { + char *content = PyString_AsString(read_method_output); + size_t content_len = PyString_Size(read_method_output); + UWSGI_RELEASE_GIL + uwsgi_response_write_body_do(wsgi_req, content, content_len); + UWSGI_GET_GIL + } + Py_DECREF(read_method_output); + } + Py_DECREF(read_method_args); + Py_DECREF(read_method); + } + } uwsgi_py_check_write_errors { uwsgi_py_write_exception(wsgi_req); } @@ -190,10 +215,36 @@ exception: } } - else if (wsgi_req->sendfile_obj == pychunk && wsgi_req->sendfile_fd != -1) { - UWSGI_RELEASE_GIL - uwsgi_response_sendfile_do(wsgi_req, wsgi_req->sendfile_fd, 0, 0); - UWSGI_GET_GIL + else if (wsgi_req->sendfile_obj == pychunk) { + if (wsgi_req->sendfile_fd >= 0) { + UWSGI_RELEASE_GIL + uwsgi_response_sendfile_do(wsgi_req, wsgi_req->sendfile_fd, 0, 0); + UWSGI_GET_GIL + } + else { + // we do not have an iterable, check for read() method + if (PyObject_HasAttrString(pychunk, "read")) { + PyObject *read_method = PyObject_GetAttrString(pychunk, "read"); + PyObject *read_method_args = PyTuple_New(0); + PyObject *read_method_output = PyEval_CallObject(read_method, read_method_args); + if (PyErr_Occurred()) { + uwsgi_manage_exception(wsgi_req, 0); + } + if (read_method_output) { + if (PyString_Check(read_method_output)) { + char *content = PyString_AsString(read_method_output); + size_t content_len = PyString_Size(read_method_output); + UWSGI_RELEASE_GIL + uwsgi_response_write_body_do(wsgi_req, content, content_len); + UWSGI_GET_GIL + } + Py_DECREF(read_method_output); + } + Py_DECREF(read_method_args); + Py_DECREF(read_method); + } + } + uwsgi_py_check_write_errors { uwsgi_py_write_exception(wsgi_req); Py_DECREF(pychunk);