summaryrefslogtreecommitdiffhomepage
path: root/src/nxt_python_wsgi.c
diff options
context:
space:
mode:
authorValentin Bartenev <vbart@nginx.com>2019-11-14 17:48:48 +0300
committerValentin Bartenev <vbart@nginx.com>2019-11-14 17:48:48 +0300
commite189d0a96c4020adca73f8fcff04255b6c9a1c5a (patch)
treeedede733acf5c5e4f447a57b501faf788d7d916c /src/nxt_python_wsgi.c
parentc7726c0eb1157ea90cd0e6eb1d0f29587f2148c0 (diff)
downloadunit-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.c23
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;