| #!/usr/bin/python3 | |
| # heavily based on Hisao Suzuki's Tiny HTTP Proxy v0.2.1 | |
| import sys | |
| import os | |
| if sys.version_info.major < 3: | |
| print("restarting in python3") | |
| os.execlp("python3", "python3", *sys.argv) | |
| from http import server | |
| from urllib.parse import urlparse | |
| import errno | |
| import socket | |
| import socketserver | |
| from shutil import copyfileobj | |
| def get_obj_path(url): | |
| h = url.path[url.path.index('/ubuntu')+8:] | |
| return os.path.join("/dev/shm/tinyDebProxy/", url.netloc, h) | |
| class SimpleDebProxy(server.BaseHTTPRequestHandler): | |
| def do_GET(self): | |
| url = urlparse(self.path, 'http') | |
| if url.fragment or not url.netloc: | |
| self.send_error(400, "bad url %s" % self.path) | |
| return | |
| if url.scheme != 'http' or url.query or url.params or '/ubuntu' not in url.path: | |
| self.send_error(400, "unsupported url %s" % self.path) | |
| return | |
| obj_path = get_obj_path(url) | |
| if os.path.exists(obj_path): | |
| self.log_request() | |
| self.log_message(" `- from %s.", obj_path) | |
| copyfileobj(open(obj_path, "rb"), self.wfile) | |
| else: | |
| os.makedirs(os.path.dirname(obj_path), exist_ok=True) | |
| f = open(obj_path, "wb") | |
| try: | |
| if not self._really_get(url, f): | |
| os.unlink(obj_path) | |
| f.close() | |
| except: | |
| os.unlink(obj_path) | |
| raise | |
| def _really_get(self, url, wfile): | |
| soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
| try: | |
| if self._connect_to(url.netloc, soc): | |
| self.log_request() | |
| soc.send(("%s %s %s\r\n" % ( | |
| self.command, | |
| url.path, | |
| self.request_version)).encode("latin1")) | |
| self.headers['Connection'] = 'close' | |
| del self.headers['Proxy-Connection'] | |
| for key_val in self.headers.items(): | |
| soc.send(("%s: %s\r\n" % key_val).encode("latin1")) | |
| soc.send(b"\r\n") | |
| while 1: | |
| b = soc.recv(8192) | |
| if not b: | |
| break | |
| self.wfile.write(b) | |
| wfile.write(b) | |
| except socket.error as e: | |
| ok = False | |
| if e.errno != errno.ECONNRESET: | |
| raise | |
| else: | |
| ok = True | |
| finally: | |
| soc.close() | |
| self.connection.close() | |
| return ok | |
| def _connect_to(self, netloc, soc): | |
| i = netloc.find(':') | |
| if i >= 0: | |
| host_port = netloc[:i], int(netloc[i+1:]) | |
| else: | |
| host_port = netloc, 80 | |
| try: | |
| soc.connect(host_port) | |
| except socket.error as arg: | |
| self.send_error(404, str(arg)) | |
| return 0 | |
| return 1 | |
| class ThreadingHTTPServer (socketserver.ThreadingMixIn, server.HTTPServer): | |
| pass | |
| if __name__ == '__main__': | |
| server.test( | |
| HandlerClass=SimpleDebProxy, | |
| ServerClass=ThreadingHTTPServer, | |
| bind="0.0.0.0") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment