1 import sys
2 from cherrypy._cpcompat import py3k
3
4 try:
5 from xmlrpclib import DateTime, Fault, ProtocolError, ServerProxy
6 from xmlrpclib import SafeTransport
7 except ImportError:
8 from xmlrpc.client import DateTime, Fault, ProtocolError, ServerProxy
9 from xmlrpc.client import SafeTransport
10
11 if py3k:
12 HTTPSTransport = SafeTransport
13
14
15 import socket
16 if not hasattr(socket, "ssl"):
17 socket.ssl = True
18 else:
20
21 """Subclass of SafeTransport to fix sock.recv errors (by using file).
22 """
23
24 - def request(self, host, handler, request_body, verbose=0):
25
26 h = self.make_connection(host)
27 if verbose:
28 h.set_debuglevel(1)
29
30 self.send_request(h, handler, request_body)
31 self.send_host(h, host)
32 self.send_user_agent(h)
33 self.send_content(h, request_body)
34
35 errcode, errmsg, headers = h.getreply()
36 if errcode != 200:
37 raise ProtocolError(host + handler, errcode, errmsg, headers)
38
39 self.verbose = verbose
40
41
42
43
44
45
46
47
48 return self.parse_response(h.getfile())
49
50 import cherrypy
51
52
54 from cherrypy import _cptools
55
56 class Root:
57
58 def index(self):
59 return "I'm a standard index!"
60 index.exposed = True
61
62 class XmlRpc(_cptools.XMLRPCController):
63
64 def foo(self):
65 return "Hello world!"
66 foo.exposed = True
67
68 def return_single_item_list(self):
69 return [42]
70 return_single_item_list.exposed = True
71
72 def return_string(self):
73 return "here is a string"
74 return_string.exposed = True
75
76 def return_tuple(self):
77 return ('here', 'is', 1, 'tuple')
78 return_tuple.exposed = True
79
80 def return_dict(self):
81 return dict(a=1, b=2, c=3)
82 return_dict.exposed = True
83
84 def return_composite(self):
85 return dict(a=1, z=26), 'hi', ['welcome', 'friend']
86 return_composite.exposed = True
87
88 def return_int(self):
89 return 42
90 return_int.exposed = True
91
92 def return_float(self):
93 return 3.14
94 return_float.exposed = True
95
96 def return_datetime(self):
97 return DateTime((2003, 10, 7, 8, 1, 0, 1, 280, -1))
98 return_datetime.exposed = True
99
100 def return_boolean(self):
101 return True
102 return_boolean.exposed = True
103
104 def test_argument_passing(self, num):
105 return num * 2
106 test_argument_passing.exposed = True
107
108 def test_returning_Fault(self):
109 return Fault(1, "custom Fault response")
110 test_returning_Fault.exposed = True
111
112 root = Root()
113 root.xmlrpc = XmlRpc()
114 cherrypy.tree.mount(root, config={'/': {
115 'request.dispatch': cherrypy.dispatch.XMLRPCDispatcher(),
116 'tools.xmlrpc.allow_none': 0,
117 }})
118
119
120 from cherrypy.test import helper
121
122
124 setup_server = staticmethod(setup_server)
125
127
128 scheme = self.scheme
129 if scheme == "https":
130 url = 'https://%s:%s/xmlrpc/' % (self.interface(), self.PORT)
131 proxy = ServerProxy(url, transport=HTTPSTransport())
132 else:
133 url = 'http://%s:%s/xmlrpc/' % (self.interface(), self.PORT)
134 proxy = ServerProxy(url)
135
136
137 self.getPage("/xmlrpc/foo")
138 self.assertBody("Hello world!")
139
140 self.assertEqual(proxy.return_single_item_list(), [42])
141 self.assertNotEqual(proxy.return_single_item_list(), 'one bazillion')
142 self.assertEqual(proxy.return_string(), "here is a string")
143 self.assertEqual(proxy.return_tuple(),
144 list(('here', 'is', 1, 'tuple')))
145 self.assertEqual(proxy.return_dict(), {'a': 1, 'c': 3, 'b': 2})
146 self.assertEqual(proxy.return_composite(),
147 [{'a': 1, 'z': 26}, 'hi', ['welcome', 'friend']])
148 self.assertEqual(proxy.return_int(), 42)
149 self.assertEqual(proxy.return_float(), 3.14)
150 self.assertEqual(proxy.return_datetime(),
151 DateTime((2003, 10, 7, 8, 1, 0, 1, 280, -1)))
152 self.assertEqual(proxy.return_boolean(), True)
153 self.assertEqual(proxy.test_argument_passing(22), 22 * 2)
154
155
156 try:
157 proxy.test_argument_passing({})
158 except Exception:
159 x = sys.exc_info()[1]
160 self.assertEqual(x.__class__, Fault)
161 self.assertEqual(x.faultString, ("unsupported operand type(s) "
162 "for *: 'dict' and 'int'"))
163 else:
164 self.fail("Expected xmlrpclib.Fault")
165
166
167
168 try:
169 proxy.non_method()
170 except Exception:
171 x = sys.exc_info()[1]
172 self.assertEqual(x.__class__, Fault)
173 self.assertEqual(x.faultString,
174 'method "non_method" is not supported')
175 else:
176 self.fail("Expected xmlrpclib.Fault")
177
178
179 try:
180 proxy.test_returning_Fault()
181 except Exception:
182 x = sys.exc_info()[1]
183 self.assertEqual(x.__class__, Fault)
184 self.assertEqual(x.faultString, ("custom Fault response"))
185 else:
186 self.fail("Expected xmlrpclib.Fault")
187