mirror of
https://github.com/python/cpython.git
synced 2025-09-11 11:17:16 +00:00
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.
This commit is contained in:
parent
956e359579
commit
5d8a88a442
2 changed files with 78 additions and 74 deletions
36
Lib/test/test_xmlrpc_net.py
Normal file
36
Lib/test/test_xmlrpc_net.py
Normal file
|
@ -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()
|
116
Lib/xmlrpclib.py
116
Lib/xmlrpclib.py
|
@ -137,6 +137,7 @@ Exported functions:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import re, time, operator
|
import re, time, operator
|
||||||
|
import httplib
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
# Internal stuff
|
# Internal stuff
|
||||||
|
@ -1110,18 +1111,10 @@ class Transport:
|
||||||
def request(self, host, handler, request_body, verbose=0):
|
def request(self, host, handler, request_body, verbose=0):
|
||||||
# issue XML-RPC request
|
# issue XML-RPC request
|
||||||
|
|
||||||
h = self.make_connection(host)
|
http_conn = self.send_request(host, handler, request_body, verbose)
|
||||||
if verbose:
|
resp = http_conn.getresponse()
|
||||||
h.set_debuglevel(1)
|
|
||||||
|
|
||||||
self.send_request(h, handler, request_body)
|
if resp.status != 200:
|
||||||
self.send_host(h, host)
|
|
||||||
self.send_user_agent(h)
|
|
||||||
self.send_content(h, request_body)
|
|
||||||
|
|
||||||
errcode, errmsg, headers = h.getreply()
|
|
||||||
|
|
||||||
if errcode != 200:
|
|
||||||
raise ProtocolError(
|
raise ProtocolError(
|
||||||
host + handler,
|
host + handler,
|
||||||
errcode, errmsg,
|
errcode, errmsg,
|
||||||
|
@ -1130,12 +1123,7 @@ class Transport:
|
||||||
|
|
||||||
self.verbose = verbose
|
self.verbose = verbose
|
||||||
|
|
||||||
try:
|
return self._parse_response(resp, None)
|
||||||
sock = h._conn.sock
|
|
||||||
except AttributeError:
|
|
||||||
sock = None
|
|
||||||
|
|
||||||
return self._parse_response(h.getfile(), sock)
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Create parser.
|
# Create parser.
|
||||||
|
@ -1181,59 +1169,35 @@ class Transport:
|
||||||
# Connect to server.
|
# Connect to server.
|
||||||
#
|
#
|
||||||
# @param host Target host.
|
# @param host Target host.
|
||||||
# @return A connection handle.
|
# @return An HTTPConnection object
|
||||||
|
|
||||||
def make_connection(self, host):
|
def make_connection(self, host):
|
||||||
# create a HTTP connection object from a host descriptor
|
# create a HTTP connection object from a host descriptor
|
||||||
import httplib
|
|
||||||
host, extra_headers, x509 = self.get_host_info(host)
|
host, extra_headers, x509 = self.get_host_info(host)
|
||||||
return httplib.HTTP(host)
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Send request header.
|
# Send HTTP request.
|
||||||
#
|
#
|
||||||
# @param connection Connection handle.
|
# @param host Host descriptor (URL or (URL, x509 info) tuple).
|
||||||
# @param handler Target RPC handler.
|
# @param handler Targer RPC handler (a path relative to host)
|
||||||
# @param request_body XML-RPC body.
|
# @param request_body The XML-RPC request body
|
||||||
|
# @param debug Enable debugging if debug is true.
|
||||||
|
# @return An HTTPConnection.
|
||||||
|
|
||||||
def send_request(self, connection, handler, request_body):
|
def send_request(self, host, handler, request_body, debug):
|
||||||
connection.putrequest("POST", handler)
|
|
||||||
|
|
||||||
##
|
|
||||||
# Send host name.
|
|
||||||
#
|
|
||||||
# @param connection Connection handle.
|
|
||||||
# @param host Host name.
|
|
||||||
|
|
||||||
def send_host(self, connection, host):
|
|
||||||
host, extra_headers, x509 = self.get_host_info(host)
|
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 extra_headers:
|
||||||
if isinstance(extra_headers, dict):
|
for key, val in extra_headers:
|
||||||
extra_headers = extra_headers.items()
|
header[key] = val
|
||||||
for key, value in extra_headers:
|
headers["Content-Type"] = "text/xml"
|
||||||
connection.putheader(key, value)
|
headers["User-Agent"] = self.user_agent
|
||||||
|
connection.request("POST", handler, request_body, headers)
|
||||||
##
|
return connection
|
||||||
# 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)
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Parse response.
|
# Parse response.
|
||||||
|
@ -1284,19 +1248,24 @@ class SafeTransport(Transport):
|
||||||
|
|
||||||
# FIXME: mostly untested
|
# FIXME: mostly untested
|
||||||
|
|
||||||
def make_connection(self, host):
|
def send_request(self, host, handler, request_body, debug):
|
||||||
# create a HTTPS connection object from a host descriptor
|
import socket
|
||||||
# host may be a string, or a (host, x509-dict) tuple
|
if not hasattr(socket, "ssl"):
|
||||||
import httplib
|
|
||||||
host, extra_headers, x509 = self.get_host_info(host)
|
|
||||||
try:
|
|
||||||
HTTPS = httplib.HTTPS
|
|
||||||
except AttributeError:
|
|
||||||
raise NotImplementedError(
|
raise NotImplementedError(
|
||||||
"your version of httplib doesn't support HTTPS"
|
"your version of httplib doesn't support HTTPS")
|
||||||
)
|
|
||||||
else:
|
host, extra_headers, x509 = self.get_host_info(host)
|
||||||
return HTTPS(host, None, **(x509 or {}))
|
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
|
# 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://localhost:8000") # local server
|
||||||
server = ServerProxy("http://time.xmlrpc.com/RPC2")
|
server = ServerProxy("http://time.xmlrpc.com/RPC2")
|
||||||
|
|
||||||
print(server)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
print(server.currentTime.getCurrentTime())
|
print(server.currentTime.getCurrentTime())
|
||||||
except Error as v:
|
except Error as v:
|
||||||
print("ERROR", v)
|
print("ERROR", v)
|
||||||
|
|
||||||
|
# The server at xmlrpc.com doesn't seem to support multicall anymore.
|
||||||
multi = MultiCall(server)
|
multi = MultiCall(server)
|
||||||
multi.currentTime.getCurrentTime()
|
multi.currentTime.getCurrentTime()
|
||||||
multi.currentTime.getCurrentTime()
|
multi.currentTime.getCurrentTime()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue