Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 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 эти данные не получит.



Страницы: 1 2 вся ветка

Форум: "Прочее";
Текущий архив: 2008.10.05;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.57 MB
Время: 0.006 c
2-1219941100
Greebanyi 2bus
2008-08-28 20:31
2008.10.05
Clock


2-1219906656
snake-as
2008-08-28 10:57
2008.10.05
Как сделать, чобы при нажатии кнопки на каждом компоненте Edit


15-1218874305
Anatoly Podgoretsky
2008-08-16 12:11
2008.10.05
ГМП


2-1220007272
vvrz
2008-08-29 14:54
2008.10.05
из Memo из Excel


15-1218274270
king
2008-08-09 13:31
2008.10.05
Опыт работы





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский