Parse mimetype from content-type

OpenAPI objects expect lowercased mimetypes, with parameters stripped.
This commit is contained in:
Correl Roush 2021-01-13 14:33:39 -05:00
parent 15a30bb1cf
commit 513166456a
5 changed files with 33 additions and 3 deletions

View file

@ -15,6 +15,7 @@ packages = [
python = "^3.7" python = "^3.7"
tornado = "^4 || ^5 || ^6" tornado = "^4 || ^5 || ^6"
openapi-core = "^0.13.4" openapi-core = "^0.13.4"
ietfparse = "^1.7.0"
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]
black = { version = "*", allow-prereleases = true } black = { version = "*", allow-prereleases = true }

16
tests/test_util.py Normal file
View file

@ -0,0 +1,16 @@
import unittest
from tornado_openapi3 import util
class TestMimetypeParsing(unittest.TestCase):
def test_parameters_are_stripped(self) -> None:
self.assertEqual("text/html", util.parse_mimetype("text/html; charset=utf-8"))
def test_mimetype_is_lowercase(self) -> None:
self.assertEqual("text/html", util.parse_mimetype("TEXT/HTML"))
def test_type_suffix_is_preserved(self) -> None:
self.assertEqual(
"application/custom+json", util.parse_mimetype("application/custom+json")
)

View file

@ -12,6 +12,8 @@ from tornado.httpclient import HTTPRequest # type: ignore
from tornado.httputil import HTTPServerRequest # type: ignore from tornado.httputil import HTTPServerRequest # type: ignore
from werkzeug.datastructures import ImmutableMultiDict, Headers from werkzeug.datastructures import ImmutableMultiDict, Headers
from .util import parse_mimetype
class TornadoRequestFactory: class TornadoRequestFactory:
@classmethod @classmethod
@ -44,8 +46,8 @@ class TornadoRequestFactory:
query=query_arguments, header=Headers(request.headers.get_all()) query=query_arguments, header=Headers(request.headers.get_all())
), ),
body=request.body if request.body else b"", body=request.body if request.body else b"",
mimetype=request.headers.get( mimetype=parse_mimetype(
"Content-Type", "application/x-www-form-urlencoded" request.headers.get("Content-Type", "application/x-www-form-urlencoded")
), ),
) )

View file

@ -6,12 +6,13 @@ from openapi_core.validation.response import validators # type: ignore
from tornado.httpclient import HTTPResponse # type: ignore from tornado.httpclient import HTTPResponse # type: ignore
from .requests import TornadoRequestFactory from .requests import TornadoRequestFactory
from .util import parse_mimetype
class TornadoResponseFactory: class TornadoResponseFactory:
@classmethod @classmethod
def create(cls, response: HTTPResponse) -> OpenAPIResponse: def create(cls, response: HTTPResponse) -> OpenAPIResponse:
mimetype = response.headers.get("Content-Type", "text/html") mimetype = parse_mimetype(response.headers.get("Content-Type", "text/html"))
return OpenAPIResponse( return OpenAPIResponse(
data=response.body if response.body else b"", data=response.body if response.body else b"",
status_code=response.code, status_code=response.code,

10
tornado_openapi3/util.py Normal file
View file

@ -0,0 +1,10 @@
import ietfparse.headers
def parse_mimetype(content_type: str) -> str:
parsed = ietfparse.headers.parse_content_type(content_type)
return "{}/{}{}".format(
parsed.content_type,
parsed.content_subtype,
"+{}".format(parsed.content_suffix) if parsed.content_suffix else "",
)