From b5c1810722f5231e8f3bdf53734b0140799bbb8c Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Wed, 28 Aug 2013 20:23:53 -0700 Subject: [PATCH] Only compiled some regexes used in HTTP parsing once Currently they are parsed and compiled once per-HTTP request, which is unnescary computation and makes stuff slower than it could be. --- gunicorn/http/message.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/gunicorn/http/message.py b/gunicorn/http/message.py index 01224825..a82ba5a8 100644 --- a/gunicorn/http/message.py +++ b/gunicorn/http/message.py @@ -9,9 +9,9 @@ from errno import ENOTCONN from gunicorn.http.unreader import SocketUnreader from gunicorn.http.body import ChunkedReader, LengthReader, EOFReader, Body -from gunicorn.http.errors import InvalidHeader, InvalidHeaderName, NoMoreData, \ -InvalidRequestLine, InvalidRequestMethod, InvalidHTTPVersion, \ -LimitRequestLine, LimitRequestHeaders +from gunicorn.http.errors import (InvalidHeader, InvalidHeaderName, NoMoreData, + InvalidRequestLine, InvalidRequestMethod, InvalidHTTPVersion, + LimitRequestLine, LimitRequestHeaders) from gunicorn.http.errors import InvalidProxyLine, ForbiddenProxyRequest from gunicorn.six import BytesIO, urlsplit, bytes_to_str @@ -19,6 +19,10 @@ MAX_REQUEST_LINE = 8190 MAX_HEADERS = 32768 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): def __init__(self, cfg, unreader): @@ -29,8 +33,6 @@ class Message(object): self.trailers = [] self.body = None - self.hdrre = re.compile("[\x00-\x1F\x7F()<>@,;:\[\]={} \t\\\\\"]") - # set headers limits self.limit_request_fields = cfg.limit_request_fields if (self.limit_request_fields <= 0 @@ -72,7 +74,7 @@ class Message(object): raise InvalidHeader(curr.strip()) name, value = curr.split(":", 1) name = name.rstrip(" \t").upper() - if self.hdrre.search(name): + if HEADER_RE.search(name): raise InvalidHeaderName(name) name, value = name.strip(), [value.lstrip()] @@ -132,9 +134,6 @@ class Message(object): class Request(Message): 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.uri = None self.path = None @@ -307,7 +306,7 @@ class Request(Message): raise InvalidRequestLine(line) # Method - if not self.methre.match(bits[0]): + if not METH_RE.match(bits[0]): raise InvalidRequestMethod(bits[0]) self.method = bits[0].upper() @@ -328,7 +327,7 @@ class Request(Message): self.fragment = parts.fragment or "" # Version - match = self.versre.match(bits[2]) + match = VERSION_RE.match(bits[2]) if match is None: raise InvalidHTTPVersion(bits[2]) self.version = (int(match.group(1)), int(match.group(2)))