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

系统代理下curl请求未走本地服务器及HTTP Debugger抓包疑问

问题分析与解决方案

1. curl请求不经过代理的原因及解决

系统代理配置通常仅对GUI应用生效,curl等命令行工具默认不会读取系统代理,需手动指定:

  • 单次请求显式带代理参数:
    curl -x http://localhost:8089 https://example.com
    
  • 终端会话内全局设置代理环境变量:
    • Linux/macOS:
      export http_proxy=http://localhost:8089
      export https_proxy=http://localhost:8089
      
    • Windows CMD:
      set http_proxy=http://localhost:8089
      set https_proxy=http://localhost:8089
      

2. 部分请求返回无内容无效响应的原因及解决

你当前的代码只是普通FastAPI服务,仅做请求打印,没有实现代理转发逻辑。FastAPI对未匹配路由的请求会返回404空响应,同时也未处理HTTPS请求必需的CONNECT隧道建立逻辑。

修改后的代理服务器代码

先安装依赖:

pip install httpx

替换原有代码:

import uvicorn
from fastapi import FastAPI, Request, Response
import httpx

app = FastAPI()

# 处理HTTP请求转发
@app.middleware("http")
async def proxy_http(request: Request, call_next):
    # 保留FastAPI自带文档路由(不需要可删除)
    if request.url.path.startswith("/docs") or request.url.path.startswith("/redoc"):
        return await call_next(request)
    
    # 剥离代理服务器地址,构建目标URL
    target_url = str(request.url).replace(f"http://{request.url.hostname}:{request.url.port}", "")
    async with httpx.AsyncClient() as client:
        # 转发请求到目标服务器
        response = await client.request(
            method=request.method,
            url=target_url,
            headers=dict(request.headers),
            content=await request.body(),
            follow_redirects=False
        )
        
        # 返回目标服务器的响应
        return Response(
            content=response.content,
            status_code=response.status_code,
            headers=dict(response.headers)
        )

# 处理HTTPS请求的CONNECT隧道建立
@app.api_route("/", methods=["CONNECT"])
async def proxy_https(request: Request):
    target_host, target_port = request.url.netloc.split(":", 1)
    target_port = int(target_port) if target_port else 443
    
    # 验证并建立到目标服务器的隧道
    async with httpx.AsyncClient() as client:
        try:
            await client.get(f"https://{target_host}:{target_port}", timeout=5)
            return Response(content=b"", status_code=200, headers={"Connection": "keep-alive"})
        except Exception:
            return Response(content=b"Failed to connect to target", status_code=502)

if __name__ == "__main__":
    uvicorn.run("main:app", host="127.0.0.1", port=8089, log_level='critical')

代码说明

  • HTTP请求:通过httpx将客户端请求转发到目标服务器,再把目标服务器的响应原样返回给客户端。
  • HTTPS请求:处理CONNECT方法,建立客户端与目标服务器之间的隧道,让客户端能通过隧道发送加密的HTTPS请求。

内容的提问来源于stack exchange,提问作者1bura

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 23:55:14