У нас есть "устаревший" скрипт, который некоторое время назад перестал работать. Совершенно уверен, что это потому, что конечная точка, к которой он подключается, изменилась с http на https, а старый адрес http теперь возвращает 301.
Я никогда не делал ничего, кроме крошечных изменений в сценариях PHP, поэтому я немного из моей глубины здесь.
Обратите внимание, что наша версия PHP старая - 5.3.0. Это вполне может быть частью проблемы.
Скрипт как есть (в любом случае соответствующий бит):
$uri = "http://www.imf.org/external/np/fin/data/rms_mth.aspx"
."?SelectDate=$date&reportType=CVSDR&tsvflag=Y";
$opts = array('http' => array(
'proxy' => 'tcp://internal.proxy.address:port',
'method' => 'GET',
'request_fulluri' => true)
);
$ctx = stream_context_create($opts);
$lines = file($uri, false, $ctx);
foreach ($lines as $line)
...
Это больше ничего не возвращает. Эта ссылка, кстати, является ссылкой МВФ для обменных курсов, так что она открыта для всех - если вы откроете ее, вы получите загрузку с таблицей курсов. Остальная часть скрипта в основном анализирует это на предмет необходимых нам данных.
Теперь мы почти уверены, что наш прокси в порядке. Выполнение некоторых тестов с помощью curl дает следующие результаты:
curl --proxy tcp://internal.proxy.address:port -v https://www.imf.org/external/np/fin/data/rms_mth.aspx?SelectDate=05/28/2020&reportType=CVSDR&tsvflag=Y
(укажите https) работает нормально.
curl --proxy tcp://internal.proxy.address:port -v http://www.imf.org/external/np/fin/data/rms_mth.aspx?SelectDate=05/28/2020&reportType=CVSDR&tsvflag=Y
(укажите http) не работает и показывает ошибку 301
curl --proxy tcp://internal.proxy.address:port -v -L http://www.imf.org/external/np/fin/data/rms_mth.aspx?SelectDate=05/28/2020&reportType=CVSDR&tsvflag=Y
(укажите http со следующими перенаправлениями), затем работает нормально.
Я попробовал кое-что после того, как погуглил. Кажется, мне нужно выбрать ssl при использовании https. Итак, я внес следующие изменения:
$uri = "https://www.imf.org/external/np/fin/data/rms_mth.aspx"
."?SelectDate=$date&reportType=CVSDR&tsvflag=Y";
$opts = array('http' => array(
'proxy' => 'tcp://internal.proxy.address:port',
'method' => 'GET',
'request_fulluri' => true),
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'SNI_enabled' => false)
);
К сожалению, флаг SNI_enabled
был введен после версии 5.3.0, поэтому я не думаю, что это помогает. Также есть опция контекста follow_location
для http, но она была введена в 5.3.4, поэтому тоже бесполезна.
(Кстати, я практически не контролирую версию PHP, которая у нас есть, поэтому, хотя я ценю, что более высокие версии могут предлагать лучшие решения, я боюсь, что это не очень полезно для меня).
В принципе, я сейчас застрял. Никакая комбинация этих параметров или настроек не возвращает никаких данных. Я вижу, что он работает через curl и прокси, так что это не общая проблема с подключением.
Все предложения с благодарностью получены!
Обновление: после добавления строк для включения отчетов об ошибках код ошибки для потока, соединяющегося:
Warning: file(https://www.imf.org/external/np/fin/data/rms_mth.aspx?SelectDate=05/28/2020&reportType=CVSDR&tsvflag=Y): failed to open stream: Cannot connect to HTTPS server through proxy in /usr/bass/apps/htdocs/BASS/mods/module.XSM.php on line 79
(строка 79 - это строка $lines = ...
)
Таким образом, он не подключается в сценарии php, но запуск того же подключения через прокси-сервер в curl работает нормально. Какая разница в php, которая вызывает это?