]> granicus.if.org Git - python/commitdiff
http.client: disable Nagle's algorithm (closes #23302)
authorBenjamin Peterson <benjamin@python.org>
Fri, 23 Jan 2015 16:02:57 +0000 (11:02 -0500)
committerBenjamin Peterson <benjamin@python.org>
Fri, 23 Jan 2015 16:02:57 +0000 (11:02 -0500)
Patch by Demian Brecht.

Lib/http/client.py
Lib/test/test_httplib.py
Misc/NEWS

index 5593b39b0e4f1c9c50b1d78a63238bbc7f4a2b46..392715b24dc4f0a0e8674f9c2e727920d98995e3 100644 (file)
@@ -681,14 +681,6 @@ class HTTPConnection:
     default_port = HTTP_PORT
     auto_open = 1
     debuglevel = 0
-    # TCP Maximum Segment Size (MSS) is determined by the TCP stack on
-    # a per-connection basis.  There is no simple and efficient
-    # platform independent mechanism for determining the MSS, so
-    # instead a reasonable estimate is chosen.  The getsockopt()
-    # interface using the TCP_MAXSEG parameter may be a suitable
-    # approach on some operating systems. A value of 16KiB is chosen
-    # as a reasonable estimate of the maximum MSS.
-    mss = 16384
 
     def __init__(self, host, port=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
                  source_address=None):
@@ -786,8 +778,9 @@ class HTTPConnection:
 
     def connect(self):
         """Connect to the host and port specified in __init__."""
-        self.sock = self._create_connection((self.host,self.port),
-                                            self.timeout, self.source_address)
+        self.sock = self._create_connection(
+            (self.host,self.port), self.timeout, self.source_address)
+        self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
 
         if self._tunnel_host:
             self._tunnel()
@@ -866,19 +859,9 @@ class HTTPConnection:
         self._buffer.extend((b"", b""))
         msg = b"\r\n".join(self._buffer)
         del self._buffer[:]
-        # If msg and message_body are sent in a single send() call,
-        # it will avoid performance problems caused by the interaction
-        # between delayed ack and the Nagle algorithm. However,
-        # there is no performance gain if the message is larger
-        # than MSS (and there is a memory penalty for the message
-        # copy).
-        if isinstance(message_body, bytes) and len(message_body) < self.mss:
-            msg += message_body
-            message_body = None
+
         self.send(msg)
         if message_body is not None:
-            # message_body was not a string (i.e. it is a file), and
-            # we must run the risk of Nagle.
             self.send(message_body)
 
     def putrequest(self, method, url, skip_host=0, skip_accept_encoding=0):
index 62612763f06b6c204da36c803f8736955b6f7e2f..08efa19d80644fea9f9c1ff21bd8d44e8ebeb634 100644 (file)
@@ -70,6 +70,9 @@ class FakeSocket:
     def close(self):
         pass
 
+    def setsockopt(self, level, optname, value):
+        pass
+
 class EPipeSocket(FakeSocket):
 
     def __init__(self, text, pipe_trigger):
@@ -658,28 +661,6 @@ class BasicTest(TestCase):
         resp.close()
         self.assertTrue(resp.closed)
 
-    def test_delayed_ack_opt(self):
-        # Test that Nagle/delayed_ack optimistaion works correctly.
-
-        # For small payloads, it should coalesce the body with
-        # headers, resulting in a single sendall() call
-        conn = client.HTTPConnection('example.com')
-        sock = FakeSocket(None)
-        conn.sock = sock
-        body = b'x' * (conn.mss - 1)
-        conn.request('POST', '/', body)
-        self.assertEqual(sock.sendall_calls, 1)
-
-        # For large payloads, it should send the headers and
-        # then the body, resulting in more than one sendall()
-        # call
-        conn = client.HTTPConnection('example.com')
-        sock = FakeSocket(None)
-        conn.sock = sock
-        body = b'x' * conn.mss
-        conn.request('POST', '/', body)
-        self.assertGreater(sock.sendall_calls, 1)
-
     def test_error_leak(self):
         # Test that the socket is not leaked if getresponse() fails
         conn = client.HTTPConnection('example.com')
index 5373f5bca8b524a814331f50f2c1bd70be3dd43f..5cd2c61e8217ca9070496aa66547261a0527c485 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -1308,6 +1308,10 @@ Library
 - Issue #22733: Fix ffi_prep_args not zero-extending argument values correctly
   on 64-bit Windows.
 
+- Issue #23302: Default to TCP_NODELAY=1 upon establishing an HTTPConnection.
+  Removed use of hard-coded MSS as it's an optimization that's no longer needed
+  with Nagle disabled.
+
 IDLE
 ----