You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python HTTPS代理(ssl+socket)开发遇400错误求助

排查HTTPS代理400 Bad Request错误的核心要点

1. 未正确处理CONNECT方法

HTTPS代理的核心逻辑是先处理客户端发送的CONNECT请求,建立TCP隧道后再转发加密流量。如果你的Server.py未针对性处理该方法,直接按普通HTTP请求解析,必然返回400错误。

需确认代码包含以下逻辑:

  • 解析请求行,判断请求方法是否为CONNECT
  • 对合法的CONNECT请求返回HTTP/1.1 200 Connection Established响应
  • 完成TCP握手后,在客户端与目标服务器之间建立双向数据转发

核心代码示例:

def handle_client(client_socket):
    raw_request = client_socket.recv(1024)
    if not raw_request:
        client_socket.close()
        return
    request_line = raw_request.split(b'\r\n')[0].decode()
    method = request_line.split()[0]
    
    if method == 'CONNECT':
        # 提取目标主机与端口
        target_addr = request_line.split()[1]
        host, port = target_addr.split(':') if ':' in target_addr else (target_addr, 443)
        port = int(port)
        
        # 连接目标服务器
        try:
            server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            server_socket.connect((host, port))
        except Exception as e:
            client_socket.send(b'HTTP/1.1 503 Service Unavailable\r\n\r\n')
            client_socket.close()
            return
        
        # 返回隧道建立成功响应
        client_socket.send(b'HTTP/1.1 200 Connection Established\r\n\r\n')
        
        # 双向转发加密流量
        try:
            while True:
                # 从客户端读数据发往服务器
                client_data = client_socket.recv(4096)
                if not client_data:
                    break
                server_socket.sendall(client_data)
                
                # 从服务器读数据发往客户端
                server_data = server_socket.recv(4096)
                if not server_data:
                    break
                client_socket.sendall(server_data)
        finally:
            server_socket.close()
            client_socket.close()
        return
    
    # 处理普通HTTP请求的逻辑...

2. 请求解析逻辑缺陷

若CONNECT请求的解析逻辑存在问题,比如未兼容不同换行符(\r\n/\n)、未处理端口缺失场景(默认443),会导致服务器无法识别目标地址,返回400错误。需确保:

  • 基于原始字节流拆分请求行,避免编码错误
  • 兜底处理端口缺失的情况
  • 不要尝试解析CONNECT请求的头部或body,隧道建立后均为加密流量

3. 响应格式不规范

返回200 Connection Established时必须严格遵循HTTP协议:

  • 状态行后必须跟两个连续的\r\n(即b'HTTP/1.1 200 Connection Established\r\n\r\n')
  • 禁止添加额外响应头或内容,否则客户端会判定响应不合法

4. 数据转发逻辑阻塞

隧道建立后需同时监听客户端与服务器的数据流,不能仅单向转发。建议用多线程或select模块实现非阻塞双向通信,避免一方数据流中断导致连接异常。

调试步骤建议

  • 在Server.py中添加日志,打印收到的原始请求字节流,确认是否为合法的CONNECT请求
  • 用curl手动测试:curl -x http://localhost:代理端口 https://www.example.com -v,查看完整请求与响应流程
  • 检查防火墙规则与端口占用,确保代理端口及目标HTTPS端口(443)可正常访问

内容的提问来源于stack exchange,提问作者Augustin Mons

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 03:57:08