summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
Diffstat (limited to 'Lib')
-rw-r--r--Lib/test/test_xmlrpc_net.py36
-rw-r--r--Lib/xmlrpclib.py114
2 files changed, 77 insertions, 73 deletions
diff --git a/Lib/test/test_xmlrpc_net.py b/Lib/test/test_xmlrpc_net.py
new file mode 100644
index 0000000..4751d57
--- /dev/null
+++ b/Lib/test/test_xmlrpc_net.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+
+import unittest
+from test import test_support
+
+import xmlrpclib
+
+class CurrentTimeTest(unittest.TestCase):
+
+ def test_current_time(self):
+ # Get the current time from xmlrpc.com. This code exercises
+ # the minimal HTTP functionality in xmlrpclib.
+ server = xmlrpclib.ServerProxy("http://time.xmlrpc.com/RPC2")
+ t0 = server.currentTime.getCurrentTime()
+
+ # Perform a minimal sanity check on the result, just to be sure
+ # the request means what we think it means.
+ t1 = xmlrpclib.DateTime()
+
+ dt0 = xmlrpclib._datetime_type(t0.value)
+ dt1 = xmlrpclib._datetime_type(t1.value)
+ if dt0 > dt1:
+ delta = dt0 - dt1
+ else:
+ delta = dt1 - dt0
+ # The difference between the system time here and the system
+ # time on the server should not be too big.
+ self.assert_(delta.days <= 1)
+
+
+def test_main():
+ test_support.requires("network")
+ test_support.run_unittest(CurrentTimeTest)
+
+if __name__ == "__main__":
+ test_main()
diff --git a/Lib/xmlrpclib.py b/Lib/xmlrpclib.py
index 83b3a04..2cb4bf5 100644
--- a/Lib/xmlrpclib.py
+++ b/Lib/xmlrpclib.py
@@ -137,6 +137,7 @@ Exported functions:
"""
import re, time, operator
+import httplib
# --------------------------------------------------------------------
# Internal stuff
@@ -1110,18 +1111,10 @@ class Transport:
def request(self, host, handler, request_body, verbose=0):
# issue XML-RPC request
- h = self.make_connection(host)
- if verbose:
- h.set_debuglevel(1)
+ http_conn = self.send_request(host, handler, request_body, verbose)
+ resp = http_conn.getresponse()
- self.send_request(h, handler, request_body)
- self.send_host(h, host)
- self.send_user_agent(h)
- self.send_content(h, request_body)
-
- errcode, errmsg, headers = h.getreply()
-
- if errcode != 200:
+ if resp.status != 200:
raise ProtocolError(
host + handler,
errcode, errmsg,
@@ -1130,12 +1123,7 @@ class Transport:
self.verbose = verbose
- try:
- sock = h._conn.sock
- except AttributeError:
- sock = None
-
- return self._parse_response(h.getfile(), sock)
+ return self._parse_response(resp, None)
##
# Create parser.
@@ -1181,59 +1169,35 @@ class Transport:
# Connect to server.
#
# @param host Target host.
- # @return A connection handle.
+ # @return An HTTPConnection object
def make_connection(self, host):
# create a HTTP connection object from a host descriptor
- import httplib
host, extra_headers, x509 = self.get_host_info(host)
- return httplib.HTTP(host)
-
- ##
- # Send request header.
- #
- # @param connection Connection handle.
- # @param handler Target RPC handler.
- # @param request_body XML-RPC body.
- def send_request(self, connection, handler, request_body):
- connection.putrequest("POST", handler)
##
- # Send host name.
+ # Send HTTP request.
#
- # @param connection Connection handle.
- # @param host Host name.
+ # @param host Host descriptor (URL or (URL, x509 info) tuple).
+ # @param handler Targer RPC handler (a path relative to host)
+ # @param request_body The XML-RPC request body
+ # @param debug Enable debugging if debug is true.
+ # @return An HTTPConnection.
- def send_host(self, connection, host):
+ def send_request(self, host, handler, request_body, debug):
host, extra_headers, x509 = self.get_host_info(host)
- connection.putheader("Host", host)
+ connection = httplib.HTTPConnection(host)
+ if debug:
+ connection.set_debuglevel(1)
+ headers = {}
if extra_headers:
- if isinstance(extra_headers, dict):
- extra_headers = extra_headers.items()
- for key, value in extra_headers:
- connection.putheader(key, value)
-
- ##
- # Send user-agent identifier.
- #
- # @param connection Connection handle.
-
- def send_user_agent(self, connection):
- connection.putheader("User-Agent", self.user_agent)
-
- ##
- # Send request body.
- #
- # @param connection Connection handle.
- # @param request_body XML-RPC request body.
-
- def send_content(self, connection, request_body):
- connection.putheader("Content-Type", "text/xml")
- connection.putheader("Content-Length", str(len(request_body)))
- connection.endheaders()
- if request_body:
- connection.send(request_body)
+ for key, val in extra_headers:
+ header[key] = val
+ headers["Content-Type"] = "text/xml"
+ headers["User-Agent"] = self.user_agent
+ connection.request("POST", handler, request_body, headers)
+ return connection
##
# Parse response.
@@ -1284,19 +1248,24 @@ class SafeTransport(Transport):
# FIXME: mostly untested
- def make_connection(self, host):
- # 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:
+ def send_request(self, host, handler, request_body, debug):
+ import socket
+ if not hasattr(socket, "ssl"):
raise NotImplementedError(
- "your version of httplib doesn't support HTTPS"
- )
- else:
- return HTTPS(host, None, **(x509 or {}))
+ "your version of httplib doesn't support HTTPS")
+
+ host, extra_headers, x509 = self.get_host_info(host)
+ connection = httplib.HTTPSConnection(host, None, **(x509 or {}))
+ if debug:
+ connection.set_debuglevel(1)
+ headers = {}
+ if extra_headers:
+ for key, val in extra_headers:
+ header[key] = val
+ headers["Content-Type"] = "text/xml"
+ headers["User-Agent"] = self.user_agent
+ connection.request("POST", handler, request_body, headers)
+ return connection
##
# Standard server proxy. This class establishes a virtual connection
@@ -1408,13 +1377,12 @@ if __name__ == "__main__":
# server = ServerProxy("http://localhost:8000") # local server
server = ServerProxy("http://time.xmlrpc.com/RPC2")
- print(server)
-
try:
print(server.currentTime.getCurrentTime())
except Error as v:
print("ERROR", v)
+ # The server at xmlrpc.com doesn't seem to support multicall anymore.
multi = MultiCall(server)
multi.currentTime.getCurrentTime()
multi.currentTime.getCurrentTime()