From e02f201b4e66475e873973abf3698b3766eb44a1 Mon Sep 17 00:00:00 2001 From: Andreas Wrede Date: Fri, 29 Apr 2016 17:08:57 +0200 Subject: [PATCH] cleanup server response, use libray to parse uri --- hbc | 2 +- hbd | 197 +++++++++++++++++++++++++----------------------------------- 2 files changed, 82 insertions(+), 117 deletions(-) diff --git a/hbc b/hbc index 1f8038b..cd3eba5 100755 --- a/hbc +++ b/hbc @@ -59,7 +59,7 @@ daemon.get_maximum_file_descriptors = get_maximum_file_descriptors PORT = 50003 INTERVAL = 10 PIDFILE = '/tmp/hbc.pid' -VER = 1 +VER = 2 MAXRECV = 32767 running = True diff --git a/hbd b/hbd index 7d417fb..66e8f81 100755 --- a/hbd +++ b/hbd @@ -19,6 +19,7 @@ import cPickle import smtplib import traceback import urllib +import urlparse import httplib import threading import Queue @@ -322,7 +323,7 @@ def log(host, m, service=None): hst = "%s " % host else: hst = "" - + msg = "%s: %s%s%s\n" % (ts, hst, srv, m) msgs.append(msg) if logfmt == "msg": @@ -364,7 +365,7 @@ def readsock(sock): msg = oldmtodict(data) else: oldclient = False - if verbose: print "readsock = %s, %s" % (msg,addrp) + if DEBUG > 2: print "readsock = %s, %s" % (msg,addrp) addr = addrp[0:2] name = shortname(msg.get('name', "unknown")) @@ -440,7 +441,7 @@ def readsock(sock): else: opkt = dicttos('ACK', rmsg) ss=sock.sendto(opkt, addr) - if verbose: print "sendto1: %s (%s) %s %s" % (addr, len(opkt), op, str(rmsg)[:50]) + if DEBUG > 2: print "sendto1: %s (%s) %s %s" % (addr, len(opkt), op, str(rmsg)[:50]) # send any commands we have queued while len(host.cmds): @@ -467,7 +468,7 @@ def readsock(sock): except Exception as e: print "opkt len is %s" % len(opkt) print "cannot send: %s" % e - + if verbose: print "sendto2: %s (%s) %s %s" % (addr, len(opkt), op, str(rmsg)[:50]) if DEBUG > 2: print "msg from %s,%s, sent %s bytes back" % (addr[0], addr[1], ss) @@ -503,20 +504,18 @@ class HttpHandler(BaseHTTPServer.BaseHTTPRequestHandler): def do_HEAD(self): - self.setheaders() + self.setheaders(200) - def setheaders(self, headerdict=None): - if not headerdict: - headerdict = {"Content-Type": "text/html; charset = ISO-8859-1" } - self.send_response(200) + def setheaders(self, code, headerdict): + self.send_response(code) self.send_header("Last-Modified", time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(now))) # self.send_header("Accept-Ranges","bytes") # self.send_header("Connection","close") for h in headerdict: self.send_header(h, headerdict[h]) self.end_headers() - + def buildhead(self, title="Heartbeat", refresh=None, extras=None): res=[] @@ -556,141 +555,107 @@ class HttpHandler(BaseHTTPServer.BaseHTTPRequestHandler): res.append('
') res.append('
hbd (Unix) Server at %s:%s
' % (hbd_host, hbd_port)) res.append('') - return res - + return code, res + def do_GET(self): global sig - xsig = 0 - headers=[] - headerdict = None - if DEBUG > 2: sys.stderr.write("handle\n") - uri = self.path - upar=string.split(uri,"?") - if len(upar) == 1: - uarg=[] - else: - uarg=string.split(upar[1],"&") - - if DEBUG > 2: sys.stderr.write("handle = %s\n" % (uri)) code = 200 - cause = "OK" - if uri == "/": + xsig = 0 + rqAcceptEncoding = self.headers.getheader('Accept-encoding',None) + headerdict = {"Content-Type": "text/html; charset = ISO-8859-1" } + if DEBUG > 2: sys.stderr.write("handle\n") + qr = urlparse.urlparse(self.path) + qa = urlparse.parse_qs(qr.query) + + if DEBUG > 2: sys.stderr.write("handle = %s\n" % (qr.geturl())) + if qr.path == "/": res=self.buildpage() - elif upar[0] == "/c": # command on host /c?h=melschserver&c=sudo%20ls - uname="" - ucmd="" - if len(uarg) != 2 or len(uarg[0]) < 3 or len(uarg[1]) < 3: - code=400 - cause='Argument error' - res=self.builderror(code, cause, "need h= and c= arguments") - else: - if uarg[0][:2] == "h=": - uname=uarg[0][2:] - if uarg[1][:2] == "c=": - ucmd=uarg[1][2:] - if ucmd != "" and uname != "" and Host.hosts.has_key(uname): - rmsg = {'cmd': urllib.unquote(ucmd)} - Host.hosts[uname].cmds.append(('CMD', rmsg)) - res=self.buildhead() - res.append("2Done") - else: - code=400 - cause='arg 2 error' - res=self.builderror(code, cause, "ucmd %s uname %s" % (ucmd, uname)) - - elif upar[0] == "/d": # drop host /d?h=melschserver - if len(uarg) != 1 or len(uarg[0]) < 3: - code=400 - cause='Argument error' - res=self.builderror(code, cause, "need h= argument") - else: - if uarg[0][:2] == "h=": - uname=uarg[0][2:] - if uname != "" and Host.hosts.has_key(uname): - log(uname, "dropped") - del Host.hosts[uname] - res=self.buildhead() - res.append("Done") - - elif upar[0] == "/n": # register name - if len(uarg) != 1 or len(uarg[0]) < 3: - code=400 - cause='Argument error' - res=self.builderror(code, cause, "need h= argument") + elif qr.path == "/c": # command on host /c?h=melschserver&c=sudo%20ls + uname=qa.get('h',[None])[0] + ucmd=qa.get('c', [None])[0] + if not ucmd or not uname: + code, res=self.builderror(400, 'Argument error', "need h= and c= arguments") + elif not Host.hosts.has_key(uname): + code, res=self.builderror(400, 'Data error', "h=%s not found" % uname) else: + Host.hosts[uname].cmds.append(('CMD', {'cmd': urllib.unquote(ucmd)})) res=self.buildhead() - if uarg[0][:2] == "h=": - uname=uarg[0][2:] - if uname != "" and Host.hosts.has_key(uname): - ll = Host.hosts[uname].registerDns() - else: - ll="name %s not found" % uname + res.append("cmd %s queued for host %s" % (uname, ucmd)) + + elif qr.path == "/d": # drop host /d?h=melschserver + uname=qa.get('h',[None])[0] + if not uname: + code, res=self.builderror(400, 'Argument error', "need h= argument") + if not uname in Host.hosts: + code, res=self.builderror(400, 'Data error', "h=%s not found" % uname) + else: + log(uname, "dropped") + del Host.hosts[uname] + res=self.buildhead() + res.append("Done") + + elif qr.path == "/n": # register name + uname=qa.get('h',[None])[0] + if not uname: + code, res=self.builderror(400, 'Argument error', "need h= argument") + if not uname in Host.hosts: + code, res=self.builderror(400, 'Data error', "h=%s not found" % uname) + else: + ll = Host.hosts[uname].registerDns() res.append(ll) log(uname, ll) - elif upar[0] == "/u": # update - uname="" - ucode="" - if len(uarg) != 2 or len(uarg[0]) < 3 or len(uarg[1]) < 3: - code=400 - cause='Argument error' - res=self.builderror(code, cause, "need h= and c= arguments") + elif qr.path == "/u": # update + uname=qa.get('h',[None])[0] + ucode=qa.get('c', [None])[0] + if not ucode or not uname: + code, res=self.builderror(400, 'Argument error', "need h= and c= arguments") + elif not Host.hosts.has_key(uname): + code, res=self.builderror(400, 'Data error', "h=%s not found" % uname) else: - if uarg[0][:2] == "h=": - uname=uarg[0][2:] - if uarg[1][:2] == "c=": - ucode=uarg[1][2:] - if ucode != "" and uname != "" and Host.hosts.has_key(uname): - err = updatecode(ucode, urllib.unquote(uname)) - res=self.buildhead() - res.append("3 Done: %s" % err if err else "OK") - else: - code=400 - cause='Argument error' - res=self.builderror(code, cause, "host not found") + err = updatecode(ucode, urllib.unquote(uname)) + res=self.buildhead() + res.append("3 Done: %s" % err if err else "OK") - - - elif upar[0] == "/api/0/hosts": # api access to host table + elif qr.path == "/api/0/hosts": # api access to host table headerdict = {"Content-Type": "application/json; charset=utf-8" } l=[] for h in Host.hosts: l.append(Host.hosts[h].jsons()) - res=["[",",".join(l),"]"] - elif upar[0] == "/api/0/messages": # api access to host table + res=["["+",".join(l)+"]"] + + elif qr.path == "/api/0/messages": # api access to host table headerdict = {"Content-Type": "application/json; charset=utf-8" } l=msgs[len(msgs)-30:] res=[json.dumps(l)] - elif upar[0] == "/r": # restart + + elif qr.path == "/r": # restart res=self.buildhead() res.append("restart request") xsig=signal.SIGHUP log(None, "restart request") else: - code=404 - cause="Not Found" - res=self.builderror(code, cause, "The requested URL was not found on this server.") + code, res=self.builderror(404, "Not Found", "requested URL was not found on this server.") - tosend = [] - for h in headers: - tosend.append("%s\r" % h) - tosend.append("\r") -# self.request.send("HTTP/1.0 %s %s\r\n" % (code, cause)) -# for h in headers: -# self.request.send("%s\r\n" % h) -# self.request.send("\r\n") - - self.setheaders(headerdict) - tosend += res - self.wfile.write(string.join(tosend, "\n")) + if 'deflate' in rqAcceptEncoding: + headerdict['Content-Encoding'] = "deflate" + towrite = zlib.compress(string.join(res, "\n"), 6) + else: + towrite = string.join(res, "\n") + headerdict['Content-Length'] = len(towrite) + headerdict['Cache-Control'] = 'private, must-revalidate, max-age=0' + headerdict['Expires'] = 'Thu, 01 Jan 1970 00:00:00 GMT' + self.setheaders(code, headerdict) + self.wfile.write(towrite) if xsig: sig = xsig + def setrunning(new): global running if DEBUG > 0: sys.stderr.write("running is now = %s\n" % (new)) @@ -707,7 +672,7 @@ def closeup(): sock6.close() except: pass - + if DEBUG > 0: sys.stderr.write("asking http server to stop\n") try: serv.shutdown() @@ -994,7 +959,7 @@ while running: sys.stderr.write("what happend just now?\n") if DEBUG > 2: sys.stderr.write("done handling, running is %s, sig is %s\n" % (running, sig)) - # check hour/day/week + # check hour/day/week for v in xrange(3): fm=tsfm[v] ts=time.strftime(tsfm[v], time.localtime(now)) @@ -1002,7 +967,7 @@ while running: lastfm[v]=ts for h in Host.hosts.keys(): Host.hosts[h].hdwcounts[v] = [Host.hosts[h].doesack, Host.hosts[h].upcount] - + if now >= next and now >= firstcheck: next = now+1 checkoverdue()