Обнаружение конца HTTP-пакета

Я должен написать PHP-скрипт, который работает как клиент с другим HTTP-сервером. Этот сервер игнорирует заголовок HTTP Connection: Close и сохраняет TCP-соединение открытым, если он не закрыт клиентом. И вот моя дилемма. I (клиент) должен deciede, когда HTTP-запрос / ответ завершен, а затем закройте соединение. Просто используйте:

$ data = file_get_contents ($ url);

.. не будет работать, так как file_get_contents возвращается, только если достигнут тайм-аут соединения (по умолчанию 30 секунд).

Поэтому я должен написать свой собственный цикл чтения, подобный этому (псевдокод):

$sock = fsockopen(...); $data = ''; while($line = fgets($sock)) { $data .= $line; if(http_package_recieved()) { break; } } 

К сожалению, в ответе нет заголовка Content-Length. Мой вопрос в том, как функция

http_package_recieved()

… должно выглядеть.

Приветствует Торстен

Если он не закрывает соединение и не указывает общую длину ответа, вы не можете узнать, были ли получены все данные.

Вы можете указать максимальный интервал времени между пакетами, но это не будет надежным.

Вы можете проверить, пуста ли $ строка, чтобы увидеть, не посылает ли сервер ничего. Вы также можете установить небольшой тайм-аут чтения в сокете с stream_set_timeout() , а затем внутри цикла проверить stream_get_meta_data() чтобы узнать, достигнуто ли это для того, чтобы вырваться.

Для этого вам лучше использовать библиотеку, такую ​​как cURL ( http://uk.php.net/manual/en/intro.curl.php ). Спецификация HTTP не проста: http://tools.ietf.org/html/rfc2616 (см. Раздел 4.4), и вы, вероятно, пропустите что-то важное.

Когда объект заканчивается, он либо руководствуется:

  • Заголовок Content-Length (которого у вас нет)
  • HTTP Chunked Transfer Encoding (см. Transfer-Encoding: chunked header: есть ли у вас один из них?).

Возможно, вам придется обработать эту закодированную кодировку передачи, если вы получите этот заголовок. Для этого есть библиотеки.

feof($sock) будет в порядке