diff options
Diffstat (limited to 'Lib/xmlrpc/client.py')
| -rw-r--r-- | Lib/xmlrpc/client.py | 49 |
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' |
