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

Skip to content

Commit 6e13225

Browse files
committed
Issue #26402: Merge XML-RPC client fix from 3.5
2 parents f799ca8 + eae3336 commit 6e13225

3 files changed

Lines changed: 44 additions & 3 deletions

File tree

Lib/test/test_xmlrpc.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import xmlrpc.client as xmlrpclib
88
import xmlrpc.server
99
import http.client
10+
import http, http.server
1011
import socket
1112
import os
1213
import re
@@ -244,6 +245,42 @@ def test_ssl_presence(self):
244245
except OSError:
245246
self.assertTrue(has_ssl)
246247

248+
@unittest.skipUnless(threading, "Threading required for this test.")
249+
def test_keepalive_disconnect(self):
250+
class RequestHandler(http.server.BaseHTTPRequestHandler):
251+
protocol_version = "HTTP/1.1"
252+
handled = False
253+
254+
def do_POST(self):
255+
length = int(self.headers.get("Content-Length"))
256+
self.rfile.read(length)
257+
if self.handled:
258+
self.close_connection = True
259+
return
260+
response = xmlrpclib.dumps((5,), methodresponse=True)
261+
response = response.encode()
262+
self.send_response(http.HTTPStatus.OK)
263+
self.send_header("Content-Length", len(response))
264+
self.end_headers()
265+
self.wfile.write(response)
266+
self.handled = True
267+
self.close_connection = False
268+
269+
def run_server():
270+
server.socket.settimeout(float(1)) # Don't hang if client fails
271+
server.handle_request() # First request and attempt at second
272+
server.handle_request() # Retried second request
273+
274+
server = http.server.HTTPServer((support.HOST, 0), RequestHandler)
275+
self.addCleanup(server.server_close)
276+
thread = threading.Thread(target=run_server)
277+
thread.start()
278+
self.addCleanup(thread.join)
279+
url = "http://{}:{}/".format(*server.server_address)
280+
with xmlrpclib.ServerProxy(url) as p:
281+
self.assertEqual(p.method(), 5)
282+
self.assertEqual(p.method(), 5)
283+
247284
class HelperTestCase(unittest.TestCase):
248285
def test_escape(self):
249286
self.assertEqual(xmlrpclib.escape("a&b"), "a&b")

Lib/xmlrpc/client.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,13 +1129,13 @@ def request(self, host, handler, request_body, verbose=False):
11291129
for i in (0, 1):
11301130
try:
11311131
return self.single_request(host, handler, request_body, verbose)
1132+
except http.client.RemoteDisconnected:
1133+
if i:
1134+
raise
11321135
except OSError as e:
11331136
if i or e.errno not in (errno.ECONNRESET, errno.ECONNABORTED,
11341137
errno.EPIPE):
11351138
raise
1136-
except http.client.RemoteDisconnected:
1137-
if i:
1138-
raise
11391139

11401140
def single_request(self, host, handler, request_body, verbose=False):
11411141
# issue XML-RPC request

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,10 @@ Core and Builtins
189189
Library
190190
-------
191191

192+
- Issue #26402: Fix XML-RPC client to retry when the server shuts down a
193+
persistent connection. This was a regression related to the new
194+
http.client.RemoteDisconnected exception in 3.5.0a4.
195+
192196
- Issue #25913: Leading ``<~`` is optional now in base64.a85decode() with
193197
adobe=True. Patch by Swati Jaiswal.
194198

0 commit comments

Comments
 (0)