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