append(): Fixing the test for convertability after consultation with
[python/dscho.git] / Demo / xmlrpc / xmlrpc_handler.py
blob193547516677d29a73260b8195f23e1deec5fd9e
2 # XML-RPC SERVER
3 # $Id$
5 # an asynchronous XML-RPC server for Medusa
7 # written by Sam Rushing
9 # Based on "xmlrpcserver.py" by Fredrik Lundh (fredrik@pythonware.com)
12 import http_server
13 import xmlrpclib
15 import sys
17 class xmlrpc_handler:
19 def match (self, request):
20 # Note: /RPC2 is not required by the spec, so you may override this method.
21 if request.uri[:5] == '/RPC2':
22 return 1
23 else:
24 return 0
26 def handle_request (self, request):
27 [path, params, query, fragment] = request.split_uri()
29 if request.command in ('post', 'put'):
30 request.collector = collector (self, request)
31 else:
32 request.error (400)
34 def continue_request (self, data, request):
35 params, method = xmlrpclib.loads (data)
36 try:
37 # generate response
38 try:
39 response = self.call (method, params)
40 response = (response,)
41 except:
42 # report exception back to server
43 response = xmlrpclib.dumps (
44 xmlrpclib.Fault (1, "%s:%s" % sys.exc_info()[:2])
46 else:
47 response = xmlrpclib.dumps (response, methodresponse=1)
48 except:
49 # internal error, report as HTTP server error
50 request.error (500)
51 else:
52 # got a valid XML RPC response
53 request['Content-Type'] = 'text/xml'
54 request.push (response)
55 request.done()
57 def call (self, method, params):
58 # override this method to implement RPC methods
59 raise "NotYetImplemented"
61 class collector:
63 "gathers input for POST and PUT requests"
65 def __init__ (self, handler, request):
67 self.handler = handler
68 self.request = request
69 self.data = ''
71 # make sure there's a content-length header
72 cl = request.get_header ('content-length')
74 if not cl:
75 request.error (411)
76 else:
77 cl = int (cl)
78 # using a 'numeric' terminator
79 self.request.channel.set_terminator (cl)
81 def collect_incoming_data (self, data):
82 self.data = self.data + data
84 def found_terminator (self):
85 # set the terminator back to the default
86 self.request.channel.set_terminator ('\r\n\r\n')
87 self.handler.continue_request (self.data, self.request)
89 if __name__ == '__main__':
91 class rpc_demo (xmlrpc_handler):
93 def call (self, method, params):
94 print 'method="%s" params=%s' % (method, params)
95 return "Sure, that works"
97 import asyncore
98 import http_server
100 hs = http_server.http_server ('', 8000)
101 rpc = rpc_demo()
102 hs.install_handler (rpc)
104 asyncore.loop()