Mercurial > p > roundup > code
view roundup/scripts/roundup_xmlrpc_server.py @ 4415:3e35233ea93c
new rdbms config item sqlite_timeout...
...makes the previously hard-coded timeout of 30 seconds
configurable. This is the time a client waits for the locked database
to become free before giving up. Used only for SQLite backend.
| author | Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net> |
|---|---|
| date | Tue, 07 Sep 2010 15:42:04 +0000 |
| parents | a728d421a65a |
| children | 86ef4ab17dc5 |
line wrap: on
line source
#! /usr/bin/env python # # Copyright (C) 2007 Stefan Seefeld # All rights reserved. # For license terms see the file COPYING.txt. # import base64, getopt, os, sys, socket, urllib from roundup.xmlrpc import translate from roundup.xmlrpc import RoundupInstance import roundup.instance from roundup.instance import TrackerError from roundup.cgi.exceptions import Unauthorised from SimpleXMLRPCServer import SimpleXMLRPCServer from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler class RequestHandler(SimpleXMLRPCRequestHandler): """A SimpleXMLRPCRequestHandler with support for basic HTTP Authentication.""" TRACKER_HOMES = {} TRACKERS = {} def is_rpc_path_valid(self): path = self.path.split('/') name = urllib.unquote(path[1]).lower() return name in self.TRACKER_HOMES def get_tracker(self, name): """Return a tracker instance for given tracker name.""" if name in self.TRACKERS: return self.TRACKERS[name] if name not in self.TRACKER_HOMES: raise Exception('No such tracker "%s"'%name) tracker_home = self.TRACKER_HOMES[name] tracker = roundup.instance.open(tracker_home) self.TRACKERS[name] = tracker return tracker def authenticate(self, tracker): # Try to extract username and password from HTTP Authentication. username, password = None, None authorization = self.headers.get('authorization', ' ') scheme, challenge = authorization.split(' ', 1) if scheme.lower() == 'basic': decoded = base64.decodestring(challenge) if ':' in decoded: username, password = decoded.split(':') else: username = decoded if not username: username = 'anonymous' db = tracker.open('admin') try: userid = db.user.lookup(username) except KeyError: # No such user db.close() raise Unauthorised, 'Invalid user' stored = db.user.get(userid, 'password') if stored != password: # Wrong password db.close() raise Unauthorised, 'Invalid user' db.setCurrentUser(username) return db def do_POST(self): """Extract username and password from authorization header.""" db = None try: path = self.path.split('/') tracker_name = urllib.unquote(path[1]).lower() tracker = self.get_tracker(tracker_name) db = self.authenticate(tracker) instance = RoundupInstance(db, tracker.actions, None) self.server.register_instance(instance) SimpleXMLRPCRequestHandler.do_POST(self) except Unauthorised, message: self.send_error(403, '%s (%s)'%(self.path, message)) except: if db: db.close() exc, val, tb = sys.exc_info() print exc, val, tb raise if db: db.close() class Server(SimpleXMLRPCServer): def _dispatch(self, method, params): retn = SimpleXMLRPCServer._dispatch(self, method, params) retn = translate(retn) return retn def usage(): print """Usage: %s: [options] [name=tracker home]+ Options: -e, --encoding -- specify the encoding to use -V -- be verbose when importing -p, --port <port> -- port to listen on """%sys.argv[0] def run(): try: opts, args = getopt.getopt(sys.argv[1:], 'e:i:p:V', ['encoding=', 'port=']) except getopt.GetoptError, e: usage() return 1 verbose = False port = 8000 encoding = None for opt, arg in opts: if opt == '-V': verbose = True elif opt in ['-p', '--port']: port = int(arg) elif opt in ['-e', '--encoding']: encoding = encoding tracker_homes = {} for arg in args: try: name, home = arg.split('=', 1) # Validate the argument tracker = roundup.instance.open(home) except ValueError: print 'Instances must be name=home' sys.exit(-1) except TrackerError: print 'Tracker home does not exist.' sys.exit(-1) tracker_homes[name] = home RequestHandler.TRACKER_HOMES=tracker_homes if sys.version_info[0:2] < (2,5): if encoding: print 'encodings not supported with python < 2.5' sys.exit(-1) server = Server(('', port), RequestHandler) else: server = Server(('', port), RequestHandler, allow_none=True, encoding=encoding) # Go into the main listener loop print 'Roundup XMLRPC server started on %s:%d' \ % (socket.gethostname(), port) try: server.serve_forever() except KeyboardInterrupt: print 'Keyboard Interrupt: exiting' if __name__ == '__main__': run()
