mirror of
https://github.com/python/cpython.git
synced 2025-09-05 00:11:10 +00:00
Issue #28548: Parse HTTP request version even if too many words received
This commit is contained in:
parent
dc0e6f9ea3
commit
e82338ddab
3 changed files with 31 additions and 15 deletions
|
@ -267,8 +267,8 @@ class BaseHTTPRequestHandler(socketserver.StreamRequestHandler):
|
||||||
are in self.command, self.path, self.request_version and
|
are in self.command, self.path, self.request_version and
|
||||||
self.headers.
|
self.headers.
|
||||||
|
|
||||||
Return True for success, False for failure; on failure, an
|
Return True for success, False for failure; on failure, any relevant
|
||||||
error is sent back.
|
error response has already been sent back.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.command = None # set in case of error on the first line
|
self.command = None # set in case of error on the first line
|
||||||
|
@ -278,10 +278,13 @@ class BaseHTTPRequestHandler(socketserver.StreamRequestHandler):
|
||||||
requestline = requestline.rstrip('\r\n')
|
requestline = requestline.rstrip('\r\n')
|
||||||
self.requestline = requestline
|
self.requestline = requestline
|
||||||
words = requestline.split()
|
words = requestline.split()
|
||||||
if len(words) == 3:
|
if len(words) == 0:
|
||||||
command, path, version = words
|
return False
|
||||||
|
|
||||||
|
if len(words) >= 3: # Enough to determine protocol version
|
||||||
|
version = words[-1]
|
||||||
try:
|
try:
|
||||||
if version[:5] != 'HTTP/':
|
if not version.startswith('HTTP/'):
|
||||||
raise ValueError
|
raise ValueError
|
||||||
base_version_number = version.split('/', 1)[1]
|
base_version_number = version.split('/', 1)[1]
|
||||||
version_number = base_version_number.split(".")
|
version_number = base_version_number.split(".")
|
||||||
|
@ -306,22 +309,22 @@ class BaseHTTPRequestHandler(socketserver.StreamRequestHandler):
|
||||||
HTTPStatus.HTTP_VERSION_NOT_SUPPORTED,
|
HTTPStatus.HTTP_VERSION_NOT_SUPPORTED,
|
||||||
"Invalid HTTP version (%s)" % base_version_number)
|
"Invalid HTTP version (%s)" % base_version_number)
|
||||||
return False
|
return False
|
||||||
elif len(words) == 2:
|
self.request_version = version
|
||||||
command, path = words
|
|
||||||
|
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
|
self.close_connection = True
|
||||||
if command != 'GET':
|
if command != 'GET':
|
||||||
self.send_error(
|
self.send_error(
|
||||||
HTTPStatus.BAD_REQUEST,
|
HTTPStatus.BAD_REQUEST,
|
||||||
"Bad HTTP/0.9 request type (%r)" % command)
|
"Bad HTTP/0.9 request type (%r)" % command)
|
||||||
return False
|
return False
|
||||||
elif not words:
|
self.command, self.path = command, path
|
||||||
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
|
|
||||||
|
|
||||||
# Examine the headers and look for a Connection directive.
|
# Examine the headers and look for a Connection directive.
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -822,6 +822,16 @@ class BaseHTTPRequestHandlerTestCase(unittest.TestCase):
|
||||||
self.assertEqual(result[0], b'<html><body>Data</body></html>\r\n')
|
self.assertEqual(result[0], b'<html><body>Data</body></html>\r\n')
|
||||||
self.verify_get_called()
|
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):
|
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')
|
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])
|
self.verify_http_server_response(result[0])
|
||||||
|
|
|
@ -128,6 +128,9 @@ Core and Builtins
|
||||||
Library
|
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.
|
- Issue #19717: Makes Path.resolve() succeed on paths that do not exist.
|
||||||
Patch by Vajrasky Kok
|
Patch by Vajrasky Kok
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue