[Python-checkins] cpython: Issue #28548: Parse HTTP request version even if too many words received
martin.panter
python-checkins at python.org
Fri Nov 18 20:19:26 EST 2016
https://hg.python.org/cpython/rev/7c98768368cb
changeset: 105185:7c98768368cb
user: Martin Panter <vadmium+py at gmail.com>
date: Sat Nov 19 01:06:37 2016 +0000
summary:
Issue #28548: Parse HTTP request version even if too many words received
files:
Lib/http/server.py | 33 +++++++++++++----------
Lib/test/test_httpservers.py | 10 +++++++
Misc/NEWS | 3 ++
3 files changed, 31 insertions(+), 15 deletions(-)
diff --git a/Lib/http/server.py b/Lib/http/server.py
--- a/Lib/http/server.py
+++ b/Lib/http/server.py
@@ -267,8 +267,8 @@
are in self.command, self.path, self.request_version and
self.headers.
- Return True for success, False for failure; on failure, an
- error is sent back.
+ Return True for success, False for failure; on failure, any relevant
+ error response has already been sent back.
"""
self.command = None # set in case of error on the first line
@@ -278,10 +278,13 @@
requestline = requestline.rstrip('\r\n')
self.requestline = requestline
words = requestline.split()
- if len(words) == 3:
- command, path, version = words
+ if len(words) == 0:
+ return False
+
+ if len(words) >= 3: # Enough to determine protocol version
+ version = words[-1]
try:
- if version[:5] != 'HTTP/':
+ if not version.startswith('HTTP/'):
raise ValueError
base_version_number = version.split('/', 1)[1]
version_number = base_version_number.split(".")
@@ -306,22 +309,22 @@
HTTPStatus.HTTP_VERSION_NOT_SUPPORTED,
"Invalid HTTP version (%s)" % base_version_number)
return False
- elif len(words) == 2:
- command, path = words
+ self.request_version = version
+
+ if not 2 <= len(words) <= 3:
+ self.send_error(
+ HTTPStatus.BAD_REQUEST,
+ "Bad request syntax (%r)" % requestline)
+ return False
+ command, path = words[:2]
+ if len(words) == 2:
self.close_connection = True
if command != 'GET':
self.send_error(
HTTPStatus.BAD_REQUEST,
"Bad HTTP/0.9 request type (%r)" % command)
return False
- elif not words:
- return False
- else:
- self.send_error(
- HTTPStatus.BAD_REQUEST,
- "Bad request syntax (%r)" % requestline)
- return False
- self.command, self.path, self.request_version = command, path, version
+ self.command, self.path = command, path
# Examine the headers and look for a Connection directive.
try:
diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py
--- a/Lib/test/test_httpservers.py
+++ b/Lib/test/test_httpservers.py
@@ -822,6 +822,16 @@
self.assertEqual(result[0], b'<html><body>Data</body></html>\r\n')
self.verify_get_called()
+ def test_extra_space(self):
+ result = self.send_typical_request(
+ b'GET /spaced out HTTP/1.1\r\n'
+ b'Host: dummy\r\n'
+ b'\r\n'
+ )
+ self.assertTrue(result[0].startswith(b'HTTP/1.1 400 '))
+ self.verify_expected_headers(result[1:result.index(b'\r\n')])
+ self.assertFalse(self.handler.get_called)
+
def test_with_continue_1_0(self):
result = self.send_typical_request(b'GET / HTTP/1.0\r\nExpect: 100-continue\r\n\r\n')
self.verify_http_server_response(result[0])
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -128,6 +128,9 @@
Library
-------
+- Issue #28548: In the "http.server" module, parse the protocol version if
+ possible, to avoid using HTTP 0.9 in some error responses.
+
- Issue #19717: Makes Path.resolve() succeed on paths that do not exist.
Patch by Vajrasky Kok
--
Repository URL: https://hg.python.org/cpython
More information about the Python-checkins
mailing list