Форум: "Прочее";
Текущий архив: 2008.10.05;
Скачать: [xml.tar.bz2];
ВнизApache + CGI + POST Найти похожие ветки
← →
Dmitry S © (2008-08-11 02:37) [0]Передача POST данных CGI программе, как я понимаю, происходит через stdin. А как отловить конец потока? Насколько я знаю последняя операция чтения либо заблокирует поток навечно либо вернет ошибку "данных нет". Причем вторая, как, опять же, я понимаю, может возникнуть и в случае, если сервер "затупил" и не вовремя передал часть данных, или типа того.
У кого есть опыт как это делается? Поделитесь.
А то не хочется ловить заголовок Content-length. Хотя может быть это и правильное решение.
← →
Ega23 © (2008-08-11 09:42) [1]
> А то не хочется ловить заголовок Content-length. Хотя может
> быть это и правильное решение.
Это ен просто правильное, это единственное решение.
← →
atruhin © (2008-08-11 13:29) [2]> [1] Ega23 © (11.08.08 09:42)
> Это ен просто правильное, это единственное решение.
C CGI не работал, но насколько я понимаю, но получает HHTP поток данных в stin.
В таком случае Content-length далеко не единственный способ определения конца потока.
← →
Dmitry S © (2008-08-11 13:37) [3]
> atruhin © (11.08.08 13:29) [2]
Как, по твоему, определить конец потока?
← →
Medbe}I{onok XML © (2008-08-11 14:31) [4]В таком случае Content-length далеко не единственный способ определения конца потока.
Если речь про клиента - то да.
Но речь не про клиента а про сервер
← →
Dmitry S © (2008-08-11 14:37) [5]
> Medbe}I{onok XML ©
А когда сервер должен сообразить, по твоему, что пора выполнить запрос и посылать ответ?
← →
palva © (2008-08-11 14:40) [6]STDIN в принципе не выдает признака конца потока. При вводе лишних символов будет ожидание, пока очередной символ не придет, либо бесконечное ожидание, если символа не будет.
← →
Dmitry S © (2008-08-11 14:43) [7]Тогда вопрос по протоколу HTTP/1.1. Насколько мне известно ВЫХОДНОЙ поток может быть разделен на части и выдаваться следующим образом:
4
test
3
foo
3
bar
т.е. передается длина следующего блока, а затем блок. И так далее.
Вопрос: а на входной поток это не распространяется?
← →
Ega23 © (2008-08-11 14:44) [8]
> А когда сервер должен сообразить, по твоему, что пора выполнить
> запрос и посылать ответ?
Ты нажал кнопочку в браузере.
Браузер установил соединение с сервером.
Браузер подал серверу данные (Post, Get, ещё какие - не важно)
Браузер должен либо получить от сервера новую станицу (HTML), либо ашипку, либо закрыть соединение по тайм-ауту.
Сервер получил запрос. В запросе сказано - CGI. Сервер запустил программу, передав ей в виде переменных окружения и в StdIn какое-то количество различных параметров. Сервер ждёт от этой программы либо в StdOut новой страницы (HTML) либо в StdErr - ашипки.
Получив - передаёт эти данные браузеру и закрывает соединение.
CGI-программа. Запускается. Что-то получает в переменные окружения. Что-то получает в StdIn. Парсит это дело. Работает с этими параметрами. Результат работы передаёт в StdOut, либо ашипку в StdErr, после чего завершает свою работу.
Примерно как-то так.
← →
Anatoly Podgoretsky © (2008-08-11 15:00) [9]> palva (11.08.2008 14:40:06) [6]
В принципе выдает и этот символ называется Конец Файла
← →
Dmitry S © (2008-08-11 15:18) [10]
> Ega23 © (11.08.08 14:44) [8]
Вот тут нюанс: сервер сам дождется от клиента Content-Length байт, а затем запустить CGI программу? Или он ее запустит программу как только начнет получать содержимое запроса и начнет передавать данные в STDIN по мере их получения от клиента?
← →
Ega23 © (2008-08-11 15:31) [11]Ну, насколько я понимаю, ты не можешь в strin передать что-то ДО запуска программы... :)
Просто чёрт его знает, что он (веб-сервер) ещё туда передать может.
Анализируй CONTENT_LENGTH, так точно не ошибёшься.
← →
McSimm © (2008-08-11 15:42) [12]
> ВЫХОДНОЙ поток может быть разделен на части и выдаваться
> следующим образом
Это Transfer-Encoding: chunked кодирование применяется в основном для response.
Никогда не встречал использование для запросов, и не знаю зачем оно может понадобиться, но сервер по идее должен понимать.
> Или он ее запустит программу как только начнет получать
Если сервер - apache, то он сначала проанализирует заголовки. При полученных неправильных заголовках будет возвращен bad request и CGI вызван не будет.
← →
Anatoly Podgoretsky © (2008-08-11 15:47) [13]> McSimm (11.08.2008 15:42:12) [12]
> Если сервер - apache, то он сначала проанализирует заголовки. При полученных неправильных заголовках будет возвращен bad request и CGI вызван не будет.
Это любой сервер обязан так работать, без этого не сможет сформировать переменные окружения.
← →
Dmitry S © (2008-08-11 15:57) [14]
> Ega23 © (11.08.08 15:31) [11]
Я, к примеру, о такой ситуации:
Я закачиваю на сервер файл с помощью POST запроса. Файл большой, поэтому закачивается, к примеру, минуту.
У сервера, по идее, происходят такие действия:1. Конект.
2. Считывание заголовка до пустой строки.
3. Анализ заголовка.
4. Если он типа POST, то анализирует Content-Length, Transfer-Encoding и прочее.
5. Принимает в течении минуты в свой буфер тело запроса. В случае таймаута или ошибки завершает данную процедуру.
6. Запускает CGI программу и передает ему в STDIN свой буфер.
7. Передает клиенту данные, которые вернула CGI программа.
Или так:1. Конект.
2. Считывание заголовка до пустой строки.
3. Анализ заголовка.
4. Запускает CGI программу.
5. Принимает в течении минуты тело запроса и, по мере поступления, скидывает его в STDIN программы. При этом забота на соответствие длины тела и заголовка возлагается на саму программу.
6. Передает клиенту данные, которые вернула CGI программа.
Тут получается палка о двух концах. Первый способ удобнее, потому, что сервер отшивает левые заголовки, делая рутинную работу. Но второй способ выгоден, когда речь идет о больших загружаемых файлах - ведь программа может рациональнее использовать память, чем веб-сервер. Все же интересно по какому пути работает веб-сервер.
← →
Ega23 © (2008-08-11 16:03) [15]
> 2. Считывание заголовка до пустой строки.
????? Это ещё чё за фигня??? Тебе переменные окружения приходят:
FCG_SV_REQUEST_METHOD = "REQUEST_METHOD";
FCG_SV_SERVER_PROTOCOL = "SERVER_PROTOCOL";
FCG_SV_URL = "URL";
FCG_SV_QUERY_STRING = "QUERY_STRING";
FCG_SV_PATH_INFO = "PATH_INFO";
FCG_SV_PATH_TRANSLATED = "PATH_TRANSLATED";
FCG_SV_HTTP_CACHE_CONTROL = "HTTP_CACHE_CONTROL";
FCG_SV_HTTP_DATE = "HTTP_DATE";
FCG_SV_HTTP_ACCEPT = "HTTP_ACCEPT";
FCG_SV_HTTP_FROM = "HTTP_FROM";
FCG_SV_HTTP_HOST = "HTTP_HOST";
FCG_SV_HTTP_IF_MODIFIED_SINCE = "HTTP_IF_MODIFIED_SINCE";
FCG_SV_HTTP_REFERER = "HTTP_REFERER";
FCG_SV_HTTP_USER_AGENT = "HTTP_USER_AGENT";
FCG_SV_HTTP_CONTENT_ENCODING = "HTTP_CONTENT_ENCODING";
FCG_SV_HTTP_CONTENT_TYPE = "HTTP_CONTENT_TYPE";
//FCG_SV_HTTP_CONTENT_LENGTH = "HTTP_CONTENT_LENGTH";
FCG_SV_HTTP_CONTENT_LENGTH = "CONTENT_LENGTH";
FCG_SV_HTTP_CONTENT_VERSION = "HTTP_CONTENT_VERSION";
FCG_SV_HTTP_DERIVED_FROM = "HTTP_DERIVED_FROM";
FCG_SV_HTTP_EXPIRES = "HTTP_EXPIRES";
FCG_SV_HTTP_TITLE = "HTTP_TITLE";
FCG_SV_REMOTE_ADDR = "REMOTE_ADDR";
FCG_SV_REMOTE_HOST = "REMOTE_HOST";
FCG_SV_SCRIPT_NAME = "SCRIPT_NAME";
FCG_SV_SERVER_PORT = "SERVER_PORT";
FCG_SV_HTTP_CONNECTION = "HTTP_CONNECTION";
FCG_SV_HTTP_COOKIE = "HTTP_COOKIE";
FCG_SV_HTTP_AUTHORIZATION = "HTTP_AUTHORIZATION";
REQEST_METHOD - это то, где сказано, Post это или Get (кстати, оба два разом вполне могут придти). В одном случае анализируешь StdIn, в другом - QUERY_STRING
← →
ketmar © (2008-08-11 16:08) [16]>[14] Dmitry S © (2008-08-11 15:57:00)
а тебе не фиолетово — сразу оно всё в stdin валит или нет? какая принципиальная разница? длину тебе отдали в content length, вот и читай, сколько там указано. меньше можно, больше — нет. всё. какие проблемы-то?
---
Do what thou wilt shall be the whole of the Law.
← →
McSimm © (2008-08-11 16:11) [17]
> вот и читай, сколько там указано. меньше можно, больше —
> нет.
А как ты узнаешь, что пришло меньше и уже закончилось?
← →
Ega23 © (2008-08-11 16:15) [18]
> А как ты узнаешь, что пришло меньше и уже закончилось?
>
Почему сразу закончилось? Может я тупо врагов дезинформирую: мне в стдин килобайт данных пришол, а я только 2 байта оттуда прочитал и радуюсь, а остальное втопку улетело... :)
← →
McSimm © (2008-08-11 16:16) [19]я просто не понял что меньше чего
← →
Ega23 © (2008-08-11 16:24) [20]
> я просто не понял что меньше чего
>
В CONTENT_LENGTH пришло значение "79".
Значит из stdin я могу читать не более 79 байт.
Я могу их вообще не читать. Я могу прочитать 78 или даже 16.
Больше - не могу.
← →
Anatoly Podgoretsky © (2008-08-11 16:26) [21]> McSimm (11.08.2008 16:11:17) [17]
По таймауту.
А вот если придет больше, а это нормально.
Протокол не имеет для этого необходимых средств, content length не обязан быть или соответствовать истине, обычно есть и обычно соответствует, но не обязано. Данные могут генерироваться динамически, а параметр передается раньше. И сервер и клиент работают одинаково в данном случае.
← →
Anatoly Podgoretsky © (2008-08-11 16:27) [22]> Ega23 (11.08.2008 16:15:18) [18]
Я так и поступаю при работе с форумом, делаю запрос, а на результат не реагирую.
← →
McSimm © (2008-08-11 16:29) [23]Да, тут просто.
Сложно, когда в Content-Length указано 79, а в действительности передано только 78. И кроме тайм-аута у сервера нет в этом случае способа определить "конец ввода", как и у CGI программы.
И вопрос, насколько я понял, состоит в том, будет ли в таком случае вообще вызван CGI или ошибку сервер самостоятельно отдаст?
← →
Ega23 © (2008-08-11 16:30) [24]
> И вопрос, насколько я понял, состоит в том, будет ли в таком
> случае вообще вызван CGI или ошибку сервер самостоятельно
> отдаст?
>
А, вопрос в этом что-ли?
Ну тут доку к конкретному серверу курить надо...
← →
Anatoly Podgoretsky © (2008-08-11 16:36) [25]> Ega23 (11.08.2008 16:24:20) [20]
Можешь, но как правило параметра в этом случае нет или он равен 0.
Обычно ВЕБ сервера очень стабильны и размер не меняется, в отличии от ФТП серверов. Там часто закачиваешь не 100% а много больше, даже тысячи. Но принчип тот же - размер имеет значение только мгновенное, а потом может изменяться по внешним причинам. Второй случай когда динамический контент, длина его заранее неизвестна, пока все не будет сгенерировано до тех пор она не определена. К счастью многие теги являются самоограничивающими. Multpart и MIME расширения.
← →
Anatoly Podgoretsky © (2008-08-11 16:38) [26]> McSimm (11.08.2008 16:29:23) [23]
Тут нет ошибки в чистом виде, прекращение поступления данных по таймауту, а не по размеру. Поэтому если пришло менее чем заявлено, то единственный вариант таймаут.
← →
Anatoly Podgoretsky © (2008-08-11 16:38) [27]> Ega23 (11.08.2008 16:30:24) [24]
Не к серверу, а к RFC
← →
Anatoly Podgoretsky © (2008-08-11 16:42) [28]Кроме RFC надо делать поправку на неверную реализацию и тут вроде бы ИЕ самый добрый, большинство ошибок прощает, некоторые другие браузеры становятся в определеную позицию. Тоже относится и к серверам. Ну нет закрывающего тега или он не вполне соответствует стандарту, ну и бог с ним, можно сжевать, что есть и по приходу следующего перейти к его обработки, все равно структура стековая, а то что не смогло обрататься просто игнорируется по окончанию приема.
← →
Medbe}I{onok XML © (2008-08-11 18:17) [29]Dmitry S © (11.08.08 14:37) [5]
> Medbe}I{onok XML ©
А когда сервер должен сообразить, по твоему, что пора выполнить запрос и посылать ответ?
Да никак не должен.
Это клиент может получать контент по явной длине или по дисконнекту сервера.
А серверу требуется контент-ленс. делать ему больше нечего как ребусы клиентские разгадывать.
← →
McSimm © (2008-08-11 18:49) [30]
> клиент может получать контент по явной длине
А что для клиента является признаком явной длины кроме длины контента или чанка ?
Дисконнект очень часто не происходит и соединение может держаться одно на много запросов.
← →
ketmar © (2008-08-11 18:52) [31]>[17] McSimm © (2008-08-11 16:11:00)
>А как ты узнаешь, что пришло меньше и уже закончилось?
ты будешь смеяться, но EOF случится. точнее, broken pipe.
---
All Your Base Are Belong to Us
← →
ketmar © (2008-08-11 18:53) [32]>[23] McSimm © (2008-08-11 16:29:00)
>будет ли в таком случае вообще вызван CGI или ошибку сервер самостоятельно
>отдаст?
а как автор захотел.
---
All Your Base Are Belong to Us
← →
McSimm © (2008-08-11 19:04) [33]
> а как автор захотел.
автор сервера ?
← →
Anatoly Podgoretsky © (2008-08-11 19:21) [34]> McSimm (11.08.2008 19:04:33) [33]
Конечно
← →
ketmar © (2008-08-11 19:25) [35]>[33] McSimm © (2008-08-11 19:04:00)
натурально.
---
Understanding is not required. Only obedience.
← →
Поросенок Винни-Пух © (2008-08-11 21:55) [36]А что для клиента является признаком явной длины кроме длины контента или чанка ?
Закрытие соединения сервером.
← →
McSimm © (2008-08-11 22:05) [37]Насколько мне известно - это не так. Клиенту необходима информация о длине.
А закрытия соединения можно долго ждать.
← →
Поросенок Винни-Пух © (2008-08-11 22:14) [38]зачем ждать?
почитай из соединения которое только что закрыто на той стороне.
← →
McSimm © (2008-08-11 23:27) [39]
> зачем ждать?
Потому что соединение далеко не всегда закрывается. keep-alive например, очень распространенная штука. Или прокси - может часами держать.
Еще раз, насколько я знаю - клиенту передается информация о длине.
Вы просто наугад говорите или знаете иначе?
← →
Тын-Дын © (2008-08-12 01:28) [40]При передаче методом POST сервер передает на вход CGI-скрипту УЖЕ ГОТОВЫЕ данные. Если сервер не получит полностью весь запрос от клиента, то и CGI эти данные не получит.
← →
McSimm © (2008-08-12 10:01) [41]Уже готовые в каком смысле ?
Там только переменные окружения выставлены и все они готовы по получении заголовков. Так что оба варианта возможны, но загружать полностью пожалуй правильнее для случаев с тайм-аутом.
Страницы: 1 2 вся ветка
Форум: "Прочее";
Текущий архив: 2008.10.05;
Скачать: [xml.tar.bz2];
Память: 0.57 MB
Время: 0.007 c