http-client无法使用https链接的proxy配置

Jason X

问题描述

这里详细描述问题
目前端点是https站点,proxy中配置https+账密鉴权,请求不到目标端点,是否http-client无法使用https的proxy呢

程序代码

$options = [
'method'          => 'GET',
'allow_redirects' => ['max' => 0],
'headers'         => array_filter(['User-Agent' => $userAgent]),
'success'         => function (HttpResponse $response) {
$statusCode = $response->getStatusCode();
$body = $response->getBody();
//成功回调逻辑
},
'error'           => function (\Throwable $e) {
//失败回调逻辑
$this->log('error', "异常: {$e->getMessage()}");
},
];

$proxy = $this->getProxy();//拼接代理username、密码信息,https链接格式
$this->log('debug', "proxy=" . ($proxy ?: '(none)') . " country=" . ($this->mainTask->country ?? '(empty)'));
if (!empty($proxy)) {
$options['proxy'] = $proxy;
//$options['context']['http']['proxy'] = $proxy;
}

$this->httpClient->request($url, $options);

报错信息

异常: The connection to xx.xx.xx.xx has been closed

操作系统及workerman/webman等框架组件具体版本

这里写具体的系统环境相关信息
依赖版本信息,没开协程:
"require": {
"php": ">=8.1",
"workerman/webman-framework": "~v2.1",
"monolog/monolog": "^2.0",
"webman/console": "^2.2",
"webman/database": "^2.1",
"illuminate/pagination": "^10.49",
"illuminate/events": "^10.49",
"symfony/var-dumper": "^6.4",
"webman/redis": "^2.1",
"workerman/crontab": "^1.0",
"webman/redis-queue": "^1.3",
"workerman/workerman": "~v5.1",
"revolt/event-loop": "^1.0",
"workerman/http-client": "^3.0",
"vlucas/phpdotenv": "^5.6"
}

51 1 0
1个回答

Jason X

已破案:
● 问题非常清楚了。关键日志:

proxyHttp=xxx.com:58688 but address=aa.bb.cc.dd:58688 - NOT MATCHING, CONNECT skipped!

根因:AsyncTcpConnection::checkConnection 中用 stream_socket_get_name($this->socket, true) 获取到的是代理服务器的解析后 IP 地址 aa.bb.cc.dd:58688,而 proxyHttp 存的是域名 xxx.com:58688。两者字符串不匹配,导致 CONNECT 隧道请求被跳过。

连接直接在代理服务器上尝试 SSL 握手,代理不理解就直接关闭了连接。

修复方案:在 ProxyHelper::setConnectionProxy 中将域名解析为 IP 存入 proxyHttp,或者反过来在 checkConnection 中做更智能的比较。最干净的方式是在 setConnectionProxy 里用 IP,因为 stream_socket_get_name 总是返回 IP。

  • 暂无评论
🔝