Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(371)

Unified Diff: Lib/xmlrpclib.py

Issue 63144: Make xmlrpclib use new HTTPConnection class Base URL: http://svn.python.org/view/*checkout*/python/trunk/
Patch Set: A new patch. We need better exception handling if we are keeping the HTTPConnection around. Created 15 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Lib/test/test_xmlrpc.py ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Lib/xmlrpclib.py
===================================================================
--- Lib/xmlrpclib.py (revision 73271)
+++ Lib/xmlrpclib.py (working copy)
@@ -140,6 +140,9 @@
from types import *
+import socket
+import errno
+
# --------------------------------------------------------------------
# Internal stuff
@@ -1158,7 +1161,27 @@
def __init__(self, use_datetime=0):
self._use_datetime = use_datetime
+ self._connection = None
+ self._extra_headers = []
+ ##
+ # Send a complete request, and parse the response.
+ # Retry request if a cached connection has disconnected.
+ #
+ # @param host Target host.
+ # @param handler Target PRC handler.
+ # @param request_body XML-RPC request body.
+ # @param verbose Debugging flag.
+ # @return Parsed response.
+ def request(self, host, handler, request_body, verbose=0):
+ #retry request if cached connection has gone cold
+ for i in (0, 1):
+ try:
+ return self.single_request(host, handler, request_body, verbose)
+ except socket.error, e:
+ if not (i == 0 and e[0] == errno.ECONNRESET):
+ raise
+
##
# Send a complete request, and parse the response.
#
@@ -1168,31 +1191,38 @@
# @param verbose Debugging flag.
# @return Parsed response.
- def request(self, host, handler, request_body, verbose=0):
+ def single_request(self, host, handler, request_body, verbose=0):
# issue XML-RPC request
h = self.make_connection(host)
if verbose:
h.set_debuglevel(1)
- self.send_request(h, handler, request_body)
- self.send_host(h, host)
- self.send_user_agent(h)
- self.send_content(h, request_body)
+ try:
+ self.send_request(h, handler, request_body)
+ self.send_extra_headers(h)
+ self.send_user_agent(h)
+ self.send_content(h, request_body)
- errcode, errmsg, headers = h.getreply(buffering=True)
+ response = h.getresponse(buffering=True)
+ if response.status == 200:
+ self.verbose = verbose
+ return self.parse_response(response)
+ except Fault:
+ raise
+ except Exception:
+ # All unexpected errors leave connection in
+ # a strange state, so we clear it.
+ self.clear_connection()
+ raise
- if errcode != 200:
- raise ProtocolError(
- host + handler,
- errcode, errmsg,
- headers
- )
+ response.read() #discard any response data
+ raise ProtocolError(
+ host + handler,
+ response.status, response.reason,
+ response.msg,
+ )
- self.verbose = verbose
-
- return self.parse_response(h.getfile())
-
##
# Create parser.
#
@@ -1240,12 +1270,24 @@
# @return A connection handle.
def make_connection(self, host):
+ if self._connection:
+ return self._connection
# create a HTTP connection object from a host descriptor
import httplib
- host, extra_headers, x509 = self.get_host_info(host)
- return httplib.HTTP(host)
+ host, self._extra_headers, x509 = self.get_host_info(host)
+ self._connection = httplib.HTTPConnection(host)
+ return self._connection
##
+ # Clear any cached connection object.
+ # Used in the event of socket errors.
+ #
+ def clear_connection(self):
+ if self._connection:
+ self._connection.close()
+ self._connection = None
+
+ ##
# Send request header.
#
# @param connection Connection handle.
@@ -1256,14 +1298,12 @@
connection.putrequest("POST", handler)
##
- # Send host name.
+ # Send extra headers.
#
# @param connection Connection handle.
- # @param host Host name.
- def send_host(self, connection, host):
- host, extra_headers, x509 = self.get_host_info(host)
- connection.putheader("Host", host)
+ def send_extra_headers(self, connection):
+ extra_headers = self._extra_headers
if extra_headers:
if isinstance(extra_headers, DictType):
extra_headers = extra_headers.items()
@@ -1295,20 +1335,19 @@
# @param file Stream.
# @return Response tuple and target method.
- def parse_response(self, file):
- # read response from input file/socket, and parse it
+ def parse_response(self, response):
+ # read response data from httpresponse, and parse it
p, u = self.getparser()
while 1:
- response = file.read(1024)
- if not response:
+ data = response.read(1024)
+ if not data:
break
if self.verbose:
- print "body:", repr(response)
- p.feed(response)
+ print "body:", repr(data)
+ p.feed(data)
- file.close()
p.close()
return u.close()
@@ -1322,18 +1361,14 @@
# FIXME: mostly untested
def make_connection(self, host):
+ if self._connection:
+ return self._connection
# create a HTTPS connection object from a host descriptor
# host may be a string, or a (host, x509-dict) tuple
import httplib
- host, extra_headers, x509 = self.get_host_info(host)
- try:
- HTTPS = httplib.HTTPS
- except AttributeError:
- raise NotImplementedError(
- "your version of httplib doesn't support HTTPS"
- )
- else:
- return HTTPS(host, None, **(x509 or {}))
+ host, self._extra_headers, x509 = self.get_host_info(host)
+ self._connection = httplib.HTTPSConnection(host, None, **(x509 or {}))
+ return self._connection
##
# Standard server proxy. This class establishes a virtual connection
« no previous file with comments | « Lib/test/test_xmlrpc.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b