[Python-checkins] cpython (merge 3.5 -> default): Issue #26402: Merge XML-RPC client fix from 3.5

martin.panter python-checkins at python.org
Thu Feb 25 07:16:56 EST 2016


https://hg.python.org/cpython/rev/70bf0d764939
changeset:   100332:70bf0d764939
parent:      100330:2193f8b956de
parent:      100331:d668b5595534
user:        Martin Panter <vadmium+py at gmail.com>
date:        Thu Feb 25 12:13:50 2016 +0000
summary:
  Issue #26402: Merge XML-RPC client fix from 3.5

files:
  Lib/test/test_xmlrpc.py |  37 +++++++++++++++++++++++++++++
  Lib/xmlrpc/client.py    |   6 ++--
  Misc/NEWS               |   4 +++
  3 files changed, 44 insertions(+), 3 deletions(-)


diff --git a/Lib/test/test_xmlrpc.py b/Lib/test/test_xmlrpc.py
--- a/Lib/test/test_xmlrpc.py
+++ b/Lib/test/test_xmlrpc.py
@@ -7,6 +7,7 @@
 import xmlrpc.client as xmlrpclib
 import xmlrpc.server
 import http.client
+import http, http.server
 import socket
 import os
 import re
@@ -244,6 +245,42 @@
         except OSError:
             self.assertTrue(has_ssl)
 
+    @unittest.skipUnless(threading, "Threading required for this test.")
+    def test_keepalive_disconnect(self):
+        class RequestHandler(http.server.BaseHTTPRequestHandler):
+            protocol_version = "HTTP/1.1"
+            handled = False
+
+            def do_POST(self):
+                length = int(self.headers.get("Content-Length"))
+                self.rfile.read(length)
+                if self.handled:
+                    self.close_connection = True
+                    return
+                response = xmlrpclib.dumps((5,), methodresponse=True)
+                response = response.encode()
+                self.send_response(http.HTTPStatus.OK)
+                self.send_header("Content-Length", len(response))
+                self.end_headers()
+                self.wfile.write(response)
+                self.handled = True
+                self.close_connection = False
+
+        def run_server():
+            server.socket.settimeout(float(1))  # Don't hang if client fails
+            server.handle_request()  # First request and attempt at second
+            server.handle_request()  # Retried second request
+
+        server = http.server.HTTPServer((support.HOST, 0), RequestHandler)
+        self.addCleanup(server.server_close)
+        thread = threading.Thread(target=run_server)
+        thread.start()
+        self.addCleanup(thread.join)
+        url = "http://{}:{}/".format(*server.server_address)
+        with xmlrpclib.ServerProxy(url) as p:
+            self.assertEqual(p.method(), 5)
+            self.assertEqual(p.method(), 5)
+
 class HelperTestCase(unittest.TestCase):
     def test_escape(self):
         self.assertEqual(xmlrpclib.escape("a&b"), "a&b")
diff --git a/Lib/xmlrpc/client.py b/Lib/xmlrpc/client.py
--- a/Lib/xmlrpc/client.py
+++ b/Lib/xmlrpc/client.py
@@ -1129,13 +1129,13 @@
         for i in (0, 1):
             try:
                 return self.single_request(host, handler, request_body, verbose)
+            except http.client.RemoteDisconnected:
+                if i:
+                    raise
             except OSError as e:
                 if i or e.errno not in (errno.ECONNRESET, errno.ECONNABORTED,
                                         errno.EPIPE):
                     raise
-            except http.client.RemoteDisconnected:
-                if i:
-                    raise
 
     def single_request(self, host, handler, request_body, verbose=False):
         # issue XML-RPC request
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -189,6 +189,10 @@
 Library
 -------
 
+- Issue #26402: Fix XML-RPC client to retry when the server shuts down a
+  persistent connection.  This was a regression related to the new
+  http.client.RemoteDisconnected exception in 3.5.0a4.
+
 - Issue #25913: Leading ``<~`` is optional now in base64.a85decode() with
   adobe=True.  Patch by Swati Jaiswal.
 

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list