diff --git a/gophersrv.py b/gophersrv.py index 09b5113..eb4ae94 100644 --- a/gophersrv.py +++ b/gophersrv.py @@ -68,12 +68,25 @@ def normalizepath(path): return '/'.join(path) # Error handling +def error(conn, ishttp, text, code): + sendheader(conn, ishttp, '1', code) + if ishttp: + conn.sendall('\n' + '\t\n' + '\t\t%s\n' + '\t\n' + '\t\n' + '\t\t

%s

\n' + '\t\n' + '' % (code, text)) + else: + conn.sendall('3%s\t/\t(null)\t0\n' % text) + def notfounderror(conn, path, ishttp): - sendheader(conn, ishttp, '1', '404 Not Found') - conn.sendall('3"%s" does not exist\t/\t(null)\t0\n' % path) + error(conn, ishttp, '"%s" does not exist' % path, '404 Not Found') + def notallowederror(conn, path, ishttp): - sendheader(conn, ishttp, '1', '403 Forbidden') - conn.sendall('3Access denied\t/\t(null)\t0\n') + error(conn, ishttp, 'Access denied', '403 Forbidden') # Server implementation def getrequest(conn): @@ -124,7 +137,8 @@ def getselector(request): # If a HTTP request with selector is used, this extrac def sendheader(conn, ishttp, selector, code = '200 OK'): if ishttp: # All others can safely be made text/plain - contenttypes = {'5': 'application/octet-stream', + contenttypes = {'1': 'text/html; charset=utf-8', + '5': 'application/octet-stream', '9': 'application/octet-stream', 'g': 'image/gif', 'h': 'text/html; charset=utf-8', @@ -158,13 +172,43 @@ def servecommon(conn, fd): fd.close() -def servecgi(conn, path): - proc = subprocess.Popen([path], stdout=subprocess.PIPE) - servecommon(conn, proc.stdout) +def servehtmlgophermap(conn, fd): + conn.sendall('\n' + '\n' + '\t\n' + '\t\tGophermap\n' + '\t\n' + '\t\n' + '\t\t

\n' + '\t\t\t.. /
\n') -def servefile(conn, path): + for line in fd: + while len(line) > 0 and line[-1] == '\n': + line = line[:-1] + + if line != '.' and line != '': + text, path, server, port = line.split('\t') + port = int(port) + selector, text = text[0], text[1:] + if selector == 'i' or selector == '3': + conn.sendall('\t\t\t%s
\n' % text) + else: + if len(path) >= 4 and path[:4] == 'URL:': + conn.sendall('\t\t\t%s
\n' % (path[4:], text)) + else: + conn.sendall('\t\t\t%s
\n' % (server, port, selector, path, text)) + + conn.sendall('\t\t

\n' + '\t\n' + '') + +def servecgi(conn, path, servefunc = servecommon): + proc = subprocess.Popen([path], stdout=subprocess.PIPE) + servefunc(conn, proc.stdout) + +def servefile(conn, path, servefunc = servecommon): f = open(path, 'r') - servecommon(conn, f) + servefunc(conn, f) def serverequest(conn, request, ishttp): # Extract selector if needed @@ -195,10 +239,15 @@ def serverequest(conn, request, ishttp): sendheader(conn, ishttp, selector) - if isexecutable(path): - servecgi(conn, path) + if ishttp and selector == '1': + servefunc = servehtmlgophermap else: - servefile(conn, path) + servefunc = servecommon + + if isexecutable(path): + servecgi(conn, path, servefunc) + else: + servefile(conn, path, servefunc) class Serve(threading.Thread): def __init__(self, conn):