cpython: 6e3e252cf047 (original) (raw)
Mercurial > cpython
changeset 94673:6e3e252cf047
merge 3.4 (#23410) [#23410]
Benjamin Peterson benjamin@python.org | |
---|---|
date | Tue, 17 Feb 2015 21:13:30 -0500 |
parents | 9a55a2a1dc6f(current diff)f9ff2a5bbbe2(diff) |
children | 4f7c5349e801 477d217ba4e8 |
files | Doc/library/http.server.rst Lib/http/server.py |
diffstat | 3 files changed, 61 insertions(+), 10 deletions(-)[+] [-] Doc/library/http.server.rst 12 Lib/http/server.py 20 Lib/test/test_httpservers.py 39 |
line wrap: on
line diff
--- a/Doc/library/http.server.rst +++ b/Doc/library/http.server.rst @@ -64,6 +64,18 @@ of which this module provides three diff Contains the server instance.
- .. attribute:: close_connection +
Boolean that should be set before :meth:`handle_one_request` returns,[](#l1.9)
indicating if another request may be expected, or if the connection should[](#l1.10)
be shut down.[](#l1.11)
- .. attribute:: requestline +
Contains the string representation of the HTTP request line. The[](#l1.15)
terminating CRLF is stripped. This attribute should be set by[](#l1.16)
:meth:`handle_one_request`. If no valid request line was processed, it[](#l1.17)
should be set to the empty string.[](#l1.18)
--- a/Lib/http/server.py +++ b/Lib/http/server.py @@ -275,7 +275,7 @@ class BaseHTTPRequestHandler(socketserve """ self.command = None # set in case of error on the first line self.request_version = version = self.default_request_version
self.close_connection = 1[](#l2.7)
self.close_connection = True[](#l2.8) requestline = str(self.raw_requestline, 'iso-8859-1')[](#l2.9) requestline = requestline.rstrip('\r\n')[](#l2.10) self.requestline = requestline[](#l2.11)
@@ -305,7 +305,7 @@ class BaseHTTPRequestHandler(socketserve "Bad request version (%r)" % version) return False if version_number >= (1, 1) and self.protocol_version >= "HTTP/1.1":
self.close_connection = 0[](#l2.16)
self.close_connection = False[](#l2.17) if version_number >= (2, 0):[](#l2.18) self.send_error([](#l2.19) HTTPStatus.HTTP_VERSION_NOT_SUPPORTED,[](#l2.20)
@@ -313,7 +313,7 @@ class BaseHTTPRequestHandler(socketserve return False elif len(words) == 2: command, path = words
self.close_connection = 1[](#l2.25)
self.close_connection = True[](#l2.26) if command != 'GET':[](#l2.27) self.send_error([](#l2.28) HTTPStatus.BAD_REQUEST,[](#l2.29)
@@ -340,10 +340,10 @@ class BaseHTTPRequestHandler(socketserve conntype = self.headers.get('Connection', "") if conntype.lower() == 'close':
self.close_connection = 1[](#l2.34)
self.close_connection = True[](#l2.35) elif (conntype.lower() == 'keep-alive' and[](#l2.36) self.protocol_version >= "HTTP/1.1"):[](#l2.37)
self.close_connection = 0[](#l2.38)
self.close_connection = False[](#l2.39) # Examine the headers and look for an Expect directive[](#l2.40) expect = self.headers.get('Expect', "")[](#l2.41) if (expect.lower() == "100-continue" and[](#l2.42)
@@ -388,7 +388,7 @@ class BaseHTTPRequestHandler(socketserve self.send_error(HTTPStatus.REQUEST_URI_TOO_LONG) return if not self.raw_requestline:
self.close_connection = 1[](#l2.47)
self.close_connection = True[](#l2.48) return[](#l2.49) if not self.parse_request():[](#l2.50) # An error code has been sent, just exit[](#l2.51)
@@ -405,12 +405,12 @@ class BaseHTTPRequestHandler(socketserve except socket.timeout as e: #a read or a write timed out. Discard this connection self.log_error("Request timed out: %r", e)
self.close_connection = 1[](#l2.56)
self.close_connection = True[](#l2.57) return[](#l2.58)
def handle(self): """Handle multiple requests if necessary."""
self.close_connection = 1[](#l2.62)
self.close_connection = True[](#l2.63)
self.handle_one_request() while not self.close_connection: @@ -496,9 +496,9 @@ class BaseHTTPRequestHandler(socketserve if keyword.lower() == 'connection': if value.lower() == 'close':
self.close_connection = 1[](#l2.71)
self.close_connection = True[](#l2.72) elif value.lower() == 'keep-alive':[](#l2.73)
self.close_connection = 0[](#l2.74)
self.close_connection = False[](#l2.75)
def end_headers(self): """Send the blank line ending the MIME headers."""
--- a/Lib/test/test_httpservers.py +++ b/Lib/test/test_httpservers.py @@ -616,6 +616,11 @@ class BaseHTTPRequestHandlerTestCase(uni self.verify_expected_headers(result[1:-1]) self.verify_get_called() self.assertEqual(result[-1], b'Data\r\n')
self.assertEqual(self.handler.requestline, 'GET / HTTP/1.1')[](#l3.7)
self.assertEqual(self.handler.command, 'GET')[](#l3.8)
self.assertEqual(self.handler.path, '/')[](#l3.9)
self.assertEqual(self.handler.request_version, 'HTTP/1.1')[](#l3.10)
self.assertSequenceEqual(self.handler.headers.items(), ())[](#l3.11)
def test_http_1_0(self): result = self.send_typical_request(b'GET / HTTP/1.0\r\n\r\n') @@ -623,6 +628,11 @@ class BaseHTTPRequestHandlerTestCase(uni self.verify_expected_headers(result[1:-1]) self.verify_get_called() self.assertEqual(result[-1], b'Data\r\n')
self.assertEqual(self.handler.requestline, 'GET / HTTP/1.0')[](#l3.19)
self.assertEqual(self.handler.command, 'GET')[](#l3.20)
self.assertEqual(self.handler.path, '/')[](#l3.21)
self.assertEqual(self.handler.request_version, 'HTTP/1.0')[](#l3.22)
self.assertSequenceEqual(self.handler.headers.items(), ())[](#l3.23)
def test_http_0_9(self): result = self.send_typical_request(b'GET / HTTP/0.9\r\n\r\n') @@ -636,6 +646,12 @@ class BaseHTTPRequestHandlerTestCase(uni self.verify_expected_headers(result[1:-1]) self.verify_get_called() self.assertEqual(result[-1], b'Data\r\n')
self.assertEqual(self.handler.requestline, 'GET / HTTP/1.0')[](#l3.31)
self.assertEqual(self.handler.command, 'GET')[](#l3.32)
self.assertEqual(self.handler.path, '/')[](#l3.33)
self.assertEqual(self.handler.request_version, 'HTTP/1.0')[](#l3.34)
headers = (("Expect", "100-continue"),)[](#l3.35)
self.assertSequenceEqual(self.handler.headers.items(), headers)[](#l3.36)
def test_with_continue_1_1(self): result = self.send_typical_request(b'GET / HTTP/1.1\r\nExpect: 100-continue\r\n\r\n') @@ -645,6 +661,12 @@ class BaseHTTPRequestHandlerTestCase(uni self.verify_expected_headers(result[2:-1]) self.verify_get_called() self.assertEqual(result[-1], b'Data\r\n')
self.assertEqual(self.handler.requestline, 'GET / HTTP/1.1')[](#l3.44)
self.assertEqual(self.handler.command, 'GET')[](#l3.45)
self.assertEqual(self.handler.path, '/')[](#l3.46)
self.assertEqual(self.handler.request_version, 'HTTP/1.1')[](#l3.47)
headers = (("Expect", "100-continue"),)[](#l3.48)
self.assertSequenceEqual(self.handler.headers.items(), headers)[](#l3.49)
def test_header_buffering_of_send_error(self): @@ -730,6 +752,7 @@ class BaseHTTPRequestHandlerTestCase(uni 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)
self.assertIsInstance(self.handler.requestline, str)[](#l3.57)
def test_header_length(self): # Issue #6791: same for headers @@ -737,6 +760,22 @@ class BaseHTTPRequestHandlerTestCase(uni b'GET / HTTP/1.1\r\nX-Foo: bar' + b'r' * 65537 + b'\r\n\r\n') self.assertEqual(result[0], b'HTTP/1.1 400 Line too long\r\n') self.assertFalse(self.handler.get_called)
self.assertEqual(self.handler.requestline, 'GET / HTTP/1.1')[](#l3.65)
- def test_close_connection(self):
# handle_one_request() should be repeatedly called until[](#l3.68)
# it sets close_connection[](#l3.69)
def handle_one_request():[](#l3.70)
self.handler.close_connection = next(close_values)[](#l3.71)
self.handler.handle_one_request = handle_one_request[](#l3.72)
close_values = iter((True,))[](#l3.74)
self.handler.handle()[](#l3.75)
self.assertRaises(StopIteration, next, close_values)[](#l3.76)
close_values = iter((False, False, True))[](#l3.78)
self.handler.handle()[](#l3.79)
self.assertRaises(StopIteration, next, close_values)[](#l3.80)
class SimpleHTTPRequestHandlerTestCase(unittest.TestCase): """ Test url parsing """