Remove unnecessary variables, optimise performance.

This commit is contained in:
L. Kärkkäinen 2020-03-01 15:38:18 +02:00
parent fc16594138
commit c0a0b50bc1
3 changed files with 27 additions and 31 deletions

View File

@ -991,7 +991,7 @@ class Sanic:
handler, args, kwargs, uri, name = self.router.get(request) handler, args, kwargs, uri, name = self.router.get(request)
# Non-streaming handlers have their body preloaded # Non-streaming handlers have their body preloaded
if request.stream and not self.router.is_stream_handler(request): if request.stream.request_body and not self.router.is_stream_handler(request):
await request.receive_body() await request.receive_body()
# -------------------------------------------- # # -------------------------------------------- #

View File

@ -42,7 +42,7 @@ class Http:
"request", "request",
"exception", "exception",
"url", "url",
"request_chunked", "request_body",
"request_bytes_left", "request_bytes_left",
"response", "response",
"response_func", "response_func",
@ -56,6 +56,7 @@ class Http:
self.protocol = protocol self.protocol = protocol
self.expecting_continue = False self.expecting_continue = False
self.stage = Stage.IDLE self.stage = Stage.IDLE
self.request_body = None
self.keep_alive = True self.keep_alive = True
self.head_only = None self.head_only = None
self.request = None self.request = None
@ -77,7 +78,7 @@ class Http:
if self.stage is Stage.RESPONSE: if self.stage is Stage.RESPONSE:
await self.send(end_stream=True) await self.send(end_stream=True)
# Consume any remaining request body (TODO: or disconnect?) # Consume any remaining request body (TODO: or disconnect?)
if self.request_bytes_left or self.request_chunked: if self.request_body:
logger.error(f"{self.request} body not consumed.") logger.error(f"{self.request} body not consumed.")
async for _ in self: async for _ in self:
pass pass
@ -124,12 +125,12 @@ class Http:
else: else:
raise Exception raise Exception
self.head_only = method.upper() == "HEAD" self.head_only = method.upper() == "HEAD"
body = False self.request_body = False
headers = [] headers = []
for name, value in (h.split(":", 1) for h in raw_headers): for name, value in (h.split(":", 1) for h in raw_headers):
name, value = h = name.lower(), value.lstrip() name, value = h = name.lower(), value.lstrip()
if name in ("content-length", "transfer-encoding"): if name in ("content-length", "transfer-encoding"):
body = True self.request_body = True
elif name == "connection": elif name == "connection":
self.keep_alive = value.lower() == "keep-alive" self.keep_alive = value.lower() == "keep-alive"
headers.append(h) headers.append(h)
@ -147,9 +148,7 @@ class Http:
request.stream = self request.stream = self
self.protocol.state["requests_count"] += 1 self.protocol.state["requests_count"] += 1
# Prepare for request body # Prepare for request body
self.request_chunked = False if self.request_body:
self.request_bytes_left = 0
if body:
headers = request.headers headers = request.headers
expect = headers.get("expect") expect = headers.get("expect")
if expect is not None: if expect is not None:
@ -159,7 +158,8 @@ class Http:
raise HeaderExpectationFailed(f"Unknown Expect: {expect}") raise HeaderExpectationFailed(f"Unknown Expect: {expect}")
request.stream = self request.stream = self
if headers.get("transfer-encoding") == "chunked": if headers.get("transfer-encoding") == "chunked":
self.request_chunked = True self.request_body = "chunked"
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 = int(headers["content-length"])
@ -225,7 +225,8 @@ class Http:
if status != 417: if status != 417:
ret = HTTP_CONTINUE + ret ret = HTTP_CONTINUE + ret
# Send response # Send response
self.log_response() if self.protocol.access_log:
self.log_response()
self.stage = Stage.IDLE if end_stream else Stage.RESPONSE self.stage = Stage.IDLE if end_stream else Stage.RESPONSE
return ret return ret
@ -284,29 +285,27 @@ class Http:
:return: None :return: None
""" """
if self.protocol.access_log: req, res = self.request, self.response
req, res = self.request, self.response extra = {
extra = { "status": getattr(res, "status", 0),
"status": getattr(res, "status", 0), "byte": getattr(self, "response_bytes_left", -1),
"byte": getattr(self, "response_bytes_left", -1), "host": "UNKNOWN",
"host": "UNKNOWN", "request": "nil",
"request": "nil", }
} if req is not None:
if req is not None: if req.ip:
if req.ip: extra["host"] = f"{req.ip}:{req.port}"
extra["host"] = f"{req.ip}:{req.port}" extra["request"] = f"{req.method} {req.url}"
extra["request"] = f"{req.method} {req.url}" access_logger.info("", extra=extra)
access_logger.info("", extra=extra)
# Request methods # Request methods
async def __aiter__(self): async def __aiter__(self):
"""Async iterate over request body.""" """Async iterate over request body."""
while True: while self.request_body:
data = await self.read() data = await self.read()
if not data: if data:
return yield data
yield data
async def read(self): async def read(self):
"""Read some bytes of request body.""" """Read some bytes of request body."""
@ -316,7 +315,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_chunked and self.request_bytes_left == 0: if self.request_body == "chunked" and self.request_bytes_left == 0:
# 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)

View File

@ -71,8 +71,6 @@ class HttpProtocol(asyncio.Protocol):
# enable or disable access log purpose # enable or disable access log purpose
"access_log", "access_log",
# connection management # connection management
"_total_request_size",
"_last_response_time",
"state", "state",
"url", "url",
"_debug", "_debug",
@ -127,7 +125,6 @@ class HttpProtocol(asyncio.Protocol):
self.keep_alive_timeout = keep_alive_timeout self.keep_alive_timeout = keep_alive_timeout
self.request_max_size = request_max_size self.request_max_size = request_max_size
self.request_class = request_class or Request self.request_class = request_class or Request
self._total_request_size = 0
self.state = state if state else {} self.state = state if state else {}
if "requests_count" not in self.state: if "requests_count" not in self.state:
self.state["requests_count"] = 0 self.state["requests_count"] = 0