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:
L. Kärkkäinen 2019-07-29 18:20:03 +03:00
parent 2363c0653e
commit fdcba79f45
2 changed files with 21 additions and 4 deletions

18
sanic/headers.py Normal file
View 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

View File

@ -4,7 +4,6 @@ import json
import sys
import warnings
from cgi import parse_header
from collections import defaultdict, namedtuple
from http.cookies import SimpleCookie
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.log import error_logger, logger
from sanic.headers import parse_options_header
try:
from ujson import loads as json_loads
@ -177,7 +176,7 @@ class Request(dict):
content_type = self.headers.get(
"Content-Type", DEFAULT_HTTP_CONTENT_TYPE
)
content_type, parameters = parse_header(content_type)
content_type, parameters = parse_options_header(content_type)
try:
if content_type == "application/x-www-form-urlencoded":
self.parsed_form = RequestParameters(
@ -551,7 +550,7 @@ def parse_multipart_form(body, boundary):
colon_index = form_line.index(":")
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 :]
)