root/py/httpmon.py/
from socket import *
import re, os, mimetypes
def chunkify(string, length):
data = []
pos = 0
curr = ''
while pos < len(string):
data.append(string[pos:pos + length])
pos += length
return data
class HTTPmon:
'''HTTP(Dae)mon'''
def __init__(self, host, port, root, commands):
self.host = host
self.port = port
self.docroot = root
self.commands = commands
self.sock = socket(AF_INET, SOCK_STREAM)
self.sock.bind((host, port))
self.sock.listen(5)
while 1:
(self.client, self.addr) = self.sock.accept()
data = self.client.recv(1048576)
for cmd, act in self.commands.items():
match = re.match(cmd, data)
if match is not None:
arglist = []
for group in match.groups():
arglist.append(group)
actd = map(getattr(self, act), arglist)[0]
getattr(self, actd[0])(actd[1:])
self.client.close()
def getreq(self, (req)):
data = req
mime = None
req = self.docroot + req
try:
data = file(req).read()
status = 'ok'
mime = mimetypes.guess_type(req)
except IOError:
try:
data = self.lsdir(req + '/')
mime = None
status = 'ok'
except:
mime = 'text/plain'
status = '_404'
return (status, data, mime)
def lsdir(self, dir):
data = 'Directory index of %s\n' % re.sub('[/]{2,}', '/', dir.replace(self.docroot, ''))
files = []
longest = 0
for elm in os.listdir(dir):
files.append((elm, os.path.getsize(dir + elm)))
if len(elm) > longest: longest = len(elm)
for elm in files:
name = elm[0].ljust(longest + 10)
data += '\n%s%s bytes' % (name, elm[1])
return data
def ok(self, (content, mime)):
chunks = '\n'.join(['%s\n%s' % (str(hex(len(chunk))), chunk) for chunk in chunkify(content, 100)])
self.client.send('''HTTP/1.1 200 OK\nContent-Type: %s\nTransfer-Encoding: chunked\n\n%s\n''' % ((mime and mime[0] or 'text/plain'), chunks))
def _404(self, (elm, mime)):
self.client.send('''HTTP/1.1 404 Not Found\nContent-Type: text/plain\n\nFile %s not found\n\nHTTPmon server on %s:%d''' % (elm, self.host, self.port))
if __name__ == '__main__':
commands = {'GET (.+) HTTP/.+\n': 'getreq'}
HTTPmon('localhost', 88, '~/public_html', commands)