【发布时间】:2021-09-29 12:47:26
【问题描述】:
好的,伙计们,我会尽量让这个问题尽可能简单(我这几天都在努力发现这个问题):
我有这个功能
function readContent($url, $sessionId)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
$cookiesFile = realpath(__DIR__.'/cookies/'.$sessionId.'.txt');
if(file_exists($cookiesFile))
{
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookiesFile);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookiesFile);
}
//DEBUG------------------------------------------------------------------
$debugFile = fopen(__DIR__.'/debug/'.$sessionId.'.txt', 'w');
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_STDERR, $debugFile);
//-----------------------------------------------------------------------
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
try
{
$output = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if($httpCode == 200)
{
file_put_contents(__DIR__.'/contents/'.$sessionId.'.html', $output);
curl_close($ch);
preg_match_all('/<[\s]*meta[\s]*http-equiv="?REFRESH"?' . '[\s]*content="?[0-9]*;[\s]*URL[\s]*=[\s]*([^>"]*)"?' . '[\s]*[\/]?[\s]*>/si', $output, $match);
if (isset($match) && is_array($match) && count($match) == 2 && count($match[1]) == 1)
{
return readContent(str_replace('&', '&', $match[1][0]), $sessionId);
}
}
}
catch(Exception $e)
{
return false;
}
}
它执行 3 个请求(来自 STDERR 文件的日志):
GET /redacted/ HTTP/2
Host: redacted.coom
accept: */*
< HTTP/2 302
< location: https://redacted.com/location1/
* Added cookie redacted="redacted" for domain redacted.com, path /, expire 1634127679
< set-cookie: redacted=redacted; path=/; expires=Wed, 13 Oct 2021 12:21:19 GMT; SameSite=Lax
multiple set-cookie / added cookie follows...
所以第一个请求是在没有任何 cookie 的情况下完成的,但它在 COOKIEFILE/COOKIEJAR 中设置了多个 cookie。一旦 CURL 遵循请求应答中指定的位置,它就会发送所有 cookie 集:
* Ignoring the response-body
* Connection #0 to host redacted.com left intact
* Issue another request to this URL: 'https://redacted.com/location1/'
> GET /location1/ HTTP/2
Host: redacted.com
accept: */*
cookie: redacted=redacted;redacted=redacted;redacted=redacted......
< HTTP/2 200
第二个请求在 html 正文中返回 200 OK 和 META REFRESH。 正如您在函数中看到的,如果它使用 META REFRESH 正则表达式检测到 200,则该函数会自行调用在 META REFRESH 上传递 URL。它去第三个请求,但这一次,它只发送了 1 个 cookie
> GET /location1/?from_meta_refresh=1 HTTP/2
Host: redacted.com
accept: */*
cookie: redacted=redacted
这是对该页面的无效请求,因为它需要另一个已设置且位于 CURLOPT_COOKIEFILE 上但未发送的 cookie。 这个唯一发送的 cookie 是 COOKIEFILE 的最后一行。我认为这可能是 cookie 上的一些参数,例如域/文件夹/安全,但我注意到文件上有另一个 cookie,具有完全相同的参数,而不是在此请求中发送:
redacted.com FALSE / FALSE 1634128519 not_sent redacted
redacted.com FALSE / FALSE 1634128519 sent redacted
请帮忙!
【问题讨论】: