From a83984700c9ff46d467994724dff98f5ab10f5f5 Mon Sep 17 00:00:00 2001 From: Ruben <ruben@rubenkerkhof.com> Date: Sun, 17 Oct 2010 17:33:46 +0200 Subject: [PATCH 10/14] 20_bugfixes-tweaks-by-blt.diff from Debian --- ajaxterm.js | 5 ++++- ajaxterm.py | 45 ++++++++++++++++++++++++++++++++++----------- qweb.py | 26 ++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 12 deletions(-) diff --git a/ajaxterm.js b/ajaxterm.js index 74eeb39..4edcb6c 100644 --- a/ajaxterm.js +++ b/ajaxterm.js @@ -1,8 +1,11 @@ ajaxterm={}; ajaxterm.Terminal_ctor=function(id,width,height) { var ie=0; + var webkit=0; if(window.ActiveXObject) ie=1; + if (navigator.userAgent.indexOf("WebKit") >= 0) + webkit=1; var sid=""+Math.round(Math.random()*1000000000); if (width==0) { @@ -242,7 +245,7 @@ ajaxterm.Terminal_ctor=function(id,width,height) { } function keydown(ev) { if (!ev) var ev=window.event; - if (ie) { + if (ie || webkit) { // s="kd keyCode="+ev.keyCode+" which="+ev.which+" shiftKey="+ev.shiftKey+" ctrlKey="+ev.ctrlKey+" altKey="+ev.altKey; // debug(s); o={9:1,8:1,27:1,33:1,34:1,35:1,36:1,37:1,38:1,39:1,40:1,45:1,46:1,112:1, diff --git a/ajaxterm.py b/ajaxterm.py index 91d938d..962e685 100755 --- a/ajaxterm.py +++ b/ajaxterm.py @@ -9,6 +9,7 @@ except: pass import array,cgi,fcntl,glob,mimetypes,optparse,os,pty,random,re,signal,select,sys,threading,time,termios,struct,pwd +from datetime import datetime os.chdir(os.path.normpath(os.path.dirname(__file__))) # Optional: Add QWeb in sys path @@ -17,6 +18,11 @@ sys.path[0:0]=glob.glob('../../python') import qweb from socket import gethostname + +def debug(str): + now = datetime.datetime.now() + print "%s - %s" % (now.isoformat(), str) + class Terminal: def __init__(self,width=80,height=24): self.width=width @@ -373,7 +379,23 @@ class SynchronizedMethod: self.lock.release() return r +class Reaper: + WAKEUP_FREQUENCY=5 + + def __init__(self,multi): + self.multi = multi + self.thread = threading.Thread(target = self.reaper_thread) + self.thread.setDaemon(True) + self.thread.start() + + def reaper_thread(self): + while True: + time.sleep(Reaper.WAKEUP_FREQUENCY) + self.multi.proc_kill_inactive() + class Multiplex: + INACTIVE_PROCESS_TIMEOUT=120 # I guess this is the IP max packet lifetime + def __init__(self,cmd=None,serverport=None): signal.signal(signal.SIGCHLD, signal.SIG_IGN) self.cmd=cmd @@ -435,19 +457,19 @@ class Multiplex: return self.alive def fds(self): return self.proc.keys() - def proc_kill(self,fd): - if fd in self.proc: - self.proc[fd]['time']=0 + def proc_kill(self, fd): + try: + os.close(fd) + os.kill(self.proc[fd]['pid'],signal.SIGHUP) + except (IOError,OSError): + pass + del self.proc[fd] + def proc_kill_inactive(self): t=time.time() for i in self.proc.keys(): t0=self.proc[i]['time'] - if (t-t0)>120: - try: - os.close(i) - os.kill(self.proc[i]['pid'],signal.SIGTERM) - except (IOError,OSError): - pass - del self.proc[i] + if (t-t0)>Multiplex.INACTIVE_PROCESS_TIMEOUT: + self.proc_kill(i) def proc_read(self,fd): try: t=self.proc[fd]['term'] @@ -493,6 +515,7 @@ class AjaxTerm: self.mime = mimetypes.types_map.copy() self.mime['.html']= 'text/html; charset=UTF-8' self.multi = Multiplex(cmd,serverport) + self.reaper = Reaper(self.multi) self.session = {} def __call__(self, environ, start_response): req = qweb.QWebRequest(environ, start_response,session=None) @@ -569,7 +592,7 @@ def main(): # f=lambda:os.system('firefox http://localhost:%s/&'%o.port) # qweb.qweb_wsgi_autorun(at,ip='localhost',port=int(o.port),threaded=0,log=o.log,callback_ready=None) try: - qweb.QWebWSGIServer(at,ip='localhost',port=int(o.port),threaded=0,log=o.log).serve_forever() + qweb.QWebWSGIServer(at,ip='localhost',port=int(o.port),threaded=1,log=o.log).serve_forever() except KeyboardInterrupt,e: sys.excepthook(*sys.exc_info()) at.multi.die() diff --git a/qweb.py b/qweb.py index 34529c2..1541035 100644 --- a/qweb.py +++ b/qweb.py @@ -1182,6 +1182,10 @@ class QWebRequest: self.buffer=[zbuf] self.response_headers['Content-Encoding']="gzip" self.response_headers['Content-Length']=str(len(zbuf)) + else: + datalen = sum(map(len, self.buffer)) + self.response_headers['Content-Length']=str(datalen) + headers = self.response_headers.get() if isinstance(self.SESSION, QWebSession): headers.extend(self.SESSION.session_get_headers()) @@ -1257,6 +1261,7 @@ class QWebWSGIHandler(BaseHTTPServer.BaseHTTPRequestHandler): self.write(buf.getvalue()) self.wfile_buf=0 def serve(self,type): + self.handleKeepalive() path_info, parameters, query = urlparse.urlparse(self.path)[2:5] environ = { 'wsgi.version': (1,0), @@ -1287,10 +1292,31 @@ class QWebWSGIHandler(BaseHTTPServer.BaseHTTPRequestHandler): # Hack to avoid may TCP packets self.bufferon() appiter=self.server.wsgiapp(environ, self.start_response) + if self.close_connection == 0: + appiter.response_headers['Connection']='keep-alive' + appiter.response_headers['Keep-Alive']='timeout=10, max=100' + for data in appiter: self.write(data) self.bufferoff() self.bufferoff() + def handleKeepalive(self): + base_version_number=self.request_version.split("/",1)[1] + version_number = base_version_number.split(".") + version_number = int(version_number[0]), int(version_number[1]) + connection_header = self.headers.get("Connection", "").lower() + if version_number == (1,0): + if connection_header == "keepalive": + self.close_connection = 0 + else: + self.close_connection = 1 + elif version_number == (1,1): + if connection_header == "close": + self.close_connection=1 + else: + self.close_connection=0 + else: + self.close_connection=1 def do_GET(self): self.serve('GET') def do_POST(self): -- 1.7.3.1