From cfc009f60d677cfc98b895b5d41b76f9f6924ba1 Mon Sep 17 00:00:00 2001 From: cheney Date: Mon, 25 May 2026 10:28:57 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=20proxy=20=E6=96=B9=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- proxy/proxy_client.py | 183 ++++++++++++++++++++++++++++++----------- proxy/proxy_manager.py | 112 ------------------------- proxy/proxy_server.py | 172 +++++++++++++++++++++++--------------- 3 files changed, 238 insertions(+), 229 deletions(-) delete mode 100644 proxy/proxy_manager.py diff --git a/proxy/proxy_client.py b/proxy/proxy_client.py index c3630a3..4a39c26 100644 --- a/proxy/proxy_client.py +++ b/proxy/proxy_client.py @@ -1,80 +1,163 @@ +# -*- coding: utf-8 -*- import socket import threading import sys -TARGET_HOST = 'superstar.geelytravel.com' -TARGET_PORT = 443 - -def handle_request(sock): - """处理从A设备收到的请求,转发到目标网站""" +def tunnel_thread(src, dst): + """Tunnel thread: continuously forward data""" try: - # 接收来自A设备的请求 - request = b"" while True: - data = sock.recv(4096) + data = src.recv(8192) if not data: break - request += data - if b"\r\n\r\n" in request: - break - - if not request: - return - - # 连接到目标网站 - target_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - target_sock.connect((TARGET_HOST, TARGET_PORT)) - - # 发送请求 - target_sock.send(request) - - # 接收响应并转发回A设备 - while True: - response = target_sock.recv(4096) - if not response: - break - sock.send(response) - - target_sock.close() + dst.sendall(data) except Exception as e: - print(f"处理请求出错: {e}") - try: - sock.send(b"HTTP/1.1 500 Internal Server Error\r\n\r\n") - except: - pass + pass -def connect_to_a_device(a_host, a_port): - """连接到A设备""" +def handle_b_device(sock): + """Handle communication with device B, establish tunnel to target website""" + print("\n[System] Connected to device B") + + try: + while True: + request = b"" + while True: + chunk = sock.recv(8192) + if not chunk: + print("[Device B] Disconnected") + return + request += chunk + if b"\r\n\r\n" in request: + break + + print("[System] Received request:", len(request), "bytes") + + target_host = None + target_port = 443 + + if request.startswith(b"CONNECT"): + try: + lines = request.decode().split("\r\n") + connect_line = lines[0] + target = connect_line.split()[1] + if ':' in target: + target_host, port_str = target.split(':') + target_port = int(port_str) + else: + target_host = target + target_port = 443 + except Exception as e: + print("[Error] Failed to parse CONNECT request:", e) + sock.send(b"HTTP/1.1 400 Bad Request\r\n\r\n") + continue + else: + try: + for line in request.split(b"\r\n"): + if line.lower().startswith(b"host:"): + host_part = line[5:].strip() + if b':' in host_part: + target_host, port_str = host_part.split(b':') + target_port = int(port_str) + else: + target_host = host_part.decode() + break + except Exception as e: + print("[Error] Failed to parse HTTP request:", e) + sock.send(b"HTTP/1.1 400 Bad Request\r\n\r\n") + continue + + if not target_host: + sock.send(b"HTTP/1.1 400 Bad Request\r\n\r\n") + continue + + print("[Target] Host:", target_host, "Port:", target_port) + + target_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + target_sock.settimeout(30) + + try: + target_sock.connect((target_host, target_port)) + print("[Target] Connected successfully") + + if request.startswith(b"CONNECT"): + sock.send(b"HTTP/1.1 200 Connection Established\r\n\r\n") + else: + target_sock.sendall(request) + + t1 = threading.Thread(target=tunnel_thread, args=(sock, target_sock)) + t2 = threading.Thread(target=tunnel_thread, args=(target_sock, sock)) + t1.start() + t2.start() + t1.join() + t2.join() + + except ConnectionRefusedError: + print("[Error] Cannot connect to target:", target_host, target_port) + error_msg = "HTTP/1.1 503 Service Unavailable\r\nContent-Type: text/plain\r\n\r\nCannot connect to " + target_host + ":" + str(target_port) + sock.send(error_msg.encode()) + except socket.timeout: + print("[Error] Connection timeout") + sock.send(b"HTTP/1.1 504 Gateway Timeout\r\n\r\n") + except Exception as e: + print("[Error] Failed to connect to target:", e) + error_msg = "HTTP/1.1 500 Internal Server Error\r\nContent-Type: text/plain\r\n\r\n" + str(e) + sock.send(error_msg.encode()) + finally: + target_sock.close() + + except ConnectionResetError: + print("[Device B] Connection forcibly closed") + except Exception as e: + print("[Error] Communication error with device B:", e) + finally: + sock.close() + +def connect_to_b_device(b_host, b_port): + """Connect to device B""" while True: try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sock.connect((a_host, a_port)) - print(f"成功连接到A设备: {a_host}:{a_port}") - print(f"准备转发请求到: {TARGET_HOST}:{TARGET_PORT}") + sock.settimeout(10) + sock.connect((b_host, b_port)) + sock.settimeout(None) - handle_request(sock) + print("\n[System] Successfully connected to device B:", b_host, ":", b_port) + + handle_b_device(sock) - sock.close() - print("与A设备的连接已断开") except ConnectionRefusedError: - print(f"A设备未就绪,重试中...") + print("[System] Device B not ready (", b_host, ":", b_port, "), retrying in 3 seconds...") + import time + time.sleep(3) + except socket.timeout: + print("[System] Connection timeout, retrying in 3 seconds...") import time time.sleep(3) except Exception as e: - print(f"连接出错: {e}") + print("[Error] Connection error:", e) import time time.sleep(3) def main(): if len(sys.argv) < 3: - print("用法: python proxy_client.py ") - print("示例: python proxy_client.py 192.168.1.50 8080") + print("=" * 60) + print(" Proxy Client (Run on Computer A)") + print("=" * 60) + print("Usage: python proxy_client.py ") + print("Example: python proxy_client.py 192.168.1.100 8080") + print("=" * 60) sys.exit(1) - a_host = sys.argv[1] - a_port = int(sys.argv[2]) + b_host = sys.argv[1] + b_port = int(sys.argv[2]) - connect_to_a_device(a_host, a_port) + print("=" * 60) + print(" Proxy Client (Run on Computer A)") + print("=" * 60) + print("Device B address:", b_host, ":", b_port) + print("=" * 60) + + connect_to_b_device(b_host, b_port) if __name__ == '__main__': main() diff --git a/proxy/proxy_manager.py b/proxy/proxy_manager.py deleted file mode 100644 index 4f151f1..0000000 --- a/proxy/proxy_manager.py +++ /dev/null @@ -1,112 +0,0 @@ -import sys -import winreg - -def get_current_proxy(): - """获取当前系统代理设置""" - try: - internet_settings = winreg.OpenKey( - winreg.HKEY_CURRENT_USER, - r'Software\Microsoft\Windows\CurrentVersion\Internet Settings', - 0, - winreg.KEY_READ - ) - proxy_server, _ = winreg.QueryValueEx(internet_settings, 'ProxyServer') - proxy_enable, _ = winreg.QueryValueEx(internet_settings, 'ProxyEnable') - winreg.CloseKey(internet_settings) - return { - 'enabled': bool(proxy_enable), - 'server': proxy_server - } - except FileNotFoundError: - return {'enabled': False, 'server': ''} - except Exception as e: - print(f"获取代理设置失败: {e}") - return {'enabled': False, 'server': ''} - -def set_proxy(proxy_host, proxy_port): - """设置系统代理""" - try: - internet_settings = winreg.OpenKey( - winreg.HKEY_CURRENT_USER, - r'Software\Microsoft\Windows\CurrentVersion\Internet Settings', - 0, - winreg.KEY_ALL_ACCESS - ) - - proxy_server = f'{proxy_host}:{proxy_port}' - winreg.SetValueEx(internet_settings, 'ProxyServer', 0, winreg.REG_SZ, proxy_server) - winreg.SetValueEx(internet_settings, 'ProxyEnable', 0, winreg.REG_DWORD, 1) - winreg.CloseKey(internet_settings) - - print(f"✅ 系统代理已设置为: {proxy_server}") - return True - except Exception as e: - print(f"❌ 设置代理失败: {e}") - return False - -def unset_proxy(): - """取消系统代理""" - try: - internet_settings = winreg.OpenKey( - winreg.HKEY_CURRENT_USER, - r'Software\Microsoft\Windows\CurrentVersion\Internet Settings', - 0, - winreg.KEY_ALL_ACCESS - ) - - winreg.SetValueEx(internet_settings, 'ProxyEnable', 0, winreg.REG_DWORD, 0) - winreg.CloseKey(internet_settings) - - print("✅ 系统代理已取消") - return True - except Exception as e: - print(f"❌ 取消代理失败: {e}") - return False - -def show_status(): - """显示当前代理状态""" - proxy = get_current_proxy() - print("\n当前代理状态:") - print(f" 代理已启用: {'是' if proxy['enabled'] else '否'}") - if proxy['enabled']: - print(f" 代理服务器: {proxy['server']}") - print() - -def main(): - if len(sys.argv) < 2: - print("=" * 50) - print(" Windows系统代理管理脚本") - print("=" * 50) - print("用法:") - print(f" {sys.argv[0]} status - 查看当前代理状态") - print(f" {sys.argv[0]} set - 设置代理服务器") - print(f" {sys.argv[0]} unset - 取消代理设置") - print(f" {sys.argv[0]} localhost - 快速设置为 localhost:8080") - print("\n示例:") - print(f" {sys.argv[0]} set 192.168.1.50 8080") - print(f" {sys.argv[0]} localhost") - print(f" {sys.argv[0]} unset") - print("=" * 50) - return - - command = sys.argv[1].lower() - - if command == 'status': - show_status() - elif command == 'set': - if len(sys.argv) < 4: - print("❌ 参数不足,请提供代理服务器地址和端口") - print(f" 示例: {sys.argv[0]} set 192.168.1.50 8080") - return - proxy_host = sys.argv[2] - proxy_port = sys.argv[3] - set_proxy(proxy_host, proxy_port) - elif command == 'unset': - unset_proxy() - elif command == 'localhost': - set_proxy('localhost', '8080') - else: - print(f"❌ 未知命令: {command}") - -if __name__ == '__main__': - main() diff --git a/proxy/proxy_server.py b/proxy/proxy_server.py index e232a11..4d15324 100644 --- a/proxy/proxy_server.py +++ b/proxy/proxy_server.py @@ -1,86 +1,124 @@ +# -*- coding: utf-8 -*- import socket import threading -import select +import sys -TARGET_HOST = 'superstar.geelytravel.com' -TARGET_PORT = 443 -LISTEN_PORT = 8080 +PORT_FOR_A = 8080 # Port for device A to connect +PORT_FOR_BROWSER = 8081 # Port for browser to connect -b_device_socket = None -client_socket = None +a_device_socket = None +a_device_lock = threading.Lock() -def handle_b_device(conn): - """处理B设备的连接""" - global b_device_socket - b_device_socket = conn - print(f"B设备已连接: {conn.getpeername()}") +def tunnel_thread(src, dst): + """Tunnel thread: continuously forward data""" + try: + while True: + data = src.recv(8192) + if not data: + break + dst.sendall(data) + except Exception as e: + pass + finally: + try: + src.close() + except: + pass + try: + dst.close() + except: + pass + +def handle_browser(conn, addr): + """Handle browser connection, establish tunnel with device A""" + global a_device_socket + + print("\n[Browser] Connected from:", addr) + + with a_device_lock: + if not a_device_socket: + conn.send(b"HTTP/1.1 503 Service Unavailable\r\nContent-Type: text/plain\r\n\r\nDevice A not connected") + conn.close() + print("[Browser] Disconnected (Device A not connected):", addr) + return + + t1 = threading.Thread(target=tunnel_thread, args=(conn, a_device_socket)) + t2 = threading.Thread(target=tunnel_thread, args=(a_device_socket, conn)) + t1.start() + t2.start() + + print("[System] Tunnel established between browser and device A") + +def handle_a_device(conn): + """Handle device A connection""" + global a_device_socket + + with a_device_lock: + if a_device_socket: + conn.send(b"ERROR: Another A device is already connected") + conn.close() + return + a_device_socket = conn + + print("\n[Device A] Connected:", conn.getpeername()) try: while True: - data = conn.recv(4096) + data = conn.recv(1) if not data: - print("B设备断开连接") - b_device_socket = None break - - if client_socket: - try: - client_socket.send(data) - except: - pass - except Exception as e: - print(f"B设备连接出错: {e}") - b_device_socket = None + except: + pass + finally: + with a_device_lock: + a_device_socket = None + conn.close() + print("[Device A] Disconnected") -def handle_client(conn): - """处理用户请求""" - global client_socket - client_socket = conn - print(f"用户连接: {conn.getpeername()}") - - try: - while True: - data = conn.recv(4096) - if not data: - print("用户断开连接") - client_socket = None - break - - if b_device_socket: - try: - b_device_socket.send(data) - except: - conn.send(b"HTTP/1.1 503 Service Unavailable\r\n\r\nDevice B not connected") - break - else: - conn.send(b"HTTP/1.1 503 Service Unavailable\r\n\r\nDevice B not connected") - break - except Exception as e: - print(f"用户连接出错: {e}") - client_socket = None - -def run_server(): +def run_browser_server(): + """Start browser listening port""" server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - server.bind(('0.0.0.0', LISTEN_PORT)) - server.listen(5) + server.bind(('0.0.0.0', PORT_FOR_BROWSER)) + server.listen(10) - print(f"A设备代理服务器已启动,监听端口 {LISTEN_PORT}") - print(f"等待B设备连接和用户请求...") + print("[System] Browser proxy port started, listening on 0.0.0.0:", PORT_FOR_BROWSER) while True: conn, addr = server.accept() - print(f"新连接: {addr}") - - # 判断是B设备还是用户(简单判断:先连接的是B设备) - if b_device_socket is None: - # 第一个连接作为B设备 - t = threading.Thread(target=handle_b_device, args=(conn,)) - t.start() - else: - # 后续连接作为用户 - t = threading.Thread(target=handle_client, args=(conn,)) - t.start() + t = threading.Thread(target=handle_browser, args=(conn, addr)) + t.start() + +def run_a_device_server(): + """Start device A connection port""" + server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + server.bind(('0.0.0.0', PORT_FOR_A)) + server.listen(1) + + print("[System] Device A port started, listening on 0.0.0.0:", PORT_FOR_A) + + while True: + conn, addr = server.accept() + t = threading.Thread(target=handle_a_device, args=(conn,)) + t.start() + +def main(): + print("=" * 60) + print(" Proxy Server (Run on Computer B)") + print("=" * 60) + print("Device A connection port:", PORT_FOR_A) + print("Browser access port:", PORT_FOR_BROWSER) + print("=" * 60) + print("Waiting for connections...\n") + + t1 = threading.Thread(target=run_a_device_server) + t2 = threading.Thread(target=run_browser_server) + t1.start() + t2.start() + + t1.join() + t2.join() if __name__ == '__main__': - run_server() + main()