502 плохой шлюз: php: // input - PullRequest
       20

502 плохой шлюз: php: // input

0 голосов
/ 07 февраля 2012

В php-файле я читаю поток ввода, который содержит изображение.

$incomingData = file_get_contents('php://input');
$fh = fopen($uploadPath, 'w');
fwrite($fh, $incomingData);
fclose($fh);

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

Журнал ошибок apache говорит:

child pid 1492 Выходной сигнал Ошибка сегментации (11)

Я пробовал это, но это не сработало.

 ini_set('default_socket_timeout', 120);

Но я не уверен, что время истекло.

edit // КОД:

$uploadFilename = time();
$uploadPath = '/path/melvin.jpg';

$fhSrc = fopen('php://input', 'r');

// Valid data?
if($fhSrc) {

    $fhDst = fopen($uploadPath, 'w');

    while (($data = fread($fhSrc, 1024)) !== FALSE) {
        fwrite($fhDst, $data);
    }

    fclose($fhSrc);
    fclose($fhDst);

}

echo 'ok';

RAW HEADERS:

POST /test.php HTTP/1.1
Host: hi.com
User-Agent: secret/1.0 (unknown, iPhone OS 5.0.1, iPhone, Scale/2.000000)
Accept: */*
Accept-Language: nl, en, fr, de, ja, it, es, pt, pt-PT, da, fi, nb, sv, ko, zh-Hans, zh-Hant, ru, pl, tr, uk, ar, hr, cs, el, he, ro, sk, th, id, ms, en-GB, ca, hu, vi, en-us;q=0.8
Accept-Encoding: gzip
Settings: {SOMEJSON}
Content-Type: application/x-www-form-urlencoded
Cookie: CAKEPHP=2b82f748fb3a64063b2e3be9bdec5c11
Connection: keep-alive
Transfer-Encoding: Chunked
Pragma: no-cache
Cache-Control: no-cache

and here in the boy the Big image

1 Ответ

2 голосов
/ 07 февраля 2012

Если вы получаете segfault, проблема здесь не связана с тайм-аутами и вообще с использованием памяти. Как было ранее наблюдавшееся здесь , способ, которым PHP часто обрабатывает ошибки OOM в * nix, заключается в сегментации ошибок. Если у вас есть файл, чтение которого занимает 15 секунд, у вас все равно будет очень большой файл, так что это неудивительно!

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

$fhSrc = fopen('php://input', 'r');
$fhDst = fopen($uploadPath, 'w');
stream_copy_to_stream($fhSrc, $fhDst);
fclose($fhSrc);
fclose($fhDst);

Если по какой-либо причине stream_copy_to_stream() недоступен или выдает ту же ошибку, быстрый и грязный вариант:

while (($data = fread($fhSrc, 1024)) !== FALSE) {
  fwrite($fhDst, $data);
}

При таком подходе не требуется считывать все данные файла в область памяти PHP, и данные передаются непосредственно из буфера веб-сервера на диск - поскольку длина чтения равна 2048 PHP никогда не потребуется больше рабочей памяти 2 КБ для выполнить операцию.

Кроме того, вы можете изменить директиву memory_limit в php.ini. Я не рекомендую это как подход, потому что, среди других причин, это сделает ваш код менее переносимым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...