commit cb482d8e8f45f933f55361f45ec852fcf332740d
parent 966eaf8f7aff4869d1ff39408a368f6ac08aeeaa
Author: Joris Vink <joris@coders.se>
Date: Wed, 14 Nov 2018 10:03:32 +0100
Always use http_response_stream() in req.response.
Keep around the python bytes object while we stream the contents
of it out over the wire. This avoids an entire copy of the data.
Diffstat:
1 file changed, 26 insertions(+), 6 deletions(-)
diff --git a/src/python.c b/src/python.c
@@ -37,6 +37,7 @@ static PyObject *python_import(const char *);
static PyObject *pyconnection_alloc(struct connection *);
static PyObject *python_callable(PyObject *, const char *);
+static int pyhttp_response_sent(struct netbuf *);
static PyObject *pyhttp_file_alloc(struct http_file *);
static PyObject *pyhttp_request_alloc(const struct http_request *);
@@ -2544,24 +2545,43 @@ pyhttp_file_alloc(struct http_file *file)
static PyObject *
pyhttp_response(struct pyhttp_request *pyreq, PyObject *args)
{
- const char *body;
- int status, len;
+ char *ptr;
+ PyObject *data;
+ Py_ssize_t length;
+ int status;
- len = -1;
+ length = -1;
- if (!PyArg_ParseTuple(args, "iy#", &status, &body, &len))
+ if (!PyArg_ParseTuple(args, "iS", &status, &data))
return (NULL);
- if (len < 0) {
+ if (PyBytes_AsStringAndSize(data, &ptr, &length) == -1)
+ return (NULL);
+
+ if (length < 0) {
PyErr_SetString(PyExc_TypeError, "invalid length");
return (NULL);
}
- http_response(pyreq->req, status, body, len);
+ Py_INCREF(data);
+
+ http_response_stream(pyreq->req, status, ptr, length,
+ pyhttp_response_sent, data);
Py_RETURN_TRUE;
}
+static int
+pyhttp_response_sent(struct netbuf *nb)
+{
+ PyObject *data;
+
+ data = nb->extra;
+ Py_DECREF(data);
+
+ return (KORE_RESULT_OK);
+}
+
static PyObject *
pyhttp_response_header(struct pyhttp_request *pyreq, PyObject *args)
{