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.server
|
||||
import http.client
|
||||
import http, http.server
|
||||
import socket
|
||||
import os
|
||||
import re
|
||||
|
@ -244,6 +245,42 @@ class XMLRPCTestCase(unittest.TestCase):
|
|||
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")
|
||||
|
|
|
@ -1129,13 +1129,13 @@ class Transport:
|
|||
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
|
||||
|
|
|
@ -79,6 +79,10 @@ Core and Builtins
|
|||
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.
|
||||
|
||||
|
|
Loading…
Reference in New Issue