diff options
author | Max Romanov <max.romanov@nginx.com> | 2017-07-05 13:31:53 +0300 |
---|---|---|
committer | Max Romanov <max.romanov@nginx.com> | 2017-07-05 13:31:53 +0300 |
commit | 41e2678110a575dfa751c284c393f42088760a0a (patch) | |
tree | ac75e443be3aa91f2425499d9f6dd45119583311 | |
parent | f3107f3896c199a5bc166f57ccd9fef2823ccdaf (diff) | |
download | unit-41e2678110a575dfa751c284c393f42088760a0a.tar.gz unit-41e2678110a575dfa751c284c393f42088760a0a.tar.bz2 |
Python WSGI: SERVER_NAME, SERVER_PORT fixed, REMOTE_ADDR introduced.
Shortcut: do not iterate over String (or Bytes) return object.
Call 'close()' for return object (if present).
-rw-r--r-- | src/nxt_application.h | 2 | ||||
-rw-r--r-- | src/nxt_python_wsgi.c | 146 | ||||
-rw-r--r-- | src/nxt_router.c | 3 |
3 files changed, 92 insertions, 59 deletions
diff --git a/src/nxt_application.h b/src/nxt_application.h index 9d8b1054..9b51ba6d 100644 --- a/src/nxt_application.h +++ b/src/nxt_application.h @@ -43,6 +43,8 @@ typedef struct { typedef struct { nxt_app_request_header_t header; nxt_app_request_body_t body; + + nxt_str_t remote; } nxt_app_request_t; diff --git a/src/nxt_python_wsgi.c b/src/nxt_python_wsgi.c index 9995e80b..77116162 100644 --- a/src/nxt_python_wsgi.c +++ b/src/nxt_python_wsgi.c @@ -436,6 +436,9 @@ nxt_python_prepare_msg(nxt_task_t *task, nxt_app_request_t *r, NXT_WRITE(&h->version); + NXT_WRITE(&r->remote); + + NXT_WRITE(&h->host); NXT_WRITE(&h->content_type); NXT_WRITE(&h->content_length); @@ -503,51 +506,82 @@ nxt_python_run(nxt_task_t *task, nxt_app_rmsg_t *rmsg, nxt_app_wmsg_t *wmsg) return NXT_ERROR; } - iterator = PyObject_GetIter(result); + item = NULL; + iterator = NULL; - /* TODO call result.close() */ + /* Shortcut: avoid iterate over result string symbols. */ + if (PyBytes_Check(result) != 0) { - Py_DECREF(result); + size = PyBytes_GET_SIZE(item); + buf = (u_char *) PyBytes_AS_STRING(item); - if (nxt_slow_path(iterator == NULL)) { - nxt_log_error(NXT_LOG_ERR, task->log, - "the application returned not an iterable object"); - return NXT_ERROR; - } + nxt_python_write(&run_ctx, buf, size, 1, 1); - while((item = PyIter_Next(iterator))) { + } else { - if (nxt_slow_path(PyBytes_Check(item) == 0)) { - nxt_log_error(NXT_LOG_ERR, task->log, - "the application returned not a bytestring object"); + iterator = PyObject_GetIter(result); - Py_DECREF(item); - Py_DECREF(iterator); + if (nxt_slow_path(iterator == NULL)) { + nxt_log_error(NXT_LOG_ERR, task->log, + "the application returned not an iterable object"); - return NXT_ERROR; + goto fail; } - size = PyBytes_GET_SIZE(item); - buf = (u_char *) PyBytes_AS_STRING(item); + while((item = PyIter_Next(iterator))) { - nxt_debug(task, "nxt_app_write(fake): %d %*s", (int)size, (int)size, - buf); - nxt_python_write(&run_ctx, buf, size, 1, 0); + if (nxt_slow_path(PyBytes_Check(item) == 0)) { + nxt_log_error(NXT_LOG_ERR, task->log, + "the application returned not a bytestring object"); - Py_DECREF(item); - } + goto fail; + } + + size = PyBytes_GET_SIZE(item); + buf = (u_char *) PyBytes_AS_STRING(item); + + nxt_debug(task, "nxt_app_write(fake): %d %*s", (int)size, (int)size, + buf); + nxt_python_write(&run_ctx, buf, size, 1, 0); - Py_DECREF(iterator); + Py_DECREF(item); + } + + Py_DECREF(iterator); - nxt_python_write(&run_ctx, NULL, 0, 1, 1); + nxt_python_write(&run_ctx, NULL, 0, 1, 1); + + if (PyObject_HasAttrString(result, "close")) { + PyObject_CallMethod(result, (char *) "close", NULL); + } + } if (nxt_slow_path(PyErr_Occurred() != NULL)) { nxt_log_error(NXT_LOG_ERR, task->log, "an application error occurred"); PyErr_Print(); - return NXT_ERROR; } + Py_DECREF(result); + return NXT_OK; + +fail: + + if (item != NULL) { + Py_DECREF(item); + } + + if (iterator != NULL) { + Py_DECREF(iterator); + } + + if (PyObject_HasAttrString(result, "close")) { + PyObject_CallMethod(result, (char *) "close", NULL); + } + + Py_DECREF(result); + + return NXT_ERROR; } @@ -669,40 +703,6 @@ nxt_python_create_environ(nxt_thread_t *thr) goto fail; } - - obj = PyString_FromString("localhost"); - - if (nxt_slow_path(obj == NULL)) { - nxt_log_alert(thr->log, - "Python failed to create the \"SERVER_NAME\" environ value"); - goto fail; - } - - if (nxt_slow_path(PyDict_SetItemString(environ, "SERVER_NAME", obj) != 0)) { - nxt_log_alert(thr->log, - "Python failed to set the \"SERVER_NAME\" environ value"); - goto fail; - } - - Py_DECREF(obj); - - - obj = PyString_FromString("80"); - - if (nxt_slow_path(obj == NULL)) { - nxt_log_alert(thr->log, - "Python failed to create the \"SERVER_PORT\" environ value"); - goto fail; - } - - if (nxt_slow_path(PyDict_SetItemString(environ, "SERVER_PORT", obj) != 0)) { - nxt_log_alert(thr->log, - "Python failed to set the \"SERVER_PORT\" environ value"); - goto fail; - } - - Py_DECREF(obj); - return environ; fail: @@ -766,9 +766,14 @@ static PyObject * nxt_python_get_environ(nxt_task_t *task, nxt_app_rmsg_t *rmsg) { size_t s; + u_char *colon; PyObject *environ; nxt_int_t rc; nxt_str_t n, v, target, path, query; + nxt_str_t host, server_name, server_port; + + static nxt_str_t def_host = nxt_string("localhost"); + static nxt_str_t def_port = nxt_string("80"); environ = PyDict_Copy(nxt_py_environ_ptyp); @@ -818,6 +823,29 @@ nxt_python_get_environ(nxt_task_t *task, nxt_app_rmsg_t *rmsg) NXT_READ("SERVER_PROTOCOL"); + NXT_READ("REMOTE_ADDR"); + + RC(nxt_app_msg_read_str(task, rmsg, &host)); + + if (host.length == 0) { + host = def_host; + } + + server_name = host; + colon = nxt_memchr(host.start, ':', host.length); + + if (colon != NULL) { + server_name.length = colon - host.start; + + server_port.start = colon + 1; + server_port.length = host.length - server_name.length - 1; + } else { + server_port = def_port; + } + + RC(nxt_python_add_env(task, environ, "SERVER_NAME", &server_name)); + RC(nxt_python_add_env(task, environ, "SERVER_PORT", &server_port)); + NXT_READ("CONTENT_TYPE"); NXT_READ("CONTENT_LENGTH"); diff --git a/src/nxt_router.c b/src/nxt_router.c index 77d830be..34d163dc 100644 --- a/src/nxt_router.c +++ b/src/nxt_router.c @@ -1105,6 +1105,9 @@ nxt_router_conn_http_header_parse(nxt_task_t *task, void *obj, void *data) } c->socket.data = ap; + + ap->r.remote.start = nxt_sockaddr_address(c->remote); + ap->r.remote.length = c->remote->address_length; } h = &ap->r.header; |