diff options
author | Bert JW Regeer <bertjw@regeer.org> | 2017-08-15 22:51:24 -0600 |
---|---|---|
committer | Bert JW Regeer <bertjw@regeer.org> | 2017-08-15 23:23:07 -0600 |
commit | e3ad2a3a2d45d796bada36ae9f9b4f87c4f15b6a (patch) | |
tree | bb6426f058d55f55aa64a069feaa0ac7ec405b03 | |
parent | c130bc20b4a04bc090ae127faeac169828baf771 (diff) | |
download | waitress-bugfix/uppercase_verb.tar.gz |
No longer allow lowercase HTTP methodsbugfix/uppercase_verb
-rw-r--r-- | waitress/parser.py | 16 | ||||
-rw-r--r-- | waitress/tests/test_parser.py | 10 |
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): |