Cloudflare Flexible模式下Python反向代理无响应体报错求助
问题分析与解决方案
核心问题原因
Cloudflare Flexible模式下,访客与CF之间走HTTPS,CF与你的反向代理源站之间走HTTP。触发ConnectionResetError的关键原因包括:
- GET请求不必要地读取请求体,导致socket流读取异常
- 源站返回的响应头部存在冲突(比如
Transfer-Encoding与Content-Length同时存在),触发CF提前关闭连接 - 手动调用
flush()强制推送数据,破坏HTTP连接的缓冲机制,导致CF端连接被强制断开
具体修复步骤
移除GET请求的body读取逻辑
GET请求规范中通常不包含请求体,强行读取Content-Length对应的内容会引发socket流异常,直接删除相关代码:# 删除以下两行 content_length = int(self.headers.get('Content-Length', 0)) body = self.rfile.read(content_length) # 同时修改requests.get调用,去掉多余的data参数 response = requests.get(target_url, headers=headers, allow_redirects=False)清理冲突的响应头部
CF在Flex模式下会自动处理响应编码,需要移除源站返回的Transfer-Encoding头部,避免与Content-Length冲突:# Send the response back to the client self.send_response(response.status_code) for header, value in response.headers.items(): # 跳过Transfer-Encoding,交给CF处理编码转换 if header.lower() == 'transfer-encoding': continue print(header, " : ", value) self.send_header(header, value)移除手动flush操作
self.wfile.flush()会强制推送缓冲数据,但CF可能已在响应头返回后开始处理连接,强制flush会触发连接重置,直接删除该行即可。添加异常捕获(可选)
为避免单个请求的连接重置导致服务崩溃,在写入响应体时捕获异常:try: self.wfile.write(response.content) except ConnectionResetError: # 忽略CF主动关闭的连接 pass
完整修复后的do_GET方法
def do_GET(self, body=True): if not self.validate_request(): self.send_response(302) self.send_header("location", "https://innocuous.website") self.end_headers() return # Forward the request to another host and port target_host = hostname # Change this to your target host # Construct the URL for the target host target_url = f"http://{target_host}{self.path}" # Extract headers from the original request headers = {header: value for header, value in self.headers.items()} print(headers) # Forward the GET request using requests library try: response = requests.get(target_url, headers=headers, allow_redirects=False) except requests.exceptions.RequestException as e: self.send_error(500, str(e)) return # Send the response back to the client self.send_response(response.status_code) for header, value in response.headers.items(): if header.lower() == 'transfer-encoding': continue print(header, " : ", value) self.send_header(header, value) if self.new_cookie != '': self.send_header("Set-Cookie", "anticrawler_id=" + self.new_cookie) self.new_cookie = '' self.end_headers() try: self.wfile.write(response.content) except ConnectionResetError: pass
额外注意事项
- 确保反向代理服务监听CF允许的HTTP端口(如80、8080)
- 在CF控制台确认Flexible SSL模式已正确开启,域名解析指向CF分配的IP
- 避免在请求头中传递CF不兼容的自定义头部,比如
Connection: keep-alive可能会被CF自动修改
内容的提问来源于stack exchange,提问作者NickWade KamrenRobbin
相关产品推荐
相关产品推荐

