Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1130c7f

Browse files
committed
merge 3.4 (#23410)
2 parents a634433 + 70e2847 commit 1130c7f

3 files changed

Lines changed: 61 additions & 10 deletions

File tree

Doc/library/http.server.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,18 @@ of which this module provides three different variants:
6464

6565
Contains the server instance.
6666

67+
.. attribute:: close_connection
68+
69+
Boolean that should be set before :meth:`handle_one_request` returns,
70+
indicating if another request may be expected, or if the connection should
71+
be shut down.
72+
73+
.. attribute:: requestline
74+
75+
Contains the string representation of the HTTP request line. The
76+
terminating CRLF is stripped. This attribute should be set by
77+
:meth:`handle_one_request`. If no valid request line was processed, it
78+
should be set to the empty string.
6779

6880
.. attribute:: command
6981

Lib/http/server.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ def parse_request(self):
275275
"""
276276
self.command = None # set in case of error on the first line
277277
self.request_version = version = self.default_request_version
278-
self.close_connection = 1
278+
self.close_connection = True
279279
requestline = str(self.raw_requestline, 'iso-8859-1')
280280
requestline = requestline.rstrip('\r\n')
281281
self.requestline = requestline
@@ -305,15 +305,15 @@ def parse_request(self):
305305
"Bad request version (%r)" % version)
306306
return False
307307
if version_number >= (1, 1) and self.protocol_version >= "HTTP/1.1":
308-
self.close_connection = 0
308+
self.close_connection = False
309309
if version_number >= (2, 0):
310310
self.send_error(
311311
HTTPStatus.HTTP_VERSION_NOT_SUPPORTED,
312312
"Invalid HTTP Version (%s)" % base_version_number)
313313
return False
314314
elif len(words) == 2:
315315
command, path = words
316-
self.close_connection = 1
316+
self.close_connection = True
317317
if command != 'GET':
318318
self.send_error(
319319
HTTPStatus.BAD_REQUEST,
@@ -340,10 +340,10 @@ def parse_request(self):
340340

341341
conntype = self.headers.get('Connection', "")
342342
if conntype.lower() == 'close':
343-
self.close_connection = 1
343+
self.close_connection = True
344344
elif (conntype.lower() == 'keep-alive' and
345345
self.protocol_version >= "HTTP/1.1"):
346-
self.close_connection = 0
346+
self.close_connection = False
347347
# Examine the headers and look for an Expect directive
348348
expect = self.headers.get('Expect', "")
349349
if (expect.lower() == "100-continue" and
@@ -388,7 +388,7 @@ def handle_one_request(self):
388388
self.send_error(HTTPStatus.REQUEST_URI_TOO_LONG)
389389
return
390390
if not self.raw_requestline:
391-
self.close_connection = 1
391+
self.close_connection = True
392392
return
393393
if not self.parse_request():
394394
# An error code has been sent, just exit
@@ -405,12 +405,12 @@ def handle_one_request(self):
405405
except socket.timeout as e:
406406
#a read or a write timed out. Discard this connection
407407
self.log_error("Request timed out: %r", e)
408-
self.close_connection = 1
408+
self.close_connection = True
409409
return
410410

411411
def handle(self):
412412
"""Handle multiple requests if necessary."""
413-
self.close_connection = 1
413+
self.close_connection = True
414414

415415
self.handle_one_request()
416416
while not self.close_connection:
@@ -496,9 +496,9 @@ def send_header(self, keyword, value):
496496

497497
if keyword.lower() == 'connection':
498498
if value.lower() == 'close':
499-
self.close_connection = 1
499+
self.close_connection = True
500500
elif value.lower() == 'keep-alive':
501-
self.close_connection = 0
501+
self.close_connection = False
502502

503503
def end_headers(self):
504504
"""Send the blank line ending the MIME headers."""

Lib/test/test_httpservers.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,13 +616,23 @@ def test_http_1_1(self):
616616
self.verify_expected_headers(result[1:-1])
617617
self.verify_get_called()
618618
self.assertEqual(result[-1], b'<html><body>Data</body></html>\r\n')
619+
self.assertEqual(self.handler.requestline, 'GET / HTTP/1.1')
620+
self.assertEqual(self.handler.command, 'GET')
621+
self.assertEqual(self.handler.path, '/')
622+
self.assertEqual(self.handler.request_version, 'HTTP/1.1')
623+
self.assertSequenceEqual(self.handler.headers.items(), ())
619624

620625
def test_http_1_0(self):
621626
result = self.send_typical_request(b'GET / HTTP/1.0\r\n\r\n')
622627
self.verify_http_server_response(result[0])
623628
self.verify_expected_headers(result[1:-1])
624629
self.verify_get_called()
625630
self.assertEqual(result[-1], b'<html><body>Data</body></html>\r\n')
631+
self.assertEqual(self.handler.requestline, 'GET / HTTP/1.0')
632+
self.assertEqual(self.handler.command, 'GET')
633+
self.assertEqual(self.handler.path, '/')
634+
self.assertEqual(self.handler.request_version, 'HTTP/1.0')
635+
self.assertSequenceEqual(self.handler.headers.items(), ())
626636

627637
def test_http_0_9(self):
628638
result = self.send_typical_request(b'GET / HTTP/0.9\r\n\r\n')
@@ -636,6 +646,12 @@ def test_with_continue_1_0(self):
636646
self.verify_expected_headers(result[1:-1])
637647
self.verify_get_called()
638648
self.assertEqual(result[-1], b'<html><body>Data</body></html>\r\n')
649+
self.assertEqual(self.handler.requestline, 'GET / HTTP/1.0')
650+
self.assertEqual(self.handler.command, 'GET')
651+
self.assertEqual(self.handler.path, '/')
652+
self.assertEqual(self.handler.request_version, 'HTTP/1.0')
653+
headers = (("Expect", "100-continue"),)
654+
self.assertSequenceEqual(self.handler.headers.items(), headers)
639655

640656
def test_with_continue_1_1(self):
641657
result = self.send_typical_request(b'GET / HTTP/1.1\r\nExpect: 100-continue\r\n\r\n')
@@ -645,6 +661,12 @@ def test_with_continue_1_1(self):
645661
self.verify_expected_headers(result[2:-1])
646662
self.verify_get_called()
647663
self.assertEqual(result[-1], b'<html><body>Data</body></html>\r\n')
664+
self.assertEqual(self.handler.requestline, 'GET / HTTP/1.1')
665+
self.assertEqual(self.handler.command, 'GET')
666+
self.assertEqual(self.handler.path, '/')
667+
self.assertEqual(self.handler.request_version, 'HTTP/1.1')
668+
headers = (("Expect", "100-continue"),)
669+
self.assertSequenceEqual(self.handler.headers.items(), headers)
648670

649671
def test_header_buffering_of_send_error(self):
650672

@@ -730,13 +752,30 @@ def test_request_length(self):
730752
result = self.send_typical_request(b'GET ' + b'x' * 65537)
731753
self.assertEqual(result[0], b'HTTP/1.1 414 Request-URI Too Long\r\n')
732754
self.assertFalse(self.handler.get_called)
755+
self.assertIsInstance(self.handler.requestline, str)
733756

734757
def test_header_length(self):
735758
# Issue #6791: same for headers
736759
result = self.send_typical_request(
737760
b'GET / HTTP/1.1\r\nX-Foo: bar' + b'r' * 65537 + b'\r\n\r\n')
738761
self.assertEqual(result[0], b'HTTP/1.1 400 Line too long\r\n')
739762
self.assertFalse(self.handler.get_called)
763+
self.assertEqual(self.handler.requestline, 'GET / HTTP/1.1')
764+
765+
def test_close_connection(self):
766+
# handle_one_request() should be repeatedly called until
767+
# it sets close_connection
768+
def handle_one_request():
769+
self.handler.close_connection = next(close_values)
770+
self.handler.handle_one_request = handle_one_request
771+
772+
close_values = iter((True,))
773+
self.handler.handle()
774+
self.assertRaises(StopIteration, next, close_values)
775+
776+
close_values = iter((False, False, True))
777+
self.handler.handle()
778+
self.assertRaises(StopIteration, next, close_values)
740779

741780
class SimpleHTTPRequestHandlerTestCase(unittest.TestCase):
742781
""" Test url parsing """

0 commit comments

Comments
 (0)