Skip to content
/ malloy Public

A cross-platform C++20 library providing embeddable server & client components for HTTP and WebSocket.

License

Notifications You must be signed in to change notification settings

Tectu/malloy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

standard license Packaging status

Packages

Packaging status

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
  • URL parsing support
  • HTTP
    • Plain or TLS (SSL) connections
    • Cookies
    • Sessions
    • Upgrading connections to WebSocket
    • Client
      • Response filters
      • File downloads directly to disk
    • 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
  • CMake 3.23 or newer

Dependencies

Required:

  • Boost 1.86.0 or newer (older versions may work but are no longer actively tested)
  • spdlog 1.8.3 or newer
  • fmt 7.1.3 or newer (must be compatible with spdlog version)

Optional:

  • OpenSSL

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()
{
    // Create malloy controller config
    malloy::server::routing_context::config cfg;
    cfg.interface   = "127.0.0.1";
    cfg.port        = 8080;
    cfg.doc_root    = "/path/to/http/docs"
    cfg.num_threads = 5;
    cfg.logger      = std::make_shared<spdlog::logger>();

    // Create malloy controller
    malloy::server::routing_context c{cfg};

    // Create the router
    auto& router = c.router();
    {
        using namespace malloy::http;

        // A simple GET route handler
        router.add(method::get, "/", [](const auto& req) {
            response res{status::ok};
            res.body() = "<html><body><h1>Hello World!</h1><p>some content...</p></body></html>";
            return res;
        });

        // Add a route to an existing file
        router.add(method::get, "/file", [](const auto& req) {
            return generator::file(examples_doc_root, "index.html");
        });

        // Add a route to a non-existing file
        router.add(method::get, "/file_nonexist", [](const auto& req) {
            return generator::file(examples_doc_root, "/some_nonexisting_file.xzy");
        });

        // Add some redirections
        router.add_redirect(status::permanent_redirect, "/redirect1", "/");
        router.add_redirect(status::temporary_redirect, "/redirect2", "/");

        // Add some file serving
        router.add_file_serving("/files", examples_doc_root);

        // Add a websocket echo endpoint
        router.add_websocket("/echo", [](const auto& req, auto writer) {
            std::make_shared<malloy::examples::ws::server_echo>(writer)->run(req);
        });
    }

    // Start
    start(std::move(c)).run();

    return EXIT_SUCCESS;
}

HTTP client:

int main()
{
    // Create the controller config
    malloy::client::controller::config cfg;
    cfg.num_threads = 1;
    cfg.logger      = create_example_logger();

    // Create the controller
    malloy::client::controller c{cfg};

    // Start
    [[maybe_unused]] auto session = start(c);

    // Make request
    auto stop_token = c.http_request(
        malloy::http::method::get,
        "http://www.google.com",
        [](auto&& resp) mutable {
            std::cout << resp << std::endl;
    });
    const auto ec = stop_token.get();
    if (ec) {
        spdlog::error("error: {}", ec.message());
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}

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:

doxygen ./Doxyfile

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:

# 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 "")

FetchContent_Declare(
    malloy
    GIT_REPOSITORY https://github.com/tectu/malloy
    GIT_TAG        main
)
FetchContent_MakeAvailable(malloy)

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
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy