Сайт на C++ своими руками с помощью библиотеки cgicc

Хочешь уверенно проходить IT-интервью?

Готовься к IT-собеседованиям уверенно с AI-тренажёром T1!

Мы понимаем, как сложно подготовиться: стресс, алгоритмы, вопросы, от которых голова идёт кругом. Но с AI тренажёром всё гораздо проще.

💡 Почему Т1 тренажёр — это мастхэв?

  • Получишь настоящую обратную связь: где затык, что подтянуть и как стать лучше
  • Научишься не только решать задачи, но и объяснять своё решение так, чтобы интервьюер сказал: "Вау!".
  • Освоишь все этапы собеседования, от вопросов по алгоритмам до диалога о твоих целях.

Зачем листать миллион туториалов? Просто зайди в Т1 тренажёр, потренируйся и уверенно удиви интервьюеров. Мы не обещаем лёгкой прогулки, но обещаем, что будешь готов!

Реклама. ООО «Смарт Гико», ИНН 7743264341. Erid 2VtzqwP8vqy


Рассказываем об основах создания простого бэкенда для сайта на обычном шаред-хостинге с помощью языка C++ и библиотеки cgicc.

Серверное окружение

Если вы думаете, что бэк на C++ возможен только на выделенном сервере, это не так: большинство шаред-хостингов имеют такую возможность. Любой веб-хост, который поддерживает CGI, поддерживает и C++ скрипты.

В зависимости от провайдера вы можете иметь или не иметь возможность компилировать сайт локально. Если вы собираетесь редактировать и компилировать скрипты через SSH, заранее об этом узнайте.

Простой пример

В примере будет рассматриваться шаред-хостинг с панелью на cPanel, но описание легко адаптируется под любой другой. cPanel предоставляет отдельный каталог cgi-bin, но использовать именно его не обязательно.

Любой файл с расширением .cgi будет автоматически обработан, если имеет корректные права доступа (обычно 0755). Ниже описаны необходимые файлы (убедитесь что используете табуляцию для отступов в Makefile).

Makefile:

all:
        g++ -O3 -s hello.cpp -o hello.cgi
clean:
        rm -f hello.cgi

hello.cpp:

#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;
void set_content_type(string content_type) {
  cout << “Content-type: “ << content_type << “\r\n\r\n”;
}
void set_page_title(string title) {
  cout << “<title>” << title << “</title>\n”;
}
void h1_text(string text) {
  cout << text << “\n”;
}
int main() {
  set_content_type(“text/html”);
  cout << “<!doctype html>\n”;
  cout << “<html lang=\”en\”>\n”;
  cout << “<head>\n”;
  set_page_title(“Hello, World!”);
  cout << “</head>\n”;
  cout << “<body>\n”;
  h1_text(“Hello, World!”);
  cout << “</body>\n”;
  cout << “</html>”;
  return 0;
}

Если на вашем аккаунте доступен компилятор (можно уточнить в техподдержке хостера), просто подключитесь к серверу по SSH переместите файлы в каталог public_html (можно и по FTP) и запустите в консоли:

make

Теперь попробуйте открыть файл в браузере:

http://your-test-site.com/hello.cgi

Вы должны увидеть на экране «Hello World».

Прежде, чем начать разбираться с кодом, давайте выясним, что происходит на сервере. Когда Apache получает запрос, он первым делом проверяет встроенный обработчик или RewriteRule, затем проверяет наличие запрашиваемого файла на диске. В нашем случае, он найдет hello.cgi и исполнит его: программа не принимает никаких данных, а просто возвращает строку. Apache возвращает строку в виде корректного ответа для браузера.

Что касается кода в текущем виде, то он написан не лучшим образом. Все, что он может делать, – отдавать строку текста, и при этом никак не структурирован. Чтобы обработка тегов выглядела опрятней и была более расширяемой, можно добавить функции для выдачи тегов, например:

void p(string text) {
  cout << “<p>” << text << “</p>\n”;
}

Таким образом, получается аккуратная обертка для параграфа:

p(“This would be paragraph text.”);

Входные данные

Обрабатывая запросы, веб-сервер передает огромное количество информации, которая хранится в переменных окружения. Чтобы получить к ней доступ, можно воспользоваться функцией getenv() из стандартной библиотеки C (не забудьте про #include <stdlib.h> в шапке файла).

К примеру, если нужно узнать запрашиваемый URI целиком, можно использовать:

string request_uri = getenv(“REQUEST_URI”);

Вот еще несколько полезных примеров:

  • REMOTE_ADDR – получить IP адрес посетителя.
  • REQUEST_METHOD – вернет метод запроса (GET, POST и так далее).
  • DOCUMENT_ROOT – получить путь к корневому каталогу.
  • QUERY_STRING – можно использовать для получения переменных из GET.

Пример с использованием cgicc

Разбираться с переменными из GET и POST-запросами, конечно, можно и вручную, но это утомительное занятие. Нужно либо писать собственные обертки, либо использовать существующую библиотеку (в нашем примере – cgicc), которая поможет работать с HTML и обрабатывать данные форм. Использование библиотек для крупных проектов позволит сохранить уйму времени.

На Debian и Ubuntu можно устанавливать библиотеки из консоли, используя утилиту apt:

apt install libcgicc5 libcgicc5-dev

На CentOS/RHEL с установкой пакетов сложнее, так что придется использовать:

cd /usr/local/src
wget ftp://ftp.gnu.org/gnu/cgicc/cgicc-3.2.19.tar.gz
tar xfz cgicc*.tar.gz
cd cgicc*
./configure — prefix=/usr
make
make install

Обратите внимание, что версия 3.2.19 актуальна на момент написания заметки. Актуальную версию можно найти в ftp://ftp.gnu.org/gnu/cgicc/ (подключитесь по через ваш FTP-клиент).

Как только библиотека установлена, можно использовать ее в проекте. Рассмотрим пример, который принимает и обрабатывает пользовательский ввод в браузере.

Makefile:

all:
        g++ -O3 -s hello.cpp -o hello.cgi
        g++ -O3 -s cgicc.cpp -o cgicc.cgi /usr/lib/libcgicc.a
clean:
        rm -f hello.cgi cgicc.cgi

cgicc.html:

<!doctype html>
<html lang="en">
<head>
  <title>cgicc Test</title>
</head>
<body>
  <form method="POST" action="cgicc.cgi">
    <label for="name">Name</label>
    <input name="name" type="text" value="">
    <input name="submit" type="submit" value="Submit">
  </form>
</body>
</html>

cgicc.cpp:

#include <iostream>
#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;
void set_content_type(string content_type) {
  cout << “Content-type: “ << content_type << “\r\n\r\n”;
}
void set_page_title(string title) {
  cout << “<title>” << title << “</title>\n”;
}
void h1_text(string text) {
  cout << text << “\n”;
}
int main() {
  Cgicc cgi;
  string name;
  set_content_type(“text/html”);
  cout << “<!doctype html>\n”;
  cout << “<html lang=\”en\”>\n”;
  cout << “<head>\n”;
  set_page_title(“cgicc Test”);
  cout << “</head>\n”;
  cout << “<body>\n”;
  cout << “<p>”;

  name = cgi(“name”);

  if (!name.empty()) {
    cout << “Name is “ << name << “\n”;
  } else {
    cout << “Name was not provided.”;
  }
  cout << “</p>\n”;
  cout << “</body>\n”;
  cout << “</html>”;
  return 0;
}

В этом примере cgicc помогает нам парсить POST и возвращает поле name. Этот пример упрощен и данные поле при попадании на сервер не проходят дополнительную обработку, что необходимо сделать на рабочем сайте, особенно, если будет взаимодействовать с базой данных.

Производительность

C++ известен своей быстротой, но это справедливо, если вы умеете писать на нем хороший код. Интерфейс CGI также несколько замедляет скорость работы приложения, но вы все равно получаете преимущество в скорости над интерпретируемыми языками, вроде PHP.

Вас также могут заинтересовать другие статьи по теме:

МЕРОПРИЯТИЯ

Комментарии

ВАКАНСИИ

Добавить вакансию
Hotel Search Team Lead (Golang)
по итогам собеседования
Golang-разработчик
Пермь, по итогам собеседования

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ