PHP + Curl:协商验证时关闭连接(HTTP 1.0?)
PHP + Curl: Connection closure while negotiation auth (HTTP 1.0?)
我在 CURL 和 PHP 之间有问题。我尝试通过 EWS 连接到 Exchange 2010 服务器。与服务器的连接在使用 CURL 的命令行中工作正常,但不能使用 PHP Curl 扩展名。
我附上了一张带有调试信息的图片。在左侧您可以看到命令行输出,在右侧可以看到 PHP 详细输出。当 PHP Curl Extension 抛出错误 "Connection closure while negotiation auth (HTTP 1.0?)" 时,命令行继续执行第三个 HTTP 请求,结果为 HTTP/1.1 302 Found:
一些附加信息:
- 我将此库用于 CURL 请求:https://github.com/jamesiarmes/php-ntlm/blob/master/src/SoapClient.php
- 我们有大约 80 个没有问题的交换服务器。仅此服务器存在问题。我们的客户讲述了一个名为 "Sophos" 的软件用作网络服务器
的代理
- CURLOPT_HTTPAUTH 是 CURLAUTH_NTLM
- PHP 版本 7.3.1 / 7.3.9 也经过测试
- cURL 信息 7.63.0 / 7.52.1 也经过测试
有人知道为什么 PHP Curl Extension 在第三次请求之前关闭连接吗?这是扩展的错误吗,我可以使用常量 PHP Curl 来避免这种情况,还是有其他解决方案?
连接已关闭,因为服务器这样说。查看您的屏幕截图,"What is the problem here?" 点上方的一行。
HTTP/1.1 401 Unauthorized
[...]
Connection: close
Content-Type: application/x-asmx
然后服务器可能会关闭连接。
所以这不是一个动作,而是一个结果。消息在 Curl_http_readwrite_headers
:
中发出
#if defined(USE_NTLM)
if(conn->bits.close &&
(((data->req.httpcode == 401) &&
(conn->http_ntlm_state == NTLMSTATE_TYPE2)) ||
((data->req.httpcode == 407) &&
(conn->proxy_ntlm_state == NTLMSTATE_TYPE2)))) {
infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n");
data->state.authproblem = TRUE;
}
#endif
#if defined(USE_SPNEGO)
if(conn->bits.close &&
(((data->req.httpcode == 401) &&
(conn->http_negotiate_state == GSS_AUTHRECV)) ||
((data->req.httpcode == 407) &&
(conn->proxy_negotiate_state == GSS_AUTHRECV)))) {
infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n");
data->state.authproblem = TRUE;
}
大概是从第一个块 (NTLM) 开始的,但这是两次出现,而且它们彼此相邻。
有趣的事实:相同的函数仅 a lot later 检查是否存在 Connection: close
header,因此设置神秘标志 conn->bits.close
可能意味着服务器已经断开连接并在 socket-level.
上检测到
旁注:比较的两侧显示出非常不同的相互作用。左边有一个几乎空的 GET
请求(提供了 Host
、Authorization
、User-Agent
和 Accept
header),而在右侧有很多更复杂的 POST
请求(相同的 headers 加上 Method
、SOAPAction
、空内容 Expect
用于继续)。
我在使用 SoapClient 时遇到过这样的问题
和 Microsoft Exchange 2010 Server,诀窍是更改 header 数组选项 'Expect: 100-continue'
至 'Expect: 200-ok'
protected function buildHeaders($action)
{
return array(
'Method: POST',
'Connection: Keep-Alive',
'User-Agent: PHP-SOAP-CURL',
'Content-Type: text/xml; charset=utf-8',
"SOAPAction: \"$action\"",
'Expect: 200-ok',
);
}
100(继续)状态代码表示已收到请求的初始部分,尚未被服务器拒绝。
200(OK)状态码表示请求成功。成功的含义因 HTTP 方法而异。
你也可以看看这个HTTP status codes
我希望这能有所帮助
我在 CURL 和 PHP 之间有问题。我尝试通过 EWS 连接到 Exchange 2010 服务器。与服务器的连接在使用 CURL 的命令行中工作正常,但不能使用 PHP Curl 扩展名。
我附上了一张带有调试信息的图片。在左侧您可以看到命令行输出,在右侧可以看到 PHP 详细输出。当 PHP Curl Extension 抛出错误 "Connection closure while negotiation auth (HTTP 1.0?)" 时,命令行继续执行第三个 HTTP 请求,结果为 HTTP/1.1 302 Found:
一些附加信息:
- 我将此库用于 CURL 请求:https://github.com/jamesiarmes/php-ntlm/blob/master/src/SoapClient.php
- 我们有大约 80 个没有问题的交换服务器。仅此服务器存在问题。我们的客户讲述了一个名为 "Sophos" 的软件用作网络服务器 的代理
- CURLOPT_HTTPAUTH 是 CURLAUTH_NTLM
- PHP 版本 7.3.1 / 7.3.9 也经过测试
- cURL 信息 7.63.0 / 7.52.1 也经过测试
有人知道为什么 PHP Curl Extension 在第三次请求之前关闭连接吗?这是扩展的错误吗,我可以使用常量 PHP Curl 来避免这种情况,还是有其他解决方案?
连接已关闭,因为服务器这样说。查看您的屏幕截图,"What is the problem here?" 点上方的一行。
HTTP/1.1 401 Unauthorized [...] Connection: close Content-Type: application/x-asmx
然后服务器可能会关闭连接。
所以这不是一个动作,而是一个结果。消息在 Curl_http_readwrite_headers
:
#if defined(USE_NTLM)
if(conn->bits.close &&
(((data->req.httpcode == 401) &&
(conn->http_ntlm_state == NTLMSTATE_TYPE2)) ||
((data->req.httpcode == 407) &&
(conn->proxy_ntlm_state == NTLMSTATE_TYPE2)))) {
infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n");
data->state.authproblem = TRUE;
}
#endif
#if defined(USE_SPNEGO)
if(conn->bits.close &&
(((data->req.httpcode == 401) &&
(conn->http_negotiate_state == GSS_AUTHRECV)) ||
((data->req.httpcode == 407) &&
(conn->proxy_negotiate_state == GSS_AUTHRECV)))) {
infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n");
data->state.authproblem = TRUE;
}
大概是从第一个块 (NTLM) 开始的,但这是两次出现,而且它们彼此相邻。
有趣的事实:相同的函数仅 a lot later 检查是否存在 Connection: close
header,因此设置神秘标志 conn->bits.close
可能意味着服务器已经断开连接并在 socket-level.
旁注:比较的两侧显示出非常不同的相互作用。左边有一个几乎空的 GET
请求(提供了 Host
、Authorization
、User-Agent
和 Accept
header),而在右侧有很多更复杂的 POST
请求(相同的 headers 加上 Method
、SOAPAction
、空内容 Expect
用于继续)。
我在使用 SoapClient 时遇到过这样的问题 和 Microsoft Exchange 2010 Server,诀窍是更改 header 数组选项 'Expect: 100-continue' 至 'Expect: 200-ok'
protected function buildHeaders($action)
{
return array(
'Method: POST',
'Connection: Keep-Alive',
'User-Agent: PHP-SOAP-CURL',
'Content-Type: text/xml; charset=utf-8',
"SOAPAction: \"$action\"",
'Expect: 200-ok',
);
}
100(继续)状态代码表示已收到请求的初始部分,尚未被服务器拒绝。
200(OK)状态码表示请求成功。成功的含义因 HTTP 方法而异。
你也可以看看这个HTTP status codes
我希望这能有所帮助