summary refs log tree commit diff
path: root/synapse/http/server.py
diff options
context:
space:
mode:
authorRichard van der Hoff <1389908+richvdh@users.noreply.github.com>2018-08-17 14:58:45 +0100
committerGitHub <noreply@github.com>2018-08-17 14:58:45 +0100
commit63260397c6ab6925da0ba3bd24d398001cd8208b (patch)
tree3ef57e48328cd2364afee5810f83d550e0304f8a /synapse/http/server.py
parentMerge pull request #3700 from matrix-org/rav/wait_for_producers (diff)
parentchangelog (diff)
downloadsynapse-63260397c6ab6925da0ba3bd24d398001cd8208b.tar.xz
Merge pull request #3701 from matrix-org/rav/use_producer_for_responses
Use a producer to stream back responses
Diffstat (limited to 'synapse/http/server.py')
-rw-r--r--synapse/http/server.py17
1 files changed, 13 insertions, 4 deletions
diff --git a/synapse/http/server.py b/synapse/http/server.py
index 4e4c02e170..2d5c23e673 100644
--- a/synapse/http/server.py
+++ b/synapse/http/server.py
@@ -27,6 +27,7 @@ from twisted.internet import defer
 from twisted.python import failure
 from twisted.web import resource
 from twisted.web.server import NOT_DONE_YET
+from twisted.web.static import NoRangeStaticProducer
 from twisted.web.util import redirectTo
 
 import synapse.events
@@ -40,6 +41,11 @@ from synapse.api.errors import (
 from synapse.util.caches import intern_dict
 from synapse.util.logcontext import preserve_fn
 
+if PY3:
+    from io import BytesIO
+else:
+    from cStringIO import StringIO as BytesIO
+
 logger = logging.getLogger(__name__)
 
 HTML_ERROR_TEMPLATE = """<!DOCTYPE html>
@@ -389,8 +395,7 @@ def respond_with_json(request, code, json_object, send_cors=False,
         return
 
     if pretty_print:
-        json_bytes = (encode_pretty_printed_json(json_object) + "\n"
-                      ).encode("utf-8")
+        json_bytes = encode_pretty_printed_json(json_object) + b"\n"
     else:
         if canonical_json or synapse.events.USE_FROZEN_DICTS:
             # canonicaljson already encodes to bytes
@@ -426,8 +431,12 @@ def respond_with_json_bytes(request, code, json_bytes, send_cors=False,
     if send_cors:
         set_cors_headers(request)
 
-    request.write(json_bytes)
-    finish_request(request)
+    # todo: we can almost certainly avoid this copy and encode the json straight into
+    # the bytesIO, but it would involve faffing around with string->bytes wrappers.
+    bytes_io = BytesIO(json_bytes)
+
+    producer = NoRangeStaticProducer(request, bytes_io)
+    producer.start()
     return NOT_DONE_YET