Cutelyst [1] — это высокопроизводительный веб-фреймворк на C++, построенный поверх библиотеки Qt. Он вдохновлён подходом веб-фреймворка Catalyst (Perl) и предлагает интересную концепцию: возможность использовать один и тот же C++/Qt код как для настольных/мобильных приложений, так и для веб-приложений. API у Cutelyst очень похож на API Perl Catalyst.
[Ключевые концепции и философия]
Основная идея Cutelyst — повторное использование кода. Если вы уже разрабатываете приложения на C++/Qt для Windows, Linux, macOS, Android или iOS, вы можете задействовать ту же кодовую базу для создания веб-версии вашего продукта. Это позволяет:
- Сократить количество команд разработки — не нужно держать отдельные команды для разных платформ. - Унифицировать бизнес-логику — один и тот же код работает везде. - Снизить накладные расходы на поддержку — меньше дублирования функциональности.
Фреймворк использует метаобъектную систему Qt для интроспекции методов контроллеров и автоматической генерации соответствующих action-методов.
[Технические возможности]
Сетевые протоколы и сервер. Cutelyst включает встроенный кроссплатформенный сервер Cutelyst::Server, который поддерживает:
- HTTP/1.1 — конвейеризация и Keep-Alive. - HTTP/2 — апгрейд с H2, ALPN-согласование на HTTPS, прямой H2C. - FastCGI — с поддержкой конвейеризации. - WebSockets. - uWSGI — поддержка протоколов HTTP/1.0, FastCGI и uWSGI.
Сервер может работать как самостоятельно, так и за прокси-сервером (Apache, nginx) через UNIX-сокеты. Cutelyst поддерживает систему диспечеризации, request/response API, плагины придерживаются концепции Model/View/Controller (MVC), поддерживающей переиспользование кода.
[Архитектура]
Фреймворк построен вокруг следующих ключевых компонентов:
Компонент
Назначение
Application
Главный класс приложения
Controller
Базовый класс для контроллеров
Context
Контекст запроса — основной способ взаимодействия с request/response
Action
Представление методов контроллера как действий
Dispatcher
Маршрутизация запросов (Chain и Path типы)
Engine
Абстракция для серверных движков
View
Компоненты для рендеринга ответов
Шаблоны и представления. Cutelyst поддерживает несколько систем шаблонов через плагины:
- Cutelee — Qt-реализация шаблонизатора Django - Grantlee — ещё одна Qt-реализация Django-шаблонов - Clearsilver - JSON — для API-ответов
[Готовая функциональность (плагины)]
Из коробки доступно множество плагинов, закрывающих типовые задачи веб-разработки:
- Сессии (Session) — управление пользовательскими сессиями. - Аутентификация (Authentication) — с поддержкой PBKDF2. - Авторизация (RoleACL) — ролевая модель доступа. - Валидация ввода (Validator) — проверка входных данных. - Защита от CSRF (CSRFProtection). - Memcached — интеграция с кеш-сервером. - Обработка загрузок (Upload parser) — работа с файлами. - REST (ActionREST) — упрощённое создание REST API.
На официальной странице документации также упоминается интеграция с TOML-конфигурациями — можно загружать настройки из TOML-файлов с помощью `app.config()->loadFromFile('config.toml')`.
[Производительность и эффективность]
Одно из главных преимуществ Cutelyst — низкое потребление ресурсов. По заявлениям разработчиков, полноценная CMS на Cutelyst занимает около 5 МБ оперативной памяти, которая может разделяться между разными экземплярами приложения. Это достигается благодаря:
- Компилируемому C++ коду (вместо интерпретируемых языков) - Эффективному управлению памятью в Qt - Возможности шаринга памяти между процессами
Для асинхронной обработки предусмотрен класс ASync, однако документация предупреждает: не стоит использовать локальные QEventLoops, это может привести к падению.
[Установка и требования]
Минимальные требования:
- CMake ≥ 3.9 - Qt ≥ 5.6
Опционально:
- uWSGI ≥ 1.9
Процесс сборки:
mkdir build && cd build cmake .. -DCMAKE_INSTALL_PREFIX=/usr make make install
Для запуска приложения используется утилита cutelystd5-qt6 (или cutelyst5-qt6 для разработки):
cutelystd5-qt6 -M --lazy -a /path/to/cutelystapp.so --h1 localhost:3000
[Достоинства и недостатки]
Плюсы Cutelyst:
● Высокая производительность и малое потребление памяти (единицы мегабайт ОЗУ) ● Переиспользование C++/Qt кода между вебом и нативными приложениями ● Кроссплатформенность из коробки ● Стабильный ABI/API — тегированные версии (v1, v2, v3) поддерживаются отдельно ● Богатый набор встроенных плагинов (сессии, авторизация, валидация, CSRF, Memcached) ● Современные протоколы — HTTP/2, WebSockets ● Лицензирование — LGPLv2+ (библиотека) / MIT (заголовочные файлы, документация, примеры)
Минусы Cutelyst:
● Маленькое сообщество — нишевый фреймворк, найти готовые решения и помощь сложнее, чем у Django, Laravel или Express. ● Ограниченная экосистема — меньше готовых пакетов, интеграций с облачными сервисами и сторонними API. ● Сложность поиска разработчиков — C++ + Qt веб-разработка не самый распространённый стек. ● Документация местами отрывиста — примеры есть, но не всегда раскрываются сложные сценарии использования. ● Не подходит для быстрого прототипирования — C++ сборки дольше, чем "сохранил-обновил-страницу" в интерпретируемых языках.
Для каких проектов подходит. Идеальный сценарий использования:
- У вас уже есть C++/Qt приложение, и вы хотите добавить к нему веб-интерфейс. - Вы разрабатываете высоконагруженное API с жёсткими требованиями к памяти и скорости. - Вам нужна максимальная эффективность на ограниченных ресурсах (встраиваемые системы, IoT). - Вы — C++ разработчик и не хотите изучать другой стек ради веб-фронта.
Стоит рассмотреть альтернативы, если:
- Вам нужна огромная экосистема пакетов и готовых решений (тогда лучше Django/Node.js). - Вы быстро прототипируете и часто меняете требования. - Ваша команда не знакома с C++ и Qt.
Cutelyst — образцово нишевый фреймворк. Он отлично решает конкретную задачу: дать возможность C++/Qt разработчикам создавать производительные веб-приложения, переиспользуя существующий код. Если вы уже в экосистеме Qt — Cutelyst станет естественным и мощным продолжением вашего инструментария. Если же вы ищете mainstream-решение с огромным сообществом — стоит посмотреть в сторону более популярных фреймворков.
Q01. Зачем было писать еще один web-фреймворк? A01. Разработка ПО должна быть удобным процессом, и его поддержка должна быть простой. Большниству разработчиков было бы комфортнее использовать для разработки знакомые инструменты. Возможность использовать gdb для отладки приложений является большим плюсом.
Q02. Почему именно C++/Qt? A02. Выбор разработчика Cutelyst основывался на опыте разработки десктопных GUI-приложений на основе QtCore, QtNetwork и других полезных модулей, не включающих код GUI.
Q03. Cutelyst включает использование собственного HTTP-сервера? A03. Да, таки и есть. В процессе развития Cutelyst оказалось, что готовые реализации серверов вносили существенные ограничения на удобство использования, производительность и расход ресурсов. Существующая сейчас реализация Cutelyst WSGI является асинхронной, этот сервер может быть встроен в ваш исполняемый файл, использует намного меньше памяти и поддерживает WebSockets, FastCGI, HTTP/2, HTTP 1.1 Pipelining и Keep-Alive (начиная с версии 2.0.x).
Q04. Требуется ли писать HTML-код в C/C++? A04. И да, и нет. Гибкость Cutelyst позволяет использовать любой вид View. В настоящее время поддерживается система шаблонов ClearSilver и Grantlee (синтаксис Django), но вы можете легко генерировать HTML из кода C/C++ и добавлять в выходной буфер.
Q05. Насколько хорошо это работает? A05. См. бенчмарки TechEmpower в сравнени с другими фреймворками:
Хотя производительность довольно сложно измерить правильно, обычный результат - уменьшение расхода RAM в 8 раз и снижение задержки обработки запросов с 18 до 2 миллисекунд. Поскольку расход ресурсов приложения получается намного меньше, у вас появляется больше свободы на встраивание ваших шаблонов и порождение большего количества потоков [4].
Q06. Включает ли Cutelyst ORM базы данных? A06. Нет. Разработчики Cutelyst сознательно отказываются от «монолитной» концепции по типу Ruby on Rails или Django, где ORM является неотъемлемой частью фреймворка. Включение ORM (например, огромного QtSql с поддержкой всех возможных СУБД или написание своего) сделало бы ядро тяжелым. В C++ это особенно критично, так как увеличение зависимостей и размера библиотеки ведет к усложнению сборки и распространения.
Примечание: ORM (Object-Relational Mapping) это технология программирования, которая позволяет работать с данными в реляционной базе данных (SQL), используя объекты языка программирования, вместо того чтобы писать прямые SQL-запросы. Простыми словами, ORM — это переводчик между миром объектов (в коде) и миром таблиц (в базе данных).
Cutelyst строится на Qt, а в экосистеме Qt уже есть несколько попыток создать полноценный ORM (объектно-реляционное отображение). Разработчики справедливо рассуждают: зачем писать свой с нуля, когда можно взять один из существующих и интегрировать его через обычные C++/Qt механизмы? Это позволяет пользователю самому выбрать инструмент под свою задачу.
Однако у этого подхода есть и обратная сторона медалиВ отличие от фреймворков с «батарейками в комплекте» (как Django), Cutelyst не предоставляет готовой, протестированной и задокументированной интеграции ни с одним из ORM. Вы сами должны выбрать ORM, подключить его к проекту (через CMake), написать код для работы с БД, и обеспечить его взаимодействие с контекстом Cutelyst (например, передавать соединение с БД в контроллеры).
Q07. Для каких приложений предназначен Cutelyst - на стороне WEB-сервера или на стороне клиента (WEB-браузера)? A07. Cutelyst — это исключительно серверный (backend) веб-фреймворк. Он предназначен для написания кода, который выполняется на стороне веб-сервера, а не в браузере клиента. Cutelyst создан для того, чтобы на C++ и Qt писать серверную логику веб-приложений. Он обрабатывает HTTP-запросы, взаимодействует с базами данных и генерирует ответ. См. врезку "Работа на стороне сервера".
Cutelyst создан для того, чтобы на C++ и Qt писать серверную логику веб-приложений. Он обрабатывает HTTP-запросы, взаимодействует с базами данных и генерирует ответ.
В официальной документации Cutelyst прямо назван "C++ Web Framework built on top of Qt" (Веб-фреймворк на C++, построенный поверх Qt). SourceForge также подтверждает это: Cutelyst помогает создавать "быстрые и современные веб-приложения".
Что делает Cutelyst как backend-фреймворк:
● Принимает входящие HTTP-запросы: серверная часть обрабатывает запросы от браузеров и других клиентов. ● Формирует ответ: генерирует HTML-страницы (через шаблонизаторы вроде Cutelee) или возвращает JSON-данные (через ViewJson), которые отправляются обратно клиенту. ● Маршрутизация: направляет запросы к нужным контроллерам. ● Работа с данными: имеет встроенную поддержку асинхронных SQL-запросов. ● Предоставляет REST API: включает специальный ActionREST для удобного создания RESTful API. ● Управление безопасностью: предлагает плагины для аутентификации, авторизации и защиты от CSRF-атак.
Пример из официального руководства показывает, как Cutelyst обрабатывает POST-запросы для создания пользователей и сообщений, что является классической серверной задачей.
[Генерация HTML vs. REST API]
Cutelyst предоставляет инструменты для двух основных подходов к созданию веб-приложений. Выбор между ними зависит от того, что именно вы хотите делать на стороне клиента:
Аспект
Традиционный серверный рендеринг (Server-Side)
Современный REST API
Место генерации интерфейса
Сервер генерирует готовые HTML-страницы.
Сервер предоставляет только данные (обычно в JSON), а интерфейс полностью строится на стороне клиента.
Роль Cutelyst
Генерирует полные HTML-документы с помощью шаблонизаторов (например, Cutelee).
Служит бэкендом для API, обрабатывая запросы и возвращая JSON-данные.
Что на стороне клиента
Браузер просто отображает полученные HTML-страницы.
Браузер выполняет JavaScript-фреймворк (React, Vue, Angular), который запрашивает данные у API Cutelyst и динамически обновляет интерфейс.
Пример использования
Простые сайты, блоги, интернет-магазины, где важен SEO и быстрая загрузка первого экрана.
Сложные веб-приложения (например, онлайн-редакторы, панели управления), а также мобильные приложения, которые используют тот же API.
[Как запустить серверное приложение на Cutelyst]
Для запуска вашего Cutelyst-приложения используется специальная утилита cutelystd5-qt6. Она поднимает HTTP/HTTPS сервер, который может работать как самостоятельно, так и за прокси-сервером (например, Apache или nginx) .
Пример запуска сервера:
# Запуск приложения на HTTP порту 3000 cutelystd5-qt6 -M --lazy -a /path/to/cutelystapp.so --h1 localhost:3000
`-a` указывает путь к скомпилированной библиотеке вашего приложения, а `--h1` включает HTTP сервер.
Уникальность Cutelyst в том, что он позволяет переиспользовать C++/Qt код между серверной частью веб-приложения и нативными десктопными или мобильными приложениями. Это его главное преимущество. Например, вы можете написать логику расчетов на C++ и использовать её как в настольной программе, так и на сервере, обрабатывающем веб-запросы. Но сам Cutelyst (как библиотека) выполняется именно на сервере, а не на клиенте.
CSRF (Cross-Site Request Forgery) — тип атаки, при котором злоумышленник заставляет браузер аутентифицированного пользователя выполнить нежелательное действие на доверенном веб-сайте.
Как работает атака. CSRF-атака становится возможной из-за того, что браузеры автоматически отправляют сохранённые куки (включая сессионные) при каждом запросе к соответствующему домену. Классическая схема атаки выглядит так:
1. Пользователь входит на сайт (например, интернет-банк) и получает аутентификационную куку. 2. Пользователь посещает вредоносный сайт (по ссылке из письма или рекламы). 3. Вредоносный сайт отправляет поддельный запрос на сайт банка — через скрытую форму, JavaScript или тег < img>. 4. Браузер автоматически добавляет куку аутентификации к этому запросу. 5. Сервер выполняет действие (перевод денег, смена пароля) от имени пользователя.
Важно понимать: CSRF нацелена на запросы, изменяющие состояние (POST, PUT, DELETE). Злоумышленник не может украсть данные, потому что не видит ответ сервера — он только инициирует действие.
Пример GET-атаки:
< !-- Вредоносный сайт может разместить такое изображение -->
< imgsrc="https://bank.com/transfer.do?acct=HACKER&amount=100000"width="0"height="0">
Браузер жертвы загрузит эту "картинку" и выполнит перевод денег без какого-либо визуального уведомления.
3. Принудительно включаем защиту для действия в исключённом пространстве имён:
Если вы исключили целое пространство имён (`setIgnoredNamespaces({"foo"})`), но хотите защитить конкретное действие, используйте :CSRFRequire:
classFoo:publicCutelyst::Controller
{ C_NAMESPACE("foo") public: // Это действие находится в исключённом пространстве имён, // но требует защиты C_ATTR(edit,:Path:CSRFRequire) voidedit(Context*c);
};
[Работа с шаблонами Cutelee]
В HTML-форму нужно добавить скрытое поле с CSRF-токеном. Для этого в шаблонах Cutelee используется специальный тег:
Разработчики Cutelyst особо отмечают одну уязвимость: поддомены могут обходить защиту CSRF. Если у вас есть поддомен (например evil.example.com) и он может устанавливать куки для основного домена .example.com, то этот поддомен сможет подделать токен и обойти защиту.
Решение: доверяйте поддомены только надёжным пользователям или приложениям.
[Принцип работы (как это устроено внутри)]
Плагин CSRFProtection работает по следующему алгоритму:
1. На каждом запросе генерируется секретный токен (с солью). 2. Токен сохраняется в куке или в сессии пользователя. 3. При отправке формы токен должен вернуться либо в скрытом поле формы, либо в заголовке `X-CSRFToken`. 4. Сервер сравнивает полученный токен с сохранённым. 5. Если токены совпадают — запрос выполняется. Если нет — возвращается ошибка 403.
Этот механизм гарантирует, что злоумышленник, не имеющий доступа к куке и не могущий предугадать случайный токен, не сможет сформировать легитимный поддельный запрос.