Minor fixes.

This commit is contained in:
L. Kärkkäinen 2020-03-01 16:34:58 +02:00
parent 5a96996003
commit 1c42a5ef4e
2 changed files with 36 additions and 29 deletions

View File

@ -251,6 +251,7 @@ class ASGIApp:
sanic_app, sanic_app,
) )
instance.request.stream = instance instance.request.stream = instance
instance.request_body = True # FIXME: Use more_body?
return instance return instance
@ -260,15 +261,15 @@ class ASGIApp:
""" """
message = await self.transport.receive() message = await self.transport.receive()
if not message.get("more_body", False): if not message.get("more_body", False):
self.request_body = False
return None return None
return message.get("body", b"") return message.get("body", b"")
async def __aiter__(self): async def __aiter__(self):
while True: while self.request_body:
data = await self.read() data = await self.read()
if not data: if data:
return yield data
yield data
def respond(self, response): def respond(self, response):
headers: List[Tuple[bytes, bytes]] = [] headers: List[Tuple[bytes, bytes]] = []

View File

@ -43,7 +43,9 @@ class Http:
"exception", "exception",
"url", "url",
"request_body", "request_body",
"request_bytes",
"request_bytes_left", "request_bytes_left",
"request_max_size",
"response", "response",
"response_func", "response_func",
"response_bytes_left", "response_bytes_left",
@ -57,6 +59,8 @@ class Http:
self.expecting_continue = False self.expecting_continue = False
self.stage = Stage.IDLE self.stage = Stage.IDLE
self.request_body = None self.request_body = None
self.request_bytes = None
self.request_max_size = protocol.request_max_size
self.keep_alive = True self.keep_alive = True
self.head_only = None self.head_only = None
self.request = None self.request = None
@ -69,7 +73,7 @@ class Http:
try: try:
# Receive and handle a request # Receive and handle a request
self.stage = Stage.REQUEST self.stage = Stage.REQUEST
self.response_func = self.http1_response_start self.response_func = self.http1_response_header
await self.http1_request_header() await self.http1_request_header()
await self.protocol.request_handler(self.request) await self.protocol.request_handler(self.request)
# Handler finished, response should've been sent # Handler finished, response should've been sent
@ -162,13 +166,13 @@ class Http:
self.request_bytes_left = 0 self.request_bytes_left = 0
pos -= 2 # One CRLF stays in buffer pos -= 2 # One CRLF stays in buffer
else: else:
self.request_bytes_left = int(headers["content-length"]) self.request_bytes_left = self.request_bytes = int(headers["content-length"])
# Remove header and its trailing CRLF # Remove header and its trailing CRLF
del buf[: pos + 4] del buf[: pos + 4]
self.stage = Stage.HANDLER self.stage = Stage.HANDLER
self.request = request self.request = request
def http1_response_start(self, data, end_stream) -> bytes: def http1_response_header(self, data, end_stream) -> bytes:
res = self.response res = self.response
# Compatibility with simple response body # Compatibility with simple response body
if not data and res.body: if not data and res.body:
@ -315,7 +319,7 @@ class Http:
await self._send(HTTP_CONTINUE) await self._send(HTTP_CONTINUE)
# Receive request body chunk # Receive request body chunk
buf = self.recv_buffer buf = self.recv_buffer
if self.request_body == "chunked" and self.request_bytes_left == 0: if self.request_bytes_left == 0 and self.request_body == "chunked":
# Process a chunk header: \r\n<size>[;<chunk extensions>]\r\n # Process a chunk header: \r\n<size>[;<chunk extensions>]\r\n
while True: while True:
pos = buf.find(b"\r\n", 3) pos = buf.find(b"\r\n", 3)
@ -330,29 +334,31 @@ class Http:
except: except:
self.keep_alive = False self.keep_alive = False
raise InvalidUsage("Bad chunked encoding") raise InvalidUsage("Bad chunked encoding")
self.request_bytes_left = size
self.protocol._total_request_size += pos + 2
del buf[: pos + 2] del buf[: pos + 2]
if self.request_bytes_left <= 0: if size <= 0:
self.request_chunked = False self.request_body = None
if size < 0:
self.keep_alive = False
raise InvalidUsage("Bad chunked encoding")
return None return None
# At this point we are good to read/return _request_bytes_left self.request_bytes_left = size
if self.request_bytes_left: self.request_bytes += size
if not buf: # Request size limit
await self._receive_more() if (self.request_bytes > self.request_max_size):
data = bytes(buf[: self.request_bytes_left]) self.keep_alive = False
size = len(data) raise PayloadTooLarge("Payload Too Large")
del buf[:size] # End of request body?
self.request_bytes_left -= size if not self.request_bytes_left:
self.protocol._total_request_size += size self.request_body = None
if ( return
self.protocol._total_request_size # At this point we are good to read/return up to request_bytes_left
> self.protocol.request_max_size if not buf:
): await self._receive_more()
self.keep_alive = False data = bytes(buf[: self.request_bytes_left])
raise PayloadTooLarge("Payload Too Large") size = len(data)
return data del buf[:size]
return None self.request_bytes_left -= size
return data
# Response methods # Response methods