From e9b7f4d7bf624ccb0ed503f20b85288a575d020d Mon Sep 17 00:00:00 2001 From: jahoti Date: Tue, 17 Aug 2021 00:00:00 +0000 Subject: Enable the hijacking proxy in the test suite to serve responses --- test/server.py | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 test/server.py (limited to 'test/server.py') diff --git a/test/server.py b/test/server.py new file mode 100644 index 0000000..d396495 --- /dev/null +++ b/test/server.py @@ -0,0 +1,106 @@ +# Copyright (C) 2021 jahoti +# Licensing information is collated in the `copyright` file + +""" +A modular "virtual network" proxy, +wrapping the classes in proxy_core.py +""" + +from proxy_core import * +from urllib.parse import parse_qs + +internet = {} # Add info here later +mime_types = { + "7z": "application/x-7z-compressed", "oga": "audio/ogg", + "abw": "application/x-abiword", "ogv": "video/ogg", + "arc": "application/x-freearc", "ogx": "application/ogg", + "bin": "application/octet-stream", "opus": "audio/opus", + "bz": "application/x-bzip", "otf": "font/otf", + "bz2": "application/x-bzip2", "pdf": "application/pdf", + "css": "text/css", "png": "image/png", + "csv": "text/csv", "sh": "application/x-sh", + "gif": "image/gif", "svg": "image/svg+xml", + "gz": "application/gzip", "tar": "application/x-tar", + "htm": "text/html", "ts": "video/mp2t", + "html": "text/html", "ttf": "font/ttf", + "ico": "image/vnd.microsoft.icon", "txt": "text/plain", + "js": "text/javascript", "wav": "audio/wav", + "jpeg": "image/jpeg", "weba": "audio/webm", + "jpg": "image/jpeg", "webm": "video/webm", + "json": "application/json", "woff": "font/woff", + "mjs": "text/javascript", "woff2": "font/woff2", + "mp3": "audio/mpeg", "xhtml": "application/xhtml+xml", + "mp4": "video/mp4", "zip": "application/zip", + "mpeg": "video/mpeg", + "odp": "application/vnd.oasis.opendocument.presentation", + "ods": "application/vnd.oasis.opendocument.spreadsheet", + "odt": "application/vnd.oasis.opendocument.text", + "xml": "application/xml" # text/xml if readable from casual users +} + +class RequestHijacker(ProxyRequestHandler): + def handle_request(self, req_body): + path_components = self.path.split('?', maxsplit=1) + path = path_components[0] + try: + # Response format: (status_code, headers (dict. of strings), + # body as bytes or filename containing body as string) + if path in internet: + info = internet[path] + if type(info) == tuple: + status_code, headers, body_file = info + if type(body_file) == str: + if 'Content-Type' not in headers and '.' in body_file: + ext = body_file.rsplit('.', maxsplit=1)[-1] + if ext in mime_types: + headers['Content-Type'] = mime_types[ext] + + with open(body_file, mode='rb') as f: + body_file = f.read() + + else: + # A function to evaluate to get the response + get_params, post_params = {}, {} + if len(path_components) == 2: + get_params = parse_qs(path_components[1]) + + # Parse POST parameters; currently only supports + # application/x-www-form-urlencoded + if req_body: + post_params = parse_qs(req_body.encode()) + + status_code, headers, body_file = info(self.command, get_params, post_params) + if type(body_file) == str: + body_file = body_file.encode() + + if type(status_code) != int or status_code <= 0: + raise Exception('Invalid status code %r' % status_code) + + for header, header_value in headers.items(): + if type(header) != str: + raise Exception('Invalid header key %r' % header) + + elif type(header_value) != str: + raise Exception('Invalid header value %r' % header_value) + else: + status_code, headers = 404, {'Content-Type': 'text/plain'} + body_file = b'Handler for this URL not found.' + + except Exception as e: + status_code, headers, body_file = 500, {'Content-Type': 'text/plain'}, b'Internal Error:\n' + repr(e).encode() + + headers['Content-Length'] = str(len(body_file)) + self.send_response(status_code) + for header, header_value in headers.items(): + self.send_header(header, header_value) + + self.end_headers() + self.wfile.write(body_file) + + + +def do_an_internet(port=1337): + """Start up the proxy/server""" + + httpd = ThreadingHTTPServer(('', port), RequestHijacker) + httpd.serve_forever() -- cgit v1.2.3