Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» CGI-скрипты на языке C

Автор: Brodyaga
Дата сообщения: 22.01.2006 18:11
ALL, будьте добры, есть ли какое нибудь Get Started по созданию CGI скриптов на С++?
Просто понять, как что и куда кампилить.
Автор: m31
Дата сообщения: 22.01.2006 18:34
это просто. почитай в мануалах к своему апачу. там просто компилишь с-шную программу, эксешник размещаешь в той директории где у тебя лежат cgi скрипты, обычно это localhost/cgi-bin/
Автор: Brodyaga
Дата сообщения: 22.01.2006 20:15
А если я собираюсь использовать С на хостинге?
Автор: vndovr
Дата сообщения: 22.01.2006 21:38
http://cgi.resourceindex.com/Programs_and_Scripts/C_and_C++/Libraries_and_Classes/
Автор: Brodyaga
Дата сообщения: 23.01.2006 13:07
Спасибо, качаю CGI++
Пытался скачать компилер BloodShed, не вышло, линк мертвый..
Есть ли компилер, маленького размера?
А то все что я вижу в теме выбор компилятора слишком велико для моего доступа
Автор: vndovr
Дата сообщения: 23.01.2006 14:31
http://www.microsoft.com/downloads/details.aspx?FamilyID=272be09d-40bb-49fd-9cb0-4bfa122fa91b&displaylang=en

Это только command line (VC++) - без среды
Автор: Brodyaga
Дата сообщения: 23.01.2006 15:26
31.4 MB
В следующем месяце на чистом траффике начну качать
Автор: KADABRA
Дата сообщения: 23.01.2006 16:04
Brodyaga

Цитата:
Есть ли компилер, маленького размера?

MinGW http://www.mingw.org/download.shtml
Автор: Brodyaga
Дата сообщения: 23.01.2006 16:20
Куда не ткнусь, 404 ашипка, может у меня с подключением проблемы?
Или SF глючит?
пробовал качать Current MinGW Runtime, MSYS
Автор: vjunk
Дата сообщения: 24.01.2006 16:32
m31
Программа работает на Windows или на Unix?
Если на Windows - то проблема с режимом работы stdout - он не двоичный
а текстовый по умолчанию.
Автор: m31
Дата сообщения: 24.01.2006 16:42
программа тестировалась в винде, не подскажете, как открыть в двоичном режиме. Спасибо за помощь!!!!!!!!

Добавлено:
vjunk
так fwrite, по-моему применяется только в двоичном режиме, оно туда пишет, но пишет не полностью так как хотелось бы
Автор: vjunk
Дата сообщения: 25.01.2006 17:02
m31
Про двоичный режим хорошо написано здесь: http://www.mingw.org/MinGWiki/index.php/binary
Под Windows/DOS даже работа функций read/write зависит от режима открытия
файла, а уж работа всех функций буферизированного ввода/вывода и подавно.
Автор: m31
Дата сообщения: 31.01.2006 17:07
Результат тот же!!! Так что проблема видимо не в этом!
Автор: vjunk
Дата сообщения: 01.02.2006 13:16
m31
Ну, тогда не знаю. На Windows я проверить не могу, а на Linux работает.
Попробуй перед концом main добавить fflush(stdout) - может проблема с
буферизацией.
Автор: Aeriss
Дата сообщения: 11.03.2007 17:02
При попытке выполнения 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с я рассчитываю подсоединиться к процессу и отлаживать его средствами среды разработки
....
Автор: Bave
Дата сообщения: 07.05.2007 00:03
Есть проблема с загрузкой файлов на сервер. Поскольку говорят, что давать ссылки на другие форумы это не хорошо - я просто скопировал свой вопрос с другого форума так как есть:

Цитата:

Доброго времени суторк,
Есть проблема с загрузкой файлов на сервер (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шники, которые с такими проблемами ессесвено не сталкивались
Автор: vjunk
Дата сообщения: 08.05.2007 20:10
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;
}
Автор: Bave
Дата сообщения: 09.05.2007 10:56
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;
}
Автор: Bave
Дата сообщения: 09.05.2007 17:20
Заработало!!!!!!
-----------------------------
Я заменил, чтение с помощью 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;

Страницы: 12

Предыдущая тема: TShellTreeView (Делфи)


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.