CURLOPT_PROXYTYPE参数差异与CURLPROXY_HTTPS作用疑问
CURLPROXY_HTTP与CURLPROXY_HTTPS的核心差异说明
PHP手册未提及CURLPROXY_HTTPS的原因
- PHP的curl扩展是对底层libcurl库的薄封装,扩展内可用的常量、能力完全匹配运行环境中实际链接的libcurl版本,PHP手册的参数列表长期没有同步libcurl的版本更新:
CURLPROXY_HTTPS是libcurl 7.52.0版本才新增的选项,仅在编译时对接了OpenSSL、GnuTLS、NSS其中任意一个TLS库的libcurl版本中可用,低版本libcurl不存在这个定义- 实际可用性可以直接在PHP环境中执行验证:
var_dump(defined('CURLPROXY_HTTPS')),只要环境libcurl版本满足要求,这个常量可以直接使用,不受手册未标注的影响
设置为CURLPROXY_HTTP仍可正常使用代理访问HTTPS站点的原因
- 这里存在一个非常普遍的概念混淆,需要先拆分两段完全独立的链路:
- 客户端到代理服务器的连接链路:指你本地程序和代理服务之间的传输用什么协议、是否加密
- 代理服务器到目标站点的连接链路:指代理帮你转发请求时,和目标站点之间的传输用什么协议
你遇到的情况,本质是用了「支持转发HTTPS站点请求的HTTP代理」,而非「本身需要HTTPS连接的HTTPS代理」
- 当
CURLOPT_PROXYTYPE设置为CURLPROXY_HTTP时,你本地到代理的链路永远是明文HTTP:- 访问HTTP站点时,客户端直接把完整HTTP请求发给代理,由代理明文转发给目标站
- 访问HTTPS站点时,客户端先向代理发送明文的
CONNECT请求,要求和目标站建立隧道,隧道打通后客户端和目标站直接走TLS加密传输,但你和代理之间的CONNECT协商过程是明文的,中间链路可以直接获取你要访问的目标域名,也可以篡改你和代理之间的协商内容
CURLPROXY_HTTPS的实际作用
- 这个选项的唯一作用,是把客户端到代理服务器本身的连接切换为TLS加密的HTTPS协议,也就是常说的加密上游代理:
- 开启后,你和代理之间的所有通信(包括CONNECT协商、所有转发的请求内容)全程走TLS加密,运营商、中间链路设备无法窃听你和代理之间的传输内容,也无法篡改发往代理的请求
- 这个选项和你访问的目标站点是HTTP还是HTTPS没有任何关联:哪怕你访问的是普通HTTP站点,只要设置了
CURLPROXY_HTTPS,你到代理的这段链路始终是加密的
- 如果你使用的代理本身要求必须用HTTPS连接(比如部分企业内网加密代理、隐私向公共加密代理),用
CURLPROXY_HTTP模式连接要么直接握手失败,要么会被代理强制降级,无法实现端到代理段的加密。你之前能正常连接,只是因为你用的代理本身就开放了明文HTTP接入端口,不属于需要CURLPROXY_HTTPS才能对接的HTTPS代理。
可以用下面的代码快速验证当前环境对该选项的支持情况:
var_dump( 'PHP版本' => PHP_VERSION, 'libcurl版本' => curl_version()['version'], 'CURLPROXY_HTTPS是否可用' => defined('CURLPROXY_HTTPS') );
内容的提问来源于stack exchange,提问作者Homer
相关产品推荐
相关产品推荐

