Split serialization and de-serialization based on Accept header appearance
This commit is contained in:
@@ -15,7 +15,7 @@ from .interfaces.serialized import SerializedResponse, SerializedRequest
|
|||||||
from .interfaces.serialized.text import TextSerializedResponse
|
from .interfaces.serialized.text import TextSerializedResponse
|
||||||
from .req_schema import UnwrappedRequest
|
from .req_schema import UnwrappedRequest
|
||||||
from .router import Router, Route
|
from .router import Router, Route
|
||||||
from .types import HandlerType, InternalHandlerType, ContentType
|
from .types import HandlerType, InternalHandlerType, ContentType, Accept
|
||||||
from .internal_types import Scope, Receive, Send, MethodType, QTYPE, BTYPE, PTYPE, HTYPE
|
from .internal_types import Scope, Receive, Send, MethodType, QTYPE, BTYPE, PTYPE, HTYPE
|
||||||
from breakshaft.convertor import ConvRepo
|
from breakshaft.convertor import ConvRepo
|
||||||
|
|
||||||
@@ -47,6 +47,26 @@ class HTTPApp(ASGIApp):
|
|||||||
charset = properties.get('charset')
|
charset = properties.get('charset')
|
||||||
|
|
||||||
if charset is None:
|
if charset is None:
|
||||||
|
# TODO: extract default charsets based on content type
|
||||||
|
if contenttype == 'application/json':
|
||||||
|
charset = 'utf-8'
|
||||||
|
else:
|
||||||
|
charset = 'latin1'
|
||||||
|
|
||||||
|
return ContentType(contenttype, charset)
|
||||||
|
|
||||||
|
def extract_accept_type(self, req: BasicRequest, ct: ContentType) -> Accept:
|
||||||
|
contenttype_header = req.headers.get('Accept')
|
||||||
|
if contenttype_header is None:
|
||||||
|
return ct
|
||||||
|
|
||||||
|
properties: dict[str, str]
|
||||||
|
contenttype, properties = parse_content_type(contenttype_header)
|
||||||
|
|
||||||
|
charset = properties.get('charset')
|
||||||
|
|
||||||
|
if charset is None:
|
||||||
|
# TODO: extract default charsets based on content type
|
||||||
if contenttype == 'application/json':
|
if contenttype == 'application/json':
|
||||||
charset = 'utf-8'
|
charset = 'utf-8'
|
||||||
else:
|
else:
|
||||||
@@ -58,7 +78,7 @@ class HTTPApp(ASGIApp):
|
|||||||
ser = self.serialize_selector.select(ct.contenttype, ct.charset)
|
ser = self.serialize_selector.select(ct.contenttype, ct.charset)
|
||||||
return ser.req.deserialize(req, ct.charset)
|
return ser.req.deserialize(req, ct.charset)
|
||||||
|
|
||||||
def serialize_response(self, req: BasicRequest, sresp: SerializedResponse, ct: ContentType) -> BasicResponse:
|
def serialize_response(self, req: BasicRequest, sresp: SerializedResponse, ct: Accept) -> BasicResponse:
|
||||||
ser = self.serialize_selector.select(ct.contenttype, ct.charset)
|
ser = self.serialize_selector.select(ct.contenttype, ct.charset)
|
||||||
sresponser = ser.resp
|
sresponser = ser.resp
|
||||||
|
|
||||||
@@ -217,6 +237,7 @@ class SlothApp(HTTPApp, WSApp, LifespanApp, MethodRoutersApp):
|
|||||||
return req.body
|
return req.body
|
||||||
|
|
||||||
self.inj_repo.add_injector(self.extract_content_type)
|
self.inj_repo.add_injector(self.extract_content_type)
|
||||||
|
self.inj_repo.add_injector(self.extract_accept_type)
|
||||||
self.inj_repo.add_injector(self.serialize_request)
|
self.inj_repo.add_injector(self.serialize_request)
|
||||||
self.inj_repo.add_injector(self.serialize_response)
|
self.inj_repo.add_injector(self.serialize_response)
|
||||||
|
|
||||||
|
|||||||
@@ -16,3 +16,6 @@ type InternalHandlerType = Callable[[Send, BasicRequest], Awaitable[None]]
|
|||||||
class ContentType:
|
class ContentType:
|
||||||
contenttype: str
|
contenttype: str
|
||||||
charset: str
|
charset: str
|
||||||
|
|
||||||
|
|
||||||
|
type Accept = ContentType
|
||||||
|
|||||||
Reference in New Issue
Block a user