Simple, small, C++ embeddable webserver with WebSockets support

Overview

Seasocks - A tiny embeddable C++ HTTP and WebSocket server for Linux

CI codecov GitHub release License ConanCenter package

Features

  • Simple C++ API
  • Serves static content from disk
  • API for building WebSocket servers
  • Simple command line binary for quick serving of static files only
  • Supports newer Hybi-10 and Hybi-16 WebSockets as well as the older Hixie style.

Stuff it doesn't do

  • It's not nearly as configurable as Apache, Lighttpd, Nginx, Jetty, etc.
  • It provides only limited support for custom content generation (e.g. Servlets).
  • It has been designed for WebSocket based control.
  • It's Linux focused and probably wont work on other systems (patches to support other systems would be welcome, but not a priority for us)

Getting started

Check out the tutorial on the wiki.

See src/app/c/ws_test.cpp for an example.

Issues
  • CMake build script updates

    CMake build script updates

    Hello! As promised after our chat at cpplang.slack#conan, a pr for better conan support. I've not (yet) looked at Windows support.

    What did I change?

    • Removed some files + added them to .gitignore
    • Added a .editorconfig file to make it easier for supported IDE's to apply formating. (See https://editorconfig.org/ for more info)
    • Use FindPythonInterp for finding python + nicer (imho) generated embedded source (too bad btw that
    • Add a SEASOCKS_SHARED and SEASOCKS_STATIC option to build shared and static libraries together. I left the possibility for building a static library without PIC support: see seasocks_obj vs seasock_pic_obj target.
    • Small change to the internal header configuration: add @ONLY to configure to don't replace cmake type variables. This does not change anything, but is safer for the future.
    • reformatted some cmake scripts. The cmake directory is appended to the CMAKE_MODULE_PATH so some module paths can be overridden by external scripts.
    • Export the cmake targets in SeasocksTargets.cmake and generate a SeasockConfig.cmake. Also make sure to link to ZLIB::ZLIB and Threads::Threads to avoid paths of the build machine being present in the exported cmake scripts. Note that this requires a find_package(Threads REQUIRED) and find_package(ZLIB REQUIRED) in the generated SeasocksConfig.cmake.
    • Remove double quotes from arguments in add_subdirectory. No functional change. But nicer imho.
    • Copy the license on installation
    • Add a conanfile build script. This should make it easier to build seasocks on Windows. Adding a conanfile.py to your repo allows the master branch in-tree, without doing releases. e.g.:
      mkdir build && cd build
      conan install ..
      conan build ..
      

      This also works on Windows. Using MSVC, you can then simply open Visual Studio using cmake --open. Also, I made sure to not patch the sources or include conanbuildinfo.cmake in your cmake scripts.

    Cheers

    opened by madebr 37
  • Response getting corrupt - question

    Response getting corrupt - question

    I have written the following code (reduced and modified to the essential parts for posting here) to implement a response to a uri path "show". I want to generate a response in the code and return it. I generated this response in many different ways, but the result is always the following error.

    When I return a response string of length >=1000, the client either does not receive the payload or receives the first few characters. For all response strings of length < 1000, it has worked well. I tried to hard code the string, read it from a file, generate it programmatically etc. I tried to return as "text/plain", "application/json","text/html", but no help. It is possible that the magic number 1000 may be just a random coincidence, but it was consistent in over 30 tests I did. When I tried to do the same long responses (>1000) by modifying the example code given in "ph_test.cpp", and it has no such problem. What am I doing wrong?

    struct DataHandler : CrackedUriPageHandler {    
        DataHandler(){}; //my code has one argument for the constructor, which is irrelevant here
        virtual std::shared_ptr<Response> handle(const CrackedUri &uri,
                                                 const Request &request) override {
            std::string resp = "";
            for(int i=0; i< 999; i++) { // <= 999 is OK, but >=1000 is giving the error  
                resp += "m";
            }
            return Response::textResponse(resp);        
        };
    };
    
    //server starting code
    auto root = make_shared<RootPageHandler>();
    auto pathHandler = make_shared<PathHandler>("show", make_shared<DataHandler>());        
    root->add(pathHandler);  
    server.addPageHandler(root);
    server.serve(server_root.data(), server_port); //server_root and server port come from elsewhere
    

    The response is like (where the length 1020 is correct, but the content is missing after one char):

    200 OK
    Server:  Seasocks/unversioned
    Date:  Tue, 19 Apr 2016 01:58:52 GMT
    Access-Control-Allow-Origin:  *
    Content-Length:  1,020
    Content-Type:  text/plain
    Connection:  keep-alive
    Last-Modified:  Tue, 19 Apr 2016 01:58:52 GMT
    Pragma:  no-cache
    Cache-Control:  no-store
    Expires:  Tue, 19 Apr 2016 01:58:52 GMT
    
    m
    

    Compiler info: gcc 4.8.5 20150623 (Red Hat 4.8.5-4) CMake options: ADD_DEFINITIONS(-Wall -Wextra -pedantic -ggdb3 -fPIC)

    bug 
    opened by skn2020 19
  • CMake changes

    CMake changes

    • Uses cmake BUILD_SHARED_LIBS
    • gets rid of some of the complexity previously needed to manage building both shared and static libs.
    • relies on cmake POSTIION_INDEPENDENT_CODE for those that need it
    • error on APPLE support, and take out any WIN32 other than to error about it.

    Two minor issues remain:

    • I can't get the EXPORT section to work
    • I don't know why I have to force PIC on the embedded object unconditionally.
    opened by mattgodbolt 15
  • Seasocks now compiles in Windows with c++17 and VS2019

    Seasocks now compiles in Windows with c++17 and VS2019

    I have been as careful as I can about the changes so as to hopefully not break the Linux compile. At least on WSL2 Linux, this code compiles and all tests pass.

    Build process is exactly the same for Windows (mkdir build && cdbuild followed by cmake ../) as it is in Linux; except in the resulting build directory there will be Visual Studio solution files that will enable seasocks to be built and debugged in visual studio. Please note I only tried the static library builds.

    Steve

    opened by sjk7 13
  • findEmbeddedContent symbol missing

    findEmbeddedContent symbol missing

    After installing the latest version of seasocks, I'm having trouble building against libseasocks.a:

    /usr/local/lib/libseasocks.a(Connection.cpp.o): In function `seasocks::Connection::sendError(seasocks::ResponseCode, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
    Connection.cpp:(.text+0x4c2c): undefined reference to `findEmbeddedContent(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
    /usr/local/lib/libseasocks.a(Connection.cpp.o): In function `seasocks::Connection::send404()':
    Connection.cpp:(.text+0x52b5): undefined reference to `findEmbeddedContent(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
    /usr/local/lib/libseasocks.a(Connection.cpp.o): In function `seasocks::Connection::processHeaders(unsigned char*, unsigned char*)':
    Connection.cpp:(.text+0x6424): undefined reference to `findEmbeddedContent(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
    collect2: error: ld returned 1 exit status
    
    opened by hoytech 12
  • Some fixes

    Some fixes

    This PR replaces the source file search by file(GLOB_RECURSE …) as this is not recommended by cmake. The 2nd commit fixes some issues I encountered recently.

    opened by offa 12
  • versioned shared library

    versioned shared library

    this commit adds versioning to libseasocks.so

    before: /usr/local/lib/ |-- libseasocks.so

    after: /usr/local/lib/ |-- libseasocks.so -> libseasocks.so.1.4.4 |-- libseasocks.so.1.4.4

    opened by Jasper-Ben 11
  • Per-message deflate as described in RFC 7692

    Per-message deflate as described in RFC 7692

    Github issue #5

    For my work-load (somewhat redundant JSON) it reduces the transmitted message sizes to nearly 1/10th their uncompressed sizes so it will be a huge bandwidth saver.

    It basically does the bare minimum to be RFC 7692 compatible. I have tested the compression with chromium and websocketpp 0.7.0 and seasocks seems to compress/decompress messages properly in both directions.

    Current limitations:

    • Can't configure the *_no_context_takeover or *_max_window_bits extensions. It will only negotiate the default (context takeover and max window bits in both directions)
    • All transmitted messages will be compressed. Ideally you should be able to opt-out of compressing particular messages (but it does support clients that compress particular messages)
    • Only ever issues one DEFLATE block per message since the seasocks API doesn't support incremental message construction (but I believe it does support receiving multiple blocks from clients that do)
    • Various tuning parameters such as buffer size and memLevel are hard-coded. Some apps might like to customise them
    • Requires linking to zlib even if no compression will be used
    • No tests :(
    opened by hoytech 11
  • CMake added

    CMake added

    This PR addes cmake as a second build tool.

    Available:

    • Building of library and apps
    • Installation using make install
    • Travis CI (Matrix using both)
    • Generation of embedded content
    • Testing compiler for emplace()
    • Optional building / running of tests using gtest / gmock (default: OFF)
    • Configure file - Config.h (based on a custom template in cmake/)

    Not (yet) available:

    • Building tests on CI using cmake

    Since google has merged gtest / gmock into one project - gmock depends on gtest though - i'm not sure how to handle this case on CI. It seems gmock requires gtest but doesn't ship it anymore in one bundle (?).

    At the moment cmake will look for both if tests are enabled, otherwise there's no dependency on gtest / gmock if disabled.

    What's different to autoconf:

    The cmake builds will use it's own Config.h (cmake directory); it has only a definition for HAVE_UNORDERED_MAP_EMPLACE, since i didn't see any usage of all the other flags. However, adding more options is simple enough.

    opened by offa 11
  • Some code related questions

    Some code related questions

    I have some code related questions:

    1. Is the -ggdb3 flag still necessary? It's enabled for all build types; but mainly debug related (correct?).
    2. Are the compiler checks for map::emplace() and override still necessary? Any C++11 conform compiler should support thesei).

    i) The test for <atomic> isn't affected by this, as it still serves a valid reason – eg. some embedded systems may not support it.

    opened by offa 10
  • Multipart responses

    Multipart responses

    I've been enjoying using seasocks for websocket content.

    I want to stream mjpegs from seasocks. To do this, I need to send a multipart http response. Seasocks looks like it really wants you to generate the entire page response and then it will send that all at once. Is there a way to send a multipart response (where the response comes back in chunks spread out over time)? I don't see it from the interface provided for the response.

    enhancement 
    opened by AustinSchuh 10
  • Clang 13 and 14 CI builds

    Clang 13 and 14 CI builds

    Adds builds for latest Clang versions.

    Both issue an error due to possible UB though:

    /home/runner/work/seasocks/seasocks/src/main/c/md5/md5.cpp:190:25: error: performing pointer subtraction with a null pointer may have undefined behavior [-Werror,-Wnull-pointer-subtraction]
                if (!((data - (const md5_byte_t*) 0) & 3)) {
                            ^ ~~~~~~~~~~~~~~~~~~~~~
    1 error generated.
    
    opened by offa 2
  • PathHandler for /:id style API

    PathHandler for /:id style API

    Hello,

    I wish to follow the convention for my REST interface:

    http://xxx.xxx.xxx.xxx:8080/resources/:id

    Where GET http://xxx.xxx.xxx.xxx:8080/resources will return a list of resources, GET http://xxx.xxx.xxx.xxx:8080/resources/:id will return a single resource with id == :id.

    Given id is part of the URI, my approach thus far has been to have a single PathHandler on resources, and inspect the CrackedURI::path()[0] element to infer if an id has been passed.

    Is there a more elegant way of achieving this?

    std::shared_ptr<seasocks::Response> ResourceEndpoint::handle(const CrackedUri &uri, const Request &request) {
     if (uri.path().size() == 1) {
        const auto base = uri.path()[0];
        if (base == "") {                                   
          switch (request.verb()) {
            case Request::Verb::Get: // return all resources
            ...
          }
        } else {
          try {
            const auto id = static_cast<uint32_t>(std::stol(base));   // return resource for 
            switch (request.verb()) {
            case Request::Verb::Get: // return resource for 'id' only
            ...
            }
          }
       }
    }
    
    opened by antoinewaugh 0
  • contiguous stream of data ?

    contiguous stream of data ?

    New to websockets here. I am developing an app that receives a data through a ZMQ socket every second, then processes it and prepares it in JSON format, and my goal was to be able to stream this real time data contiguously serving it through websockets, so a React app can grab it and make visuals with it.

    My questions:

    • is it possible to stream JSON data regardless of if a client is connected to the endpoint, and once the client connects, it starts doing something with the data the server is streaming ?
    • can you add multiple / routes, and run them on separate threads ? My goal is to add a / route for each ZMQ socket receiving data, to later stream them on different tabs on the React app.

    Thanks !

    opened by chromafunk 1
  • Conform to conan licensing practices

    Conform to conan licensing practices

    Conan expects a license folder in its projects:

    [HOOK - conan-center.py] post_package(): ERROR: [PACKAGE LICENSE (KB-H012)] No 'licenses' folder found in package: /home/jasper/.conan/data/seasocks/1.4.4/_/_/package/ac7e8914e54bce4e93d8fd34e732e8c13c5913f2 (https://github.com/conan-io/conan-center-index/blob/master/docs/error_knowledge_base.md#KB-H012)

    We should conform to this standard practice, as demonstrated by the zlib conan package:

        |-- conaninfo.txt
        |-- conanmanifest.txt
        |-- include
        |   |-- zconf.h
        |   `-- zlib.h
        |-- lib
        |   `-- libz.a
        `-- licenses
            `-- LICENSE
    
    
    
    opened by Jasper-Ben 2
Releases(v1.4.4)
  • v1.4.4(Aug 7, 2020)

  • v1.4.3(Jan 24, 2020)

  • v1.4.2(Apr 15, 2019)

  • v1.4.1(Oct 8, 2018)

    • Requires C++14.
    • Support for Python 3 in build process.
    • Various CMake improvements.
    • Internal improvements to better use smart pointers, and to take advantage of C++14 features.
    • Fix to CMake build process (plays better with Conan)
    Source code(tar.gz)
    Source code(zip)
  • v1.3.2(Sep 9, 2017)

    Seasock supports latest GCC 7 and Clang 5 compiler now. SONAME is available through CMake and Catch uses v1.10 which notable reduces the test runtime.

    Note:

    Development is going to upgrade to C++14 from v1.4.x onwards.

    Source code(tar.gz)
    Source code(zip)
  • v1.3.1(Apr 26, 2017)

    In 1.3.0 we added streaming, which introduced a dependency on libz. For those who don't want this dependency, in this release configuring with -DDEFLATE_SUPPORT=Off will drop the dependency.

    Source code(tar.gz)
    Source code(zip)
  • v1.3.0(Mar 23, 2017)

  • v1.2.6(Jan 18, 2017)

    Added the ability to change the buffer size used for clients.

    Internal fixes to make CMake builds more consistent.

    Enums are now enum classes: apologies for the API change. I suck at semantic versioning, it turns out :(

    Source code(tar.gz)
    Source code(zip)
  • v1.2.4(Mar 16, 2016)

  • v1.2.2(Mar 7, 2016)

  • v1.2.1(Mar 6, 2016)

  • v1.2.0(Mar 6, 2016)

    New asynchronous interface allows handlers to defer sending their replies until they're ready. This also makes streaming possible.

    If you have custom Responses and don't want to change them, consider deriving them from SynchronousResponse.

    The async_test example in src/apps/c will give some idea of how asynchronous responses should be performed.

    Source code(tar.gz)
    Source code(zip)
  • v1.1.6(Sep 28, 2015)

  • v1.1.5(May 27, 2015)

    A minor release that fixes the slightly weird behaviour of split() in StringUtil which returned {""} for splitting an empty string instead of {}.

    This has a knock-on effect for the CrackedUriPageHandler: now the "/" handler will have an empty path instead of a single empty element.

    Source code(tar.gz)
    Source code(zip)
  • v1.1.2(Oct 27, 2014)

    A fix for Firefox: isupport websocket upgrade "Connection:" header with comma-separated values. Previously prevented Firefox from talking to websockets.

    Source code(tar.gz)
    Source code(zip)
  • v1.1.1(Jul 24, 2014)

    Fixes in the JSON code:

    • jsonToStream is now available for user objects: define a member function void jsonToStream(std::ostream &); and stream out your contents.
    • Array and map generation for container types now need to be explicitly called out with makeMapFromContainer and makeArrayFromContainer. They work on all container and map types now too.
    Source code(tar.gz)
    Source code(zip)
  • v1.0.1(Apr 15, 2014)

  • v1.0(Mar 27, 2014)

  • v0.1(Oct 15, 2013)

Owner
Matt Godbolt
Compiler Explorer and jsbeeb creator, ex-Google, ex-games, ex-trading chap.
Matt Godbolt
Chocolate Doom WebAssembly port with WebSockets support

Wasm Doom This is a Chocolate Doom WebAssembly port with WebSockets support. Requirements You need to install Emscripten and a few other tools first:

Cloudflare 157 Jun 17, 2022
C library for easy WebSockets server.

libwebsock C library for easy WebSockets servers. This library allows a developer to quickly develop WebSocket servers by focusing on the actual logic

Payden Sutherland 205 Apr 23, 2022
WebSockets in C for Embedded Applications

WebSockets in C WIC is a C99 implementation of rfc6455 websockets designed for embedded applications. WIC decouples the websocket protocol from the tr

Cameron Harper 49 May 2, 2022
A webserver hosting a bank system for Minecraft, able to be used from web browser or from CC/OC if you're playing modded.

CCash A webserver hosting a bank system for Minecraft, able to be used from web browser or from CC/OC if you're playing modded. Description the curren

William Katz 24 Dec 10, 2021
Various utilities such as WebServer, JSON, WebSocket server, REST framework

DumaisLib This is a library containing several utilities for some projects of Patrick Dumais. Previously, the libraries were all individual but it bec

Patrick Dumais 25 Feb 22, 2022
ESP 32 webserver to serve a static page for wifi settings

ESP32 Settings WebServer This is a ESP32 Firmware developed in PlatformIO which consists in a HTTP server for serve static files and provides an API f

Mateus Mello de Oliveira 2 Oct 29, 2021
Building a personal webserver/framework piece by piece

Building a personal webserver/framework piece by piece

E 1 May 11, 2022
Webserver written in C-99 in nano just for fun.

Welcome to Cornelia Web Server CrazedoutSoft 2022 by Fredrik Roos.

CrazedoutSoft 3 Jan 31, 2022
Simple embeddable C++11 async tcp,http and websocket serving.

net11 Simple embeddable C++11 async tcp,http and websocket serving. What is it? An easily embeddable C++11 networking library designed to make buildin

Jonas Lund 9 Mar 28, 2020
Embeddable C++ HTTP server

Boost.Http This library implements a core HTTP server for Boost that can be used from resource-constrained devices to powerful machines that have plen

null 159 Jun 19, 2022
Embeddable HTTP server.

yocto HTTP server The yocto HTTP server is a small embeddable web server, with a convenient public domain licence. Use it to add a web server to your

Tom Seddon 73 Jan 22, 2022
Small and fast cross-platform networking library, with support for messaging, IPv6, HTTP, SSL and WebSocket.

frnetlib Frnetlib, is a cross-platform, small and fast networking library written in C++. There are no library dependencies (unless you want to use SS

Fred Nicolson 22 May 16, 2022
Simple and small reliable UDP networking library for games

libquicknet Simple and small reliable UDP networking library for games ❗ libquicknet is under development and not suitable for production code ❗ The m

null 23 May 12, 2022
Open source file system for small embedded systems

STORfs Open Source File System Release Version 1.0.2 Created by: KrauseGLOBAL Solutions, LLC What is STORfs? STORfs is an open source flash file syste

null 16 Apr 23, 2022
A small C utility that encodes bytes into whitespace characters.

Whitespacer - a whitespace encoder/decoder What is it? Whitespacer is an encoder and decoder that encodes bytes into whitespace characters

Greg Foletta 14 Jan 2, 2022
Small utility that leverages eBPF to dump the traffic of a unix domain socket

UnixDump UnixDump is a small eBPF powered utility that can be used to dump unix socket traffic. System requirements This project was developed on a Ub

Guillaume Fournier 5 Dec 1, 2021
Graphical small-internet client for windows, linux, MacOS X and BSDs. Supports gemini, http, https, gopher, finger.

Graphical small-internet client for windows, linux, MacOS X and BSDs. Supports gemini, http, https, gopher, finger.

Felix Queißner 536 Jun 24, 2022
A small, minimal HTTP library written in C.

trail - A small, minimal HTTP library written in C. trail is a small, minimal, and easy-to-use HTTP library written in C that supports GET and POST re

null 4 Feb 1, 2022
A small data-oriented and SIMD-optimized 3D rigid body physics library.

nudge Nudge is a small data-oriented and SIMD-optimized 3D rigid body physics library. For more information, see: http://rasmusbarr.github.io/blog/dod

null 231 Jun 10, 2022