Skip to content

Instantly share code, notes, and snippets.

@chipaca
Last active November 16, 2015 13:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chipaca/58552b58a1a75cd1607b to your computer and use it in GitHub Desktop.
Save chipaca/58552b58a1a75cd1607b to your computer and use it in GitHub Desktop.
Tiny Deb Proxy
#!/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