summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBert JW Regeer <bertjw@regeer.org>2017-08-15 22:51:24 -0600
committerBert JW Regeer <bertjw@regeer.org>2017-08-15 23:23:07 -0600
commite3ad2a3a2d45d796bada36ae9f9b4f87c4f15b6a (patch)
treebb6426f058d55f55aa64a069feaa0ac7ec405b03
parentc130bc20b4a04bc090ae127faeac169828baf771 (diff)
downloadwaitress-bugfix/uppercase_verb.tar.gz
No longer allow lowercase HTTP methodsbugfix/uppercase_verb
-rw-r--r--waitress/parser.py16
-rw-r--r--waitress/tests/test_parser.py10
2 files changed, 21 insertions, 5 deletions
diff --git a/waitress/parser.py b/waitress/parser.py
index fc71d68..fcc16d8 100644
--- a/waitress/parser.py
+++ b/waitress/parser.py
@@ -291,8 +291,20 @@ def crack_first_line(line):
version = m.group(5)
else:
version = None
- command = m.group(1).upper()
+ method = m.group(1)
+
+ # the request methods that are currently defined are all uppercase:
+ # https://www.iana.org/assignments/http-methods/http-methods.xhtml and
+ # the request method is case sensitive according to
+ # https://tools.ietf.org/html/rfc7231#section-4.1
+
+ # By disallowing anything but uppercase methods we save poor
+ # unsuspecting souls from sending lowercase HTTP methods to waitress
+ # and having the request complete, while servers like nginx drop the
+ # request onto the floor.
+ if method != method.upper():
+ raise ParsingError('Malformed HTTP method "%s"' % tostr(method))
uri = m.group(2)
- return command, uri, version
+ return method, uri, version
else:
return b'', b'', b''
diff --git a/waitress/tests/test_parser.py b/waitress/tests/test_parser.py
index 781d7c7..9b1a7e8 100644
--- a/waitress/tests/test_parser.py
+++ b/waitress/tests/test_parser.py
@@ -288,15 +288,19 @@ class Test_crack_first_line(unittest.TestCase):
return crack_first_line(line)
def test_crack_first_line_matchok(self):
- result = self._callFUT(b'get / HTTP/1.0')
+ result = self._callFUT(b'GET / HTTP/1.0')
self.assertEqual(result, (b'GET', b'/', b'1.0'))
+ def test_crack_first_line_lowercase_method(self):
+ from waitress.parser import ParsingError
+ self.assertRaises(ParsingError, self._callFUT, b'get / HTTP/1.0')
+
def test_crack_first_line_nomatch(self):
- result = self._callFUT(b'get / bleh')
+ result = self._callFUT(b'GET / bleh')
self.assertEqual(result, (b'', b'', b''))
def test_crack_first_line_missing_version(self):
- result = self._callFUT(b'get /')
+ result = self._callFUT(b'GET /')
self.assertEqual(result, (b'GET', b'/', None))
class TestHTTPRequestParserIntegration(unittest.TestCase):