Version: v0.1.0 | Language: C++23 | Build: CMake 3.14+ + Make
make deps # Install system dependencies via apt
make release # Build release mode (default)
make debug # Build debug mode
make clean # Remove build directory
# Direct CMake
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make -j$(nproc)
./bin/pacprismNo automated test framework - manual testing only:
# Run full integration test suite
cd test && bash test_pacprism.sh
# Run individual test manually
./build/bin/pacprism & # Start server in background
curl http://localhost:9001/ # Test 1: Basic request
curl http://localhost:9001/debian/README # Test 2: File download
curl -H "Range: bytes=0-1023" http://localhost:9001/debian/README # Test 3: Range request
curl -H "If-None-Match: <etag>" http://localhost:9001/debian/README # Test 4: Conditional
curl http://localhost:9001/api/dht/verify/test_node # Test 5: DHT verifyNo lint commands - run make release to verify compilation.
- Header guards: Use
#pragma once(NOT#ifndefguards) - Include order: Standard library → Boost → Project headers
- Separate implementation in
.cppfrom declarations in.hpp - Headers go in
include/, sources insrc/
- Classes: PascalCase (
ServerTrans,FileCache,Validator) - Functions/Methods: snake_case (
get_or_fetch,verify_entry,start_accept) - Variables: snake_case (
node_id,cache_path,http_code) - Member variables:
m_prefix (m_io_context,m_router,m_cache) - Constants: UPPER_SNAKE_CASE (
MAX_RETRIES,BUFFER_SIZE) - Types: PascalCase for user-defined (
RequestType,RangeInfo,dht_entry) - Namespaces: lowercase (
beast,http,net,fsfor Boost.Beast aliases)
- Indentation: 4 spaces (no tabs)
- Braces: K&R style (opening brace on same line)
- Line length: Keep under 100-120 characters
- Comments: Minimal - do NOT add comments unless explicitly requested
- Blank lines: Single blank line between functions, two between sections
- Use
std::shared_ptr<T>for response objects - Use
std::variant<T1, T2, ...>for multiple response types - Pass large objects by
const std::string&reference - Use references for dependency injection (
DHT_operation& dht) - Use
std::unique_ptrfor exclusive ownership (std::unique_ptr<tcp::acceptor>) - Use
autowith lambdas and iterators, explicit types otherwise
namespace beast = boost::beast;
namespace http = beast::http;
namespace net = boost::asio;
using tcp = net::ip::tcp;
// Response types
using router_response = std::variant<
std::shared_ptr<http::response<http::string_body>>,
std::shared_ptr<http::response<http::file_body>>,
std::shared_ptr<http::response<http::empty_body>>
>;- Use
try-catchfor Boost.Beast operations and JSON parsing - Print errors to
std::cerrwith descriptive messages - Return appropriate HTTP status codes via
default_response_builder() - Check error codes:
if (ec) { std::cerr << "Error: " << ec.message(); return; } - Use
boolreturn values for simple validation functions - Throw
std::runtime_errorfor recoverable errors with retry logic
Factory Pattern with Private Constructor:
class ServerTrans {
public:
static std::shared_ptr<ServerTrans> create(net::io_context& io, Router& router) {
return std::shared_ptr<ServerTrans>(new ServerTrans(io, router));
}
private:
explicit ServerTrans(net::io_context& io, Router& router) : m_io_context(io), m_router(router) {}
};Dependency Injection:
class Router {
public:
Router(DHT_operation& dht, Validator& validator, FileCache& cache);
};HTTP Routing:
auto response = m_router.global_router(request);
std::visit([](auto&& r) {
http::async_write(*socket, *r, [](auto ec, auto) { /* handle */ });
}, response);File Operations:
beast::error_code ec;
response->body().open(cache_path.c_str(), beast::file_mode::read, ec);
if (ec) { std::cerr << "Failed to open: " << ec.message(); return nullptr; }- Add
.hpptoinclude/directory - Add
.cpptosrc/directory - Update
src/CMakeLists.txt:add_library(name SHARED source.cpp)configure_library_target(name)target_link_libraries(name PRIVATE dependencies)get_version_info(name)
- Link in main executable or other libraries
- Plain client: Direct paths (
/debian/...) or query param (/?target=/...) - Node API:
/api/dht/{operation}format (verify, store, query, clean/expiry, clean/liveness) - All responses: Set
"server"header with version info - Status codes: 200 OK, 201 Created, 206 Partial Content, 304 Not Modified, 4xx/5xx for errors
- Config file:
config/pacprism.conf(key=value format) - Access via
Configclass:config.get_upstream(),config.get_cache_dir() - Defaults: upstream=
ftp.debian.org, cache_dir=./cache
- No comments in code unless explicitly requested
- Linux-only - removed Windows support
- No automated tests - manual testing with curl only
- No linting - just ensure compilation succeeds
- No structured logging - use
std::cout/std::cerr - Dependencies: Boost.Beast, OpenSSL, nlohmann-json, cxxopts (via apt)