Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.10.05;
Скачать: CL | DM;

Вниз

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;
Скачать: CL | DM;

Наверх




Память: 0.59 MB
Время: 0.016 c
2-1219852683
TStas
2008-08-27 19:58
2008.10.05
Сохранение из OleContainer а


2-1219304173
начинающий
2008-08-21 11:36
2008.10.05
как выбрать данные?


2-1219667707
Alex05
2008-08-25 16:35
2008.10.05
Поиск и замена текста в Edit e


15-1218713820
cyborg
2008-08-14 15:37
2008.10.05
Алгоритм Ахо-Карасик


3-1207533571
yus
2008-04-07 05:59
2008.10.05
Изменить программно парвметры псевдонима БД