Мой скрипт получает сжатые данные из настольного приложения через POST, которые он извлекает и обрабатывает из $HTTP_RAW_POST_DATA
.В PHP 5.2.16 (ISAPI) $HTTP_RAW_POST_DATA
правильно заполняется ожидаемыми двоичными данными.После обновления до PHP 5.3.9 (FastCGI) $HTTP_RAW_POST_DATA
не определяется.Как я могу получить данные?
Я использую IIS 5.1 под 32-битной Windows XP SP3.
Документы относительно $HTTP_RAW_POST_DATA
утверждают, что 'недоступно с enctype = "multipart / form-data"' , но я не использую этот тип содержимого.(Вспомните, что тот же самый код отлично работает в PHP 5.2, поэтому тип контента тогда тоже был бы проблемой.)
Когда я включил директиву always_populate_raw_post_data
ini , ничего не изменилось.phpinfo()
сообщает, что установлено значение «Вкл.», Но переменная по-прежнему не устанавливается.
Документы также предполагают, что предпочтительным способом получения этих данных является чтение их из потока php://input
.Я попытался сделать это следующим образом:
$HTTP_RAW_POST_DATA = file_get_contents('php://input');
, но сценарий просто висит на этой строке, предположительно потому, что он ожидает данные (то есть, конец файла не отправляется).Даже если я ограничу максимальную длину значением, равным одному байту, как показано ниже, он все равно зависнет.
$HTTP_RAW_POST_DATA = file_get_contents('php://input', false, null, -1, 1);
Единственный раз, когда он не зависает на этой строке, это когда я устанавливаю maxlen до 0
, что означает, что он не пытается ничего читать, но также не помогает.: -)
Если $HTTP_RAW_POST_DATA
не заполнится, когда я заставлю его, и я ничего не могу получить от php://input
, как я могу получить данные?
тот факт, что php://input
, по-видимому, пустой, указывает на разницу между ISAPI и FastCGI?Я не читал ничего, что подсказывало бы, что необработанные POST ведут себя по-другому или теряются при использовании FastCGI.
Вот некоторые соответствующие части $_SERVER
.Все эти значения идентичны при запуске сценария с PHP 5.2 и PHP 5.3.
[CONTENT_LENGTH] => 4294967295
[CONTENT_TYPE] => application/client-gzip
[HTTP_HOST] => 127.0.0.1
[HTTP_CONTENT_TYPE] => application/client-gzip
[HTTP_TRANSFER_ENCODING] => chunked
[HTTP_ACCEPT_ENCODING] => gzip
[HTTP_EXPECT] => 100-continue
[REQUEST_METHOD] => POST
[SERVER_NAME] => 127.0.0.1
[SERVER_PORT] => 80
[SERVER_PROTOCOL] => HTTP/1.1
(Примечание: я знаю, что длина содержимого в 4 ГБ выглядит странно, но потому, что он использует кодированное кодирование ), CONTENT_LENGTH
игнорируется.)
Поскольку заголовок CONTENT_LENGTH
не используется, могу ли я проверить, что данные действительно где-то принимаются PHP, а непотерян IIS?
Так как данные отправляются из двоичной библиотеки в клиенте рабочего стола, изменение формата POST не вариант.Независимо от плюсов и минусов использования $HTTP_RAW_POST_DATA
, вот так я должен это делать.Раньше это работало так, поэтому я полностью ожидаю, что это сработает сейчас.Любое понимание искренне приветствуется!
Обновление
Вот простой сценарий, иллюстрирующий мою проблему.Есть два файла:
postsend.php
<?php
$headers = array(
"Content-Type: application/client-gzip",
// "Transfer-Encoding: chunked",
);
$text = 'This text is superior to your text even though it is useless.';
$data = gzdeflate($text);
echo "text: $text<br />gzip: $data<br />";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://localhost/server/postreceive.php");
curl_setopt($ch, CURLOPT_USERPWD, "user:pass");
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
echo $result;
postreceive.php
<?php
if (!empty($HTTP_RAW_POST_DATA)) {
printf(
'HTTP_RAW_POST_DATA set!<br />gzip:%s<br />text: %s',
$HTTP_RAW_POST_DATA,
gzinflate($HTTP_RAW_POST_DATA)
);
} else {
echo 'No raw data. :-(';
}
В PHP 5.3 (FastCGI) это работает, когда я запускаю postsend.phpи вывод:
text: This text is superior to your text even though it is useless.
gzip: ÉÈ,V(I(QÒÅ¥©E™ùE %ù •ù¥E‰Ô²Ô<…’ŒüÒô …L°ºÒâÔœÔâb=
HTTP_RAW_POST_DATA set!
gzip: ÉÈ,V(I(QÒÅ¥©E™ùE %ù •ù¥E‰Ô²Ô<…’ŒüÒô …L°ºÒâÔœÔâb=
text: This text is superior to your text even though it is useless.
Однако, если я раскомментирую строку с заголовком Transfer-Encoding
, все будет зависать при запуске postsend.php.Итак, получение chunked-кодировки, похоже, нарушает его.
Есть ли какая-то конфигурация IIS или FastCGI, которая мне не хватает, которая позволила бы этому работать при получении chunked-кодировки?(Если да, то теперь это более уместно в качестве вопроса ServerFault?) Я видел настройки, которые позволяют отправлять чанкованное кодирование, но не принимать чанкованное кодирование.