summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGraham.Dumpleton <devnull@localhost>2007-07-04 07:21:45 +0000
committerGraham.Dumpleton <devnull@localhost>2007-07-04 07:21:45 +0000
commita52f2e6af7cc5871d2bb0debbe1215f5a8cc14af (patch)
tree93fac0d674516d8c9a1b0bb7a6a40969bc2e6def
parent4550ad32d276c962abc328ad6b7ba2b2325bd0a5 (diff)
downloadmod_wsgi-a52f2e6af7cc5871d2bb0debbe1215f5a8cc14af.tar.gz
Not detecting client connection being closed when streaming data. Also use
bucket brigade directly when Apache 2.X to avoid increases in memory use over time when streaming data.
-rw-r--r--mod_wsgi.c52
1 files changed, 49 insertions, 3 deletions
diff --git a/mod_wsgi.c b/mod_wsgi.c
index 711cfcb..53eb88b 100644
--- a/mod_wsgi.c
+++ b/mod_wsgi.c
@@ -1810,6 +1810,9 @@ static PyTypeObject Input_Type = {
typedef struct {
PyObject_HEAD
request_rec *r;
+#if AP_SERVER_MAJORVERSION_NUMBER >= 2
+ apr_bucket_brigade *bb;
+#endif
WSGIRequestConfig *config;
InputObject *input;
LogObject *log;
@@ -1831,6 +1834,10 @@ static AdapterObject *newAdapterObject(request_rec *r)
self->r = r;
+#if AP_SERVER_MAJORVERSION_NUMBER >= 2
+ self->bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
+#endif
+
self->config = (WSGIRequestConfig *)ap_get_module_config(r->request_config,
&wsgi_module);
@@ -1847,6 +1854,10 @@ static AdapterObject *newAdapterObject(request_rec *r)
static void Adapter_dealloc(AdapterObject *self)
{
+#if AP_SERVER_MAJORVERSION_NUMBER >= 2
+ apr_brigade_destroy(self->bb);
+#endif
+
Py_XDECREF(self->headers);
Py_XDECREF(self->sequence);
@@ -2053,9 +2064,44 @@ static int Adapter_output(AdapterObject *self, const char *data, int length)
}
if (length) {
- ap_rwrite(data, length, self->r);
- if (!self->config->output_buffering)
- ap_rflush(self->r);
+#if AP_SERVER_MAJORVERSION_NUMBER >= 2
+ apr_bucket *b;
+
+ if (self->r->connection->aborted) {
+ PyErr_SetString(PyExc_IOError, "client connection closed");
+ return 0;
+ }
+
+ b = apr_bucket_transient_create(data, length,
+ self->r->connection->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(self->bb, b);
+
+ if (!self->config->output_buffering) {
+ b = apr_bucket_flush_create(self->r->connection->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(self->bb, b);
+ }
+
+ if (ap_pass_brigade(self->r->output_filters,
+ self->bb) != APR_SUCCESS) {
+ PyErr_SetString(PyExc_IOError, "failed to pass data "
+ "to bucket brigade");
+ return 0;
+ }
+
+ apr_brigade_cleanup(self->bb);
+#else
+ if (ap_rwrite(data, length, self->r) == -1) {
+ PyErr_SetString(PyExc_IOError, "failed to write data");
+ return 0;
+ }
+
+ if (!self->config->output_buffering) {
+ if (ap_rflush(self->r) == -1) {
+ PyErr_SetString(PyExc_IOError, "failed to flush data");
+ return 0;
+ }
+ }
+#endif
}
return 1;