New \grammartoken markup, similar to \token but allowed everywhere.
[python/dscho.git] / Demo / xmlrpc / xmlrpc_handler.py
blob9fa17667c3b7ceaf23a90e3f9be1a1bb7291f5a1
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 regex
16 import string
17 import sys
19 class xmlrpc_handler:
21 def match (self, request):
22 # Note: /RPC2 is not required by the spec, so you may override this method.
23 if request.uri[:5] == '/RPC2':
24 return 1
25 else:
26 return 0
28 def handle_request (self, request):
29 [path, params, query, fragment] = request.split_uri()
31 if request.command in ('post', 'put'):
32 request.collector = collector (self, request)
33 else:
34 request.error (400)
36 def continue_request (self, data, request):
37 params, method = xmlrpclib.loads (data)
38 try:
39 # generate response
40 try:
41 response = self.call (method, params)
42 response = (response,)
43 except:
44 # report exception back to server
45 response = xmlrpclib.dumps (
46 xmlrpclib.Fault (1, "%s:%s" % (sys.exc_type, sys.exc_value))
48 else:
49 response = xmlrpclib.dumps (response, methodresponse=1)
50 except:
51 # internal error, report as HTTP server error
52 request.error (500)
53 else:
54 # got a valid XML RPC response
55 request['Content-Type'] = 'text/xml'
56 request.push (response)
57 request.done()
59 def call (self, method, params):
60 # override this method to implement RPC methods
61 raise "NotYetImplemented"
63 class collector:
65 "gathers input for POST and PUT requests"
67 def __init__ (self, handler, request):
69 self.handler = handler
70 self.request = request
71 self.data = ''
73 # make sure there's a content-length header
74 cl = request.get_header ('content-length')
76 if not cl:
77 request.error (411)
78 else:
79 cl = string.atoi (cl)
80 # using a 'numeric' terminator
81 self.request.channel.set_terminator (cl)
83 def collect_incoming_data (self, data):
84 self.data = self.data + data
86 def found_terminator (self):
87 # set the terminator back to the default
88 self.request.channel.set_terminator ('\r\n\r\n')
89 self.handler.continue_request (self.data, self.request)
91 if __name__ == '__main__':
93 class rpc_demo (xmlrpc_handler):
95 def call (self, method, params):
96 print 'method="%s" params=%s' % (method, params)
97 return "Sure, that works"
99 import asyncore
100 import http_server
102 hs = http_server.http_server ('', 8000)
103 rpc = rpc_demo()
104 hs.install_handler (rpc)
106 asyncore.loop()