summaryrefslogtreecommitdiffstats
path: root/Lib/xmlrpc/client.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/xmlrpc/client.py')
-rw-r--r--Lib/xmlrpc/client.py49
1 files changed, 33 insertions, 16 deletions
diff --git a/Lib/xmlrpc/client.py b/Lib/xmlrpc/client.py
index ca2ac9f..9de5111 100644
--- a/Lib/xmlrpc/client.py
+++ b/Lib/xmlrpc/client.py
@@ -135,7 +135,6 @@ from datetime import datetime
import http.client
import urllib.parse
from xml.parsers import expat
-import socket
import errno
from io import BytesIO
try:
@@ -447,8 +446,13 @@ class ExpatParser:
self._parser.Parse(data, 0)
def close(self):
- self._parser.Parse("", 1) # end of data
- del self._target, self._parser # get rid of circular references
+ try:
+ parser = self._parser
+ except AttributeError:
+ pass
+ else:
+ del self._target, self._parser # get rid of circular references
+ parser.Parse(b"", True) # end of data
# --------------------------------------------------------------------
# XML-RPC marshalling and unmarshalling code
@@ -827,7 +831,7 @@ class MultiCallIterator:
raise ValueError("unexpected type in multicall result")
class MultiCall:
- """server -> a object used to boxcar method calls
+ """server -> an object used to boxcar method calls
server should be a ServerProxy object.
@@ -1052,7 +1056,7 @@ def gzip_decode(data, max_decode=20971520):
decoded = gzf.read()
else:
decoded = gzf.read(max_decode + 1)
- except IOError:
+ except OSError:
raise ValueError("invalid data")
f.close()
gzf.close()
@@ -1080,8 +1084,10 @@ class GzipDecodedResponse(gzip.GzipFile if gzip else object):
gzip.GzipFile.__init__(self, mode="rb", fileobj=self.io)
def close(self):
- gzip.GzipFile.close(self)
- self.io.close()
+ try:
+ gzip.GzipFile.close(self)
+ finally:
+ self.io.close()
# --------------------------------------------------------------------
@@ -1139,8 +1145,9 @@ class Transport:
for i in (0, 1):
try:
return self.single_request(host, handler, request_body, verbose)
- except socket.error as e:
- if i or e.errno not in (errno.ECONNRESET, errno.ECONNABORTED, errno.EPIPE):
+ except OSError as e:
+ if i or e.errno not in (errno.ECONNRESET, errno.ECONNABORTED,
+ errno.EPIPE):
raise
except http.client.BadStatusLine: #close after we sent request
if i:
@@ -1177,7 +1184,7 @@ class Transport:
##
# Create parser.
#
- # @return A 2-tuple containing a parser and a unmarshaller.
+ # @return A 2-tuple containing a parser and an unmarshaller.
def getparser(self):
# get parser and unmarshaller
@@ -1235,9 +1242,10 @@ class Transport:
# Used in the event of socket errors.
#
def close(self):
- if self._connection[1]:
- self._connection[1].close()
+ host, connection = self._connection
+ if connection:
self._connection = (None, None)
+ connection.close()
##
# Send HTTP request.
@@ -1332,6 +1340,11 @@ class Transport:
class SafeTransport(Transport):
"""Handles an HTTPS transaction to an XML-RPC server."""
+ def __init__(self, use_datetime=False, use_builtin_types=False, *,
+ context=None):
+ super().__init__(use_datetime=use_datetime, use_builtin_types=use_builtin_types)
+ self.context = context
+
# FIXME: mostly untested
def make_connection(self, host):
@@ -1345,7 +1358,7 @@ class SafeTransport(Transport):
# host may be a string, or a (host, x509-dict) tuple
chost, self._extra_headers, x509 = self.get_host_info(host)
self._connection = host, http.client.HTTPSConnection(chost,
- None, **(x509 or {}))
+ None, context=self.context, **(x509 or {}))
return self._connection[1]
##
@@ -1388,13 +1401,14 @@ class ServerProxy:
"""
def __init__(self, uri, transport=None, encoding=None, verbose=False,
- allow_none=False, use_datetime=False, use_builtin_types=False):
+ allow_none=False, use_datetime=False, use_builtin_types=False,
+ *, context=None):
# establish a "logical" server connection
# get the url
type, uri = urllib.parse.splittype(uri)
if type not in ("http", "https"):
- raise IOError("unsupported XML-RPC protocol")
+ raise OSError("unsupported XML-RPC protocol")
self.__host, self.__handler = urllib.parse.splithost(uri)
if not self.__handler:
self.__handler = "/RPC2"
@@ -1402,10 +1416,13 @@ class ServerProxy:
if transport is None:
if type == "https":
handler = SafeTransport
+ extra_kwargs = {"context": context}
else:
handler = Transport
+ extra_kwargs = {}
transport = handler(use_datetime=use_datetime,
- use_builtin_types=use_builtin_types)
+ use_builtin_types=use_builtin_types,
+ **extra_kwargs)
self.__transport = transport
self.__encoding = encoding or 'utf-8'