summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMax Romanov <max.romanov@nginx.com>2017-07-05 13:31:53 +0300
committerMax Romanov <max.romanov@nginx.com>2017-07-05 13:31:53 +0300
commit41e2678110a575dfa751c284c393f42088760a0a (patch)
treeac75e443be3aa91f2425499d9f6dd45119583311
parentf3107f3896c199a5bc166f57ccd9fef2823ccdaf (diff)
downloadunit-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.h2
-rw-r--r--src/nxt_python_wsgi.c146
-rw-r--r--src/nxt_router.c3
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;