@re-shell/cli
Version:
Full-stack development platform uniting microservices and microfrontends. Build complete applications with .NET (ASP.NET Core Web API, Minimal API), Java (Spring Boot, Quarkus, Micronaut, Vert.x), Rust (Actix-Web, Warp, Rocket, Axum), Python (FastAPI, Dja
604 lines (504 loc) • 14.9 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.beastTemplate = void 0;
exports.beastTemplate = {
id: 'beast',
name: 'beast',
displayName: 'Boost.Beast WebSocket & HTTP',
description: 'Modern C++ library for HTTP, WebSocket, and networking protocols built on Boost.Asio',
framework: 'beast',
language: 'cpp',
version: '1.83.0',
tags: ['cpp', 'beast', 'boost', 'websocket', 'http', 'async', 'networking'],
port: 8085,
features: ['websockets', 'authentication', 'cors', 'logging', 'testing', 'docker'],
dependencies: {},
devDependencies: {},
files: {
// CMakeLists.txt
'CMakeLists.txt': `cmake_minimum_required(VERSION 3.16)
project({{serviceName}} VERSION 1.0.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# Find packages
find_package(Boost 1.83 REQUIRED COMPONENTS system thread)
find_package(Threads REQUIRED)
find_package(OpenSSL REQUIRED)
# Include FetchContent
include(FetchContent)
# Fetch nlohmann/json
FetchContent_Declare(
json
GIT_REPOSITORY https://github.com/nlohmann/json.git
GIT_TAG v3.11.3
)
FetchContent_MakeAvailable(json)
# Fetch spdlog
FetchContent_Declare(
spdlog
GIT_REPOSITORY https://github.com/gabime/spdlog.git
GIT_TAG v1.12.0
)
FetchContent_MakeAvailable(spdlog)
# Fetch jwt-cpp
FetchContent_Declare(
jwt-cpp
GIT_REPOSITORY https://github.com/Thalhammer/jwt-cpp.git
GIT_TAG v0.7.0
)
FetchContent_MakeAvailable(jwt-cpp)
# Fetch Google Test
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG v1.14.0
)
FetchContent_MakeAvailable(googletest)
# Source files
set(SOURCES
src/main.cpp
src/server/http_server.cpp
src/server/websocket_server.cpp
src/handlers/http_handler.cpp
src/handlers/websocket_handler.cpp
src/handlers/api_handler.cpp
src/session/session_manager.cpp
src/middleware/auth_middleware.cpp
src/middleware/cors_middleware.cpp
src/middleware/logging_middleware.cpp
src/services/user_service.cpp
src/utils/jwt_utils.cpp
src/utils/ssl_context.cpp
src/config/config.cpp
)
# Main executable
add_executable(\${PROJECT_NAME} \${SOURCES})
target_include_directories(\${PROJECT_NAME} PRIVATE
\${CMAKE_CURRENT_SOURCE_DIR}/include
\${Boost_INCLUDE_DIRS}
)
target_link_libraries(\${PROJECT_NAME} PRIVATE
\${Boost_LIBRARIES}
nlohmann_json::nlohmann_json
spdlog::spdlog
jwt-cpp::jwt-cpp
\${CMAKE_THREAD_LIBS_INIT}
\${OPENSSL_LIBRARIES}
)
# Compiler options
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
target_compile_options(\${PROJECT_NAME} PRIVATE
-Wall -Wextra -Wpedantic -Wno-unused-parameter
$<$<CONFIG:Debug>:-g -O0>
$<$<CONFIG:Release>:-O3>
)
endif()
# Tests
enable_testing()
add_executable(tests
tests/test_main.cpp
tests/test_http_handler.cpp
tests/test_websocket_handler.cpp
tests/test_auth.cpp
)
target_link_libraries(tests PRIVATE
\${Boost_LIBRARIES}
nlohmann_json::nlohmann_json
spdlog::spdlog
jwt-cpp::jwt-cpp
GTest::gtest
GTest::gtest_main
\${CMAKE_THREAD_LIBS_INIT}
\${OPENSSL_LIBRARIES}
)
target_include_directories(tests PRIVATE
\${CMAKE_CURRENT_SOURCE_DIR}/include
\${Boost_INCLUDE_DIRS}
)
add_test(NAME unit_tests COMMAND tests)
`,
// Main application
'src/main.cpp': `
std::atomic<bool> running{true};
void signal_handler(int signal) {
spdlog::info("Received signal {}, shutting down...", signal);
running = false;
}
int main(int argc, char* argv[]) {
try {
// Setup logging
auto console = spdlog::stdout_color_mt("console");
spdlog::set_default_logger(console);
spdlog::set_level(spdlog::level::info);
spdlog::set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%^%l%$] [thread %t] %v");
// Setup signal handling
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
// Load configuration
auto config = Config::load("config.json");
// Create io_context
boost::asio::io_context ioc{config.threads};
// Create HTTP server
auto http_server = std::make_shared<HttpServer>(ioc, config);
http_server->start();
// Create WebSocket server
auto ws_server = std::make_shared<WebSocketServer>(ioc, config);
ws_server->start();
spdlog::info("{{serviceName}} started on port {} (HTTP) and {} (WebSocket)",
config.http_port, config.ws_port);
// Run the I/O service on multiple threads
std::vector<std::thread> threads;
threads.reserve(config.threads - 1);
for(auto i = config.threads - 1; i > 0; --i) {
threads.emplace_back([&ioc] {
ioc.run();
});
}
// Run on main thread
while (running) {
try {
ioc.run();
break;
} catch (std::exception& e) {
spdlog::error("Error in main loop: {}", e.what());
}
}
// Stop servers
http_server->stop();
ws_server->stop();
// Join threads
for(auto& t : threads) {
t.join();
}
spdlog::info("{{serviceName}} shutdown complete");
return 0;
}
catch (std::exception& e) {
spdlog::error("Fatal error: {}", e.what());
return 1;
}
}
`,
// Configuration
'include/config/config.hpp': `
struct Config {
std::string host = "0.0.0.0";
unsigned short http_port = {{port}};
unsigned short ws_port = {{port}} + 1;
int threads = 4;
bool use_ssl = false;
std::string cert_path;
std::string key_path;
std::string jwt_secret = "your-secret-key-change-in-production";
int jwt_expiry_hours = 24;
std::string cors_origin = "*";
bool enable_cors = true;
std::string log_level = "info";
static Config load(const std::string& filename);
void save(const std::string& filename) const;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(Config, host, http_port, ws_port, threads,
use_ssl, cert_path, key_path, jwt_secret,
jwt_expiry_hours, cors_origin, enable_cors, log_level)
};
`,
'src/config/config.cpp': `
Config Config::load(const std::string& filename) {
Config config;
try {
std::ifstream file(filename);
if (file.is_open()) {
nlohmann::json j;
file >> j;
config = j.get<Config>();
spdlog::info("Configuration loaded from {}", filename);
} else {
spdlog::warn("Configuration file {} not found, using defaults", filename);
// Save default config
config.save(filename);
}
} catch (const std::exception& e) {
spdlog::error("Error loading configuration: {}", e.what());
}
return config;
}
void Config::save(const std::string& filename) const {
try {
nlohmann::json j = *this;
std::ofstream file(filename);
file << j.dump(4);
spdlog::info("Configuration saved to {}", filename);
} catch (const std::exception& e) {
spdlog::error("Error saving configuration: {}", e.what());
}
}
`,
// HTTP Server
'include/server/http_server.hpp': `
namespace beast = boost::beast;
namespace http = beast::http;
namespace net = boost::asio;
namespace ssl = boost::asio::ssl;
using tcp = boost::asio::ip::tcp;
class HttpServer : public std::enable_shared_from_this<HttpServer> {
public:
HttpServer(net::io_context& ioc, const Config& config);
~HttpServer();
void start();
void stop();
private:
void do_accept();
void on_accept(beast::error_code ec, tcp::socket socket);
net::io_context& ioc_;
const Config& config_;
tcp::acceptor acceptor_;
std::shared_ptr<ssl::context> ssl_ctx_;
};
`,
'src/server/http_server.cpp': `
HttpServer::HttpServer(net::io_context& ioc, const Config& config)
: ioc_(ioc)
, config_(config)
, acceptor_(net::make_strand(ioc)) {
if (config_.use_ssl) {
ssl_ctx_ = create_ssl_context(config_.cert_path, config_.key_path);
}
}
HttpServer::~HttpServer() {
stop();
}
void HttpServer::start() {
beast::error_code ec;
// Open the acceptor
tcp::endpoint endpoint{net::ip::make_address(config_.host), config_.http_port};
acceptor_.open(endpoint.protocol(), ec);
if (ec) {
spdlog::error("Failed to open acceptor: {}", ec.message());
return;
}
// Allow address reuse
acceptor_.set_option(net::socket_base::reuse_address(true), ec);
if (ec) {
spdlog::error("Failed to set socket option: {}", ec.message());
return;
}
// Bind to the server address
acceptor_.bind(endpoint, ec);
if (ec) {
spdlog::error("Failed to bind: {}", ec.message());
return;
}
// Start listening
acceptor_.listen(net::socket_base::max_listen_connections, ec);
if (ec) {
spdlog::error("Failed to listen: {}", ec.message());
return;
}
spdlog::info("HTTP server listening on {}:{}", config_.host, config_.http_port);
do_accept();
}
void HttpServer::stop() {
beast::error_code ec;
acceptor_.close(ec);
if (ec) {
spdlog::error("Error closing acceptor: {}", ec.message());
}
}
void HttpServer::do_accept() {
acceptor_.async_accept(
net::make_strand(ioc_),
beast::bind_front_handler(&HttpServer::on_accept, shared_from_this()));
}
void HttpServer::on_accept(beast::error_code ec, tcp::socket socket) {
if (ec) {
spdlog::error("Accept failed: {}", ec.message());
} else {
// Create HTTP session
if (config_.use_ssl && ssl_ctx_) {
std::make_shared<HttpsSession>(std::move(socket), *ssl_ctx_, config_)->run();
} else {
std::make_shared<HttpSession>(std::move(socket), config_)->run();
}
}
// Accept another connection
do_accept();
}
`,
// WebSocket Server
'include/server/websocket_server.hpp': `
namespace beast = boost::beast;
namespace websocket = beast::websocket;
namespace net = boost::asio;
using tcp = boost::asio::ip::tcp;
class WebSocketServer : public std::enable_shared_from_this<WebSocketServer> {
public:
WebSocketServer(net::io_context& ioc, const Config& config);
~WebSocketServer();
void start();
void stop();
private:
void do_accept();
void on_accept(beast::error_code ec, tcp::socket socket);
net::io_context& ioc_;
const Config& config_;
tcp::acceptor acceptor_;
};
`,
// Dockerfile
'Dockerfile': `# Multi-stage build for C++ Beast application
FROM ubuntu:22.04 AS builder
# Install build dependencies
RUN apt-get update && apt-get install -y \\
build-essential \\
cmake \\
git \\
libboost-all-dev \\
libssl-dev \\
pkg-config \\
&& rm -rf /var/lib/apt/lists/*
# Set working directory
WORKDIR /app
# Copy source files
COPY . .
# Build the application
RUN mkdir build && cd build && \\
cmake -DCMAKE_BUILD_TYPE=Release .. && \\
make -j$(nproc)
# Runtime stage
FROM ubuntu:22.04
# Install runtime dependencies
RUN apt-get update && apt-get install -y \\
libboost-system1.74.0 \\
libboost-thread1.74.0 \\
libssl3 \\
&& rm -rf /var/lib/apt/lists/*
# Create non-root user
RUN useradd -m -u 1000 appuser
# Copy built application
COPY --from=builder /app/build/{{serviceName}} /usr/local/bin/
COPY --from=builder /app/config.json /etc/{{serviceName}}/
# Set ownership
RUN chown -R appuser:appuser /etc/{{serviceName}}
# Switch to non-root user
USER appuser
# Expose ports
EXPOSE {{port}} {{port}}+1
# Run the application
CMD ["{{serviceName}}"]
`,
// Package management
'conanfile.txt': `[requires]
boost/1.83.0
openssl/3.1.3
nlohmann_json/3.11.3
spdlog/1.12.0
jwt-cpp/0.7.0
gtest/1.14.0
[generators]
CMakeDeps
CMakeToolchain
[options]
boost:shared=True
boost:without_test=True
boost:without_python=True
boost:without_wave=True
boost:without_graph=True
boost:without_graph_parallel=True
boost:without_mpi=True
[imports]
bin, *.dll -> ./bin
lib, *.dylib* -> ./bin
lib, *.so* -> ./bin
`,
// README
'README.md': `# {{serviceName}}
A high-performance C++ server built with Boost.Beast for HTTP/HTTPS and WebSocket support.
## Features
- HTTP/HTTPS server with RESTful API
- WebSocket server for real-time communication
- JWT authentication
- CORS support
- Multi-threaded async I/O
- SSL/TLS support
- Structured logging with spdlog
- Docker support
## Requirements
- C++17 compiler
- CMake 3.16+
- Boost 1.83+
- OpenSSL
- Conan or vcpkg (optional)
## Building
\`\`\`bash
# Using CMake directly
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make -j$(nproc)
# Using Conan
conan install . --output-folder=build --build=missing
cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake
make -j$(nproc)
\`\`\`
## Running
\`\`\`bash
# Run with default config
./{{serviceName}}
# Run with custom config
./{{serviceName}} --config custom-config.json
\`\`\`
## Configuration
Edit \`config.json\` to customize:
- Server ports
- SSL certificates
- JWT settings
- CORS settings
- Thread pool size
## Testing
\`\`\`bash
cd build
ctest --verbose
\`\`\`
## Docker
\`\`\`bash
# Build image
docker build -t {{serviceName}} .
# Run container
docker run -p {{port}}:{{port}} -p $(({{port}}+1)):$(({{port}}+1)) {{serviceName}}
\`\`\`
## API Endpoints
- \`GET /health\` - Health check
- \`POST /api/auth/login\` - User login
- \`GET /api/users\` - List users (authenticated)
- \`WebSocket ws://localhost:$(({{port}}+1))/ws\` - WebSocket endpoint
`
}
};