timeouts.

master
Yorick van Pelt 2015-03-01 22:14:10 +01:00
parent 843ebb41f5
commit c84a886890
2 changed files with 27 additions and 2 deletions

View File

@ -16,13 +16,19 @@ class Server(object):
reads = [self.listening_socket] + [c.sock for c in self.clients]
writes = [c.sock for c in self.clients if c.should_write()]
others = [c.sock for c in self.clients]
[rlist, wlist, xlist] = select.select(reads, writes, others)
try:
timeout = min([c.next_timeout() for c in self.clients])
except ValueError:
timeout = None
[rlist, wlist, xlist] = select.select(reads, writes, others, timeout)
for readable in rlist:
self.handlers[readable].do_read()
for writable in wlist:
self.handlers[writable].do_write()
for otherable in xlist:
self.handlers[otherable].do_other()
for c in self.clients:
c.try_timeout()
def do_read(self):
(sock, addrinfo) = self.listening_socket.accept()
c = self.connection_class(self, sock, addrinfo)
@ -31,6 +37,7 @@ class Server(object):
def client_closed(self, c):
self.clients.remove(c)
del self.handlers[c.sock]
print "%d open connections" % len(self.clients)
def close(self):
self.listening_socket.close()
@ -67,6 +74,9 @@ class Client(object):
def do_other(self): pass
def on_error(self):
self.parent.client_closed(self)
def try_timeout(self): pass
def next_timeout(self):
return None
def write(self, msg):
self.write_buf += msg
def close(self):

View File

@ -1,6 +1,7 @@
import os.path, mimetypes
from urllib import unquote
import hashlib
from datetime import datetime, timedelta
import asyncserver
@ -22,7 +23,9 @@ class HTTPClient(asyncserver.Client):
"""docstring for HTTPClient"""
def __init__(self, parent, sock, addrinfo):
super(HTTPClient, self).__init__(parent, sock, addrinfo)
self.set_timeout()
def on_data(self):
self.set_timeout()
try:
idx = self.read_buf.index("\r\n\r\n")
except ValueError:
@ -31,6 +34,8 @@ class HTTPClient(asyncserver.Client):
headers = self.read_buf[:idx]
self.read_buf = self.read_buf[idx+4:]
self.on_request(headers)
def set_timeout(self):
self.timeout = datetime.today() + timedelta(seconds=10)
def on_request(self, req):
headers = req.split('\r\n')
if not (headers[0].startswith("GET ") and headers[0].endswith("HTTP/1.1")):
@ -50,6 +55,16 @@ class HTTPClient(asyncserver.Client):
pass
def on_GET(self, url, headers):
print("got GET", url, headers)
def next_timeout(self):
if self.timeout:
return (self.timeout - datetime.today()).total_seconds()
else:
return None
def try_timeout(self):
if self.timeout < datetime.today():
print("connection timed out")
self.timeout = None
self.close()
def send_file(self, code, headers, fname, orig_etag):
(type, encoding) = mimetypes.guess_type(fname, strict = False)
if type:
@ -88,7 +103,7 @@ class HTTPDirClient(HTTPClient):
if not reqpath.startswith(os.path.abspath("./content/")):
self.send_response(404, {}, "Not Found, sorry\n")
return
print reqpath, os.path.isdir(reqpath)
print "GET", url
if os.path.isdir(reqpath) and not url.endswith('/'):
self.send_response(301, {"Location": url + '/'}, "")
reqpath += "/index.html"