import socket, threading, select, base64, json, re, sys """TCP proxy forwarder for authenticated upstream proxies. Usage: python tcp_forwarder.py [proxy_json_path] [local_port] - proxy_json_path: JSON file with proxy pool (default: C:/Users/User/tmp/bpproxy_live.json) - local_port: local port to listen on (default: 9129) The script picks the FIRST proxy from the pool. Edit UPSTREAM_HOST/UPSTREAM_PORT/AUTH directly if you want a specific proxy. Why TCP instead of HTTP-based: http.server.HTTPServer + BaseHTTPRequestHandler breaks CONNECT tunnels for Chrome. Chrome gets chrome-error://chromewebdata/ while curl works fine. Raw TCP relay handles CONNECT properly. """ # --- CONFIG --- DEFAULT_PROXY_POOL = r"C:\Users\User\tmp\bpproxy_live.json" LOCAL_PORT = int(sys.argv[2]) if len(sys.argv) > 2 else 9129 # Load proxy from pool pool_path = sys.argv[1] if len(sys.argv) > 1 else DEFAULT_PROXY_POOL pool = json.loads(open(pool_path).read()) proxy = pool[0]['url'] if isinstance(pool[0], dict) else pool[0] match = re.match(r'http://([^:]+):([^@]+)@([^:]+):(\d+)', proxy) user, password, host, port = match.groups() UPSTREAM_HOST = host UPSTREAM_PORT = int(port) AUTH = base64.b64encode(f'{user}:{password}'.encode()).decode() def handle_client(client_sock): try: data = b'' while b'\r\n\r\n' not in data: chunk = client_sock.recv(4096) if not chunk: return data += chunk request = data.decode('latin-1', errors='replace') first_line = request.split('\r\n')[0] method, target, _ = first_line.split(' ', 2) if method == 'CONNECT': host, port_str = target.rsplit(':', 1) port = int(port_str) remote = socket.create_connection((UPSTREAM_HOST, UPSTREAM_PORT), timeout=10) connect_req = ( f'CONNECT {host}:{port} HTTP/1.1\r\n' f'Host: {host}:{port}\r\n' f'Proxy-Authorization: Basic {AUTH}\r\n\r\n' ) remote.send(connect_req.encode()) resp = b'' while b'\r\n\r\n' not in resp: resp += remote.recv(4096) if b'200' not in resp.split(b'\r\n')[0]: client_sock.send(b'HTTP/1.1 502 Bad Gateway\r\n\r\n') remote.close() return client_sock.send(b'HTTP/1.1 200 Connection Established\r\n\r\n') _relay(client_sock, remote) else: remote = socket.create_connection((UPSTREAM_HOST, UPSTREAM_PORT), timeout=10) remote.send(data) _relay(client_sock, remote) except Exception: pass finally: try: client_sock.close() except Exception: pass def _relay(a, b): a.settimeout(30) b.settimeout(30) socks = [a, b] while True: r, _, _ = select.select(socks, [], [], 30) if not r: break for s in r: try: d = s.recv(8192) if not d: return dst = b if s is a else a dst.sendall(d) except Exception: return def main(): server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server.bind(('127.0.0.1', LOCAL_PORT)) server.listen(50) print(f'[*] TCP Proxy: 127.0.0.1:{LOCAL_PORT} -> {UPSTREAM_HOST}:{UPSTREAM_PORT}', flush=True) while True: client, addr = server.accept() t = threading.Thread(target=handle_client, args=(client,), daemon=True) t.start() if __name__ == '__main__': main()