summaryrefslogtreecommitdiff
path: root/django/core/servers/basehttp.py
diff options
context:
space:
mode:
authorKonstantin Alekseev <mail@kalekseev.com>2018-12-06 18:08:01 +0300
committerCarlton Gibson <carlton.gibson@noumenal.es>2018-12-19 11:27:08 +0100
commitb514dc14f4e1c364341f5931b354e83ef15ee12d (patch)
treeb67ab081db929f87b83dec0a234861f79dc7be30 /django/core/servers/basehttp.py
parent1939dd49d142b65fa22eb5f85cee0d20864d3730 (diff)
Fixed #30015 -- Ensured request body is properly consumed for keep-alive connections.
Diffstat (limited to 'django/core/servers/basehttp.py')
-rw-r--r--django/core/servers/basehttp.py19
1 files changed, 19 insertions, 0 deletions
diff --git a/django/core/servers/basehttp.py b/django/core/servers/basehttp.py
index 8a36b67eef..01487527f8 100644
--- a/django/core/servers/basehttp.py
+++ b/django/core/servers/basehttp.py
@@ -14,6 +14,7 @@ import sys
from wsgiref import simple_server
from django.core.exceptions import ImproperlyConfigured
+from django.core.handlers.wsgi import LimitedStream
from django.core.wsgi import get_wsgi_application
from django.utils.module_loading import import_string
@@ -80,6 +81,20 @@ class ThreadedWSGIServer(socketserver.ThreadingMixIn, WSGIServer):
class ServerHandler(simple_server.ServerHandler):
http_version = '1.1'
+ def __init__(self, stdin, stdout, stderr, environ, **kwargs):
+ """
+ Setup a limited stream, so we can discard unread request data
+ at the end of the request. Django already uses `LimitedStream`
+ in `WSGIRequest` but it shouldn't discard the data since the
+ upstream servers usually do this. Hence we fix this only for
+ our testserver/runserver.
+ """
+ try:
+ content_length = int(environ.get('CONTENT_LENGTH'))
+ except (ValueError, TypeError):
+ content_length = 0
+ super().__init__(LimitedStream(stdin, content_length), stdout, stderr, environ, **kwargs)
+
def cleanup_headers(self):
super().cleanup_headers()
# HTTP/1.1 requires us to support persistent connections, so
@@ -92,6 +107,10 @@ class ServerHandler(simple_server.ServerHandler):
if self.headers.get('Connection') == 'close':
self.request_handler.close_connection = True
+ def close(self):
+ self.get_stdin()._read_limited()
+ super().close()
+
def handle_error(self):
# Ignore broken pipe errors, otherwise pass on
if not is_broken_pipe_error():