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