From dd2f3df431212c2a8877e773affea488659d51b2 Mon Sep 17 00:00:00 2001 From: Izalia Mae Date: Sun, 24 Oct 2021 13:22:41 -0400 Subject: [PATCH] http_server_async: reuse response --- izzylib/http_server_async/application.py | 44 ++++++++++-------------- izzylib/http_server_async/response.py | 38 ++++++++++++++++---- izzylib/http_server_async/view.py | 5 +-- 3 files changed, 53 insertions(+), 34 deletions(-) diff --git a/izzylib/http_server_async/application.py b/izzylib/http_server_async/application.py index 1c7cb26..2e4c134 100644 --- a/izzylib/http_server_async/application.py +++ b/izzylib/http_server_async/application.py @@ -166,6 +166,7 @@ class Application: try: request = self.cfg.request_class(self, reader, writer.get_extra_info('peername')[0]) + response = self.cfg.response_class() await request.parse_headers() handler = self.get_route(request.path, request.method) @@ -173,10 +174,10 @@ class Application: await self.handle_middleware(request) if handler.params: - handler_response = await handler.target(request, **handler.params) + handler_response = await handler.target(request, response, **handler.params) else: - handler_response = await handler.target(request) + handler_response = await handler.target(request, response) if isinstance(handler_response, dict): response = self.cfg.response_class(**handler_response) @@ -184,41 +185,31 @@ class Application: elif isinstance(handler_response, Response): response = handler_response + elif not handler_response: + pass + else: raise error.ServerError() - except NotFound: - response = self.cfg.response_class() - response.error('Not Found', 404) - - except MethodNotAllowed: - response = self.cfg.response_class() - response.error('Method Not Allowed', 405) - - except error.HttpError as e: - response = self.cfg.response_class() - response.error(e.message, e.status) - - except: - traceback.print_exc() - response = self.cfg.response_class() - response.error('Server Error', 500) - - try: await self.handle_middleware(request, response) + except NotFound: + response = self.cfg.response_class.new_error('Not Found', 404) + + except MethodNotAllowed: + response = self.cfg.response_class.new_error('Method Not Allowed', 405) + + except error.HttpError as e: + response = self.cfg.response_class.new_error(e.message, e.status) + except: traceback.print_exc() - response = Response() - response.error('Server Error', 500) + response = self.cfg.response_class.new_error('Server Error', 500) try: response.headers.update(self.cfg.default_headers) - writer.write(response.compile()) await writer.drain() - writer.close() - await writer.wait_closed() if request: logging.info(f'{request.remote} {request.method} {request.path} {response.status} {len(response.body)} {request.agent}') @@ -226,6 +217,9 @@ class Application: except: traceback.print_exc() + writer.close() + await writer.wait_closed() + async def handle_middleware(self, request, response=None): for middleware in self.middleware['response' if response else 'request']: diff --git a/izzylib/http_server_async/response.py b/izzylib/http_server_async/response.py index 7e3c57a..c8fbcfa 100644 --- a/izzylib/http_server_async/response.py +++ b/izzylib/http_server_async/response.py @@ -49,26 +49,50 @@ class Response: self._body += self._parse_body_data(data) + def delete_cookie(self, cookie): + cookie.set_delete() + self.cookies[cookie.key] = cookie + + + @classmethod + def new_html(cls, body, **kwargs): + response = cls(**kwargs) + response.set_html(body) + + return response + + + @classmethod + def new_json(cls, body, activity=False, **kwargs): + response = cls(**kwargs) + response.set_json(body, activity) + + return response + + + @classmethod + def new_error(cls, message, status=500, **kwargs): + response = cls(**kwargs) + response.set_error(message, status) + + return response + + def set_html(self, body=b''): self.content_type = 'text/html' self.body = body - def json(self, body={}, activity=False): + def set_json(self, body={}, activity=False): self.content_type = 'application/activity+json' if activity else 'application/json' self.body = body - def error(self, message, status=500): + def set_error(self, message, status=500): self.body = f'HTTP Error {status}: {message}' self.status = status - def delete_cookie(self, cookie): - cookie.set_delete() - self.cookies[cookie.key] = cookie - - def compile(self): data = bytes(f'HTTP/1.1 {self.status}', 'utf-8') diff --git a/izzylib/http_server_async/view.py b/izzylib/http_server_async/view.py index e47ee80..646a68f 100644 --- a/izzylib/http_server_async/view.py +++ b/izzylib/http_server_async/view.py @@ -33,7 +33,7 @@ class View: def Static(src): src = Path(src) - async def StaticHandler(request, path=None): + async def StaticHandler(request, response, path=None): try: if not path: src_path = src @@ -49,6 +49,7 @@ def Static(src): headers = {} - return dict(body=data, content_type=mime) + response.body = data + response.content_type = mime return StaticHandler