http_server_async: reuse response
This commit is contained in:
parent
5f79d2796f
commit
dd2f3df431
|
@ -166,6 +166,7 @@ class Application:
|
||||||
|
|
||||||
try:
|
try:
|
||||||
request = self.cfg.request_class(self, reader, writer.get_extra_info('peername')[0])
|
request = self.cfg.request_class(self, reader, writer.get_extra_info('peername')[0])
|
||||||
|
response = self.cfg.response_class()
|
||||||
await request.parse_headers()
|
await request.parse_headers()
|
||||||
|
|
||||||
handler = self.get_route(request.path, request.method)
|
handler = self.get_route(request.path, request.method)
|
||||||
|
@ -173,10 +174,10 @@ class Application:
|
||||||
await self.handle_middleware(request)
|
await self.handle_middleware(request)
|
||||||
|
|
||||||
if handler.params:
|
if handler.params:
|
||||||
handler_response = await handler.target(request, **handler.params)
|
handler_response = await handler.target(request, response, **handler.params)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
handler_response = await handler.target(request)
|
handler_response = await handler.target(request, response)
|
||||||
|
|
||||||
if isinstance(handler_response, dict):
|
if isinstance(handler_response, dict):
|
||||||
response = self.cfg.response_class(**handler_response)
|
response = self.cfg.response_class(**handler_response)
|
||||||
|
@ -184,41 +185,31 @@ class Application:
|
||||||
elif isinstance(handler_response, Response):
|
elif isinstance(handler_response, Response):
|
||||||
response = handler_response
|
response = handler_response
|
||||||
|
|
||||||
|
elif not handler_response:
|
||||||
|
pass
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise error.ServerError()
|
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)
|
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:
|
except:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
response = Response()
|
response = self.cfg.response_class.new_error('Server Error', 500)
|
||||||
response.error('Server Error', 500)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
response.headers.update(self.cfg.default_headers)
|
response.headers.update(self.cfg.default_headers)
|
||||||
|
|
||||||
writer.write(response.compile())
|
writer.write(response.compile())
|
||||||
await writer.drain()
|
await writer.drain()
|
||||||
writer.close()
|
|
||||||
await writer.wait_closed()
|
|
||||||
|
|
||||||
if request:
|
if request:
|
||||||
logging.info(f'{request.remote} {request.method} {request.path} {response.status} {len(response.body)} {request.agent}')
|
logging.info(f'{request.remote} {request.method} {request.path} {response.status} {len(response.body)} {request.agent}')
|
||||||
|
@ -226,6 +217,9 @@ class Application:
|
||||||
except:
|
except:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|
||||||
|
writer.close()
|
||||||
|
await writer.wait_closed()
|
||||||
|
|
||||||
|
|
||||||
async def handle_middleware(self, request, response=None):
|
async def handle_middleware(self, request, response=None):
|
||||||
for middleware in self.middleware['response' if response else 'request']:
|
for middleware in self.middleware['response' if response else 'request']:
|
||||||
|
|
|
@ -49,26 +49,50 @@ class Response:
|
||||||
self._body += self._parse_body_data(data)
|
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''):
|
def set_html(self, body=b''):
|
||||||
self.content_type = 'text/html'
|
self.content_type = 'text/html'
|
||||||
self.body = body
|
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.content_type = 'application/activity+json' if activity else 'application/json'
|
||||||
self.body = body
|
self.body = body
|
||||||
|
|
||||||
|
|
||||||
def error(self, message, status=500):
|
def set_error(self, message, status=500):
|
||||||
self.body = f'HTTP Error {status}: {message}'
|
self.body = f'HTTP Error {status}: {message}'
|
||||||
self.status = status
|
self.status = status
|
||||||
|
|
||||||
|
|
||||||
def delete_cookie(self, cookie):
|
|
||||||
cookie.set_delete()
|
|
||||||
self.cookies[cookie.key] = cookie
|
|
||||||
|
|
||||||
|
|
||||||
def compile(self):
|
def compile(self):
|
||||||
data = bytes(f'HTTP/1.1 {self.status}', 'utf-8')
|
data = bytes(f'HTTP/1.1 {self.status}', 'utf-8')
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ class View:
|
||||||
def Static(src):
|
def Static(src):
|
||||||
src = Path(src)
|
src = Path(src)
|
||||||
|
|
||||||
async def StaticHandler(request, path=None):
|
async def StaticHandler(request, response, path=None):
|
||||||
try:
|
try:
|
||||||
if not path:
|
if not path:
|
||||||
src_path = src
|
src_path = src
|
||||||
|
@ -49,6 +49,7 @@ def Static(src):
|
||||||
|
|
||||||
headers = {}
|
headers = {}
|
||||||
|
|
||||||
return dict(body=data, content_type=mime)
|
response.body = data
|
||||||
|
response.content_type = mime
|
||||||
|
|
||||||
return StaticHandler
|
return StaticHandler
|
||||||
|
|
Loading…
Reference in a new issue