From f7b79fdc1bd6dbb7cb5757b5a47a8c7aa6e81025 Mon Sep 17 00:00:00 2001 From: randomuser Date: Mon, 19 Jul 2021 15:11:31 -0500 Subject: [PATCH] the server is somewhat usable now --- esgd.py | 44 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/esgd.py b/esgd.py index 2e688c6..43c6413 100644 --- a/esgd.py +++ b/esgd.py @@ -1,9 +1,12 @@ import socketserver +import subprocess import os class GopherError(BaseException): pass class RequestError(GopherError): pass +print(os.getcwd()) + def recieveRequest(context): data = b'' while data[-2:] != b'\r\n': @@ -12,6 +15,7 @@ def recieveRequest(context): return decoded def requestParser(request): + if '..' in request: raise RequestError try: if request[0] == '/': request = request[1:] except IndexError: pass @@ -39,6 +43,9 @@ def fileCGI(file): def notFound(context): context.request.sendall(b"3error: file not found!\r\n.\r\n") +def invalid(context): + context.request.sendall(b"3error: selector contains '..'!\r\n.\r\n") + def sendFile(file, context): with open(file, "r") as fd: [context.request.sendall( @@ -46,21 +53,50 @@ def sendFile(file, context): ) for i in fd.readlines()] context.request.sendall(b".\r\n") +def cgi(file, query, context): + env = {} + env['QUERY_STRING'] = query + env['SCRIPT_NAME'] = "/" + file + env['REMOTE_ADDR'] = context.client_address[0] + + proc = subprocess.Popen( + [os.getcwd() + "/" + file], + stdout = subprocess.PIPE, + env = env + ) + + try: out, err = proc.communicate(timeout=10) + except TimeoutExpired: + proc.kill() + out, err = proc.communicate() + + return out.decode('utf-8').replace('\r', '').split('\n') + class gopherHandler(socketserver.BaseRequestHandler): def handle(self): decoded = recieveRequest(self) - parsed = requestParser(decoded) + try: + parsed = requestParser(decoded) + except RequestError: + invalid(self) + return + + print(self.client_address) try: file = returnRelative(parsed[0]) except RequestError: notFound(self) return - - if fileSendable(file[0]): sendFile(file[0], self) + if fileCGI(file[0]): + ret = cgi(file[0], parsed[1], self) + for i in ret: + self.request.sendall((i + '\r\n').encode('utf-8')) + self.request.sendall(b'.\r\n') + elif fileSendable(file[0]): sendFile(file[0], self) else: notFound(self) if __name__ == "__main__": - HOST, PORT = "localhost", 85 + HOST, PORT = "localhost", 72 with socketserver.TCPServer((HOST, PORT), gopherHandler) as server: server.serve_forever()