Issue #26402: Fix XML-RPC client retrying after server disconnection
This is a regression introduced in 3.5 by revision eba80326ba53. Fix by Jelte Fennema, test case by me.
This commit is contained in:
parent
f828218d65
commit
eae3336e42
|
@ -7,6 +7,7 @@ from unittest import mock
|
||||||
import xmlrpc.client as xmlrpclib
|
import xmlrpc.client as xmlrpclib
|
||||||
import xmlrpc.server
|
import xmlrpc.server
|
||||||
import http.client
|
import http.client
|
||||||
|
import http, http.server
|
||||||
import socket
|
import socket
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
@ -244,6 +245,42 @@ class XMLRPCTestCase(unittest.TestCase):
|
||||||
except OSError:
|
except OSError:
|
||||||
self.assertTrue(has_ssl)
|
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):
|
class HelperTestCase(unittest.TestCase):
|
||||||
def test_escape(self):
|
def test_escape(self):
|
||||||
self.assertEqual(xmlrpclib.escape("a&b"), "a&b")
|
self.assertEqual(xmlrpclib.escape("a&b"), "a&b")
|
||||||
|
|
|
@ -1129,13 +1129,13 @@ class Transport:
|
||||||
for i in (0, 1):
|
for i in (0, 1):
|
||||||
try:
|
try:
|
||||||
return self.single_request(host, handler, request_body, verbose)
|
return self.single_request(host, handler, request_body, verbose)
|
||||||
|
except http.client.RemoteDisconnected:
|
||||||
|
if i:
|
||||||
|
raise
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
if i or e.errno not in (errno.ECONNRESET, errno.ECONNABORTED,
|
if i or e.errno not in (errno.ECONNRESET, errno.ECONNABORTED,
|
||||||
errno.EPIPE):
|
errno.EPIPE):
|
||||||
raise
|
raise
|
||||||
except http.client.RemoteDisconnected:
|
|
||||||
if i:
|
|
||||||
raise
|
|
||||||
|
|
||||||
def single_request(self, host, handler, request_body, verbose=False):
|
def single_request(self, host, handler, request_body, verbose=False):
|
||||||
# issue XML-RPC request
|
# issue XML-RPC request
|
||||||
|
|
|
@ -79,6 +79,10 @@ Core and Builtins
|
||||||
Library
|
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
|
- Issue #25913: Leading ``<~`` is optional now in base64.a85decode() with
|
||||||
adobe=True. Patch by Swati Jaiswal.
|
adobe=True. Patch by Swati Jaiswal.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue