The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  ВХОД  слежка  RSS
"Траблы с stdin'ом (C++, Apache, Windows)"
Вариант для распечатки  
Пред. тема | След. тема 
Форумы WEB технологии (Public)
Изначальное сообщение [Проследить за развитием треда]

"Траблы с stdin'ом (C++, Apache, Windows)"  
Сообщение от Павел (??) on 09-Мрт-06, 13:12 
Чес слово, искал везде, но ответа на вопрос не нашел :-( поэтому рискнул, ожидая ругательских выражений (типа "ну и какого??!! уже сто раз об этом говорили!!!"), написать сюда.

Итак, у меня Apache 2.0.53-win32, Windows XP SP2. Я хочу написать cgi-приложение на C++ (средство разработки - VS). Все бы хорошо, вот только библиотек нормальных не нашел (кстати, а встречается ли такое в природе?), поэтому решил поколупаться сам, тем более что форматы простые, разбираются без проблем. Ну и наткнулся на непреодолимое препятствие в виде баги (я так думаю, что это больше всего похоже на апачевскую багу, хотя, по отзывам выдавших мне в руки софт, у них в перловом скрипте такого не наблюдается).

Суть проблемы - из формы (enctype="multipart..." method = "post") клиент пытается выполнить передачу файла на сервер. Если файл короткий, проблем не возникает - читаю stdin (обычным read'ом, побайтно), разбираю его - все нормально. Но вот если он длинный (обычно траблы начинаются за пределами 64К) - получается индейское жилище. stdin просто оканчивается на 72К, без заключительных разделителей и прочего.

Пробовалось на файлах разной длины, разного наполнения (текстовые, исполняемые, картинки и т.д.). Поиски баги в сети ничего не дали, чаще всего люди глючат в смысле binmode (кстати, тоже интересный вопрос - ведь stdin, я так понимаю, в текстовом режиме открыт, кто как борется с этим делом?), в баглистах на apache.org че-то тоже ничего похожего не нашел...

Че ж делать-то? Может, я не сделал чего-то нужного с stdin'ом?

Могу и сырцы выложить, если кто интересуется и думает, что я просто глючный :-)

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

 Оглавление

Сообщения по теме [Сортировка по времени, UBB]


1. "Траблы с stdin'ом (C++, Apache, Windows)"  
Сообщение от Павел (??) on 10-Мрт-06, 09:53 
Ну что, у кого есть идеи?

сырцы:

// типа проверка длины, test.c
#include <stdio.h>
#include <io.h>
#include <fcntl.h>

int main()
{
int l = lseek(fileno(stdin),0,SEEK_END);
printf("Content-type: text/html\n\n");
printf("stdin length %d\n",l);
return 0;
}

// тестовая страничка
<FORM enctype="multipart/form-data" action="test.exe" method="post">
<input name="file" type="file"/>
</FORM>

Пытаюсь зафигачить файл длиной примерно 1 Мб (фотка)
// результат
stdin length 73536

Если вывести содержимое, получается типа:
----------------------id
Content-Disposition: name="file"; filename="(имя файла с путем на клиенте)"
Content-Type: (не помню уже)

(начало содержимого файла)
....
....

И все, почти стандартно на 73356 данные обрубаются. Почему "почти"? Потому что это иногда происходит на 8194, 65536 и прочих местах, я сначала думал, что глюки от последовательности в файле зависят - а фиг-то там, он один и тот же файл на разных местах оборвать может. Даже в логах нифига не пишется, как будто так и положено.

Я тут еще варианты придумал - может, дело в том, что у меня как-нибудь не так апач настроен? Хотя я его как поставил, не трогал, только каталог свой завел, безо всяких извратов...

В общем, даже проспавшись (уже в который раз :-)), я не решил вопрос... Вот еще попробую 2.0.55 поставить, может, будут изменения...

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

2. "Траблы не исчезли"  
Сообщение от Павел (??) on 10-Мрт-06, 14:10 
Попробовал я версию 2.0.55, траблы остались на месте... Мне теперь кажется, что бага не апачевская... Где-то что-то я не догоняю, это факт. Либо, как вариант, настройки операционки у меня какие-то не такие. Попробую на другой машине.
Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

3. "Траблы не исчезли"  
Сообщение от Павел (??) on 10-Мрт-06, 14:59 
Пробы на другой машине дали аналогичный результат...
Недавно прочитал интересный текст (http://oreilly.jungles.ru/weblinux/cgi/ch03_01.htm):

3.1.1.1. STDIN
When a web server receives ...

!!! Note that there is no end-of-file marker, so if you try to read more data than is available, your CGI script will hang, waiting for more data on STDIN that will never come (eventually, the web server or browser should time out and kill this CGI script but this wastes system resources). !!!

... For POST requests, you should always refer to the value of the Content-Length header and read only that many bytes.

Короче, смысл-то вроде бы понятен, stdin в перлах (наверное, на юниксах) читается до тех пор, пока хочется, а дабы предохраниться от "втыкания" сервера, узнается CONTENT_LENGTH.

Но в моем случае не юниксы и не перл. STDIN имеет длину (может, это длина буфера?) и почему-то имеет "конец файла". Типа как-то надо дать понять драйверу, что я уже прочитал и надо бы следующий фрагментик в буфер кинуть... Вот только КАК?

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

4. "Траблы загнулись"  
Сообщение от Павел (??) on 10-Мрт-06, 17:40 
Короче, действительно, есть буфер stdin'а (кто бы сомневался :-)), и он обновляется по меоре чтения. И "конец файла" - на самом деле еще не конец :-).

Я сделал через API функции (GetStdHandle, ReadFile) - и, о счастье, все заработало! Даже FlushConsoleInputBuffer оказалсе ненужным. Просто надо читать подряд до тех пор, пока прочитанных байт возвращается не 0. Вот такие они, винды, ось со слабопредсказуемым поведением....

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

Архив | Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Оцените тред (1=ужас, 5=супер)? [ 1 | 2 | 3 | 4 | 5 ] [Рекомендовать для помещения в FAQ]




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2025 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру