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).
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
|
||||
@@ -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() */
|
||||
|
||||
Py_DECREF(result);
|
||||
|
||||
if (nxt_slow_path(iterator == NULL)) {
|
||||
nxt_log_error(NXT_LOG_ERR, task->log,
|
||||
"the application returned not an iterable object");
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
while((item = PyIter_Next(iterator))) {
|
||||
|
||||
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);
|
||||
Py_DECREF(iterator);
|
||||
|
||||
return NXT_ERROR;
|
||||
}
|
||||
/* Shortcut: avoid iterate over result string symbols. */
|
||||
if (PyBytes_Check(result) != 0) {
|
||||
|
||||
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);
|
||||
nxt_python_write(&run_ctx, buf, size, 1, 1);
|
||||
|
||||
Py_DECREF(item);
|
||||
} else {
|
||||
|
||||
iterator = PyObject_GetIter(result);
|
||||
|
||||
if (nxt_slow_path(iterator == NULL)) {
|
||||
nxt_log_error(NXT_LOG_ERR, task->log,
|
||||
"the application returned not an iterable object");
|
||||
|
||||
goto fail;
|
||||
}
|
||||
|
||||
while((item = PyIter_Next(iterator))) {
|
||||
|
||||
if (nxt_slow_path(PyBytes_Check(item) == 0)) {
|
||||
nxt_log_error(NXT_LOG_ERR, task->log,
|
||||
"the application returned not a bytestring object");
|
||||
|
||||
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(item);
|
||||
}
|
||||
|
||||
Py_DECREF(iterator);
|
||||
|
||||
nxt_python_write(&run_ctx, NULL, 0, 1, 1);
|
||||
|
||||
if (PyObject_HasAttrString(result, "close")) {
|
||||
PyObject_CallMethod(result, (char *) "close", NULL);
|
||||
}
|
||||
}
|
||||
|
||||
Py_DECREF(iterator);
|
||||
|
||||
nxt_python_write(&run_ctx, NULL, 0, 1, 1);
|
||||
|
||||
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");
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user