Add Request properties for HTTP method info (#2516)
This commit is contained in:
parent
8e9342e188
commit
7827b1b41d
|
@ -34,6 +34,15 @@ class LocalCertCreator(str, Enum):
|
|||
|
||||
|
||||
HTTP_METHODS = tuple(HTTPMethod.__members__.values())
|
||||
SAFE_HTTP_METHODS = (HTTPMethod.GET, HTTPMethod.HEAD, HTTPMethod.OPTIONS)
|
||||
IDEMPOTENT_HTTP_METHODS = (
|
||||
HTTPMethod.GET,
|
||||
HTTPMethod.HEAD,
|
||||
HTTPMethod.PUT,
|
||||
HTTPMethod.DELETE,
|
||||
HTTPMethod.OPTIONS,
|
||||
)
|
||||
CACHEABLE_HTTP_METHODS = (HTTPMethod.GET, HTTPMethod.HEAD)
|
||||
DEFAULT_HTTP_CONTENT_TYPE = "application/octet-stream"
|
||||
DEFAULT_LOCAL_TLS_KEY = "key.pem"
|
||||
DEFAULT_LOCAL_TLS_CERT = "cert.pem"
|
||||
|
|
|
@ -38,7 +38,12 @@ from httptools import parse_url
|
|||
from httptools.parser.errors import HttpParserInvalidURLError
|
||||
|
||||
from sanic.compat import CancelledErrors, Header
|
||||
from sanic.constants import DEFAULT_HTTP_CONTENT_TYPE
|
||||
from sanic.constants import (
|
||||
CACHEABLE_HTTP_METHODS,
|
||||
DEFAULT_HTTP_CONTENT_TYPE,
|
||||
IDEMPOTENT_HTTP_METHODS,
|
||||
SAFE_HTTP_METHODS,
|
||||
)
|
||||
from sanic.exceptions import BadRequest, BadURL, ServerError
|
||||
from sanic.headers import (
|
||||
AcceptContainer,
|
||||
|
@ -975,6 +980,33 @@ class Request:
|
|||
|
||||
return self.transport.scope
|
||||
|
||||
@property
|
||||
def is_safe(self) -> bool:
|
||||
"""
|
||||
:return: Whether the HTTP method is safe.
|
||||
See https://datatracker.ietf.org/doc/html/rfc7231#section-4.2.1
|
||||
:rtype: bool
|
||||
"""
|
||||
return self.method in SAFE_HTTP_METHODS
|
||||
|
||||
@property
|
||||
def is_idempotent(self) -> bool:
|
||||
"""
|
||||
:return: Whether the HTTP method is iempotent.
|
||||
See https://datatracker.ietf.org/doc/html/rfc7231#section-4.2.2
|
||||
:rtype: bool
|
||||
"""
|
||||
return self.method in IDEMPOTENT_HTTP_METHODS
|
||||
|
||||
@property
|
||||
def is_cacheable(self) -> bool:
|
||||
"""
|
||||
:return: Whether the HTTP method is cacheable.
|
||||
See https://datatracker.ietf.org/doc/html/rfc7231#section-4.2.3
|
||||
:rtype: bool
|
||||
"""
|
||||
return self.method in CACHEABLE_HTTP_METHODS
|
||||
|
||||
|
||||
class File(NamedTuple):
|
||||
"""
|
||||
|
|
|
@ -243,3 +243,54 @@ def test_request_stream_id(app):
|
|||
|
||||
_, resp = app.test_client.get("/")
|
||||
assert resp.text == "Stream ID is only a property of a HTTP/3 request"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"method,safe",
|
||||
(
|
||||
("DELETE", False),
|
||||
("GET", True),
|
||||
("HEAD", True),
|
||||
("OPTIONS", True),
|
||||
("PATCH", False),
|
||||
("POST", False),
|
||||
("PUT", False),
|
||||
),
|
||||
)
|
||||
def test_request_safe(method, safe):
|
||||
request = Request(b"/", {}, None, method, None, None)
|
||||
assert request.is_safe is safe
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"method,idempotent",
|
||||
(
|
||||
("DELETE", True),
|
||||
("GET", True),
|
||||
("HEAD", True),
|
||||
("OPTIONS", True),
|
||||
("PATCH", False),
|
||||
("POST", False),
|
||||
("PUT", True),
|
||||
),
|
||||
)
|
||||
def test_request_idempotent(method, idempotent):
|
||||
request = Request(b"/", {}, None, method, None, None)
|
||||
assert request.is_idempotent is idempotent
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"method,cacheable",
|
||||
(
|
||||
("DELETE", False),
|
||||
("GET", True),
|
||||
("HEAD", True),
|
||||
("OPTIONS", False),
|
||||
("PATCH", False),
|
||||
("POST", False),
|
||||
("PUT", False),
|
||||
),
|
||||
)
|
||||
def test_request_cacheable(method, cacheable):
|
||||
request = Request(b"/", {}, None, method, None, None)
|
||||
assert request.is_cacheable is cacheable
|
||||
|
|
Loading…
Reference in New Issue
Block a user