[Python-3000-checkins] r57024 - in python/branches/py3k/Lib: test/test_xmlrpc_net.py xmlrpclib.py

jeremy.hylton python-3000-checkins at python.org
Tue Aug 14 18:47:42 CEST 2007


Author: jeremy.hylton
Date: Tue Aug 14 18:47:39 2007
New Revision: 57024

Added:
   python/branches/py3k/Lib/test/test_xmlrpc_net.py
Modified:
   python/branches/py3k/Lib/xmlrpclib.py
Log:
Change xmlrpclib to use the newer httplib interface.

Note that it's hard to test xmlrpclib, because the server it attempts
to connect to doesn't seem to support the expected interfaces.  Many
of the links via xmlrpc.com are dead, so I couldn't find another
server to use for tests.


Added: python/branches/py3k/Lib/test/test_xmlrpc_net.py
==============================================================================
--- (empty file)
+++ python/branches/py3k/Lib/test/test_xmlrpc_net.py	Tue Aug 14 18:47:39 2007
@@ -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()

Modified: python/branches/py3k/Lib/xmlrpclib.py
==============================================================================
--- python/branches/py3k/Lib/xmlrpclib.py	(original)
+++ python/branches/py3k/Lib/xmlrpclib.py	Tue Aug 14 18:47:39 2007
@@ -137,6 +137,7 @@
 """
 
 import re, time, operator
+import httplib
 
 # --------------------------------------------------------------------
 # Internal stuff
@@ -1110,18 +1111,10 @@
     def 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)
+        http_conn = self.send_request(host, handler, request_body, verbose)
+        resp = http_conn.getresponse()
 
-        errcode, errmsg, headers = h.getreply()
-
-        if errcode != 200:
+        if resp.status != 200:
             raise ProtocolError(
                 host + handler,
                 errcode, errmsg,
@@ -1130,12 +1123,7 @@
 
         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 @@
     # 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 @@
 
     # 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 @@
     # 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()


More information about the Python-3000-checkins mailing list