Merge pull request #603 from alex/compile-re-once

Only compiled some regexes used in HTTP parsing once
This commit is contained in:
Benoit Chesneau 2013-08-31 01:40:27 -07:00
commit 36e5ae05bb

View File

@ -9,9 +9,9 @@ from errno import ENOTCONN
from gunicorn.http.unreader import SocketUnreader from gunicorn.http.unreader import SocketUnreader
from gunicorn.http.body import ChunkedReader, LengthReader, EOFReader, Body from gunicorn.http.body import ChunkedReader, LengthReader, EOFReader, Body
from gunicorn.http.errors import InvalidHeader, InvalidHeaderName, NoMoreData, \ from gunicorn.http.errors import (InvalidHeader, InvalidHeaderName, NoMoreData,
InvalidRequestLine, InvalidRequestMethod, InvalidHTTPVersion, \ InvalidRequestLine, InvalidRequestMethod, InvalidHTTPVersion,
LimitRequestLine, LimitRequestHeaders LimitRequestLine, LimitRequestHeaders)
from gunicorn.http.errors import InvalidProxyLine, ForbiddenProxyRequest from gunicorn.http.errors import InvalidProxyLine, ForbiddenProxyRequest
from gunicorn.six import BytesIO, urlsplit, bytes_to_str from gunicorn.six import BytesIO, urlsplit, bytes_to_str
@ -19,6 +19,10 @@ MAX_REQUEST_LINE = 8190
MAX_HEADERS = 32768 MAX_HEADERS = 32768
MAX_HEADERFIELD_SIZE = 8190 MAX_HEADERFIELD_SIZE = 8190
HEADER_RE = re.compile("[\x00-\x1F\x7F()<>@,;:\[\]={} \t\\\\\"]")
METH_RE = re.compile(r"[A-Z0-9$-_.]{3,20}")
VERSION_RE = re.compile(r"HTTP/(\d+).(\d+)")
class Message(object): class Message(object):
def __init__(self, cfg, unreader): def __init__(self, cfg, unreader):
@ -29,8 +33,6 @@ class Message(object):
self.trailers = [] self.trailers = []
self.body = None self.body = None
self.hdrre = re.compile("[\x00-\x1F\x7F()<>@,;:\[\]={} \t\\\\\"]")
# set headers limits # set headers limits
self.limit_request_fields = cfg.limit_request_fields self.limit_request_fields = cfg.limit_request_fields
if (self.limit_request_fields <= 0 if (self.limit_request_fields <= 0
@ -72,7 +74,7 @@ class Message(object):
raise InvalidHeader(curr.strip()) raise InvalidHeader(curr.strip())
name, value = curr.split(":", 1) name, value = curr.split(":", 1)
name = name.rstrip(" \t").upper() name = name.rstrip(" \t").upper()
if self.hdrre.search(name): if HEADER_RE.search(name):
raise InvalidHeaderName(name) raise InvalidHeaderName(name)
name, value = name.strip(), [value.lstrip()] name, value = name.strip(), [value.lstrip()]
@ -132,9 +134,6 @@ class Message(object):
class Request(Message): class Request(Message):
def __init__(self, cfg, unreader, req_number=1): def __init__(self, cfg, unreader, req_number=1):
self.methre = re.compile("[A-Z0-9$-_.]{3,20}")
self.versre = re.compile("HTTP/(\d+).(\d+)")
self.method = None self.method = None
self.uri = None self.uri = None
self.path = None self.path = None
@ -307,7 +306,7 @@ class Request(Message):
raise InvalidRequestLine(line) raise InvalidRequestLine(line)
# Method # Method
if not self.methre.match(bits[0]): if not METH_RE.match(bits[0]):
raise InvalidRequestMethod(bits[0]) raise InvalidRequestMethod(bits[0])
self.method = bits[0].upper() self.method = bits[0].upper()
@ -328,7 +327,7 @@ class Request(Message):
self.fragment = parts.fragment or "" self.fragment = parts.fragment or ""
# Version # Version
match = self.versre.match(bits[2]) match = VERSION_RE.match(bits[2])
if match is None: if match is None:
raise InvalidHTTPVersion(bits[2]) raise InvalidHTTPVersion(bits[2])
self.version = (int(match.group(1)), int(match.group(2))) self.version = (int(match.group(1)), int(match.group(2)))