PEP 594 has cgi module scheduled for deprecation in Python 3.8. Reimplement
cgi.parse_header in Sanic. The new implementation is much faster than either cgi.parse_header or equivalent werkzeug.parse_options_header, and unlike the two, handles also quoted values with semicolons or \" in them.
This commit is contained in:
parent
2363c0653e
commit
fdcba79f45
18
sanic/headers.py
Normal file
18
sanic/headers.py
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import re
|
||||||
|
|
||||||
|
token, quoted = r"([\w!#$%&'*+\-.^_`|~]+)", r'"((?:[^"]|\\")*)"'
|
||||||
|
parameter = re.compile(f';\s*{token}=(?:{token}|{quoted})', re.ASCII)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_options_header(value: str):
|
||||||
|
"""Parse HTTP header values of Content-Type format."""
|
||||||
|
pos = value.find(';')
|
||||||
|
if pos == -1:
|
||||||
|
options = {}
|
||||||
|
else:
|
||||||
|
options = {
|
||||||
|
m.group(1).lower(): m.group(2) or m.group(3).replace(r'\"', '"')
|
||||||
|
for m in parameter.finditer(value[pos:])
|
||||||
|
}
|
||||||
|
value = value[:pos]
|
||||||
|
return value.strip().lower(), options
|
|
@ -4,7 +4,6 @@ import json
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
from cgi import parse_header
|
|
||||||
from collections import defaultdict, namedtuple
|
from collections import defaultdict, namedtuple
|
||||||
from http.cookies import SimpleCookie
|
from http.cookies import SimpleCookie
|
||||||
from urllib.parse import parse_qs, parse_qsl, unquote, urlunparse
|
from urllib.parse import parse_qs, parse_qsl, unquote, urlunparse
|
||||||
|
@ -13,7 +12,7 @@ from httptools import parse_url
|
||||||
|
|
||||||
from sanic.exceptions import InvalidUsage
|
from sanic.exceptions import InvalidUsage
|
||||||
from sanic.log import error_logger, logger
|
from sanic.log import error_logger, logger
|
||||||
|
from sanic.headers import parse_options_header
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from ujson import loads as json_loads
|
from ujson import loads as json_loads
|
||||||
|
@ -177,7 +176,7 @@ class Request(dict):
|
||||||
content_type = self.headers.get(
|
content_type = self.headers.get(
|
||||||
"Content-Type", DEFAULT_HTTP_CONTENT_TYPE
|
"Content-Type", DEFAULT_HTTP_CONTENT_TYPE
|
||||||
)
|
)
|
||||||
content_type, parameters = parse_header(content_type)
|
content_type, parameters = parse_options_header(content_type)
|
||||||
try:
|
try:
|
||||||
if content_type == "application/x-www-form-urlencoded":
|
if content_type == "application/x-www-form-urlencoded":
|
||||||
self.parsed_form = RequestParameters(
|
self.parsed_form = RequestParameters(
|
||||||
|
@ -551,7 +550,7 @@ def parse_multipart_form(body, boundary):
|
||||||
|
|
||||||
colon_index = form_line.index(":")
|
colon_index = form_line.index(":")
|
||||||
form_header_field = form_line[0:colon_index].lower()
|
form_header_field = form_line[0:colon_index].lower()
|
||||||
form_header_value, form_parameters = parse_header(
|
form_header_value, form_parameters = parse_options_header(
|
||||||
form_line[colon_index + 2 :]
|
form_line[colon_index + 2 :]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user