5 # an asynchronous XML-RPC server for Medusa
7 # written by Sam Rushing
9 # Based on "xmlrpcserver.py" by Fredrik Lundh (fredrik@pythonware.com)
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':
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
)
36 def continue_request (self
, data
, request
):
37 params
, method
= xmlrpclib
.loads (data
)
41 response
= self
.call (method
, params
)
42 response
= (response
,)
44 # report exception back to server
45 response
= xmlrpclib
.dumps (
46 xmlrpclib
.Fault (1, "%s:%s" % (sys
.exc_type
, sys
.exc_value
))
49 response
= xmlrpclib
.dumps (response
, methodresponse
=1)
51 # internal error, report as HTTP server error
54 # got a valid XML RPC response
55 request
['Content-Type'] = 'text/xml'
56 request
.push (response
)
59 def call (self
, method
, params
):
60 # override this method to implement RPC methods
61 raise "NotYetImplemented"
65 "gathers input for POST and PUT requests"
67 def __init__ (self
, handler
, request
):
69 self
.handler
= handler
70 self
.request
= request
73 # make sure there's a content-length header
74 cl
= request
.get_header ('content-length')
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"
102 hs
= http_server
.http_server ('', 8000)
104 hs
.install_handler (rpc
)