5 # an asynchronous XML-RPC server for Medusa
7 # written by Sam Rushing
9 # Based on "xmlrpcserver.py" by Fredrik Lundh (fredrik@pythonware.com)
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':
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
)
34 def continue_request (self
, data
, request
):
35 params
, method
= xmlrpclib
.loads (data
)
39 response
= self
.call (method
, params
)
40 response
= (response
,)
42 # report exception back to server
43 response
= xmlrpclib
.dumps (
44 xmlrpclib
.Fault (1, "%s:%s" % sys
.exc_info()[:2])
47 response
= xmlrpclib
.dumps (response
, methodresponse
=1)
49 # internal error, report as HTTP server error
52 # got a valid XML RPC response
53 request
['Content-Type'] = 'text/xml'
54 request
.push (response
)
57 def call (self
, method
, params
):
58 # override this method to implement RPC methods
59 raise "NotYetImplemented"
63 "gathers input for POST and PUT requests"
65 def __init__ (self
, handler
, request
):
67 self
.handler
= handler
68 self
.request
= request
71 # make sure there's a content-length header
72 cl
= request
.get_header ('content-length')
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"
100 hs
= http_server
.http_server ('', 8000)
102 hs
.install_handler (rpc
)