对于由代理运营方定义的请求头,Requests 提供了 HTTPAdapter.proxy_headers 作为重写入口:

from urllib.parse import urlsplit
import requests
from requests.adapters import HTTPAdapter

class TaggedProxy(HTTPAdapter):
    def proxy_headers(self, proxy):
        headers = super().proxy_headers(proxy)
        endpoint = urlsplit(proxy)
        if (endpoint.scheme == 'http'
                and endpoint.hostname == 'proxy.example'
                and endpoint.port == 8080):
            headers['X-Proxy-Account'] = 'department-a'
        return headers

with requests.Session() as session:
    adapter = TaggedProxy()
    session.mount('http://', adapter)
    session.mount('https://', adapter)
    response = session.get(
        'https://service.example/data',
        proxies={'https': 'http://proxy.example:8080'},
        timeout=15,
    )

X-Proxy-Account 只是这个特定代理能理解的字段示例,并不是面向所有中间环节的通用认证方式。

从 super().proxy_headers(proxy) 开始。当 URL 提供 Basic 账号时,Requests 用该方法生成 Proxy-Authorization。整体替换返回值可能会丢掉这一行为。

适配器会把这些值传给 urllib3 的 ProxyManager。在 HTTPS 隧道中,它们随 CONNECT 一起发送。普通的请求头映射描述的是之后发往目标站点的请求。

代理管理器按代理 URL 缓存。若某个值必须每次调用都变化,不要把此钩子当作按业务请求逐次触发的无缓存回调。账号标识变化时,应据此选择由谁持有传输层。

在普通 HTTP 转发中,代理字段仍需遵循中间环节预期的处理策略。请求头在客户端 API 中属于代理专用,并不等于代理继续转发时仍有保密保证。

相关文章