Apache2 и CGI - как сохранить Apache от буферизации данных POST? - PullRequest
5 голосов
/ 07 июля 2010

Я пытаюсь выполнить прямой анализ загрузки файла в CGI и показать данные на экране по мере их загрузки.

Однако Apache2, похоже, хочет дождаться полного завершения POST, прежде чем отправлять CGI-приложение вообще.

Как я могу заставить Apache2 прекратить буферизацию POST для моего приложения CGI?

EDIT

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

1) Выход буферизуется. Я попытался SetEnvIf (и просто SetEnv) для "! Nogzip", "nogzip" и "! Gzip" без успеха (в пределах определения Справочника CGI).

2) Похоже, что Apache2 не читает выходные данные CGI, пока не завершится процесс CGI? Я заметил, что мое CGI-приложение (очищенное или нет) постоянно зависает на линии "fwrite (..., stdout)" на отметке 80K.

EDIT

Хорошо, Firefox связывается со мной. Если я отправляю файл размером 150 Кбайт, то нет блокировки CGI в районе 80 Кбайт. Если файл 2G, то есть блокировка. Итак, Firefox не читает выходные данные с сервера, пока он пытается отправить файл ... есть ли заголовок или альтернативный тип содержимого, чтобы изменить это поведение?

EDIT

Хорошо, я полагаю, что блокировка вывода CGI для больших файлов на самом деле не важна. Мне не нужно повторять файл! Я отлаживаю проблему, вызванную средствами отладки. :)

Полагаю, тогда это работает достаточно хорошо. Спасибо!

ЗАКЛЮЧИТЕЛЬНОЕ ПРИМЕЧАНИЕ

Как примечание ... я думал, что Apache2 буферизовал входные данные, потому что я всегда получал переменную окружения "Content-Length". Я полагаю, что FireFox достаточно умен, чтобы предварительно рассчитать длину содержимого загрузки из нескольких частей, и Apache2 это передал. Я думал, что Apache2 буферизует ввод и сообщает саму длину.

Ответы [ 3 ]

3 голосов
/ 07 июля 2010

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

(Выходная буферизация обычно вызывается либо неосуществленнымstdout в сценарии или с помощью фильтров. Обычным виновником является фильтр DEFLATE, который часто используется для сжатия всех text/ ответов, независимо от того, приходят ли они из статического файла или сценария. В целом, это хорошая идеяСжатие вывода сценариев, но побочный эффект заключается в том, что это приведет к полной буферизации ответа. Если вам нужен немедленный ответ, вам нужно отключить его для этого одного сценария или всех сценариев, ограничивая применениеAddOutputFilterByType для конкретных <Directory> с или с помощью mod_setenvif для установки заметки !nogzip. *

Аналогично, входной фильтр (включая, опять же, DEFLATE) может привести к тому, что вход CGI будетс буферизацией, если вы используете какой-либо.Но они менее широко используются.

Редактировать: сейчас просто закомментируйте любой httpd conf, который у вас есть, включив фильтр дефляции.Вы можете выбрать его обратно выборочно, как только вы убедитесь, что ваш IO без буферизации без него.

Я заметил, что мое приложение CGI (сбрасывается или нет) постоянно зависает на "fwrite (..., stdout) "строка около 80K.

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

Над чем вы здесь работаете?В общем случае не имеет смысла выводить информацию о прогрессе в ответ на прямую форму POST, потому что браузеры обычно не отображают ее.Если вы хотите предоставить отзыв о ходе загрузки при отправке формы в формате HTML, это обычно делается с помощью таких хаков, как проверка соединения AJAX с обратной связью, чтобы увидеть, как происходит загрузка (то есть информация о ходе работы должна передаваться, например, в базе данных).) или с использованием компонента Flash-загрузки.

0 голосов
/ 22 декабря 2011

Вот полезное руководство по управлению буферизацией при использовании perl на стороне сервера:

http://perl.plover.com/FAQs/Buffering.html

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

0 голосов
/ 07 июля 2010

Из (старой версии) руководств Apache HTTP Server:

Каждый раз, когда ваш скрипт выполняет "сброс" выводить данные, эти данные передаются на клиенте. Некоторые сценарии языки, например Perl, имеют их собственная буферизация для вывода - это можно отключить, установив $ | специальная переменная к 1. Конечно, это действительно увеличивает общее количество передаваемые пакеты, которые могут привести к ощущению медлительности для конечный пользователь.

Вы пытались сбросить STDOUT или проверить, есть ли у используемого языка буферизация, которую вы можете отключить?

...