diff options
author | Valentin Bartenev <vbart@nginx.com> | 2019-11-14 17:48:48 +0300 |
---|---|---|
committer | Valentin Bartenev <vbart@nginx.com> | 2019-11-14 17:48:48 +0300 |
commit | e189d0a96c4020adca73f8fcff04255b6c9a1c5a (patch) | |
tree | edede733acf5c5e4f447a57b501faf788d7d916c /src | |
parent | c7726c0eb1157ea90cd0e6eb1d0f29587f2148c0 (diff) | |
download | unit-e189d0a96c4020adca73f8fcff04255b6c9a1c5a.tar.gz unit-e189d0a96c4020adca73f8fcff04255b6c9a1c5a.tar.bz2 |
Python: fixed handling of errors on response object iteration.
According to the documentation, PyIter_Next():
| If there are no remaining values, returns NULL with no exception set.
| If an error occurs while retrieving the item, returns NULL and passes
| along the exception.
Previously, this exception wasn't properly handled and the response was
finalized as successful.
This issue was introduced in b0148ec28c4d.
A check for PyErr_Occurred() located in the code below might print this
traceback or occasionally catch an exception from one of the two response
close() calls.
Albeit that exceptions from the close() calls also need to be catched,
it's clear that this particular check wasn't supposed to do so. This is
another issue and it will be fixed later.
Diffstat (limited to '')
-rw-r--r-- | src/nxt_python_wsgi.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/src/nxt_python_wsgi.c b/src/nxt_python_wsgi.c index 6c726a20..e95d4898 100644 --- a/src/nxt_python_wsgi.c +++ b/src/nxt_python_wsgi.c @@ -429,9 +429,21 @@ nxt_python_request_handler(nxt_unit_request_info_t *req) goto fail; } - while (run_ctx.bytes_sent < run_ctx.content_length - && (item = PyIter_Next(iterator))) - { + while (run_ctx.bytes_sent < run_ctx.content_length) { + item = PyIter_Next(iterator); + + if (item == NULL) { + if (nxt_slow_path(PyErr_Occurred() != NULL)) { + nxt_unit_req_error(req, "Python failed to iterate over " + "the application response object"); + PyErr_Print(); + + goto fail; + } + + break; + } + if (nxt_slow_path(!PyBytes_Check(item))) { nxt_unit_req_error(req, "the application returned " "not a bytestring object"); @@ -454,11 +466,6 @@ nxt_python_request_handler(nxt_unit_request_info_t *req) } } - if (nxt_slow_path(PyErr_Occurred() != NULL)) { - nxt_unit_req_error(req, "an application error occurred"); - PyErr_Print(); - } - Py_DECREF(result); rc = NXT_UNIT_OK; |