xmlrpc_handler.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. # -*- Mode: Python -*-
  2. # See http://www.xml-rpc.com/
  3. # http://www.pythonware.com/products/xmlrpc/
  4. # Based on "xmlrpcserver.py" by Fredrik Lundh (fredrik@pythonware.com)
  5. VERSION = "$Id: xmlrpc_handler.py,v 1.6 2004/04/21 14:09:24 akuchling Exp $"
  6. import http_server
  7. import xmlrpclib
  8. import string
  9. import sys
  10. class xmlrpc_handler:
  11. def match (self, request):
  12. # Note: /RPC2 is not required by the spec, so you may override this method.
  13. if request.uri[:5] == '/RPC2':
  14. return 1
  15. else:
  16. return 0
  17. def handle_request (self, request):
  18. [path, params, query, fragment] = request.split_uri()
  19. if request.command == 'POST':
  20. request.collector = collector (self, request)
  21. else:
  22. request.error (400)
  23. def continue_request (self, data, request):
  24. params, method = xmlrpclib.loads (data)
  25. try:
  26. # generate response
  27. try:
  28. response = self.call (method, params)
  29. if type(response) != type(()):
  30. response = (response,)
  31. except:
  32. # report exception back to server
  33. response = xmlrpclib.dumps (
  34. xmlrpclib.Fault (1, "%s:%s" % (sys.exc_type, sys.exc_value))
  35. )
  36. else:
  37. response = xmlrpclib.dumps (response, methodresponse=1)
  38. except:
  39. # internal error, report as HTTP server error
  40. request.error (500)
  41. else:
  42. # got a valid XML RPC response
  43. request['Content-Type'] = 'text/xml'
  44. request.push (response)
  45. request.done()
  46. def call (self, method, params):
  47. # override this method to implement RPC methods
  48. raise "NotYetImplemented"
  49. class collector:
  50. "gathers input for POST and PUT requests"
  51. def __init__ (self, handler, request):
  52. self.handler = handler
  53. self.request = request
  54. self.data = []
  55. # make sure there's a content-length header
  56. cl = request.get_header ('content-length')
  57. if not cl:
  58. request.error (411)
  59. else:
  60. cl = int(cl)
  61. # using a 'numeric' terminator
  62. self.request.channel.set_terminator (cl)
  63. def collect_incoming_data (self, data):
  64. self.data.append(data)
  65. def found_terminator (self):
  66. # set the terminator back to the default
  67. self.request.channel.set_terminator ('\r\n\r\n')
  68. self.handler.continue_request ("".join(self.data), self.request)
  69. if __name__ == '__main__':
  70. class rpc_demo (xmlrpc_handler):
  71. def call (self, method, params):
  72. print 'method="%s" params=%s' % (method, params)
  73. return "Sure, that works"
  74. import asyncore_25 as asyncore
  75. hs = http_server.http_server ('', 8000)
  76. rpc = rpc_demo()
  77. hs.install_handler (rpc)
  78. asyncore.loop()