Python: bytearray body support for ASGI module.
@filiphanes requested support for bytearray and memoryview in the request body here: <https://github.com/nginx/unit/issues/648> This patch implements bytearray body support only. Memoryview body still need to be implemented.
This commit is contained in:
committed by
andrey-zelenkov
parent
f71ead5fa5
commit
697a585062
@@ -78,6 +78,12 @@ can be used as a unique request identifier.
|
|||||||
</para>
|
</para>
|
||||||
</change>
|
</change>
|
||||||
|
|
||||||
|
<change type="feature">
|
||||||
|
<para>
|
||||||
|
bytearray in response body for ASGI applications.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
<change type="feature">
|
<change type="feature">
|
||||||
<para>
|
<para>
|
||||||
ServerRequest.flushHeaders() implemented in Node.js module to make it compatible
|
ServerRequest.flushHeaders() implemented in Node.js module to make it compatible
|
||||||
|
|||||||
@@ -362,16 +362,6 @@ nxt_py_asgi_http_response_body(nxt_py_asgi_http_t *http, PyObject *dict)
|
|||||||
Py_ssize_t body_len, body_off;
|
Py_ssize_t body_len, body_off;
|
||||||
nxt_py_asgi_ctx_data_t *ctx_data;
|
nxt_py_asgi_ctx_data_t *ctx_data;
|
||||||
|
|
||||||
body = PyDict_GetItem(dict, nxt_py_body_str);
|
|
||||||
if (nxt_slow_path(body != NULL && !PyBytes_Check(body))) {
|
|
||||||
return PyErr_Format(PyExc_TypeError, "'body' is not a byte string");
|
|
||||||
}
|
|
||||||
|
|
||||||
more_body = PyDict_GetItem(dict, nxt_py_more_body_str);
|
|
||||||
if (nxt_slow_path(more_body != NULL && !PyBool_Check(more_body))) {
|
|
||||||
return PyErr_Format(PyExc_TypeError, "'more_body' is not a bool");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nxt_slow_path(http->complete)) {
|
if (nxt_slow_path(http->complete)) {
|
||||||
return PyErr_Format(PyExc_RuntimeError,
|
return PyErr_Format(PyExc_RuntimeError,
|
||||||
"Unexpected ASGI message 'http.response.body' "
|
"Unexpected ASGI message 'http.response.body' "
|
||||||
@@ -382,10 +372,27 @@ nxt_py_asgi_http_response_body(nxt_py_asgi_http_t *http, PyObject *dict)
|
|||||||
return PyErr_Format(PyExc_RuntimeError, "Concurrent send");
|
return PyErr_Format(PyExc_RuntimeError, "Concurrent send");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
more_body = PyDict_GetItem(dict, nxt_py_more_body_str);
|
||||||
|
if (nxt_slow_path(more_body != NULL && !PyBool_Check(more_body))) {
|
||||||
|
return PyErr_Format(PyExc_TypeError, "'more_body' is not a bool");
|
||||||
|
}
|
||||||
|
|
||||||
|
body = PyDict_GetItem(dict, nxt_py_body_str);
|
||||||
|
|
||||||
if (body != NULL) {
|
if (body != NULL) {
|
||||||
|
if (PyBytes_Check(body)) {
|
||||||
body_str = PyBytes_AS_STRING(body);
|
body_str = PyBytes_AS_STRING(body);
|
||||||
body_len = PyBytes_GET_SIZE(body);
|
body_len = PyBytes_GET_SIZE(body);
|
||||||
|
|
||||||
|
} else if (PyByteArray_Check(body)) {
|
||||||
|
body_str = PyByteArray_AS_STRING(body);
|
||||||
|
body_len = PyByteArray_GET_SIZE(body);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return PyErr_Format(PyExc_TypeError,
|
||||||
|
"'body' is not a byte string or bytearray");
|
||||||
|
}
|
||||||
|
|
||||||
nxt_unit_req_debug(http->req, "asgi_http_response_body: %d, %d",
|
nxt_unit_req_debug(http->req, "asgi_http_response_body: %d, %d",
|
||||||
(int) body_len, (more_body == Py_True) );
|
(int) body_len, (more_body == Py_True) );
|
||||||
|
|
||||||
|
|||||||
20
test/python/body_bytearray/asgi.py
Normal file
20
test/python/body_bytearray/asgi.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
async def application(scope, receive, send):
|
||||||
|
assert scope['type'] == 'http'
|
||||||
|
|
||||||
|
body = b''
|
||||||
|
while True:
|
||||||
|
m = await receive()
|
||||||
|
body += m.get('body', b'')
|
||||||
|
if not m.get('more_body', False):
|
||||||
|
body = bytearray(body)
|
||||||
|
break
|
||||||
|
|
||||||
|
await send(
|
||||||
|
{
|
||||||
|
'type': 'http.response.start',
|
||||||
|
'status': 200,
|
||||||
|
'headers': [(b'content-length', str(len(body)).encode())],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
await send({'type': 'http.response.body', 'body': body})
|
||||||
@@ -218,6 +218,14 @@ def test_asgi_application_shm_ack_handle():
|
|||||||
assert resp['body'] == body, 'keep-alive 1'
|
assert resp['body'] == body, 'keep-alive 1'
|
||||||
|
|
||||||
|
|
||||||
|
def test_asgi_application_body_bytearray():
|
||||||
|
client.load('body_bytearray')
|
||||||
|
|
||||||
|
body = '0123456789'
|
||||||
|
|
||||||
|
assert client.post(body=body)['body'] == body
|
||||||
|
|
||||||
|
|
||||||
def test_asgi_keepalive_body():
|
def test_asgi_keepalive_body():
|
||||||
client.load('mirror')
|
client.load('mirror')
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user