*** empty log message ***
[pli.git] / pli / net / xmlrpcserver.py
blob03597b01031df6627786475bbd8f555f15311cdf
1 #=======================================================================
3 __version__ = '''0.0.07'''
4 __sub_version__ = '''20041016142240'''
5 __copyright__ = '''(c) Alex A. Naanou 2003-2004'''
8 #=======================================================================
10 import SocketServer, BaseHTTPServer
11 import xmlrpclib
12 import sys
13 import traceback
17 #-----------------------------------------------------------------------
18 #----------------------------------------------------XMLRPCServerExit---
19 class XMLRPCServerExit(Exception):
20 '''
21 '''
23 #-----------------------------------------------------------------------
24 #------------------------------------------------------RequestHandler---
25 # this is based on the xmlrpc server included in xmlrpc lib
26 # (xmlrpcserver.py) written by Fredrik Lundh, January 1999
27 # and coprighted:
28 # Copyright (c) 1999 by Secret Labs AB.
29 # Copyright (c) 1999 by Fredrik Lundh.
30 # fredrik@pythonware.com
31 # http://www.pythonware.com
33 # this code is modified by Alex A. Naanou <alex_nanou@yahoo.com>
35 #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
37 # TODO do a more thorough security check + test...
38 # TODO do a proper GET handler...
39 # TODO do a https server...
41 class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
42 '''
43 this is the basic xmlrpc request handler.
44 '''
45 # debug mode...
46 __server_debug__ = False
47 __verbosity__ = 0
48 # this enables/disables basic security
49 _sec_enabled = False
50 # this defines the iterable containing the allowed client addresses
51 ## _sec_allowed_client_addr = ['127.0.0.1']
53 def do_POST(self):
54 '''
55 the POST http command handler.
56 '''
57 # do security check...
58 ##!!!
59 if self._sec_enabled and hasattr(self, '_sec_allowed_client_addr'):
60 if self.client_address[0] not in self._sec_allowed_client_addr:
61 # return err response...
62 self.send_response(403)
63 self.end_headers()
64 self.wfile.write(response)
65 # shut down the connection
66 self.wfile.flush()
67 self.connection.shutdown(1)
68 return
69 # handle the actual request...
70 try:
71 # get arguments
72 data = self.rfile.read(int(self.headers["content-length"]))
73 if self.__server_debug__ and self.__verbosity__ > 2:
74 print '=' * 72
75 print 'Request:'
76 print '-' * 72
77 print data
78 print '=' * 72
79 try:
80 # parse the request...
81 params, method = xmlrpclib.loads(data)
82 # generate response
83 response = self.call(method, params)
84 if type(response) != type(()):
85 response = (response,)
86 ## except XMLRPCServerExit:
87 ## ##!!! prepare for exit...
88 ## self._exit_now = True
89 ## response = xmlrpclib.dumps(0, methodresponse=1)
90 except:
91 # report exception back to server
92 exc_type, exc_value, exc_trackback = sys.exc_info()
93 if self.__server_debug__:
94 # TODO verbosity level...
95 print '=' * 72
96 print 'ERR:', "%s:%s" % (exc_type, exc_value)
97 if self.__verbosity__ > 1:
98 print '-' * 72
99 traceback.print_tb(exc_trackback)
100 print '=' * 72
101 response = xmlrpclib.dumps(xmlrpclib.Fault(1, "%s:%s" % (exc_type, exc_value)))
102 else:
103 ##!!! use an encoding....
104 ## response = xmlrpclib.dumps(response, methodresponse=1, encoding='cp1251')
105 response = xmlrpclib.dumps(response, methodresponse=1)
106 if self.__server_debug__ and self.__verbosity__ > 2:
107 print '=' * 72
108 print 'Response:'
109 print '-' * 72
110 print response
111 print '=' * 72
112 except:
113 # internal error, report as HTTP server error
114 self.send_response(500)
115 self.end_headers()
116 else:
117 # got a valid XML RPC response
118 self.send_response(200)
119 self.send_header("Content-type", "text/xml")
120 self.send_header("Content-length", str(len(response)))
121 self.end_headers()
122 self.wfile.write(response)
123 # shut down the connection (from Skip Montanaro)
124 self.wfile.flush()
125 self.connection.shutdown(1)
126 ## if hasattr(self, '_exit_now') and self._exit_now:
127 ## ##!!!
128 ## print 'Exiting...'
129 ## raise XMLRPCServerExit
130 # the GET handler
131 ## do_GET = do_POST
132 def do_GET(self):
134 the GET http command handler.
136 # this currently does not differ from post...
137 return self.do_POST()
138 # override this method to implement RPC methods
139 def call(self, method, params):
141 base rpc call dispatch method (not for direct use).
143 raise NotImplementedError, 'this method is not for direct use. (Call: %s(%s))' % (method, params)
144 # utill methods...
145 ## def Error(self, faultCode=1, faultString='', **extra):
146 ## '''
147 ## '''
148 ## pass
152 #=======================================================================
153 if __name__ == '__main__':
154 server = SocketServer.TCPServer(('', 8000), RequestHandler)
155 server.serve_forever()
159 #=======================================================================
160 # vim:set ts=4 sw=4 nowrap :