Packages

Overview
Malloy is a small, embeddable HTTP & WebSocket server & client built on top of boost.
The main use case for this library is a C++ project which needs to embedd an HTTP and/or WebSocket server and/or client.
This library is being used successfully on:
- Windows (with both MSVC and MinGW)
- Linux (Ubuntu, Debian, Fedora, ...)
- MacOS
- FreeBSD
Features
The following list provides an overview of the currently implemented features. Some of these are optional and can be enabled/disabled.
- High-level controller to setup I/O context, SSL context, worker threads and more
- HTTP
- Plain or TLS (SSL) connections
- Cookies
- Sessions
- Upgrading connections to WebSocket
- Client
- Server
- Routing
- Simple handlers (useful for building REST APIs)
- Target matching via regex
- Capturing groups via regex
- Sub-routers (nested/chained routers)
- Redirections
- File serving locations
- Optional cache-control directives
- Preflight responses
- Access policies
- HTTP basic auth
- Custom access policies
- Websocket endpoints (with auto-upgrade from HTTP)
- Connection logging
- Request filters
- WebSocket
- Client
- Server
- Connections upgradable from HTTP
- HTML
- Forms
- Supported encoding types
application/x-www-form-urlencoded
multipart/form-data
text/plain
- Parsing
- Rendering
Licensing
This library is BSD-3-Clause licensed. Dependencies ship with their own licensing models.
Requirements
Building (and using) this library requires:
- A C++20 capable compiler
- GCC >= 10.3 (MinGW works!)
- Clang >= 13
- MSVC >= 19.29 (VS 2019)
- CMake 3.23 or newer
Dependencies
Required:
- Boost 1.79.0 or newer
- spdlog 1.8.3 or newer
- fmt 7.1.3 or newer (must be compatible with spdlog version)
Optional:
Examples
A variety of examples can be found in the /examples
directory. You should definitely check those out! What follows are snippets for a simple HTTP server and a simple HTTP client.
HTTP Server:
int main()
{
cfg.
logger = std::make_shared<spdlog::logger>();
auto& router = c.router();
{
router.add(method::get, "/", [](const auto& req) {
res.body() = "<html><body><h1>Hello World!</h1><p>some content...</p></body></html>";
return res;
});
router.add(method::get, "/file", [](const auto& req) {
return generator::file(examples_doc_root, "index.html");
});
router.add(method::get, "/file_nonexist", [](const auto& req) {
return generator::file(examples_doc_root, "/some_nonexisting_file.xzy");
});
router.add_redirect(status::permanent_redirect, "/redirect1", "/");
router.add_redirect(status::temporary_redirect, "/redirect2", "/");
router.add_file_serving("/files", examples_doc_root);
router.add_websocket("/echo", [](const auto& req, auto writer) {
std::make_shared<malloy::examples::ws::server_echo>(writer)->run(req);
});
}
start(std::move(c)).run();
return EXIT_SUCCESS;
}
Definition: response.hpp:22
A high-level controller.
Definition: routing_context.hpp:30
std::shared_ptr< spdlog::logger > logger
Definition: controller_run_result.hpp:28
std::size_t num_threads
Definition: controller_run_result.hpp:23
Definition: routing_context.hpp:39
std::string interface
Definition: routing_context.hpp:48
std::filesystem::path doc_root
Definition: routing_context.hpp:61
std::uint16_t port
Definition: routing_context.hpp:53
HTTP client:
int main()
{
cfg.
logger = create_example_logger();
[[maybe_unused]] auto session = start(c);
malloy::http::method::get,
"www.google.com",
80,
"/"
);
auto stop_token = c.http_request(req, [](auto&& resp) mutable {
std::cout << resp << std::endl;
});
const auto ec = stop_token.get();
if (ec) {
spdlog::error(ec.message());
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
Definition: controller.hpp:69
Definition: request.hpp:19
Definition: controller.hpp:81
Motivation
This started off with the intention of creating a more complex, real-world example of how to use boost.beast
.
Security
This is a work in progress and should generally be perceived as unfit for any production use.
As of today, no security research has been performed on this library.
Malloy is an open-source library provided WITHOUT any WARRANTY or GUARANTEE regarding security, safety, functionality or anything else. Use at your own risk!
Documentation
Available documentation sources:
- API documentation (doxygen)
Doxygen
The Doxygen API documentation can be generated with little hassle:
The generated output(s) may be found under /docs/doxygen
. Simply open /docs/doxygen/html/index.html
in the web browser of your choosing.
Integration
Malloy is designed to be an embeddable component for other C++ applications. As this is a CMake based project there are various ways to integrate this library into another project:
- Via CMake's
FetchContent()
.
- Building the library locally, installing it on the system and using CMake's
find_package()
.
- Installing the corresponding package for your OS/environment and using CMake's
find_package()
.
FetchContent()
The easiest way to integrate Malloy is via CMake's FetchContent()
infrastructure:
FetchContent_Declare(
malloy
GIT_REPOSITORY https://github.com/tectu/malloy
GIT_TAG main
)
FetchContent_MakeAvailable(malloy)
If you like to modify set some of Malloy's CMake variables, the FetchContent_MakeAvailable()
call can be replaced accordingly:
FetchContent_Declare(
malloy
GIT_REPOSITORY https://github.com/tectu/malloy
GIT_TAG main
)
FetchContent_GetProperties(malloy)
if(NOT malloy_POPULATED)
FetchContent_Populate(malloy)
# Change various malloy cmake options
set(MALLOY_BUILD_EXAMPLES OFF CACHE INTERNAL "")
set(MALLOY_BUILD_TESTS OFF CACHE INTERNAL "")
set(MALLOY_BUILD_SHARED ON CACHE INTERNAL "")
set(MALLOY_FEATURE_CLIENT OFF CACHE INTERNAL "")
set(MALLOY_FEATURE_SERVER ON CACHE INTERNAL "")
set(MALLOY_FEATURE_TLS ON CACHE INTERNAL "")
add_subdirectory(${malloy_SOURCE_DIR} ${malloy_BINARY_DIR})
endif()
You may replace GIT_TAG
with a commit hash or a release tag such as 1.0.0
.
After fetching the content, it's only a matter of linking the malloy library target(s) to the consuming application:
target_link_libraries(
my_application
PRIVATE
malloy-server # Link malloy's server components
malloy-client # Link malloy's client components
)
Where my_application
is your application (or library) target that should consume malloy.
Options
Various cmake
options are available to control the build:
Build
Option | Default | Description |
MALLOY_BUILD_EXAMPLES | ON | Whether to build examples. |
MALLOY_BUILD_TESTS | ON | Whether to build the test suite(s). |
MALLOY_BUILD_SHARED | OFF | Whether to build shared libraries. If set to OFF , static libraries will be built. |
Features
Option | Default | Description |
MALLOY_FEATURE_CLIENT | ON | Enable client features. |
MALLOY_FEATURE_SERVER | ON | Enable server features. |
MALLOY_FEATURE_HTML | ON | Whether to enable HTML support. |
MALLOY_FEATURE_TLS | OFF | Whether to enable TLS support. |
Dependencies
Option | Default | Description |
MALLOY_DEPENDENCY_SPDLOG_DOWNLOAD | ON | Whether to use FetchContent() to pull in spdlog . If set to OFF , find_package() is used instead. |
MALLOY_DEPENDENCY_FMT_DOWNLOAD | ON | Same as above but for fmt |