[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: fsockopen и глюки с приемом HTTP/1.1
smbd
Всем здрасте.
Столкнулся с одной проблемой, которая впрочем решилась. Но мне не совсем понятно, отчего происходит именно так.

Есть некий php-скрипт, назовем его get_data.php, в котором совершаются запросы по HTTP методом GET.
В этом скрипте используется, в зависимости от наличия загруженных модулей, cURL или fsockopen. В случае с курлом проблем нет, а с fsockopen - имеются.
get_data.php может посылать запросы на два ресурса. Первый - тоже php скрипт, который отдает файл (он выдает несколько заголовков, а затем и содержимое файла с помощью readfile()); и запрос, и ответ - по HTTP/1.1. Второй ресурс - perl-скрипт, который выдает несколько заголовков типа Content-Type, Status и несколько кастомных, и некий XML.

get_data.php с первым ресурсом работает без проблем, а вот со вторым не хочет.
В get_data.php примерно такой алгоритм:

Код
$sock = fsockopen("remote.host.com", 80, $errno, $errstr, 20);
$out = "GET /get_xml.pl?a=1 HTTP/1.1\r\n";
$out .= "Host: remote.host.com\r\n";
$out .= "Connection: close\r\n";
$out .= еще несколько заголовков...
$out .= "\r\n\r\n";

$response = "";
if($sock){
    fputs($sock, $out);
    while(!feof($sock)){
        $response .= fgets($sock, 4096);
    }
    fclose($sock);
}


Проблема заключается в том, что в получаемый ответ fgets (а может и не он...) вставляет текстом количество принятых (отдаваемых текущим вызовом) байт. Т.е. на выходе получаем примерно следующее:

Код
HTTP/1.1 200 Ok
Date: <значение>
Server: <значение>
Pragma: no-cache
Connection: close
Content-Type: application/xml; charset=UTF-8
<кастомный заголовок>: <значение>

f9c
<?xml ...> ... и еще данные до 4096 байт
1000
<еще 4096 байт данных>
1000
<еще 4096 байт данных>
1000
...


В итоге в ответе имеем левый текст "f9c", "1000", обрамленный переводами строк, который мы получаем от fgets. Похоже, что этот текст - шестнадцатеричное число равное количеству принятых байт за один вызов fgets. Соответственно, появляются глюки в парсинге такого запроса и get_data.php считает, что этот ответ - лажовый и его игнорирует...
Этот левый текст не появляется в ответе, если запрос делать по HTTP/1.0, т.е. если
Код
# вместо
$out = "GET /get_xml.pl?a=1 HTTP/1.1\r\n";
#написать
$out = "GET /get_xml.pl?a=1 HTTP/1.0\r\n";


В результате получаем красивый и правильный ответ.
Ошибки в перловом скрипте, который обрабатывает запросы от get_data.php не видится, т.к. он принимает запросы и от других перловых и руби-скриптов и никаких ошибок пока не замечено. Даже если его из браузера вызвать - тоже все в порядке (единственное, что насторожило, что если из get_data.php запрос сделать по HTTP/1.0, ответ получаю как HTTP/1.1, но это скорее веб-сервер, чем скрипт).

В общем, проясните, пожалуйста, если это возможно, с чем связано такое поведение fsockopen/fgets при запросах по HTTP/1.1??
Заранее спасибо.



Спустя 3 часа, 1 минута, 2 секунды (11.12.2007 - 17:03) pavel написал(а):
Сталкивался с тем же самым при запросе к яндексу http://www.phpforum.ru/index.php?showtopic=5027&hl=

может vasa_c прояснит? smile.gif

Спустя 6 дней, 21 час, 23 минуты, 10 секунд (18.12.2007 - 14:26) Ghost написал(а):
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2025 Invision Power Services, Inc.