Skip to content

Commit

Permalink
Merge pull request #170 from Pylons/bugfix/uppercase_verb
Browse files Browse the repository at this point in the history
No longer allow lowercase HTTP methods
  • Loading branch information
digitalresistor authored Aug 16, 2017
2 parents 87311e8 + e3ad2a3 commit c18aa5e
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 5 deletions.
16 changes: 14 additions & 2 deletions waitress/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,8 +294,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''
10 changes: 7 additions & 3 deletions waitress/tests/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,15 +298,19 @@ def _callFUT(self, line):
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):
Expand Down

0 comments on commit c18aa5e

Please sign in to comment.