用 Requests 的 HTTPAdapter.proxy_headers 设置代理请求头
扩展 HTTPAdapter.proxy_headers 以添加代理自定义字段,同时保留 Requests 现有的代理认证头生成逻辑。
对于由代理运营方定义的请求头,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 中属于代理专用,并不等于代理继续转发时仍有保密保证。