Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Industrial programming >> Язык C

Веб-программирование на C++ с CGI: полное руководство

Что такое CGI?

Common Gateway Interface (CGI) — это набор стандартов, определяющих обмен информацией между веб-сервером и пользовательским скриптом. Спецификации CGI поддерживает NCSA. Текущая версия — CGI/1.1, CGI/1.2 в разработке.

Как работает веб-просмотр

  1. Браузер запрашивает URL у HTTP-сервера.
  2. Сервер разбирает URL, ищет файл. Если найден — отправляет его браузеру, иначе — ошибку.
  3. Браузер отображает полученный файл или сообщение об ошибке.

Однако сервер можно настроить так, чтобы файлы в определённой директории выполнялись как программы, а их вывод отправлялся браузеру. CGI-программы могут быть написаны на Python, Perl, Shell, C, C++ и др.

Архитектура CGI

Веб-программирование на C++ с CGI: полное руководство

Настройка веб-сервера

Перед началом убедитесь, что сервер поддерживает CGI и настроен на выполнение CGI-программ. По умолчанию Apache использует директорию /var/www/cgi-bin. CGI-файлы обычно имеют расширение .cgi (даже если это скомпилированные C++ программы).

Для изменения директории отредактируйте httpd.conf:

<Directory "/var/www/cgi-bin">
    AllowOverride None
    Options ExecCGI
    Order allow,deny
    Allow from all
</Directory>
<Directory "/var/www/cgi-bin">
    Options All
</Directory>

Первая CGI-программа на C++

#include <iostream>
using namespace std;

int main() {
    cout << "Content-type:text/html\r\n\r\n";
    cout << "<html>\n";
    cout << "<head>\n";
    cout << "<title>Hello World - First CGI Program</title>\n";
    cout << "</head>\n";
    cout << "<body>\n";
    cout << "<h2>Hello World! This is my first CGI program</h2>\n";
    cout << "</body>\n";
    cout << "</html>\n";
    return 0;
}

Скомпилируйте и назовите исполняемый файл cplusplus.cgi. Поместите в /var/www/cgi-bin и сделайте исполняемым: chmod 755 cplusplus.cgi.

Ключевая строка — Content-type:text/html\r\n\r\n. Она сообщает браузеру тип содержимого (MIME). Без неё браузер не поймёт, как отобрать вывод.

HTTP-заголовки

Заголовки имеют формат Имя: Значение. Основные заголовки:

№Заголовок и описание
1Content-type: MIME-тип возвращаемого файла (например, text/html).
2Expires: дата, когда информация устаревает (формат: 01 Jan 1998 12:00:00 GMT).
3Location: URL для перенаправления запроса.
4Last-modified: дата последнего изменения ресурса.
5Content-length: длина данных в байтах.
6Set-Cookie: установка cookie.

Переменные окружения CGI

CGI-программы имеют доступ к переменным окружения, важным для обработки запросов:

№Переменная и описание
1CONTENT_TYPE — тип данных, отправляемых клиентом (например, при загрузке файлов).
2CONTENT_LENGTH — длина данных запроса (только для POST).
3HTTP_COOKIE — установленные cookie в виде пар ключ-значение.
4HTTP_USER_AGENT — информация о браузере клиента.
5PATH_INFO — путь к CGI-скрипту.
6QUERY_STRING — URL-закодированные данные метода GET.
7REMOTE_ADDR — IP-адрес клиента.
8REMOTE_HOST — полное имя хоста клиента.
9REQUEST_METHOD — метод запроса (GET, POST).
10SCRIPT_FILENAME — полный путь к скрипту.
11SCRIPT_NAME — имя скрипта.
12SERVER_NAME — имя хоста или IP сервера.
13SERVER_SOFTWARE — название и версия ПО сервера.

Пример программы для вывода всех переменных окружения:

#include <iostream>
#include <stdlib.h>
using namespace std;

const string ENV[24] = {
    "COMSPEC", "DOCUMENT_ROOT", "GATEWAY_INTERFACE", "HTTP_ACCEPT",
    "HTTP_ACCEPT_ENCODING", "HTTP_ACCEPT_LANGUAGE", "HTTP_CONNECTION",
    "HTTP_HOST", "HTTP_USER_AGENT", "PATH", "QUERY_STRING", "REMOTE_ADDR",
    "REMOTE_PORT", "REQUEST_METHOD", "REQUEST_URI", "SCRIPT_FILENAME",
    "SCRIPT_NAME", "SERVER_ADDR", "SERVER_ADMIN", "SERVER_NAME",
    "SERVER_PORT", "SERVER_PROTOCOL", "SERVER_SIGNATURE", "SERVER_SOFTWARE"
};

int main() {
    cout << "Content-type:text/html\r\n\r\n";
    cout << "<html><head><title>CGI Environment Variables</title></head><body>";
    cout << "<table border=\"0\" cellspacing=\"2\">";
    for (int i = 0; i < 24; i++) {
        cout << "<tr><td>" << ENV[i] << "</td><td>";
        char *value = getenv(ENV[i].c_str());
        if (value) cout << value;
        else cout << "Environment variable does not exist.";
        cout << "</td></tr>\n";
    }
    cout << "</table></body></html>";
    return 0;
}

Библиотека C++ CGI (cgicc)

Для реальных задач удобно использовать библиотеку cgicc. Установка:

$ tar xzf cgicc-X.X.X.tar.gz
$ cd cgicc-X.X.X/
$ ./configure --prefix=/usr
$ make
$ make install

Методы GET и POST

Браузеры передают данные на сервер двумя основными способами: GET и POST.

GET-метод

Данные добавляются к URL после ?: https://example.com/cgi-bin/cpp.cgi?key1=value1&key2=value2. Ограничение — до 1024 символов. Не используйте для паролей. Данные доступны через переменную окружения QUERY_STRING.

Пример с библиотекой cgicc

#include <iostream>
#include <vector>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <cgicc/CgiDefs.h>
#include <cgicc/Cgicc.h>
#include <cgicc/HTTPHTMLHeader.h>
#include <cgicc/HTMLClasses.h>
using namespace std;
using namespace cgicc;

int main() {
    Cgicc formData;
    cout << "Content-type:text/html\r\n\r\n";
    cout << "<html><head><title>Using GET and POST Methods</title></head><body>";
    form_iterator fi = formData.getElement("first_name");
    if (!fi->isEmpty() && fi != (*formData).end()) {
        cout << "First name: " << **fi << endl;
    } else {
        cout << "No text entered for first name" << endl;
    }
    cout << "<br/>\n";
    fi = formData.getElement("last_name");
    if (!fi->isEmpty() && fi != (*formData).end()) {
        cout << "Last name: " << **fi << endl;
    } else {
        cout << "No text entered for last name" << endl;
    }
    cout << "<br/>\n</body></html>";
    return 0;
}

Компиляция: g++ -o cpp_get.cgi cpp_get.cpp -lcgicc

Вызов: /cgi-bin/cpp_get.cgi?first_name=ZARA&last_name=ALI

POST-метод

Более надёжный: данные передаются в теле запроса (stdin), а не в URL. Тот же CGI-скрипт обрабатывает и GET, и POST.

Передача данных формы: чекбоксы, радиокнопки, текстовые области, выпадающие списки

Для каждого типа элемента формы приводятся HTML-примеры и соответствующие C++ CGI-скрипты с использованием библиотеки cgicc. Основные методы:

Работа с Cookie

HTTP — протокол без состояния. Cookie позволяют сохранять информацию между страницами. Cookie устанавливаются через заголовок Set-Cookie перед строкой Content-type.

Установка cookie

cout << "Set-Cookie:UserID = XYZ;\r\n";
cout << "Set-Cookie:Password = XYZ123;\r\n";
cout << "Set-Cookie:Domain = www.example.com;\r\n";
cout << "Set-Cookie:Path = /perl;\n";
cout << "Content-type:text/html\r\n\r\n";

Получение cookie

Cookie хранятся в переменной окружения HTTP_COOKIE. Библиотека cgicc предоставляет итератор const_cookie_iterator для перебора.

Загрузка файлов

HTML-форма должна иметь enctype="multipart/form-data". В C++ используйте cgi.getFile("userfile") для получения загруженного файла и записи его в поток или сохранения на диск.

Язык C

  1. Освоение пространств имен в C#: организация, область видимости и лучшие практики
  2. Освоение операторов C++: полное руководство с практическими примерами
  3. Комментарии в C++: лучшие практики для читаемого и поддерживаемого кода
  4. Как передавать массивы в функции в C++: практическое руководство
  5. Освоение программирования на C: подробное руководство для начинающих
  6. Язык программирования C++: обзор и ключевые особенности
  7. Константы и литералы в C++: типы, синтаксис и лучшие практики
  8. Полное руководство по операторам C++: типы, использование и лучшие практики
  9. Работа с числовыми типами в C++: практическое руководство
  10. Ссылки в C++: ключевые концепции и отличия от указателей