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 {
|
typedef struct {
|
||||||
nxt_app_request_header_t header;
|
nxt_app_request_header_t header;
|
||||||
nxt_app_request_body_t body;
|
nxt_app_request_body_t body;
|
||||||
|
|
||||||
|
nxt_str_t remote;
|
||||||
} nxt_app_request_t;
|
} 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(&h->version);
|
||||||
|
|
||||||
|
NXT_WRITE(&r->remote);
|
||||||
|
|
||||||
|
NXT_WRITE(&h->host);
|
||||||
NXT_WRITE(&h->content_type);
|
NXT_WRITE(&h->content_type);
|
||||||
NXT_WRITE(&h->content_length);
|
NXT_WRITE(&h->content_length);
|
||||||
|
|
||||||
@@ -503,16 +506,26 @@ nxt_python_run(nxt_task_t *task, nxt_app_rmsg_t *rmsg, nxt_app_wmsg_t *wmsg)
|
|||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
item = NULL;
|
||||||
|
iterator = NULL;
|
||||||
|
|
||||||
|
/* 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_python_write(&run_ctx, buf, size, 1, 1);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
iterator = PyObject_GetIter(result);
|
iterator = PyObject_GetIter(result);
|
||||||
|
|
||||||
/* TODO call result.close() */
|
|
||||||
|
|
||||||
Py_DECREF(result);
|
|
||||||
|
|
||||||
if (nxt_slow_path(iterator == NULL)) {
|
if (nxt_slow_path(iterator == NULL)) {
|
||||||
nxt_log_error(NXT_LOG_ERR, task->log,
|
nxt_log_error(NXT_LOG_ERR, task->log,
|
||||||
"the application returned not an iterable object");
|
"the application returned not an iterable object");
|
||||||
return NXT_ERROR;
|
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
while((item = PyIter_Next(iterator))) {
|
while((item = PyIter_Next(iterator))) {
|
||||||
@@ -521,10 +534,7 @@ nxt_python_run(nxt_task_t *task, nxt_app_rmsg_t *rmsg, nxt_app_wmsg_t *wmsg)
|
|||||||
nxt_log_error(NXT_LOG_ERR, task->log,
|
nxt_log_error(NXT_LOG_ERR, task->log,
|
||||||
"the application returned not a bytestring object");
|
"the application returned not a bytestring object");
|
||||||
|
|
||||||
Py_DECREF(item);
|
goto fail;
|
||||||
Py_DECREF(iterator);
|
|
||||||
|
|
||||||
return NXT_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size = PyBytes_GET_SIZE(item);
|
size = PyBytes_GET_SIZE(item);
|
||||||
@@ -541,13 +551,37 @@ nxt_python_run(nxt_task_t *task, nxt_app_rmsg_t *rmsg, nxt_app_wmsg_t *wmsg)
|
|||||||
|
|
||||||
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)) {
|
if (nxt_slow_path(PyErr_Occurred() != NULL)) {
|
||||||
nxt_log_error(NXT_LOG_ERR, task->log, "an application error occurred");
|
nxt_log_error(NXT_LOG_ERR, task->log, "an application error occurred");
|
||||||
PyErr_Print();
|
PyErr_Print();
|
||||||
return NXT_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Py_DECREF(result);
|
||||||
|
|
||||||
return NXT_OK;
|
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;
|
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;
|
return environ;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
@@ -766,9 +766,14 @@ static PyObject *
|
|||||||
nxt_python_get_environ(nxt_task_t *task, nxt_app_rmsg_t *rmsg)
|
nxt_python_get_environ(nxt_task_t *task, nxt_app_rmsg_t *rmsg)
|
||||||
{
|
{
|
||||||
size_t s;
|
size_t s;
|
||||||
|
u_char *colon;
|
||||||
PyObject *environ;
|
PyObject *environ;
|
||||||
nxt_int_t rc;
|
nxt_int_t rc;
|
||||||
nxt_str_t n, v, target, path, query;
|
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);
|
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("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_TYPE");
|
||||||
NXT_READ("CONTENT_LENGTH");
|
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;
|
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;
|
h = &ap->r.header;
|
||||||
|
|||||||
Reference in New Issue
Block a user