xmlrpclib for python 2.2; initial checkin
diff --git a/Demo/xmlrpc/xmlrpc_handler.py b/Demo/xmlrpc/xmlrpc_handler.py
new file mode 100644
index 0000000..9fa1766
--- /dev/null
+++ b/Demo/xmlrpc/xmlrpc_handler.py
@@ -0,0 +1,106 @@
+#
+# XML-RPC SERVER
+# $Id$
+#
+# an asynchronous XML-RPC server for Medusa
+#
+# written by Sam Rushing
+#
+# Based on "xmlrpcserver.py" by Fredrik Lundh (fredrik@pythonware.com)
+#
+
+import http_server
+import xmlrpclib
+
+import regex
+import string
+import sys
+
+class xmlrpc_handler:
+
+    def match (self, request):
+        # Note: /RPC2 is not required by the spec, so you may override this method.
+        if request.uri[:5] == '/RPC2':
+            return 1
+        else:
+            return 0
+
+    def handle_request (self, request):
+        [path, params, query, fragment] = request.split_uri()
+
+        if request.command in ('post', 'put'):
+            request.collector = collector (self, request)
+        else:
+            request.error (400)
+
+    def continue_request (self, data, request):
+        params, method = xmlrpclib.loads (data)
+        try:
+            # generate response
+            try:
+                response = self.call (method, params)
+                response = (response,)
+            except:
+                # report exception back to server
+                response = xmlrpclib.dumps (
+                    xmlrpclib.Fault (1, "%s:%s" % (sys.exc_type, sys.exc_value))
+                    )
+            else:
+                response = xmlrpclib.dumps (response, methodresponse=1)
+        except:
+            # internal error, report as HTTP server error
+            request.error (500)
+        else:
+            # got a valid XML RPC response
+            request['Content-Type'] = 'text/xml'
+            request.push (response)
+            request.done()
+
+    def call (self, method, params):
+        # override this method to implement RPC methods
+        raise "NotYetImplemented"
+
+class collector:
+
+    "gathers input for POST and PUT requests"
+
+    def __init__ (self, handler, request):
+
+        self.handler = handler
+        self.request = request
+        self.data = ''
+
+        # make sure there's a content-length header
+        cl = request.get_header ('content-length')
+
+        if not cl:
+            request.error (411)
+        else:
+            cl = string.atoi (cl)
+            # using a 'numeric' terminator
+            self.request.channel.set_terminator (cl)
+
+    def collect_incoming_data (self, data):
+        self.data = self.data + data
+
+    def found_terminator (self):
+        # set the terminator back to the default
+        self.request.channel.set_terminator ('\r\n\r\n')
+        self.handler.continue_request (self.data, self.request)
+
+if __name__ == '__main__':
+
+    class rpc_demo (xmlrpc_handler):
+
+        def call (self, method, params):
+            print 'method="%s" params=%s' % (method, params)
+            return "Sure, that works"
+
+    import asyncore
+    import http_server
+
+    hs = http_server.http_server ('', 8000)
+    rpc = rpc_demo()
+    hs.install_handler (rpc)
+
+    asyncore.loop()