2020-09-17 03:04:11 +00:00
|
|
|
import itertools
|
2020-11-26 03:23:23 +00:00
|
|
|
from urllib.parse import parse_qsl
|
|
|
|
from typing import Union
|
2020-09-17 03:04:11 +00:00
|
|
|
|
|
|
|
from openapi_core.validation.request.datatypes import ( # type: ignore
|
|
|
|
OpenAPIRequest,
|
2020-12-05 02:01:22 +00:00
|
|
|
RequestParameters,
|
|
|
|
RequestValidationResult,
|
2020-09-17 03:04:11 +00:00
|
|
|
)
|
2020-11-20 17:00:43 +00:00
|
|
|
from openapi_core.validation.request import validators # type: ignore
|
2024-10-15 21:31:10 +00:00
|
|
|
from tornado.httpclient import HTTPRequest
|
|
|
|
from tornado.httputil import HTTPServerRequest, parse_cookie
|
2020-09-17 03:04:11 +00:00
|
|
|
from werkzeug.datastructures import ImmutableMultiDict, Headers
|
|
|
|
|
2021-01-13 19:33:39 +00:00
|
|
|
from .util import parse_mimetype
|
|
|
|
|
2020-09-17 03:04:11 +00:00
|
|
|
|
|
|
|
class TornadoRequestFactory:
|
2021-02-26 17:03:04 +00:00
|
|
|
"""Factory for converting Tornado requests to OpenAPI request objects."""
|
2021-02-26 20:34:54 +00:00
|
|
|
|
2020-09-17 03:04:11 +00:00
|
|
|
@classmethod
|
2020-11-26 03:23:23 +00:00
|
|
|
def create(cls, request: Union[HTTPRequest, HTTPServerRequest]) -> OpenAPIRequest:
|
2021-02-26 17:03:04 +00:00
|
|
|
"""Creates an OpenAPI request from Tornado request objects.
|
|
|
|
|
|
|
|
Supports both :class:`tornado.httpclient.HTTPRequest` and
|
|
|
|
:class:`tornado.httputil.HTTPServerRequest` objects.
|
|
|
|
|
|
|
|
"""
|
2020-11-26 03:23:23 +00:00
|
|
|
if isinstance(request, HTTPRequest):
|
|
|
|
if request.url:
|
|
|
|
path, _, querystring = request.url.partition("?")
|
|
|
|
query_arguments: ImmutableMultiDict[str, str] = ImmutableMultiDict(
|
|
|
|
parse_qsl(querystring)
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
path = ""
|
|
|
|
query_arguments = ImmutableMultiDict()
|
2020-09-17 03:04:11 +00:00
|
|
|
else:
|
2020-12-04 18:29:32 +00:00
|
|
|
path, _, _ = request.full_url().partition("?")
|
2020-12-04 18:37:25 +00:00
|
|
|
if path == "://":
|
|
|
|
path = ""
|
2020-11-26 03:23:23 +00:00
|
|
|
query_arguments = ImmutableMultiDict(
|
|
|
|
itertools.chain(
|
|
|
|
*[
|
|
|
|
[(k, v.decode("utf-8")) for v in vs]
|
|
|
|
for k, vs in request.query_arguments.items()
|
|
|
|
]
|
|
|
|
)
|
2020-09-17 03:04:11 +00:00
|
|
|
)
|
|
|
|
return OpenAPIRequest(
|
|
|
|
full_url_pattern=path,
|
|
|
|
method=request.method.lower() if request.method else "get",
|
|
|
|
parameters=RequestParameters(
|
2021-01-18 18:23:31 +00:00
|
|
|
query=query_arguments,
|
|
|
|
header=Headers(request.headers.get_all()),
|
|
|
|
cookie=parse_cookie(request.headers.get("Cookie", "")),
|
2020-09-17 03:04:11 +00:00
|
|
|
),
|
2024-08-05 14:42:54 +00:00
|
|
|
body=request.body if request.body else None,
|
2021-01-13 19:33:39 +00:00
|
|
|
mimetype=parse_mimetype(
|
|
|
|
request.headers.get("Content-Type", "application/x-www-form-urlencoded")
|
2020-11-20 00:37:58 +00:00
|
|
|
),
|
2020-09-17 03:04:11 +00:00
|
|
|
)
|
2020-11-20 17:00:43 +00:00
|
|
|
|
|
|
|
|
|
|
|
class RequestValidator(validators.RequestValidator):
|
2021-02-26 17:03:04 +00:00
|
|
|
"""Validator for Tornado HTTP Requests."""
|
2021-02-26 20:34:54 +00:00
|
|
|
|
2020-12-05 02:01:22 +00:00
|
|
|
def validate(
|
|
|
|
self, request: Union[HTTPRequest, HTTPServerRequest]
|
|
|
|
) -> RequestValidationResult:
|
2021-02-26 17:03:04 +00:00
|
|
|
"""Validate a Tornado HTTP request object."""
|
2020-11-20 17:00:43 +00:00
|
|
|
return super().validate(TornadoRequestFactory.create(request))
|
2020-11-26 03:23:23 +00:00
|
|
|
|
|
|
|
|
|
|
|
__all__ = ["RequestValidator", "TornadoRequestFactory"]
|