Local HTTP Proxy Server – Bypass Host Regex Match – Multi Destination Client Connection

No usage documentation, however, posting this for historical purposes:

#ok:www.google.com:false
python3 proxy.py ~/.proxy.txt host:port
export https_proxy='http://127.0.0.1:9090'
import os, sys, re
import select, socket, socketserver


class proxysrv(socketserver.BaseRequestHandler):
    def init(self):
        self.size = (8 * 1024)
        self.file = sys.argv[1]
        self.info = sys.argv[2].split(":")
        self.host = (self.info[0], int(self.info[1]), True)
        self.sock = self.request

    def config(self, file):
        proxlist = []
        try:
            fobj = open(file, "r")
            for line in fobj.readlines():
                line = line.strip().split(":")
                stat = False
                if ("true" in line[2].lower()):
                    stat = True
                proxlist.append([line[0], line[1], stat])
        except:
            print("error","config")
        return proxlist

    def checks(self, conf, data):
        try:
            proxyreq = data.decode().split("\n")
            hostreqs = proxyreq[0].strip().split(" ")
            hostinfo = hostreqs[1].split(":")
            hostname = hostinfo[0]
            hostport = int(hostinfo[1])
            lasthost = ()
            for item in conf:
                regx = re.match("^.*%s$" % (item[1]), hostname)
                if ((item[0] == "no") and (not regx)):
                    lasthost = (hostname, hostport, item[2])
                if ((item[0] == "ok") and regx):
                    lasthost = (hostname, hostport, item[2])
            if (lasthost and (not lasthost[2])):
                return lasthost
        except:
            print("error","checks")
        return self.host

    def newcon(self, srcs, data, host):
        try:
            senddata = "HTTP/1.1 200 Connection established\r\nProxy-Connection: Keep-Alive\r\n\r\n".encode()
            sockobjc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sockobjc.connect((host[0], host[1]))
            if (host[2]):
                sockobjc.sendall(data)
            else:
                srcs.sendall(senddata)
            return sockobjc
        except:
            print("error","newcon")
        return None

    def relays(self, srcs, dsts):
        try:
            while True:
                (readlist, _, _) = select.select([srcs, dsts], [], [])
                for sockitem in readlist:
                    if (sockitem == dsts):
                        data = dsts.recv(self.size)
                        print("dsts",len(data))
                        if (not data):
                            raise
                        srcs.sendall(data)
                    if (sockitem == srcs):
                        data = srcs.recv(self.size)
                        print("srcs",len(data))
                        if (not data):
                            raise
                        dsts.sendall(data)
        except:
            pass

    def handle(self):
        self.init()

        proxlist = self.config(self.file)
        recvdata = self.sock.recv(self.size)
        desthost = self.checks(proxlist, recvdata)
        sockobjc = self.newcon(self.sock, recvdata, desthost)

        print("addr",self.client_address)
        print("data",recvdata)
        print("host",desthost)

        if (sockobjc):
            self.relays(self.sock, sockobjc)


if (__name__ == "__main__"):
    for e in ["http_proxy", "https_proxy", "no_proxy"]:
        for v in [e.upper(), e.lower()]:
            print("envr",v)
            os.environ[v] = ""

    sockobjc = socketserver.TCPServer(("127.0.0.1", 9090), proxysrv)
    sockobjc.serve_forever()

One thought on “Local HTTP Proxy Server – Bypass Host Regex Match – Multi Destination Client Connection

Leave a comment