Skip to content

Instantly share code, notes, and snippets.

@DylanLacey
Created September 14, 2018 04:53
Show Gist options
  • Save DylanLacey/5891a46922efd0e5f561d6587e0a1046 to your computer and use it in GitHub Desktop.
Save DylanLacey/5891a46922efd0e5f561d6587e0a1046 to your computer and use it in GitHub Desktop.
Proxy from localhost safely.
#! python
# encoding: utf-8
import sys
import logging
import logging.handlers
import urllib
from urlparse import urlsplit, urlunsplit, urljoin
import monocle
from monocle import _o, Return
monocle.init("twisted")
from monocle.stack import eventloop
from monocle.stack.network import add_service
from monocle.stack.network.http import (HttpServer, HttpClient, HttpHeaders,
write_request, read_response, VERSION)
import re
PORTS = range(50000, 52000)
PROXY = {"host": "127.0.0.1", "port": 5555}
pattern = r"PROXY (\d+\.\d+\.\d+\.\d+):(\d+)"
f = open("pac.js", "r")
for line in f:
matched = re.search(pattern, line)
if matched:
PROXY["host"] = matched.groups()[0]
PROXY["port"] = matched.groups()[1]
log = logging.getLogger("localhost_web_server")
mlog = logging.getLogger("monocle")
class ProxyingHttpClient(HttpClient):
@_o
def request(self, url, headers=None, method='GET', body=None):
if not headers:
headers = HttpHeaders()
headers.setdefault('User-Agent', 'monocle/%s' % VERSION)
if body is not None:
headers['Content-Length'] = str(len(body))
yield write_request(self.client, method, url, headers, body)
response = yield read_response(self.client)
yield Return(response)
@_o
def proxy(req):
log.info("Systems are go")
client = ProxyingHttpClient()
headers = HttpHeaders()
for key, vals in req.requestHeaders.getAllRawHeaders():
for val in vals:
headers.add(key, val)
body = req.content.getvalue()
log.info("proxying localhost (%s %s) to %s", req.method, req.uri, PROXY)
try:
yield client.connect(PROXY['host'], PROXY['port'])
except Exception:
content = ("""<div style="font-size: 30px; text-align: center">"""
""" Couldn't contact Sauce Connect.</div>""")
yield Return(200, {}, content)
log.debug("HOST: %s", headers['host'])
log.debug("URL: %s", req.uri)
log.debug("TOGETHER: %s%s" % (headers['host'], req.uri))
urldict = urlsplit(req.uri)
scheme_and_host = "%s://%s" % (urldict.scheme, headers['host'])
corrected_url = urljoin(scheme_and_host, req.uri)
log.debug("Turned %s into %s" % (req.uri, corrected_url))
resp = yield client.request(corrected_url,
method=req.method,
headers=headers,
body=body)
log.info("response from tunnel for localhost proxy: %s", resp.code)
yield Return(int(resp.code), resp.headers, resp.body)
def main():
ch = logging.StreamHandler(sys.stdout)
ch.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
log.addHandler(ch)
log.setLevel("INFO")
mlog.addHandler(ch)
mlog.setLevel("INFO")
log.info("Proxying to %s on %s" % (PROXY["host"], PROXY["port"]))
for port in PORTS:
try:
if monocle.VERSION < '0.26':
log.debug("Adding port %s", port)
add_service(HttpServer(proxy, port))
else:
log.debug("Adding port %s", port)
add_service(HttpServer(port, proxy))
except Exception:
log.exception("Failed to listen on port %s, skipping", port)
main()
eventloop.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment