Как правильно обрабатывать запрос кодирования по частям?

У меня есть два веб-сайта: один с Lighttpd с PHP, а второй с Apache, и ни один из них не обрабатывает кодировку передачи по частям должным образом.

Я отправляю этот запрос со своего мобильного, J2ME, и нет возможности изменить этот тип передачи на любой другой.

Таким образом, мой единственный способ - обрабатывать закодированные запросы на передачу по частям другим способом. Любое решение будет хорошим, пока я могу включить его на своем сервере CentOS, где я могу установить и изменить все, что будет необходимо.

Итак, мой вопрос: как правильно обрабатывать запрос на кодирование по частям на стороне сервера?


person Tomasz Smykowski    schedule 20.07.2010    source источник


Ответы (1)


РЕДАКТИРОВАТЬ: Какую версию PHP/Apache/LightHTTP вы используете? Так как раньше в PHP была эта ошибка, но, похоже, она исчезла в версии 5.2. .13 и 5.3.2.

Если ссылка выше не помогает, я хотел бы точно знать, что видит PHP, можете ли вы поместить это в свой API и опубликовать результаты? (отредактировано, конечно).

$input = file_get_contents('php://input');
$stdin = file_get_contents('php://stdin');

print "FILES: ";
print_r($_FILES);

print("<br>POST: ");
print_r($_POST);

print("<br>input: ".$input);
print("<br>stdin: ".$stdin);
die;

Таким образом, мы можем видеть то, что видит PHP, и если он НЕ декодирует фрагментированное кодирование, то мы МОЖЕМ декодировать его вручную.

Конец РЕДАКТИРОВАТЬ. (оставив ниже на случай, если кто-то еще сочтет это полезным)

Я предполагаю, что это продолжение вашего предыдущего вопроса. И я предполагаю, что вы читаете поток с PHP?

Я написал это несколько лет назад, он читается из фрагментированного закодированного потока, после чего вы можете делать с выводом все, что хотите. Если это большой файл, не читайте его в строку, а записывайте в файл.

<?php
define('CRLF', "\r\n");
define('BUFFER_LENGTH', 8192);
$headers = '';
$body = '';
$length = 0;

$fp = fsockopen($host, $port, $errno, $errstr, $timeout);

// get headers FIRST
do
{
    // use fgets() not fread(), fgets stops reading at first newline
    // or buffer which ever one is reached first
    $data = fgets($fp, BUFFER_LENGTH);
    // a sincle CRLF indicates end of headers
    if ($data === false || $data == CRLF || feof($fp)) {
        // break BEFORE OUTPUT
        break;
    }
    $headers .= $data;
}
while (true);
// end of headers

// read from chunked stream
// loop though the stream
do
{
    // NOTE: for chunked encoding to work properly make sure
    // there is NOTHING (besides newlines) before the first hexlength

    // get the line which has the length of this chunk (use fgets here)
    $line = fgets($fp, BUFFER_LENGTH);

    // if it's only a newline this normally means it's read
    // the total amount of data requested minus the newline
    // continue to next loop to make sure we're done
    if ($line == CRLF) {
        continue;
    }

    // the length of the block is sent in hex decode it then loop through
    // that much data get the length
    // NOTE: hexdec() ignores all non hexadecimal chars it finds
    $length = hexdec($line);

    if (!is_int($length)) {
        trigger_error('Most likely not chunked encoding', E_USER_ERROR);
    }

    // zero is sent when at the end of the chunks
    // or the end of the stream or error
    if ($line === false || $length < 1 || feof($fp)) {
        // break out of the streams loop
        break;
    }

    // loop though the chunk
    do
    {
        // read $length amount of data
        // (use fread here)
        $data = fread($fp, $length);

        // remove the amount received from the total length on the next loop
        // it'll attempt to read that much less data
        $length -= strlen($data);

        // PRINT out directly
        #print $data;
        #flush();
        // you could also save it directly to a file here

        // store in string for later use
        $body .= $data;

        // zero or less or end of connection break
        if ($length <= 0 || feof($fp))
        {
            // break out of the chunk loop
            break;
        }
    }
    while (true);
    // end of chunk loop
}
while (true);
// end of stream loop

// $body and $headers should contain your stream data
?>
person Viper_Sb    schedule 20.07.2010
comment
Я не читаю поток из PHP, но мой PHP-скрипт вызывается с вызовом POST с фрагментами. Как прочитать поток этого вызова POST? Знаете наверное? - person Tomasz Smykowski; 20.07.2010
comment
Таким образом, J2ME вызывает ваш PHP-скрипт и ожидает вывода фрагментированного кодирования, и что apache и lighthttpd НЕ отправляют правильно фрагментированное кодирование? С моей точки зрения, ваш php-скрипт должен был бы записывать свои данные в блоках, закодированных фрагментами. 1. вызывается api 2. обрабатывает результаты 3. запускается буферизация вывода 4. в буфер собираются ошибки или корректные данные 5. буфер обрабатывается и преобразуется в CE 6. отправляются ПРАВИЛЬНЫЕ заголовки 7. отправляются закодированные данные фрагмента у вас еще нет кода, вы можете найти что-нибудь в Интернете? Если нет, то несложно создать для него класс. - person Viper_Sb; 21.07.2010
comment
Выглядит это так: J2ME отправляет кодировку чанков на apache или lighttpd, и оба эти сервера не могут нормально принять этот запрос - они получают только первый чанк и не читают дальше. - person Tomasz Smykowski; 22.07.2010