#!/usr/bin/env python3
import socket, threading, select, sys, time

LISTENING_ADDR = '0.0.0.0'
LISTENING_PORT = 80
BUFLEN = 4096 * 4
# Pointing to Dropbear Port 442
TARGET_HOST = '127.0.0.1'
TARGET_PORT = 442
RESPONSE = b'HTTP/1.1 101 Dexter Eskalarte\r\n\r\n'

class Server(threading.Thread):
    def __init__(self, host, port):
        super().__init__()
        self.host, self.port = host, port
        self.running = False
    def run(self):
        self.soc = socket.socket(socket.AF_INET)
        self.soc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        try:
            self.soc.bind((self.host, int(self.port)))
        except Exception as e:
            print(f"Error: Could not bind to port {self.port}: {e}")
            return
        self.soc.listen(100)
        self.running = True
        while self.running:
            try:
                c, addr = self.soc.accept()
                ConnectionHandler(c, addr).start()
            except: pass
    def close(self): 
        self.running = False
        self.soc.close()

class ConnectionHandler(threading.Thread):
    def __init__(self, client, addr):
        super().__init__()
        self.client = client
        self.addr = addr
    def run(self):
        try:
            # Read the initial HTTP Request (the Upgrade request)
            data = self.client.recv(BUFLEN)
            if b'GET' in data or b'POST' in data or b'CONNECT' in data:
                self.target = socket.socket()
                self.target.connect((TARGET_HOST, TARGET_PORT))
                # Send the 101 response back to the VPN app
                self.client.sendall(RESPONSE)
                self.exchange_loop()
            else:
                self.client.close()
        except: 
            self.client.close()

    def exchange_loop(self):
        socs = [self.client, self.target]
        while True:
            try:
                r, _, _ = select.select(socs, [], [], 60)
                if not r: break
                for s in r:
                    data = s.recv(BUFLEN)
                    if not data: return
                    if s is self.client:
                        self.target.sendall(data)
                    else:
                        self.client.sendall(data)
            except: break
        self.target.close()

if __name__ == '__main__':
    print(f"Starting WebSocket Proxy on port {LISTENING_PORT}...")
    server = Server(LISTENING_ADDR, LISTENING_PORT)
    server.daemon = True
    server.start()
    while True:
        time.sleep(10)

