Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No longer allow lowercase HTTP methods #170

Merged
merged 1 commit into from
Aug 16, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions waitress/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -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''
10 changes: 7 additions & 3 deletions waitress/tests/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,15 +288,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