import threading import time from Event import IllegalEventException from logger import Logger import BaseHTTPServer import SocketServer import cgi import urlparse import time import Queue import Entry import AdminFuncs class LocalException(Exception): def __init__(self, msg): Logger.log("Exception in HttpCmdReceiver: %s" % msg) self.msg = msg class HttpCmdHandler(BaseHTTPServer.BaseHTTPRequestHandler): server_version = "YadynCMDHTTP/1.0" def log_request(self, code='-', size='-'): pass @classmethod def setClassParams(cls, entries, dnsq, nullAddress): cls.entries = entries cls.dnsq = dnsq cls.nullAddress = nullAddress def do_GET(self): Logger.debug("Request: %s, %s" % (self.path, self.client_address)) try: if self.command == "GET": q = urlparse.urlparse(self.path).query c = cgi.parse_qs(q) if not c.has_key('c'): raise LocalException('no cmd given') cmd = c['c'][0] Logger.debug("Cmd: " + cmd) if cmd == 'register': self.register(c) elif cmd == 'start': self.setAddress(c, self.client_address[0]) elif cmd == 'stop': self.setAddress(c, HttpCmdHandler.nullAddress) else: raise LocalException('unknown cmd') self.send_response(200, "OK") self.send_header("Content-Length", "0") self.end_headers() except IllegalEventException, e: Logger.log("Some failure (%s), not notifying user" % e.msg) self.send_response(200, "OK") self.send_header("Content-Length", "0") self.end_headers() except AdminFuncs.AdminFuncException, e: self.send_response(400, e.msg) self.end_headers() except LocalException, e: self.send_response(400, e.msg) self.end_headers() def register(self, c): try: dynid = c['dynid'][0] subdomain = c['subdomain'][0] zone = c['zone'][0] sharedSecret = c['sharedsecret'][0] checkSum = c['checksum'][0] except KeyError, e: raise LocalException('Parameter missing: ' + str(e)) AdminFuncs.AdminFuncs.register(dynid, subdomain, zone, sharedSecret, checkSum) def setAddress(self, c, address): try: dynId = c['d'][0] sharedSecret = c['s'][0] except KeyError, e: raise LocalException('Parameter missing: ' + str(e)) if not HttpCmdHandler.entries.has_key(dynId): raise IllegalEventException("unknown dynid %s" % dynId) entry = HttpCmdHandler.entries[dynId] if entry.sharedSecret != sharedSecret: raise IllegalEventException("shared secret %s does not match to dynid %s" % (sharedSecret, dynId)) entry.lastEventTime = int(time.time()) entry.address = address Logger.debug("Set in DNS: %s -> %s" % (entry.name, entry.address)) try: HttpCmdHandler.dnsq.put_nowait(entry) except Queue.Full, e: Logger.log("Dns Queue overrun, drop event for %s" % str(entry)) class HttpCmdServer(SocketServer.ThreadingTCPServer): def __init__(self, serverAddr): self.allow_reuse_address = True SocketServer.ThreadingTCPServer.__init__(self, serverAddr, HttpCmdHandler) class HttpCmdReceiver(threading.Thread): def __init__(self, httpCmdRecvAddr, entries, dnsq, nullAddress): threading.Thread.__init__(self) self.httpCmdRecvAddr = httpCmdRecvAddr HttpCmdHandler.setClassParams(entries, dnsq, nullAddress) self.setDaemon(True) def run(self): server = HttpCmdServer(self.httpCmdRecvAddr) server.serve_forever()