mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 11:49:12 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			104 lines
		
	
	
	
		
			2.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			104 lines
		
	
	
	
		
			2.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
#
 | 
						|
# 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 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_info()[:2])
 | 
						|
                    )
 | 
						|
            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 = int (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()
 |