mirror of
https://github.com/frappe/gunicorn.git
synced 2026-01-14 11:09:11 +08:00
allow gunicorn to send chunked response (if Transfer-Encoding ==
chunked)
This commit is contained in:
parent
b6693a81aa
commit
6df6e89cbc
@ -48,6 +48,7 @@ class Request(object):
|
|||||||
self.parser = Parser()
|
self.parser = Parser()
|
||||||
self.start_response_called = False
|
self.start_response_called = False
|
||||||
self.log = logging.getLogger(__name__)
|
self.log = logging.getLogger(__name__)
|
||||||
|
self.response_chunked = False
|
||||||
|
|
||||||
def read(self):
|
def read(self):
|
||||||
environ = {}
|
environ = {}
|
||||||
@ -154,6 +155,9 @@ class Request(object):
|
|||||||
self.response_status = status
|
self.response_status = status
|
||||||
for name, value in response_headers:
|
for name, value in response_headers:
|
||||||
name = normalize_name(name)
|
name = normalize_name(name)
|
||||||
|
if name == "Transfer-Encoding":
|
||||||
|
if value.lower() == "chunked":
|
||||||
|
self.response_chunked = True
|
||||||
if not isinstance(value, basestring):
|
if not isinstance(value, basestring):
|
||||||
value = str(value)
|
value = str(value)
|
||||||
self.response_headers.append((name, value.strip()))
|
self.response_headers.append((name, value.strip()))
|
||||||
|
|||||||
@ -14,6 +14,7 @@ class Response(object):
|
|||||||
self.headers = req.response_headers or []
|
self.headers = req.response_headers or []
|
||||||
self.status = req.response_status
|
self.status = req.response_status
|
||||||
self.SERVER_VERSION = req.SERVER_VERSION
|
self.SERVER_VERSION = req.SERVER_VERSION
|
||||||
|
self.chunked = req.response_chunked
|
||||||
|
|
||||||
def send(self):
|
def send(self):
|
||||||
# send headers
|
# send headers
|
||||||
@ -31,8 +32,15 @@ class Response(object):
|
|||||||
|
|
||||||
write(self.sock, "%s\r\n" % "".join(resp_head))
|
write(self.sock, "%s\r\n" % "".join(resp_head))
|
||||||
|
|
||||||
|
last_chunk = None
|
||||||
for chunk in list(self.data):
|
for chunk in list(self.data):
|
||||||
write(self.sock, chunk)
|
write(self.sock, chunk, self.chunked)
|
||||||
|
last_chunk = chunk
|
||||||
|
|
||||||
|
if self.chunked:
|
||||||
|
if last_chunk or last_chunk is None:
|
||||||
|
# send last chunk
|
||||||
|
write_chunk("")
|
||||||
|
|
||||||
close(self.sock)
|
close(self.sock)
|
||||||
|
|
||||||
|
|||||||
@ -94,23 +94,29 @@ def close(sock):
|
|||||||
def read_partial(sock, length):
|
def read_partial(sock, length):
|
||||||
return sock.recv(length)
|
return sock.recv(length)
|
||||||
|
|
||||||
def write(sock, data):
|
def write_chunk(sock, data):
|
||||||
|
chunk = "".join(("%X\r\n" % len(data), data, "\r\n"))
|
||||||
|
sock.sendall(chunk)
|
||||||
|
|
||||||
|
def write(sock, data, chunked=False):
|
||||||
|
if chunked:
|
||||||
|
return write_chunk(sock, data)
|
||||||
sock.sendall(data)
|
sock.sendall(data)
|
||||||
|
|
||||||
def write_nonblock(sock, data):
|
def write_nonblock(sock, data, chunked=False):
|
||||||
timeout = sock.gettimeout()
|
timeout = sock.gettimeout()
|
||||||
if timeout != 0.0:
|
if timeout != 0.0:
|
||||||
try:
|
try:
|
||||||
sock.setblocking(0)
|
sock.setblocking(0)
|
||||||
return write(sock, data)
|
return write(sock, data, chunked)
|
||||||
finally:
|
finally:
|
||||||
sock.setblocking(1)
|
sock.setblocking(1)
|
||||||
else:
|
else:
|
||||||
return write(sock, data)
|
return write(sock, data, chunked)
|
||||||
|
|
||||||
def writelines(sock, lines):
|
def writelines(sock, lines, chunked=False):
|
||||||
for line in list(lines):
|
for line in list(lines):
|
||||||
write(sock, line)
|
write(sock, line, chunked)
|
||||||
|
|
||||||
def write_error(sock, msg):
|
def write_error(sock, msg):
|
||||||
html = textwrap.dedent("""\
|
html = textwrap.dedent("""\
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user