Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » CGI-скрипты на языке C

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3

Открыть новую тему     Написать ответ в эту тему

m31

Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
программа тестировалась в винде, не подскажете, как открыть в двоичном режиме. Спасибо за помощь!!!!!!!!  
 
Добавлено:
vjunk
так fwrite, по-моему применяется только в двоичном режиме, оно туда пишет, но пишет не полностью так как хотелось бы

Всего записей: 4 | Зарегистр. 22-01-2006 | Отправлено: 17:42 24-01-2006
vjunk

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
m31
Про двоичный режим хорошо написано здесь: http://www.mingw.org/MinGWiki/index.php/binary
Под Windows/DOS даже работа функций read/write зависит от режима открытия
файла, а уж работа всех функций буферизированного ввода/вывода и подавно.

Всего записей: 303 | Зарегистр. 23-02-2005 | Отправлено: 18:02 25-01-2006
m31

Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Результат тот же!!! Так что проблема видимо не в этом!

Всего записей: 4 | Зарегистр. 22-01-2006 | Отправлено: 18:07 31-01-2006
vjunk

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
m31
Ну, тогда не знаю. На Windows я проверить не могу, а на Linux работает.
Попробуй перед концом main добавить fflush(stdout) - может проблема с
буферизацией.

Всего записей: 303 | Зарегистр. 23-02-2005 | Отправлено: 14:16 01-02-2006 | Исправлено: vjunk, 14:17 01-02-2006
Aeriss

Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
При попытке выполнения cgi-скрипта из-под Apache просто выводится пустая страница без каких-либо сообщений об ошибках, при этом в error.log пишет, что не найден файл favicon.ico. Причем при создании данного файла и записи в соответствующую папку результат тот же. Подскажите, плиз, в чем может быть проблема.
 
Добавлено:
С иконкой я вроде разобралась, теперь не пишется вообще никаких ошибок, но скрипт все равно не работает, т.е. просто моментально грузится совершенно пустая страница и процесс уничтожается, хотя у меня в начале программы написано следующее:
int main(int argc, char* argv[])
{
  setmode( 1, O_BINARY);  //YES-S-S
  setmode( 0, O_BINARY);  //YES-S-S
 
  cout << "Content-type: text/html; charset=UTF-8" << endl;
  cout << "Expires: Mon, 26 Jul 1997 05:00:00 GMT" << endl;
  cout << "Pragma: no-cache" << endl;
  cout << "Cache-Control: no-store, no-cache, must-revalidate" << endl << endl;
 
#ifdef _WIN32
  CoInitialize(0);
#endif
 
  try
  {
     
    Sleep(20000);  //в течении этих 20с я рассчитываю подсоединиться к процессу и отлаживать его средствами среды разработки  
    ....

Всего записей: 13 | Зарегистр. 14-04-2006 | Отправлено: 17:02 11-03-2007
Bave

Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Есть проблема с загрузкой файлов на сервер. Поскольку говорят, что давать ссылки на другие форумы это не хорошо - я просто скопировал свой вопрос с другого форума так как есть:

Цитата:
 
Доброго времени суторк,
Есть проблема с загрузкой файлов на сервер (web-сервер, Apache 2.2) - проблема возникает когда размер файла превышает 1024 байта (когдаразмер контента более чем 1024 байта). Т.е. фактически проблема возникает, когда размер контента превышает стандартный размер STDIN, но  
сама проблема совсем не в переполнении буфера - далее постараюсь описать подробней:
Пользователь пересылает файлы на сервер через форму, т.е.
<form action="..." enctype="multipart/data-form" method="POST">
На стороне сервера обработку формы и сохранение данных выполняет шлюз (.cgi -модуль) - все .cgi модули я пишу на C++.
Т.е. фактически шлюзы это исполняемые модули, кторые Apache при запросе запускает как дочерние процессы.
Если я правильно понимаю как работает Apach - он делает
следующее, он создаёт не именованый pipe-канал для записи
и перед запуском дочернего процесса, он направляет это
pipe-канал на STDIN запускаемого дочернего процесса и потом принимаемый контент он просто записывает в pipe создный для записи - так вот тут то и проблема:
Apache записывает сперва только первые 1024 байта (чтоб не переполнить STDIN шлюза). После чтения буфера stdin внутри шлюза Apache НЕ ЗАПИСЫВАЕТ СЛЕДУЮЩИЕ 1024 байта!!!!! - c одной стороны ессесвено, он ведь не знает, что я уже считал первые 1024 байта, с другой стороны не понятно, как ему сообщить, мол гони дальше остатки контента??? Может что-то нужно в stdout выдать, чтоб он понял? Нигде не могу найти ответа на этот вопрос - кругом PHPшники, которые с такими проблемами ессесвено не сталкивались  
 

Всего записей: 31 | Зарегистр. 13-10-2005 | Отправлено: 01:03 07-05-2007 | Исправлено: Bave, 01:04 07-05-2007
vjunk

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Bave
Не указана операционная система, под линуксом у меня работает без проблем (на C под Apache 2.0).
Программа:

Код:
 
#include <stdio.h>
 
int main(int ac, char **av, char **env)
    {
    FILE *save;
    int c;
    int count;
 
    printf("Content-Type: text/plain\r\n\r\n");
    while(NULL!=*env)
        {
        printf("%s\r\n", *env);
        env++;
        }
    printf("***\r\n");
 
    save=fopen("cgi.bin", "wb");
    if(NULL==save)
        {
        printf("Can't create file!\r\n");
        return 0;
        }
    count=0;
    while(EOF!=(c=getchar()))
        {
        putc(c, save);
        ++count;
        }
    fclose(save);
    printf("Form data saved (%d bytes)\r\n", count);
 
    return 0;
    }
 

Форма:

Код:
 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=utf-8">
<TITLE>CGI upload test</TITLE>
</HEAD>
 
<BODY>
 
<FORM METHOD="POST"  ENCTYPE="multipart/form-data" ACTION="cgi.cgi">
Имя файла <INPUT TYPE="file" NAME="file_name" >
<INPUT TYPE="submit" NAME="upload" VALUE="Загрузить файл">
</FORM>
 
</BODY>
</HTML>
 

Результат:
Подробнее...

Всего записей: 303 | Зарегистр. 23-02-2005 | Отправлено: 21:10 08-05-2007
Bave

Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
1. Операционка W2k
2. Все .cgi-шлюзы запускают библтотеку bgatemt.dll - в ней я  релизовал всё, что связано с вытаскиванием контента из пришедшего HTTP запроса - т.е. вот код:

Код:
 
//Шлюз описывает структура (что-то типа дескриптора шлюза самапального):
typedef struct tagGATE_S        //Дескриптор шлюза
{
    BYTE    m_bMethod;    //используемый метод
    BYTE    m_bContentType;    //тип контента (фактически enctype)
    LPSTR    m_lpszContentBuff;    //указатель на память под контент
    LPSTR    m_lpszQuery;    //query string из URL выделяется одельно  
    UINT    m_uQuerySize;          //её размер
    UINT    m_uContentSize;       //размер контента
    LPSTR    m_lpszUserName;      //имя пользователя  - если вкл. авторизация
    DWORD    m_dwCSLimit;    //Content Size Limit - ограничение
    HANDLE    m_hMutex;    //Mutex для синхр. доступа шлюзов к базам данных
 
    //Только для для случаев: multipart/form-data
    PBYTE    m_pBoundary;    //Уникальный разделитель  
    WORD    m_wBoundarySize;    //его размер
} GATE_S, *PGATE_S;
 
//И вот собсно метод, который контент и вытаскивает и некоторые части заголовка  
//запроса тоже:  
 
BOOL _declspec(dllexport) bgate::httplookup(PGATE_S p_gate)  
{
    if(NULL == p_gate) return FALSE;
 
                //Определяем метод:
    char sz_method[8];
    memset(sz_method, 0, sizeof(sz_method));
    memcpy(sz_method, getenv(REQUEST_METHOD),  
                strlen(geten(REQUEST_METHOD)));
 
    if(0 == strncmp(sz_method, "GET", 3)) p_gate->m_bMethod =    
                GATE_METHOD_GET;
    else
    {
        if(0 == strncmp(sz_method, "POST", 4)) p_gate->m_bMethod =    
                                 GATE_METHOD_POST;
        else  
        {
            return FALSE;
        }
    }
 
    //Определение кодировки данных:
    LPSTR    lpszContentType = _strdup(getenv(CONTENT_TYPE));
    
    if(NULL == lpszContentType)  
    {
        p_gate->m_bContentType = GATE_CONTENT_URLENCODE;
    }
    else
    {
        LPSTR    lpszEncode = NULL;
        LPSTR    lpszBoundary = NULL;
        p_gate->m_bContentType = 0;
        if((lpszEncode = strstr(lpszContentType, "multipart/form-data")) != NULL)
        {
            if(lpszEncode == lpszContentType)  
            {
                p_gate->m_bContentType = GATE_CONTENT_MULTIPART;
 
                //Получаем разделитель:
                if((lpszBoundary = strstr(lpszContentType, "boundary=")) == NULL) return FALSE;
                else
                {
                    lpszBoundary+=strlen("boundary=");
                    p_gate->m_wBoundarySize = (strlen(lpszBoundary) + 1);
                    p_gate->m_pBoundary = (PBYTE)malloc(p_gate->m_wBoundarySize);
                    memcpy(p_gate->m_pBoundary, lpszBoundary, p_gate->m_wBoundarySize);
                    if(p_gate->m_wBoundarySize < 2) return FALSE;
                }
            }
        }
        if(0 == p_gate->m_bContentType) p_gate->m_bContentType = GATE_CONTENT_URLENCODE;
    }
 
 
    if(lpszContentType) ::free(lpszContentType);  
    
    p_gate->m_lpszUserName = _strdup(getenv(REMOTE_USER));  
    //strlen(getenv(REMOTE_USER)));
 
    //Вот тут то и начинаем вытаскивать контент:
    switch(p_gate->m_bMethod)
    {
    case GATE_METHOD_GET:  
        {
            //URL only:
            p_gate->m_uContentSize = strlen(getenv(QUERY_STRING));
            p_gate->m_lpszContentBuff = (LPSTR)malloc(p_gate->m_uContentSize + 1);
            
            if(NULL == p_gate->m_lpszContentBuff) return FALSE;
 
            memcpy(p_gate->m_lpszContentBuff, getenv(QUERY_STRING), p_gate->m_uContentSize);
            p_gate->m_lpszContentBuff[p_gate->m_uContentSize] = '\0';
            p_gate->m_lpszQuery = p_gate->m_lpszContentBuff;
            p_gate->m_uQuerySize = p_gate->m_uContentSize;
        } break;
    case GATE_METHOD_POST:  
        {
            //HTTP:
            p_gate->m_uContentSize = (unsigned int)atoi(getenv(CONTENT_LENGTH));
 
            //Проверка на  превышение Content Size Limit:
            if(p_gate->m_uContentSize > p_gate->m_dwCSLimit) return FALSE;
 
            p_gate->m_lpszContentBuff = (LPSTR)malloc(p_gate->m_uContentSize + 1);
            
            if(NULL == p_gate->m_lpszContentBuff) return FALSE;
 
            switch(p_gate->m_bContentType)
            {
            case GATE_CONTENT_URLENCODE:
                {
                    fread(p_gate->m_lpszContentBuff, p_gate->m_uContentSize, 1, stdin);
                    p_gate->m_lpszContentBuff[p_gate->m_uContentSize] = '\0';
                } break;
            case GATE_CONTENT_MULTIPART:
                {
//А вот тут как раз и засада вся!!!
//Я уже вся ко пробовал и кусками читать по 1024 байта и по 512 байт читать пробовал
//И размер буфера менять, и переназначать буффер ввода на выделенную собой же память и т.д. и т.п. но после первых 1024 байт идёт пустотота!!!!
                } break;
            }
 
            //URL:
            p_gate->m_lpszQuery = _strdup(getenv(QUERY_STRING));
            if(NULL != p_gate->m_lpszQuery) p_gate->m_uQuerySize = strlen(p_gate->m_lpszQuery);
        } break;
    }
    
    return TRUE;  
}
 

 
 
3. putc(c, save);  - а зачем принимаемые данные записывать прямо в тот модуль, который  
собсно и выполняет у тебя их приём save же утебя поток на cgi.bin?
4. На настройки сервера твоего было бы любопытно взглянуть - может у меня из-за них проблемы (тот сервер на которм сейчас всё работает - я его настраивал перввый раз в жизни ).  
 
   

Всего записей: 31 | Зарегистр. 13-10-2005 | Отправлено: 11:56 09-05-2007 | Исправлено: Bave, 11:57 09-05-2007
Bave

Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Заработало!!!!!!
-----------------------------
Я заменил, чтение с помощью fread на побайтовое чтение используя getchar и всё - весь контент прощёл - кидаюсь файлами по 10 по 20 kb и они тока так проходят -Круто!!!!
Тока не понятно почему при использовании fread часть контента терялась?!
 
Сейчас у меня вот так сделано:

Код:
 
case GATE_CONTENT_MULTIPART:
{    
#ifdef _DEBUG
    BOOL isdbg = FALSE;
#endif
 
BYTE    bOctet = 0;
 
for(unsigned int index = 0; index < p_gate->m_uContentSize; index++)
{
                    
      bOctet = getchar();
      p_gate->m_lpszContentBuff[index] = bOctet;
#ifdef _DEBUG
      if((index > 1124) && (isdbg))
      {
            __asm _emit 0xCC
       }
#endif
}
//....
 
// ...
} break;
 

---------------------
Спасибо за помощь, ато я уже был на грани совершения суецида апстену.

Всего записей: 31 | Зарегистр. 13-10-2005 | Отправлено: 18:20 09-05-2007
Открыть новую тему     Написать ответ в эту тему

Страницы: 1 2 3

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » CGI-скрипты на языке C


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2025

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru