mirror of https://github.com/python/cpython
Merged revisions 87317 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r87317 | antoine.pitrou | 2010-12-16 17:48:36 +0100 (jeu., 16 déc. 2010) | 4 lines Issue #10714: Limit length of incoming request in http.server to 65536 bytes for security reasons. Initial patch by Ross Lagerwall. ........ (also backported some tests)
This commit is contained in:
parent
fd1cf6f832
commit
47d9b0e08a
|
@ -310,7 +310,13 @@ class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
self.raw_requestline = self.rfile.readline()
|
self.raw_requestline = self.rfile.readline(65537)
|
||||||
|
if len(self.raw_requestline) > 65536:
|
||||||
|
self.requestline = ''
|
||||||
|
self.request_version = ''
|
||||||
|
self.command = ''
|
||||||
|
self.send_error(414)
|
||||||
|
return
|
||||||
if not self.raw_requestline:
|
if not self.raw_requestline:
|
||||||
self.close_connection = 1
|
self.close_connection = 1
|
||||||
return
|
return
|
||||||
|
|
|
@ -484,10 +484,119 @@ class CGIHTTPServerTestCase(BaseTestCase):
|
||||||
(res.read(), res.getheader('Content-type'), res.status))
|
(res.read(), res.getheader('Content-type'), res.status))
|
||||||
self.assertEqual(os.environ['SERVER_SOFTWARE'], signature)
|
self.assertEqual(os.environ['SERVER_SOFTWARE'], signature)
|
||||||
|
|
||||||
|
|
||||||
|
class SocketlessRequestHandler(SimpleHTTPRequestHandler):
|
||||||
|
def __init__(self):
|
||||||
|
self.get_called = False
|
||||||
|
self.protocol_version = "HTTP/1.1"
|
||||||
|
|
||||||
|
def do_GET(self):
|
||||||
|
self.get_called = True
|
||||||
|
self.send_response(200)
|
||||||
|
self.send_header('Content-Type', 'text/html')
|
||||||
|
self.end_headers()
|
||||||
|
self.wfile.write(b'<html><body>Data</body></html>\r\n')
|
||||||
|
|
||||||
|
def log_message(self, format, *args):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class RejectingSocketlessRequestHandler(SocketlessRequestHandler):
|
||||||
|
def handle_expect_100(self):
|
||||||
|
self.send_error(417)
|
||||||
|
return False
|
||||||
|
|
||||||
|
class BaseHTTPRequestHandlerTestCase(unittest.TestCase):
|
||||||
|
"""Test the functionaility of the BaseHTTPServer.
|
||||||
|
|
||||||
|
Test the support for the Expect 100-continue header.
|
||||||
|
"""
|
||||||
|
|
||||||
|
HTTPResponseMatch = re.compile(b'HTTP/1.[0-9]+ 200 OK')
|
||||||
|
|
||||||
|
def setUp (self):
|
||||||
|
self.handler = SocketlessRequestHandler()
|
||||||
|
|
||||||
|
def send_typical_request(self, message):
|
||||||
|
input = StringIO(message)
|
||||||
|
output = StringIO()
|
||||||
|
self.handler.rfile = input
|
||||||
|
self.handler.wfile = output
|
||||||
|
self.handler.handle_one_request()
|
||||||
|
output.seek(0)
|
||||||
|
return output.readlines()
|
||||||
|
|
||||||
|
def verify_get_called(self):
|
||||||
|
self.assertTrue(self.handler.get_called)
|
||||||
|
|
||||||
|
def verify_expected_headers(self, headers):
|
||||||
|
for fieldName in b'Server: ', b'Date: ', b'Content-Type: ':
|
||||||
|
self.assertEqual(sum(h.startswith(fieldName) for h in headers), 1)
|
||||||
|
|
||||||
|
def verify_http_server_response(self, response):
|
||||||
|
match = self.HTTPResponseMatch.search(response)
|
||||||
|
self.assertTrue(match is not None)
|
||||||
|
|
||||||
|
def test_http_1_1(self):
|
||||||
|
result = self.send_typical_request(b'GET / HTTP/1.1\r\n\r\n')
|
||||||
|
self.verify_http_server_response(result[0])
|
||||||
|
self.verify_expected_headers(result[1:-1])
|
||||||
|
self.verify_get_called()
|
||||||
|
self.assertEqual(result[-1], b'<html><body>Data</body></html>\r\n')
|
||||||
|
|
||||||
|
def test_http_1_0(self):
|
||||||
|
result = self.send_typical_request(b'GET / HTTP/1.0\r\n\r\n')
|
||||||
|
self.verify_http_server_response(result[0])
|
||||||
|
self.verify_expected_headers(result[1:-1])
|
||||||
|
self.verify_get_called()
|
||||||
|
self.assertEqual(result[-1], b'<html><body>Data</body></html>\r\n')
|
||||||
|
|
||||||
|
def test_http_0_9(self):
|
||||||
|
result = self.send_typical_request(b'GET / HTTP/0.9\r\n\r\n')
|
||||||
|
self.assertEqual(len(result), 1)
|
||||||
|
self.assertEqual(result[0], b'<html><body>Data</body></html>\r\n')
|
||||||
|
self.verify_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])
|
||||||
|
self.verify_expected_headers(result[1:-1])
|
||||||
|
self.verify_get_called()
|
||||||
|
self.assertEqual(result[-1], b'<html><body>Data</body></html>\r\n')
|
||||||
|
|
||||||
|
def test_request_length(self):
|
||||||
|
# Issue #10714: huge request lines are discarded, to avoid Denial
|
||||||
|
# of Service attacks.
|
||||||
|
result = self.send_typical_request(b'GET ' + b'x' * 65537)
|
||||||
|
self.assertEqual(result[0], b'HTTP/1.1 414 Request-URI Too Long\r\n')
|
||||||
|
self.assertFalse(self.handler.get_called)
|
||||||
|
|
||||||
|
class SimpleHTTPRequestHandlerTestCase(unittest.TestCase):
|
||||||
|
""" Test url parsing """
|
||||||
|
def setUp(self):
|
||||||
|
self.translated = os.getcwd()
|
||||||
|
self.translated = os.path.join(self.translated, 'filename')
|
||||||
|
self.handler = SocketlessRequestHandler()
|
||||||
|
|
||||||
|
def test_query_arguments(self):
|
||||||
|
path = self.handler.translate_path('/filename')
|
||||||
|
self.assertEqual(path, self.translated)
|
||||||
|
path = self.handler.translate_path('/filename?foo=bar')
|
||||||
|
self.assertEqual(path, self.translated)
|
||||||
|
path = self.handler.translate_path('/filename?a=b&spam=eggs#zot')
|
||||||
|
self.assertEqual(path, self.translated)
|
||||||
|
|
||||||
|
def test_start_with_double_slash(self):
|
||||||
|
path = self.handler.translate_path('//filename')
|
||||||
|
self.assertEqual(path, self.translated)
|
||||||
|
path = self.handler.translate_path('//filename?foo=bar')
|
||||||
|
self.assertEqual(path, self.translated)
|
||||||
|
|
||||||
|
|
||||||
def test_main(verbose=None):
|
def test_main(verbose=None):
|
||||||
try:
|
try:
|
||||||
cwd = os.getcwd()
|
cwd = os.getcwd()
|
||||||
test_support.run_unittest(BaseHTTPRequestHandlerTestCase,
|
test_support.run_unittest(BaseHTTPRequestHandlerTestCase,
|
||||||
|
SimpleHTTPRequestHandlerTestCase,
|
||||||
BaseHTTPServerTestCase,
|
BaseHTTPServerTestCase,
|
||||||
SimpleHTTPServerTestCase,
|
SimpleHTTPServerTestCase,
|
||||||
CGIHTTPServerTestCase
|
CGIHTTPServerTestCase
|
||||||
|
|
|
@ -447,6 +447,7 @@ Andrej Krpic
|
||||||
Ivan Krstić
|
Ivan Krstić
|
||||||
Andrew Kuchling
|
Andrew Kuchling
|
||||||
Vladimir Kushnir
|
Vladimir Kushnir
|
||||||
|
Ross Lagerwall
|
||||||
Cameron Laird
|
Cameron Laird
|
||||||
Łukasz Langa
|
Łukasz Langa
|
||||||
Tino Lange
|
Tino Lange
|
||||||
|
|
|
@ -22,6 +22,9 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #10714: Limit length of incoming request in http.server to 65536 bytes
|
||||||
|
for security reasons. Initial patch by Ross Lagerwall.
|
||||||
|
|
||||||
- Issue #9558: Fix distutils.command.build_ext with VS 8.0.
|
- Issue #9558: Fix distutils.command.build_ext with VS 8.0.
|
||||||
|
|
||||||
- Issue #10695: passing the port as a string value to telnetlib no longer
|
- Issue #10695: passing the port as a string value to telnetlib no longer
|
||||||
|
|
Loading…
Reference in New Issue