Your high performance web application C framework

Overview

GitHub Build Status Codacy Badge codecov

facil.io is a C micro-framework for web applications. facil.io includes:

  • A fast HTTP/1.1 and Websocket static file + application server.
  • Support for custom network protocols for both server and client connections.
  • Dynamic types designed with web applications in mind (Strings, Hashes, Arrays etc').
  • Performant JSON parsing and formatting for easy network communication.
  • A pub/sub process cluster engine for local and Websocket pub/sub.
  • Optional connectivity with Redis.

facil.io provides high performance TCP/IP network services to Linux / BSD (and macOS) by using an evented design (as well as thread pool and forking support) and provides an easy solution to the C10K problem.

You can read more about facil.io on the facil.io website.

Important to Note

The master branch on the git repo is the development branch and is likely to be broken at any given time (especially when working on major revisions, as I am at the moment).

Please select a release version for any production needs.

Who's running on facil.io

An HTTP example

#include "http.h" /* the HTTP facil.io extension */

// We'll use this callback in `http_listen`, to handles HTTP requests
void on_request(http_s *request);

// These will contain pre-allocated values that we will use often
FIOBJ HTTP_X_DATA;

// Listen to HTTP requests and start facil.io
int main(int argc, char const **argv) {
  // allocating values we use often
  HTTP_X_DATA = fiobj_str_new("X-Data", 6);
  // listen on port 3000 and any available network binding (NULL == 0.0.0.0)
  http_listen("3000", NULL, .on_request = on_request, .log = 1);
  // start the server
  facil_run(.threads = 1);
  // deallocating the common values
  fiobj_free(HTTP_X_DATA);
}

// Easy HTTP handling
void on_request(http_s *request) {
  http_set_cookie(request, .name = "my_cookie", .name_len = 9, .value = "data",
                  .value_len = 4);
  http_set_header(request, HTTP_HEADER_CONTENT_TYPE,
                  http_mimetype_find("txt", 3));
  http_set_header(request, HTTP_X_DATA, fiobj_str_new("my data", 7));
  http_send_body(request, "Hello World!\r\n", 14);
}

Using facil.io in your project

It's possible to either start a new project with facil.io or simply add it to an existing one. GNU make is the default build system and CMake is also supported.

facil.io should be C99 compatible.

Starting a new project with facil.io

To start a new project using the facil.io framework, run the following command in the terminal (change appname to whatever you want):

 $ bash <(curl -s https://raw.githubusercontent.com/boazsegev/facil.io/master/scripts/new/app) appname

You can review the script here. In short, it will create a new folder, download a copy of the stable branch, add some demo boiler plate code and run make clean (which is required to build the tmp folder structure).

Next, edit the makefile to remove any generic features you don't need, such as the DUMP_LIB feature, the DEBUG flag or the DISAMS disassembler and start development.

Credit to @benjcal for suggesting the script.

Notice: The master branch is the development branch. Please select the latest release tag for the latest stable release version.

Adding facil.io to an existing project

facil.io is a source code library, so it's easy to copy the source code into an existing project and start using the library right away.

The make libdump command will dump all the relevant files in a single folder called libdump, and you can copy them all or divide them into header ands source files.

It's also possible to compile the facil.io library separately using the make lib command.

Using facil.io as a CMake submodule

facil.io also supports both git and CMake submodules. Credit to @OwenDelahoy (PR#8).

First, add the repository as a submodule using git:

git submodule add https://github.com/boazsegev/facil.io.git

Then add the following line the project's CMakeLists.txt

add_subdirectory(facil.io)

Using facil.io with Meson

facil.io is available at Meson Wrap DB.

First, install the wrap file:

meson wrap install facil

Then add the following line to your project's meson.build:

facil_dep = subproject('facil').get_variable('facil_dep')

More Examples

The examples folder includes code examples for a telnet echo protocol, a Simple Hello World server, an example for Websocket pub/sub with (optional) Redis, etc'.

You can find more information on the facil.io website


Forking, Contributing and all that Jazz

The contribution guide can be found here.

Sure, why not. If you can add Solaris or Windows support to evio and sock, that could mean facil would become available for use on these platforms as well.

If you encounter any issues, open an issue (or, even better, a pull request with a fix) - that would be great :-)

Hit me up if you want to:

  • Write tests... I always need more tests...

  • Help me write HPACK / HTTP2 protocol support.

  • Help me design / write a generic HTTP routing helper library for the http_s struct.

  • If you want to help me write a new SSL/TLS library or have an SSL/TLS solution we can fit into facil (as source code)... Note: SSL/TLS solutions should fit both client and server modes.

  • If you want to help promote the library, that would be great as well. Perhaps publish benchmarks or share your story.

  • Writing documentation into the facil.io website would be great. I keep the source code documentation fairly updated, but the documentation should be copied to the docs folder to get the documentation website up and running.

Issues
  • A route handler for Facil.io

    A route handler for Facil.io

    I saw that a generic HTTP routing helper library for the http_s struct was on your wishlist. I've been developing a collection of higher-level abstractions for Facil.io called Sencillo, which adds (among other things) a route handler to Facil.io.

    Sencillo's route handler does quite a bit that is far outside the scope of Facil.io (https://github.com/epixoip/sencillo/blob/main/sencillo.h#L1030-L1166), therefore a modified implementation that is more inline with Facil.io's goals is provided below for your consideration:

    bool http_path_matches(http_s *request, char *__route) {
        // make a mutable copy of the route
        char *route = strdup(__route);
    
        if (!route) {
            FIO_LOG_ERROR("Failed to allocate memory!");
            return false;
        }
    
        char *path = fiobj_obj2cstr(request->path).data;
    
        // truncate the path at the query string delimiter,
        // as we only care about the path itself and the 
        // query string is parsed by http_parse_query()
        path = strtok(path, "?");
    
        // does the route contain any inline path variables?
        if (strchr(route, ':') == null) {
            // no - perform direct string comparison
            if (strcmp(route, path) == 0) {
                free(route);
                return true;
            } else {
                free(route);
                return false;
            }
        }
    
        int route_part_cnt = 0;
        int path_part_cnt  = 0;
    
        // count the number of parts in the route and the path
        for (int i = 0; route[i]; route[i] == '/' ? route_part_cnt++, i++ : i++);
        for (int i = 0; path[i];  path[i]  == '/' ? path_part_cnt++,  i++ : i++);
    
        // do we have an equal number of parts?
        if (route_part_cnt != path_part_cnt) {
            return false;
        }
    
        char *route_parts[route_part_cnt];
        char *path_parts[path_part_cnt];
    
        char *route_remaining;
        char *path_remaining;
    
        int matches = 0;
    
        // loop through each part
    
        char *route_next_part = strtok_r(route, "/", &route_remaining);
        char *path_next_part  = strtok_r(path,  "/", &path_remaining);
    
        while (route_next_part && path_next_part) {
            // if the route part is an inline variable, extract the variable name and its value
            if (route_next_part[0] == ':') {
                route_parts[matches]  = route_next_part + 1;
                path_parts[matches++] = path_next_part;
            } else {
                // the route part is literal, does it match the path part?
                if (strcmp(route_next_part, path_next_part)) {
                    free(route);
                    return false;
                }
            }
    
            route_next_part = strtok_r(null, "/", &route_remaining);
            path_next_part  = strtok_r(null, "/", &path_remaining);
        }
    
        free(route);
    
        // add the inline path variable names and values to the request params
        for (int i = 0; i < matches; i++) {
            http_add2hash(request->params, route_parts[i], strlen(route_parts[i]), path_parts[i], strlen(path_parts[i]), 1);
        }
    
        return true;
    }
    

    There are a couple ways you could implement http_path_matches depending on the desired experience.

    First, you could create macros for simple conditionals:

    #define http_route_get(_h, _route) \
        if (strcmp(fiobj_obj2cstr(request->method).data, "GET") == 0 && http_path_matches(_h, _route))
    
    #define http_route_post(_h, _route) \
        if (strcmp(fiobj_obj2cstr(request->method).data, "POST") == 0 && http_path_matches(_h, _route))
    
    #define http_route_put(_h, _route) \
        if (strcmp(fiobj_obj2cstr(request->method).data, "PUT") == 0 && http_path_matches(_h, _route))
    
    #define http_route_delete(_h, _route) \
        if (strcmp(fiobj_obj2cstr(request->method).data, "DELETE") == 0 && http_path_matches(_h, _route))
    

    Use of these macros would be straightforward:

    static void on_http_request(http_s *h) {
        http_parse_query(h);
        http_parse_body(h);
    
        http_route_get(h, "/user/:id") {
            FIOBJ id_str = fiobj_str_new("id", 2);
            FIOBJ id_val = fiobj_hash_get(request->params, id_str);
    
            char *id = fiobj_obj2cstr(id_val).data;
            
            char greeting[32];
            snprintf(greeting, sizeof greeting, "Welcome user %s!", id);
    
            fiobj_free(id_str);
            fiobj_free(id_val);
    
            http_send_body(h, greeting, strlen(greeting));
            return;
        }
    }
    

    Another way would be to create macros that map each route to a function:

    #define http_route_handler(_h, _method, _route, _func) {                                                \
        if (strcmp(fiobj_obj2cstr(request->method).data, _method) == 0 && http_path_matches(_h, _route)) {  \
            FIO_LOG_DEBUG("Matched route %s %s", _method, _route);                                          \
            _func(_h);                                                                                      \
            return;                                                                                         \
        }                                                                                                   \
    }
    
    #define http_route_get(_h, _route, _func) \
        http_route_handler(_h, "GET", _route, _func)
    
    #define http_route_post(_h, _route, _func) \
        http_route_handler(_h, "POST", _route, _func)
    
    #define http_route_put(_h, _route, _func) \
        http_route_handler(_h, "PUT", _route, _func)
    
    #define http_route_delete(_h, _route, _func) \
        http_route_handler(_h, "DELETE", _route, _func)
    

    Which could simply be incorporated as:

    static void on_http_request(http_s *h) {
        http_parse_query(h);
        http_parse_body(h);
    
        http_route_get(h, "/user/:id", getUserById);
    }
    
    opened by epixoip 0
  • Support for WebSocket Protocol header

    Support for WebSocket Protocol header

    The problem I was facing was that I'm using Javascript running in a browser. Therefore I need to connect to a WebSocket with the default JS functions and unable to use a 3rd party alternative for NodeJS. I needed to authorize before the WebSocket connection is opened else it leaves you vulnerable to DDoS attacks. This leaves one secure option: passing the token in the sec-websocket-protocol header. I found out there was no support in Facil.io yet.

    There are three different types of requests coming in:

    1. Has no sec-websocket-protocol header header, so no header will be in the response.
    2. Has a single string as value and passes the same value back in the response.
    3. Has an array of values as a string separated by colons. Takes the first value and passes it in the response.

    Any other way would fail to connect. Normally would there be checks if the WebSocket Server actually supports those protocols. This code just makes it possible that no matter the value you are still able to connect.

    opened by joeyhoek 3
  • OpenSSL Not Detected

    OpenSSL Not Detected

    Debian Testing (11), openssl 1.1.1i-1 is installed (normal and dev packages)

    The makefile says that it can't find any suitable SSL library, it doesn't give any helpful info beyond that (is there a way to get the makefile to be noisier?)

    Building with cmake includes a fio_tls_openssl.o file in the archive, so I assume that it works correctly there.

    opened by tekktonic 4
  • Build Failure

    Build Failure

    Hi All,

    I am trying to build and getting an error concerning explicit type casting.

    This is just to give a heads-up on this.

    facil-build-error

    opened by dAgbeve 5
  • Put release date for each version in CHANGELOG.md file

    Put release date for each version in CHANGELOG.md file

    Please consider putting release date for each version in CHANGELOG.md file. Without this, such information can be found only at the github release page.

    opened by bluegol 1
  • unclear how to add openssl support

    unclear how to add openssl support

    Hi, i was able to use facil.io as websocket client, now i need tls support and tried to add openssl...

    I cloned openssl, compiled it and added the headers to the include search path - but if i include <fio_tls.h> and call fio_tls_s * tls = fio_tls_new("www.example.com", NULL, NULL, NULL); then i get the output: FATAL: No supported SSL/TLS library available.

    i also tried setting some defines i found in the source:

    #define HAVE_OPENSSL
    #define FIO_TLS_FOUND
    
    #include <http.h>
    #include <fio.h>
    #include <fio_tls.h>
    

    this did not change anything, unfortunately

    opened by stoneburner 3
  • how to use http_connect with keep-alive

    how to use http_connect with keep-alive

    I sent http request body with the first time on_response, and process the returned second time on_response body.

    so, how can I keep a http client connection alive to reuse the http socket connection to some server? Can I do that? @boazsegev

    Thanks

    enhancement API design 
    opened by stephenkgu 2
  • fix deprecated API usage in boiler_plate example

    fix deprecated API usage in boiler_plate example

    • use fio_url_s type instead of deprecated http_url_s

    Signed-off-by: Toni Uhlig [email protected]

    opened by lnslbrty 7
Releases(0.7.5)
  • 0.7.5(May 18, 2020)

    v. 0.7.5 (2020-05-18)

    Security: backport the 0.8.x HTTP/1.1 parser and it's security updates to the 0.7.x version branch. This fixes a request smuggling attack vector and Transfer Encoding attack vector that were exposed by Sam Sanoop from the Snyk Security team (snyk.io). The parser was updated to deal with these potential issues.

    Fix: (http) fixes an issue with date calculation by backporting code from the 0.8.x branch.

    Fix: (fio) call less signal handlers during shutdown.

    from v. 0.7.4

    Fix: (http) fixes an issue and improves support for chunked encoded payloads. Credit to Ian Ker-Seymer ( @ianks ) for exposing this, writing tests (for the Ruby wrapper) and opening both the issue boazsegev/iodine#87 and the PR boazsegev/iodine#88.

    Fix: (http) requests will fail when the path contains a dangling ? (empty query). Credit to @adam12 for exposing this and opening issue boazsegev/iodine#86.

    Source code(tar.gz)
    Source code(zip)
  • 0.7.3(Oct 4, 2019)

    Fix: (http) fixes a security issue in the static file name resolution logic, where a maliciously encoded request could invoke an arbitrary response.

    Fix: (fio, fiobj) improved C++ compatibility. Credit to Joey (@joeyhoek) for PR #76.

    Fix: (fio) fixes an issue where timer cleanup wasn't performed after fio_stop (or SIGINT/SIGTERM). No a "clean slate" will be provided if fio_start is called more then once. Note: this may break previous behavior, which should be considered undocumented and unexpected behavior. (this fax may be deferred to version 0.8.x, still undecided). Credit to @fbrausse for opening issue #72.

    Fix: (fio) fixes an issue where timer cleanup would be performed after the AT_EXIT state callbacks. Now the timer cleanup callbacks will be performed before the AT_EXIT callback (as they should). (See issue #72).

    Fix: (fio) fixes signal handler (re)establishment test to prevent recursive signal calling.

    Source code(tar.gz)
    Source code(zip)
  • 0.7.2(Aug 28, 2019)

    Fix: (fio_tls) fixes a memory leak in the trusted certificate chain. Credit to @fbrausse for opening PR #71.

    Fix: (fio_tls) fixes compilation / linking flags (including a bug caused by the gcc optimizer -fipa-icf) and improves support for OpenSSL using pkg-config. Credit to @fbrausse for PR #71.

    Fix: (http1) fixes a race-condition between the on_ready and on_data events, that could result in the on_data event being called twice instead of once (only possible with some clients). On multi-threaded workers, this could result in the CPU spinning while the task lock remains busy. Credit to Néstor Coppi (@Shelvak) for exposing the issue and providing an example application with detailed reports. Issue #75.

    Source code(tar.gz)
    Source code(zip)
  • 0.7.1(May 17, 2019)

    v. 0.7.1

    Security: a heap-overflow vulnerability was fixed in the WebSocket parser. This attack could have been triggered remotely by a maliciously crafted message-header. Credit to Dane ([email protected]) for exposing this issue and providing a Python script demonstrating the attack.

    Source code(tar.gz)
    Source code(zip)
  • 0.7.0(Mar 29, 2019)

    Stable API release. Future API updates will be wait for the 0.8.x release.

    Fix: (fio, fiobj) fixed some gcc and clang compatibility issues and warnings.

    Fix: (http) fixed HTTP date format to force the day of the month to use two digits. Credit to @ianks (Ian Ker-Seymer) for exposing this issue (iodine#64).

    Compatibility: (http) updated time-zone compile-time tests with a safer fall-back.

    Source code(tar.gz)
    Source code(zip)
  • 0.7.0.beta8(Mar 3, 2019)

    We've been hard at work authoring this (hopefully last) beta release to the 0.7.x facil.io.

    There's just one or two planned API updates for the HTTP module (which is why we're still in beta phase). These changes shouldn't effect any code, but they will effect ABI compatibility, so if you need ABI compatibility, you'll need to wait a bit longer.

    Here's what this update includes:

    Security: (fio) Slowloris mitigation is now part of the core library, where FIO_SLOWLORIS_LIMIT pending calls to write (currently 1,024 backlogged calls) will flag the connection as an attacker and either close the connection or ignore it. This protocol independent approach improves security.

    Security: (http) HTTP/1.1 client throttling - new requests will not be consumed until pending responses were sent. Since HTTP/1.1 is a response-request protocol, this protocol specific approach should protect the HTTP application against slow clients.

    Fix: (fio) fixed fallback implementation for fio_atomic_xchange when missing atomic primitives in compiler (older compilers). Credit to @Low-power for identifying and fixing the issue (PR #55).

    Fix: (fio) fixed a possible unreleased lock when a memory allocation failed (no memory in the system). Credit to @Low-power for identifying and fixing the issue (PR #54).

    Fix: (fio) fixed the fio_sock_sendfile_from_fd fall-back for a missing sendfile. Credit to @Low-power for identifying and fixing the typo (PR #49).

    Fix: (fio) fixed fio_pending not decrementing packet count before reaching zero.

    Fix: (fio) fixed logging message for overflowing log messages. Credit to @weskerfoot (Wesley Kerfoot) and @adam12 (Adam Daniels) for exposing the issue (issue iodine/#56).

    Fix: (fio, fio_risky_hash) Florian Weber (@Florianjw) exposed a byte ordering error (last 7 byte reading order) and took time challenge the algorithm. The exposed errors were fixed and the exposed a possible attack on RiskyHash using a variation on a Meet-In-The-Middle attack, written by Hening Makholm (@hmakholm). This prompted an update and fixes to the function.

    Fix: (fio) fixed fio_str_resize where data might be lost if data was written beyond the current size and the requested size is larger then the String's capacity (i.e., when fio_str_resize is (mis)used as an alternative to fio_str_capa_assert).

    Fix: (json / redis) fixed JSON formatting error caused by buffer reallocation when multiple (more then 48) escape sequences were detected. This issue also effected the Redis command callback handler (which was using JSON for IPC).

    Fix: (redis) fixed a potential double free call.

    Fix: (redis) fixed a recursive endless loop when converting nested Hash Tables to Redis objects (which normally wouldn't happen anyway, since they would be processed as JSON).

    Fix: (redis) fixed Redis reconnection. Address and port data was mistakingly written at the wrong address, causing it to be overwritten by incoming (non-pub/sub) data.

    Fix: (redis) fixed a race condition in the Redis reconnection logic which might have caused more then a single pub/sub connection to be established and the first pending command to be sent again.

    Fix: (fio) fix capacity maximization log to accommodate issues where getrlimit would return a rlim_max that's too high for rlim_cur (macOS).

    Fix: (fio) fix uninitialized kqueue message in fio_poll_remove_fd.

    Fix: (http) possible fix for http_connect, where host header length might have been left uninitialized, resulting in possible errors.

    Fix: (fio) fixed logging error message for long error messages.

    Update: (fio / makefile) improved detection for polling system call, sendfile, etc'.

    Update: (fio) improved signal handling. Signal handling now propagates to pre-existing signal handlers. In addition, the fio_signal_handler_reset function was made public, allowing facil.io signal handlers to be removed immediately following startup (using fio_state_callback_add with FIO_CALL_PRE_START to call fio_signal_handler_reset).

    Update: (fio) improved pub/sub memory usage to minimize message copying in cluster mode (same memory is used for IPC and local-process message publishing).

    Update: (fio) updated the non-cryptographic PRG algorithm for performance and speed. Now the fio_rand functions are modeled after the xoroshiro128+ algorithm, with an automated re-seeding counter based on RiskyHash. This should improve performance for non cryptographic random requirements.

    Compatibility: (fio) mitigate undefined MAP_ANONYMOUS on MacOS <= 10.10. Credit to @xicreative (Evan Pavlica) for iodine/PR#61.

    Compatibility: (fio) various Solaris OS compatibility patches, courtesy of @Low-power (PR #52, #53).

    Source code(tar.gz)
    Source code(zip)
  • 0.7.0.beta7(Jan 18, 2019)

    I spent a bunch of time learning about Hash Map and Hash function security concerns, realizing Hash Map security should be prioritized over a goof Hash function. I also Implemented a TLS client in iodine (the Ruby wrapper for facil.io) and learned a bunch of stuff that required some API changes.

    On the positive side, it appears that the 0.7.x API is fairly finalized and facil.io could probably move to a 0.7.0 release soon.

    The main changes in the this beta release are:

    BREAK: (fio_tls) breaking API changes to the SSL/TLS API... I know, I'm sorry, especially since there's a small and misleading change in argument ordering for fio_tls_cert_add and fio_tls_new... but if we don't fix the API now, before the 0.7.0 release, bad design might ruin our Wednesday meditation for all eternity.

    BREAK: (http) breaking API changes to http_connect were required in order to support Unix Socket connections in client mode.

    Deprecation: (http) deprecating the http_url_parse in favor of fio_url_parse (moved the function to the core library and rewrote it in part).

    Security: facil.io hash maps now limit the number of full-collisions allowed in a hash map. This mitigates the effects of hash flooding attacks. As a side effect, hash maps that are under attack might return false results for collision objects.

    Fix: (websocket) fixed an issue with the WebSocket parser where network byte order for long message lengths wasn't always respected and integer bit size was wrong for larger payloads. Credit to Marouane Elmidaoui (@moxgeek) for exposing the issue.

    Fix: (http) fixed udata in WebSocket client callback for failed WebSocket client connections.

    Fix: (fio) logging message when listening to a Unix Socket.

    Fix: (fio) numerous minor design fixes, such as Big-Endian string memory access, allowing fio.h to be used as a header only library (requires FIO_FORCE_MALLOC) and other adjustments.

    Fix: (fio) fixed unaligned memory access in SipHash implementation and added secret randomization for each application restart.

    Fix: (redis) fixed an issue where destroying the Redis engine and exiting pre-maturely, before running facio.io (fio_start), will cause a segmentation fault during cleanup.

    Update: (fio) added Risky Hash, for fast hashing of safe data. This is a fast hashing function (about twice as fast as the default SipHash1-3 secure function) that wasn't tested for security. For this reason it should be limited to internal / safe data, such as CLI argument names.

    Source code(tar.gz)
    Source code(zip)
  • 0.7.0.beta6(Dec 31, 2018)

    This is a security release with partial support for TLS, using OpenSSL.

    TLS support is still under development and the API related to TLS should be considered fragile (I will release 0.7.0 once the API is solid enough and things work).

    BREAK: (fio_tls) breaking API changes to the SSL/TLS API, adding support for password protected private key files. Note: The TLS API is still fragile and should only be considered stable once version 0.7.0 is released with SSL/TLS support.

    Security / Fix: (http) fixed an issue with the HTTP/1.1 parser, where maliciously crafted white-space data could cause a segmentation fault, resulting a potential DoS.

    Fix: (fio) fixed an issue exposed by implementing the TLS layer, where the highet fd for a connection that wasn't assigned a protocol_s object immediately after the connection was opened, might avoid timeout review or avoid cleanup during shutdown (which will be marked as a memory leak).

    Update: (fio_tls) added experimental support for OpenSSL. This was only partially tested and should be considered experimental.

    Update: (fio) added, the fio_rw_hook_replace_unsafe to allow r/w hook switching from within a r/w hook callback.

    Update: (fio_cli) a common user-error is a a missing fio_cli_end, resulting in a memory leak notification. Now facil.io protects against this common error by automatically calling fio_cli_end during the exit stage, if fio_cli_start was called.

    Source code(tar.gz)
    Source code(zip)
  • 0.7.0.beta5(Dec 26, 2018)

    This is a quick fix release, fixing a minor issue introduced in the 0.7.0.beta4 version:

    Fix: (fio_cli) fixed an issue introduced in version 0.7.0.beta4, where fio_cli_get_i would dereference NULL if the value wasn't set. Now fio_cli_get_i returns zero (0) for missing values, as expected. Note: this related to the new hex and binary base support in command line numerals.

    Source code(tar.gz)
    Source code(zip)
  • 0.7.0.beta4(Dec 25, 2018)

    BREAK: (fio_cli) breaking API changes make this extension easier than ever to use... I do apologize for this, but part of the reason 0.7.0 is still in beta is to test the API itself for ease of use and readability.

    Fix: (fio) fixed a minor memory leak in cluster mode, caused by the root process not freeing the hash map used for child process subscription monitoring.

    Fix: (fio) fixed superfluous and potentially erroneous pub/sub engine callback calls to unsubscribe, caused by (mistakingly) reporting filter channel closure.

    Fix: (mustache, FIOBJ) added support for dot notation in mustache templates.

    Fix: (http/1.1) avoid processing further requests if the connection was closed.

    Fix: (fio_test) fixed some memory leaks in the testing functions.

    Update: (fio_cli) stylize and beautify FIO_CLI_PRINT_HEADER lines.

    Update: (fio) updated the automatic concurrency calculations to leave resources for the system when a negative value is provided (was only available for worker count calculations, now available for thread count as well).

    Source code(tar.gz)
    Source code(zip)
  • 0.7.0.beta3(Dec 13, 2018)

    Fix: (fio) Fixed superfluous ping events that might occur after a fio_write (but before the scheduled write actually occurred).

    Fix: (mustache) updated the mustache parser to fix an issue with template loading path names. The partial template path resolution logic was re-written, fixed and improved (I hope). This also adds support for text in mustache lambda, though not applicable when used with FIOBJ.

    Fix: (fio) Prevent Read/Write Hooks from delaying fio_force_close when an error occures while polling a connection.

    Fix: (fio) Deletes Unix sockets once done listening. Fixes an issue where the files would remain intact.

    Fix: (fio) Replaced fio_malloc existing memory allocation / free-list implementation. This also fixes an issue with large memory pools being retained on multi-core systems with many reported CPU cores.

    Fix: (fio) The FIO_FORCE_MALLOC flag was fixed to accommodate for the fact that fio_malloc returns zeroed data (all bytes are set to zero) vs. the system's malloc which might return junk data.

    Fix: (http) fixes a possible memory leak in http_mimetype_register, where clearing the registry wouldn't free the FIOBJ Strings.

    Update: (cli) updated handling of empty strings in CLI values by ignoring the argument rather than printing an error or experiencing an undefined value.

    Optimization: (fio) pub/sub channel names appear to be (often) objects with a long life-span. Hence, these objects now use malloc (instead of fio_malloc). Also, temporary allocations in fio_subscribe were removed.

    Optimization: (fio) pub/sub meta-data information and callbacks now use an Array (instead of link lists and a hash map). This should improve cache locality when setting and retrieving pub/sub meta-data.

    Optimization: (fio) added an urgent task queue for outbound IO, possibly improving protection against non-evented / blocking user code.

    Optimization: (http) WebSocket broadcasting optimizations are now automated.

    Source code(tar.gz)
    Source code(zip)
  • 0.7.0.beta2(Nov 13, 2018)

    Breaking Changes!

    A lot of the code was re-written and re-organized, minimizing the name space used by the core library and consolidating the core library into a two file library (fio.h and fio.c).

    This translated directly to breaking the API and ABI and bumping the version number.

    This should make the library easier to copy and use as well as minimize possible name collisions (at the price of maintaining a couple of monolithic files as the core library).

    These are the main changes:

    • Extracted the FIOBJ library from the core library, making it an add-on that could used by the extensions (such as the HTTP extension) rather than a core requirement.

    • Condensed the core library and it's namespace to two files (fio.h and fio.c) - replaced all facil_ function names with fio_ to accommodate the new namespace.

      ...why?

      It's a choice to sacrifice ease of maintainability in favor of ease of use.

      Although two files are more difficult to maintain than 10 files (assuming it's the same amount of code)... it seems that two files are easier for other developers to copy and paste into their projects.

    • Added poll support to allow for performance testing and CYGWIN compatibility. The system epoll/kqueue calls should perform better for higher loads, but now you can see for yourself.

    • Timers are now in user space, allowing for more timers and less kernel dependencies.

    • The on_idle and on_finish settings in facil_run (now fio_start) were removed, replaced by the more flexible fio_state_callback_add approach.

    • The fio_listen and http_listen functions now return the listening socket's uuid (much like fio_connect and http_connect did).

    • The Protocol's on_shutdown callback is now expected to return a uint8_t, hinting at a requested timeout before the socket is forcefully closed. A return value of 0 will indicate immediate socket closure with an 8 second timeout for outgoing buffer flushing.

    • The cluster messaging system and the Pub/Sub system were both refactored, the API changed and the FIOBJ dependency was removed. This change cascades to effect all the Pub/Sub system elements.

    • The Pub/Sub system's use_pattern was replaced with the optional callback argument match (a function pointer), allowing for custom pattern matching approaches (such as implementing NATs and RabbitMQ pattern matching). The previous glob matching approach (Redis compatible) is available using the provided FIO_MATCH_GLOB function pointer.

    • The WebSocket upgrade (http_upgrade2ws) now matches the SSE upgrade function (starts with the handle http_s * and named arguments come later).

    • The CLI API and implementation was completely rewritten.

      The new code is slightly more "monolithic" (one long function does most of the work), but should waste less memory with a simpler API (also got rid of some persistent data).

    • The Read/Write socket hooks were redesigned.

    • An SSL/TLS API stub was designed for SSL/TLS library abstraction (not implemented yet).

      This API is experimental and might change as I author the first SSL/TLS library wrappers (roadmap includes OpenSSL and BearSSL).

    Update: (fio_mem => fio.h) updated the allocator defaults to lower the price of a longer life allocation. Reminder: the allocator was designed for short/medium allocation life-spans or large allocations (as they directly map to mmap). Now 16Kb will be considered a larger allocation and the price of holding on to memory is lower (less fragmentation).

    Fix: (fio) fixed a typo in the shutdown output. Credit to @bjeanes (Bo Jeanes) for the Iodine#39 PR.

    Feature: (FIOBJ) added mustache template support.

    Logo: Logo created by @area55git (Area55)

    Documentation: A new website!

    Source code(tar.gz)
    Source code(zip)
  • 0.6.4(May 11, 2018)

    This is a bug squashing release.

    Fix: (sock) fixed an issue where calls to sock_write could potentially add data to the outgoing queue even after sock_close in cases where the outgoing queue isn't empty.

    Fix: (facil.io) fixed a race condition between pre-scheduled tasks (defer calls) and the worker process initialization. The race condition might have resulted in some pre-scheduled tasks not running on all the workers.

    Fix: (http) fixed an issue with the HTTP request logging, where the peer address wasn't shown.

    Fix: (websocket) made sure that on_ready is never called before on_open returns.

    Fix: (fio_mem, facil, http) fixed compatibility issues with Alpine Linux distro and older OS X versions (< 10.12).

    Fix: (http) fixed the http_date2rfc2109 method where a space wasn't written to the buffer after the month name (resulting in a junk byte).

    Fix: (pubsub) made sure that newly registered engines get the full list of existing subscriptions (no need to call pubsub_engine_resubscribe).

    Fix: (facil) possible fix for protocol attachment with NULL protocol.

    Source code(tar.gz)
    Source code(zip)
  • 0.6.3(Apr 26, 2018)

    Welcome EventSource (SSE) support into the mix - using the .on_upgrade callback with "sse" as the requested protocol identifier, it's now easy to support SSE on facil.io applications.

    The details:

    Fix: (fio_hashmap / fiobj_hash) fixed a possible issue that could occur when compacting a severely fragmented Hash (where the length of the new storage requirements is shorter than the fragmented ordered array of data).

    Fix: (http / websocket) fixed an issue where the WebSocket's on_close callback wouldn't be called if certain errors prevented the upgrade. Now the on_close callback is always called.

    Fix: (http) fixed an issue where the Content-Type header might be missing when sending unrecognized files. Now an additional best attempt to detect the content type (this time using the URL instead of the file name) will be performed. If no content type is detected, the default RFC content type will be attached (application/octet-stream).

    Fix: (http1_parser) fixed a possible unaligned memory access concern.

    Fix: (FIOBJ) fixed compiler compatibility concerns with the fiobj_num_new logic, removing some possibly undefined behavior.

    Fix: (facil) a missing on_data protocol callback (missing during facil_attach) will now call facil_quite, preventing the event from firing endlessly.

    Update: (http) the on_upgrade callback now supports SSE connections with sse protocol identifier and the http_upgrade2sse function.

    Update: (sock) initial support for TCP Fast Open (TFO) when listening for connections.

    Source code(tar.gz)
    Source code(zip)
  • 0.6.2(Apr 6, 2018)

    This version fixes a number of issues, including a serious issue that prevented sockets from fully flushing their buffer.

    This version also improved the shutdown and hot restart logic and fixes numerous issues with cluster mode an pub/sub services.

    Note that the pubsub_engine_s struct was updated, which might break ABI for those that write custom extensions to the library (reminder: this is a source code library, I try to keep the ABI stable, but I take more liberty while still in development versioning).

    It's recommended that all 0.6.0.beta, 0.6.0 and 0.6.1 upgrade to this version.

    Security: (http1) added a hard-coded limit on the number of headers allowed per request (regardless of size). HTTP_MAX_HEADER_COUNT defaults to 128, which should be enough by all accounts.

    Fix: (pubsub, facil, redis-engine) fixed numerous cluster and Pub/Sub issues, including support for new on_startup callback for pubsub_engine_s objects (to make handling forks that much easier. This fixes a memory leak, a reference counting error that freed memory prematurely, message parsing errors on fragmented messages, an obsolete ping formatting error, and more.

    Fix: (sock, facil) fixed an issue where socket buffers wouldn't be completely cleared (the on_ready event wouldn't be properly re-armed). This was discovered as a serious issue and upgrading to 0.6.2 is recommended.

    Fix: (http) fixed an HTTP status string output error, where status codes above 410 would degrade to status 500 (internal error) instead of printing the correct status string to the response.

    Fix: (websockets) fixed a missing "close" packet signal that should have been sent immediately after the user's on_shutdown callback.

    Fix: (FIOBJ) fixed the fiobj_str_tmp function to add thread safety (temp string should be stored in the thread's local storage, not globally accessible).

    Fix: (redis) fixed a race condition in the Redis engine that could prevent publishing connections from being established in worker processes.

    Fix: (facil) fixed an issue where facil_attach wouldn't call the on_close callback if the failure was due to the file descriptor being equal to -1.

    Fix: (facil) fixed a signaling issue where a SIGUSR1 sent to a worker process might inadvertently shutdown the server instead or wind down the specific worker and re-spawn a new one.

    Fix: (facil) fixed a signal handling logic to make it async-safe, protecting it against possible deadlocks or cluster stream corruption.

    Update/Fix: (facil) the on_data event will no longer be fired for sockets that were flagged to be closed using sock_close.

    Update: (FIOBJ) updated the fiobj_str_readfile to allow for a negative stat_at position (calculated from the end of file of the file backwards).

    Update: (facil) strengthened the on_shutdown callback lock to prevent the on_shutdown callback from being called while the on_data callback (or other connection tasks) is running.

    Update: (facil) shutdown logic provides more time for socket buffers to flush (only when required).

    Source code(tar.gz)
    Source code(zip)
  • 0.6.1(Mar 25, 2018)

    Fixed a few issues and cleaned up some code.

    Fix: (pubsub) fixed a possible issue where a channel name might be freed before it's callback is handled. This was overlooked during the Hash caching logic update that prevented key hashing when the last item of the ordered Hash is removed.

    Fix: (pubsub) pubsub will now compact the memory used for client and channel data if the storage becomes excessively fragmented.

    Fix: (hashmap) fixed a possible memory reading issue that could occur when a Hash contains only one object and that object is removed (causing a memory read into the location just before the Hash map's address).

    Fix: (defer) defer now prefers the statically allocated buffer over the dynamically allocated buffer when all tasks have completed, preventing the last allocated buffer from leaking during the shutdown stage.

    Fix: (websocket) subscriptions created during the on_close callback (besides indicating that the API was being abused) are now properly removed.

    Source code(tar.gz)
    Source code(zip)
  • 0.6.0(Mar 19, 2018)

    Version 0.6.0 is a major release, changing much of the extension API (HTTP, pub/sub, CLI) and some of the core API (i.e., moving the evio polling from level-triggered to one-shot polling, a rewrite to the facil.io dynamic object types FIOBJ, and more).

    The following updates are included in this release (in addition to the beta updates):

    Fix: (pubsub) Fixed an issue where deferred pub/sub messages would have udata2 set to udata1 instead of the actual correct value.

    Fix: (facil) Fixed the facil_is_running() function, which could crash if facil.io wasn't initialized before the function was called.

    Fix: (facil) Fix CPU limit detection. Negative values are now meaningful (fraction of CPU cores, so -2 == cores/2). Zero values are replaced by facil.io.

    Update: (facil) Hot restart is now available for cluster mode. By sending the SIGUSR1 signal to the program, facil.io will shutdown any worker processes and re-spawn new workers, allowing for a hot restart feature. Disable using FACIL_DISABLE_HOT_RESTART

    Update: (facil) Dedicated system mode can be toggled by setting the FIO_DEDICATED_SYSTEM macro during compile time. When FIO_DEDICATED_SYSTEM is set, facil.io will assume all the CPU cores are available and it will activate threads sooner. When FIO_DEDICATED_SYSTEM is defined as 0, facil.io will limit thread to protect against slow user code (rather than attempt concurrent IO).

    Update: (fio_mem) replaced the double linked list logic with a single linked list to make the library more independent as well as reduce some operations.

    As well as some refactoring, minor adjustments and the beta updates.

    Source code(tar.gz)
    Source code(zip)
  • 0.5.10(Mar 13, 2018)

    This is a back ported fix to the facil.io cluster messaging system in the 0.5.x release branch.

    Fix: (facil / pubsub) fixed an issue where cluster messages would be corrupted when passed in high succession. Credit to Dmitry Davydov (@haukot) for exposing this issue through the Iodine server implementation (the Ruby port).

    It should be noted that this doesn't fix the core weakness related to large cluster or pub/sub messages, which is caused by a design weakness in the pipe implementation (in some kernels).

    The only solution for large message corruption is to use the new pub/sub engine introduced in the facil.io 0.6.x release branch, which utilizes Unix Sockets instead of pipes.

    Source code(tar.gz)
    Source code(zip)
  • 0.6.0.beta.8(Mar 2, 2018)

    I still have a few features to roll out before 0.6.0 is officially released. Otherwise, this version would have been the actual release.

    This version appears to be both more stable and more mature than the 0.5.9 release.

    One of the best performance enhancers in this release is the custom memory allocator. It's tuned for the network style use and probably shouldn't be used for persistent data... it's also thread-friendly and fast.

    The cookie implementation is also sweeter, now with easy cookie parsing (both for client and server modes) as well as cookie authoring.

    Fix: (defer) the defer_free_thread symbol is now correctly marked as weak, allowing the function to be overridden.

    Fix: (http) fixes an issue where cookies without an explicit age would be marked for immediate deletion (instead of the expected "session" lifetime).

    Fix: (http) fixes a potential issue where a missing or corrupt accept-encoding header could cause a segmentation fault.

    Fix: (http) fixes an issue where a cookie encoding errors would reported repeatedly.

    Fix: (fio_hash) fixes an issue where resubmitting a removed object wouldn't increase the object count.

    Fix: (fiobj) fixes an issue where testing the type of specific FIOBJ_T_NUMBER objects using FIOBJ_TYPE_IS would return a false positive for the types FIOBJ_T_HASH or FIOBJ_T_STRING.

    Update: Added an experimental custom memory allocator (fio_mem.h) optimized for small concurrent short-lived allocations (anything over 16Kb and reallocations start to take a toll). It can replace the system's malloc function family when FIO_OVERRIDE_MALLOC is defined. To use tcmalloc or jemalloc, define FIO_FORCE_MALLOC to prevent fio_mem from compiling.

    Update: (http) added cookie parsing.

    Update: minor optimizations, fio_malloc incorporation and documentation updates.

    Source code(tar.gz)
    Source code(zip)
  • 0.6.0.beta.7(Feb 11, 2018)

    This beta 7 release is a big step towards an actual 0.6.0 release, with some important bugs being squashed.

    I still want to implement a few features and live-test the beta versions in an actual project before a full version release...

    ... However, by now the 0.6.0.beta.x releases are far superior than the 0.5.x releases in terms of API, extendibility and ease of use. Where 0.5.x was a closer to being a platform than a framework, the 0.6.0 release is definitely a framework.

    Enjoy.

    Fix: (websockets) fixed an issue with client pinging would break the protocol in a way that would result in either loss of data or disconnections.

    Fix: (websockets) removed the debugging ping (3 seconds interval ping) from the Websocket client. Pings can be sent manually or by setting the connection's timeout using facil_set_timeout.

    Fix: (websockets) made sure the client mask is never zero by setting a few non-random bits.

    Fix: (redis) fixed an issue where the command queue (for busy pipelined Redis commands and for reconnection) would send the last message repeatedly instead of sending the messages in the queue.

    Fix: (facil) Fixed a possible memory leak related to facil_connect and failed connections to localhost. Improved process exit cleanup.

    Fix: (pubsub) improved process exit cleanup.

    Fix: (fio_cli) fixed text coloring on terminal output.

    Fix: (fio_hash) fixed looping logic to remove the need for the "data-end" marker optimizing allocations in a very small way.

    Update: (websockets) added a client example using the terminal IO for Websocket text communication.

    Source code(tar.gz)
    Source code(zip)
  • 0.6.0.beta.6(Feb 8, 2018)

    This beta release is a performance oriented release and includes mostly performance related changes.

    This release updates some default values to make them more reasonable for common use cases and to help minimize memory consumption.

    These values, such as the LIB_SOCK_MAX_CAPACITY, FIO_HASH_INITIAL_CAPACITY and the FIOBJ_ARRAY_DEFAULT_CAPA values, can be updated during compile time.

    Some of these default values can be bypassed during runtime by using specific function calls (such as fio_hash_new2).

    Other notable performance changes include the short string hash cashing (shortening the FIOBJ short-string capacity in exchange for reducing fio_siphash calls).

    These are lessons learned from the TechEmpower benchmarks... although they will not be reflected in the Round 15 results.

    Source code(tar.gz)
    Source code(zip)
  • 0.6.0.beta.5(Feb 6, 2018)

    Releasing fixes for issues related to the TechEmpower Framework Benchmarks 80 core startup.

    Fix: fixed error handling during cluster mode startup, making sure facil.io fails to start.

    Update: capped maximum core detection value to 120 cores. Any value larger than 120 will raise a warning and the cap (120) will be used.

    Source code(tar.gz)
    Source code(zip)
  • 0.6.0.beta.4(Feb 6, 2018)

    This release should have no significant changes from the beta.3 release. This release signifies a testing milestone for the beta stage.

    A facil.io server was stress tested, malicious data was sent, connections were abruptly terminated, timeouts were held on to and abuse was generally attempted... and all was well :-)

    There's also some minor refactoring and minor JSON performance enhancements were attempted... these are negligible.

    Source code(tar.gz)
    Source code(zip)
  • 0.6.0.beta.3(Feb 4, 2018)

    The long awaited Websocket Client support is here and it's working (limited testing so far, but hey... it's super fun 🎉).

    Breaking Change: (websockets) the websocket on_close callback signature had changed to allow it to be called on connection/upgrade failures as well (easier udata cleanup).

    Fix (facil): fixes an issue introduced in the beta.2 version, where deferred events that where scheduled before a call to facil_run would only be called for the parent process. Now these events would perform as intended (once in the root process and once in each worker process).

    Fix (facil): updates the logical assumption about open connections, to make sure any open connections are closed when re-spawning a child worker. This shift the connection assumption from unsafe (forked connections should be closed by extensions) to safe (reconnection should be handled by extension). This change should effect internal extensions only, since active connections aren't handled by the root process in clustered mode.

    Change (websocket): the protocol is now more forgiving in cases where clients don't mask empty messages.

    Feature (websockets): A simple and easy Websocket client using websocket_connect as well as support for more complex clients (with authentication logic etc') using a combination of the http_connect and http_upgrade2ws functions.

    Minor: some changes to the inner HTTP logic, fixed some error messages, and other minor updates.

    Source code(tar.gz)
    Source code(zip)
  • 0.6.0.dev(Jan 20, 2018)

    This is a major release, changing much of the extension API (HTTP, pub/sub, cli) and some of the core API (i.e., moving the evio polling to One-Shot polling).

    Migration isn't difficult, but is not transparent either.

    Note About Fixes:

    • I simply rewrote much of the code to know if the issues I fixed were present in the 0.5.x version or not.

      I believe some things work better. Some of the locking concerns will have less contention and I think I fixed some issues in the fiobj core types as well as the http extension.

      However, experience tells me a new major release (0.6.0) is always more fragile than a patch release. I did my best to test the new code, but experience tells me my tests are often as buggy as the code they test.

      Anyway, I'm releasing 0.6.0 knowing it works better than the 0.5.8 version, but also knowing it wasn't battle tested just yet.

    Changes!: (fiobj / facil.io objects):

    • Major API changes.

      The facil.io dynamic type library moved closer to facil.io's core, integrating itself into the HTTP request/response handling, the Pub/Sub engine, the Websocket internal buffer and practically every aspect of the library.

      This required some simplification of the fiobj and making sure future changes would require less of a migration process.

    • The Symbol and Couplet types were removed, along with nesting protection support (which nobody seemed to use anyway).

    • We're back to static typing with enum, using macros and inline functions for type identification (better performance at the expense of making extendability somewhat harder).

    • Hashes are now 100% collision resistant and have improved memory locality, at the expense of using more memory and performing calling memcmp (this can be avoided when seeking / removing / deleting items, but not when overwriting items).

    Changes!: (http):

    • The HTTP API and engine was completely re-written (except the HTTP/1.1 parser), both to support future client mode (including chunked encoding for trailing headers) and to make routing and request parsing easier.

    • The updates to the HTTP API might result in decreased performance during the HTTP request reading due to the need to allocate resources and possibly copy some of the data into dynamic storage... For example, header Hash Tables replaced header Arrays, improving lookup times and increasing creation time.

    • The HTTP parser now breaks down long URI schemes into a short URI + host header (which might become an array if it's included anyway).

    Changes!: (websocket):

    • The Websocket API includes numerous breaking changes, not least is the pub/sub API rewrite that now leverages FIOBJ Strings / Symbols.

    • websocket_write_each was deprecated (favoring a pub/sub only design).

    Changes!: (pubsub):

    • The pubsub API was redesigned after re-evaluating the function of a pub/sub engine and in order to take advantage of the FIOBJ type system.

    • Channel names now use a hash map with collision protection (using memcmp to compare channel names). The means that the 4 but trie is no longer in use and will be deprecated.

    Changes!: (redis):

    • The redis_engine was rewritten, along with the RESP parser, to reflect the changes in the new pubsub service and to remove obsolete code.

    Changes!: (facil):

    • Slight API changes:

      • facil_last_tick now returns struct timespec instead of time_t, allowing for more accurate time stamping.

      • facil_cluster_send and facil_cluster_set_handler were redesigned to reflect the new cluster engine (now using Unix Sockets instead of pipes).

    • Internal updates to accommodate changes to other libraries.

    • Cluster mode now behaves as sentinel, re-spawning any crashed worker processes (except in DEBUG mode).

    Changes!: (evio):

    • the evented IO library was redesigned for one-shot notifications, requiring a call to evio_add or evio_set_timer in order to receive future notifications.

      This was a significant change in behavior and the changes to the API (causing backwards incompatibility) were intentional.

    • the code was refactored to separate system specific logic into different files. making it easier to support more systems in the future.

    Changes!: (sock):

    • the socket library now supports automatic Unix detection (set port to NULL and provide a valid Unix socket path in the address field).

    • the socket library's Read/Write hooks API was revised, separating the function pointers from the user data. At server loads over 25%, this decreases the memory footprint.

    • the socket library's packet buffer API was deprecated and all sock_write2(...) operations take ownership of the memory/file (enforce move).

    • The internal engine was updated, removing pre-allocated packet buffers altogether and enabling packet header allocation using malloc, which introduces a significant changes to the internal behavior, possibly effecting embedded systems.

    Changes!: (defer):

    • Removed forking from the defer library, moving the fork logic into the main facil source code.

    • Defer thread pools and now include two weak functions that allow for customized thread scheduling (wakeup/wait). These are overwritten by facil.io (in facil.c).

      By default, defer will use nanosleep.

    Refactoring: (fiobj) moved the underlying Dynamic Array and Hash Table logic into single file libraries that support void * pointers, allowing the same logic to be used for any C object collection (as well as the facil.io objects).

    Source code(tar.gz)
    Source code(zip)
  • 0.5.9(Dec 29, 2017)

    Fix: (websocket_parser)

    The websocket parser had a rare memory offset and alignment handling issue in it's unmasking (XOR) logic and the new memory alignment protection code.

    The issue would impact the parser in rare occasions when multiple messages where pipelined in the internal buffer and their length produced an odd alignment (the issue would occur with very fast clients, or a very stressed server).

    The issue was discovering during testing of the 0.6.0-dev version branch and the fix was backported to the 0.5.x version.

    Source code(tar.gz)
    Source code(zip)
  • 0.5.8(Dec 10, 2017)

    This version is a minor patch to the 0.5.7 version, which broke Linux compilation on some GCC versions:

    Fix: (defer, fiobj) fix Linux compatibility concerns (when using GCC). Credit goes to @kotocom for opening issue #23.

    Source code(tar.gz)
    Source code(zip)
  • 0.5.7(Dec 8, 2017)

    This release marks an improvement to the defer core. Next up are changes to the evio core which will probably require a version bump (from 0.5.x to 0.6.x).

    This version includes the following changes:

    Fix: (defer) fixes the non-debug version of the new (v.0.5.6) defer, which didn't define some debug macros.

    Fix: Added cmake_minimum_required and related CMake fixes to the CMake file and generator. Credit to David Morán (@david-moran) for PR #22 fixing the CMakelist.txt.

    Compatibility: (websocket_parser) removed unaligned memory access from the XOR logic in the parser, making it more compatible with older CPU systems that don't support unaligned memory access or 64 bit word lengths.

    Optimization: (defer) rewrote the data structure to use a hybrid cyclic buffer and linked list for the task queue (instead of a simple linked list), optimizing locality and minimizing memory allocations.

    Misc: minor updates and tweaks, such as adding the fiobj_ary2prt function for operations such as quick sort, updating some documentation etc'.

    Source code(tar.gz)
    Source code(zip)
  • 0.5.5(Nov 9, 2017)

    Fix: (fiobj) fixed an issue #21, where gcc would complain about overwriting the fio_cstr_s struct due to const members. Credit to @vit1251 for exposing this issue.

    Fix: (fiobj) fixed NULL pointer testing for fiobj_free(NULL).

    Fix/Compatibility: (gcc-6) Fix some compatibility concerns with gcc version 6, as well as some warnings that were exposed when testing with gcc.

    Optimization: (fiobj) optimized the JSON parsing memory allocations as well as fixed some of the function declarations to add the const keyword where relevant.

    Source code(tar.gz)
    Source code(zip)
  • 0.5.4(Oct 31, 2017)

    The 0.5.4 release focused on updating the internal code's design and includes all the fixes and changes from the (unreleased) 0.5.3 code base

    Some notable updates include native JSON support and the new fiobj dynamic type system.

    These include:

    Change/Update: (fiobj) The dynamic type library (a version 0.5.3 feature) was redesigned to make it extendable. This means that code that used type testing using a switch statement needs to be rewritten.

    Change: minor changes to the versioning scheme removed some version MACROS... this isn't API related, so I don't consider it a breaking change, but it might effect code that relied too much on internal workings. The only valid version macros are the FACIL_VERSION_* macros, in the facil.h header.

    Change: (http) the HTTP/1.x parser was re-written and replaced. It should perform the same, while being easier to maintain. Also, the new parser could potentially be used to author an HTTP client.

    Change: (websocket) the Websocket parser was re-written and replaced, decoupling the parser and message wrapper from the IO layer. Performance might slightly improve, but should mostly remain the same. However, the new code is easier to maintain and easier to port to other implementations. Also, the new parser supports a client mode (message masking).

    Fix: (websocket) issues with the new websocket parser were fixed. Credit to Tom Lahti (@uidzip) for exposing the issues.

    Fix: (websocket) fix #16, where a client's first message could have been lost due to long on_open processing times. This was fixed by fragmenting the upgrade event into two events, adding the facil_attach_locked feature and attaching the new protocol before sending the response. Credit to @madsheep and @nilclass for exposing the issue and tracking it down to the on_open callbacks.

    Fix: (sock) sockets created using the TCP/IP sock library now use TCP_NODELAY as the new default. This shouldn't be considered a breaking change as much as it should be considered a fix.

    Fix: (http1) HTTP/1.x is now more fragmented, avoiding a read loop to allow for mid-stream / mid-processing protocol upgrades. This also fixes #16 at it's root (besides the improved websocket callback handling).

    Fix: (http1) HTTP/1.x now correctly initializes the udata pointer to NULL fore each new request.

    Fix: (facil) the facil_run_every function now correctly calls the on_finish callback when a timer initialization fails. This fixes a leak that could have occurred due to inconsistent API expectations. Workarounds written due to this issue should be removed.

    Fix: (facil) connection timeout is now correctly ignored for timers.

    Fix: (defer) a shutdown issue in defer_perform_in_fork was detected by @cdkrot and his fix was implemented.

    Fix: (evio) fixed an issue where the evented IO library failed to reset the state indicator after evio_close was called, causing some functions to believe that events are still processed. Now the evio_isactive will correctly indicate that the evented IO is inactive after evio_close was called.

    Fix: (evio) fixes an issue where evio_add_timer would fail with EEXIST instead of reporting success (this might be related to timer consolidation concerns in the Linux kernel).

    Fix: (evio) better timer fd creation compatibility with different Linux kernels.

    Fix: (documentation) credit to @cdkrot for reporting an outdated demo in the README.

    Fix: (linking) added the missing -lm linker flag for gcc/Linux (I was using clang, which automatically links to the math library, so I didn't notice this).

    Portability: added extern "C" directive for untested C++ support.

    Feature: 🎉 added a CLI helper service, allowing easy parsing and publishing of possible command line arguments.

    Feature: 🎉🎉 added a dynamic type library to facil.io's core, making some common web related tasks easier to manage.

    Feature: 🎉🎉🎉 added native JSON support. JSON strings can be converted to fiobj_s * objects and fiobj_s * objects can be rendered as JSON! I'm hoping to get it benchmarked publicly.

    Source code(tar.gz)
    Source code(zip)
Owner
Bo
Musician and Programmer by love and trade. My intention is to leave this world in a more compassionate, loving and free state than it was when I entered it.
Bo
🌱Light and powerful C++ web framework for highly scalable and resource-efficient web application. It's zero-dependency and easy-portable.

Oat++ News Hey, meet the new oatpp version 1.2.5! See the changelog for details. Check out the new oatpp ORM - read more here. Oat++ is a modern Web F

Oat++ 4.7k Dec 3, 2021
Drogon: A C++14/17 based HTTP web application framework running on Linux/macOS/Unix/Windows

English | 简体中文 | 繁體中文 Overview Drogon is a C++14/17-based HTTP application framework. Drogon can be used to easily build various types of web applicat

An Tao 6.5k Dec 6, 2021
A C++ Web Framework built on top of Qt, using the simple approach of Catalyst (Perl) framework.

Cutelyst - The Qt Web Framework A Web Framework built on top of Qt, using the simple and elegant approach of Catalyst (Perl) framework. Qt's meta obje

Cutelyst 721 Dec 7, 2021
Crow is very fast and easy to use C++ micro web framework (inspired by Python Flask)

Crow is C++ microframework for web. (inspired by Python Flask) #include "crow.h" int main() { crow::SimpleApp app; CROW_ROUTE(app, "/")([]()

Jaeseung Ha 6.6k Dec 5, 2021
QDjango, a Qt-based C++ web framework

QDjango - a Qt-based C++ web framework Copyright (c) 2010-2015 Jeremy Lainé About QDjango is a web framework written in C++ and built on top of the Qt

Jeremy Lainé 231 Nov 26, 2021
This is a proof-of-concept of a modern C web-framework that compiles to WASM and is used for building user interfaces.

DanCing Web ?? ?? (DCW) Getting Started Dancing Web is now distributed with the Tarantella Package Manager — a tool I've made to simplify setup of pro

Danilo Chiarlone 3 Sep 11, 2021
Experimental, scalable, high performance HTTP server

Lwan Web Server Lwan is a high-performance & scalable web server. The project web site contains more details. Build status OS Arch Release Debug Stati

Leandro A. F. Pereira 5.5k Dec 2, 2021
A high-performance REST Toolkit written in C++

Pistache Pistache is a modern and elegant HTTP and REST framework for C++. It is entirely written in pure-C++14 and provides a clear and pleasant API.

null 2.6k Dec 3, 2021
Cetus is a high performance, stable, protocol aware proxy for MySQL Group Replication.

Introduction Cetus is a high performance, stable, protocol aware proxy for MySQL Group Replication. Getting started 1. Prerequisites cmake gcc glib2-d

null 34 Dec 6, 2021
C++ application development framework, to help developers create and deploy applications quickly and simply

ULib - C++ library Travis CI: Coverity Scan: ULib is a highly optimized class framework for writing C++ applications. I wrote this framework as my too

stefano casazza 936 Nov 26, 2021
The application framework for developer module of EdgeGallery platform

crane-framework crane-framework将可复用的计算和软件功能抽象成插件,APP开发者面向使用插件进行MEC APP开发。这样屏蔽了和MEC平台交互的细节,实现MCE APP和MEC平台的松耦合。而且插件框架基础能力可裁剪,按需提供最小的APP系统。 特性介绍 为了方便开发者

EdgeGallery 21 Aug 30, 2021
Embedded C/C++ web server

CivetWeb The official home of CivetWeb is https://github.com/civetweb/civetweb Continuous integration for Linux and macOS (Travis CI): Continuous inte

null 1.9k Nov 30, 2021
C library to create simple HTTP servers and Web Applications.

Onion http server library Travis status Coverity status Onion is a C library to create simple HTTP servers and Web Applications. master the developmen

David Moreno Montero 1.8k Dec 2, 2021
A C++11 RESTful web server library

Served Overview Served is a C++ library for building high performance RESTful web servers. Served builds upon Boost.ASIO to provide a simple API for d

Meltwater 675 Nov 23, 2021
cserv is an event-driven and non-blocking web server

cserv is an event-driven and non-blocking web server. It ideally has one worker process per cpu or processor core, and each one is capable of handling thousands of incoming network connections per worker. There is no need to create new threads or processes for each connection.

null 35 Sep 10, 2021
Corvusoft's Restbed framework brings asynchronous RESTful functionality to C++14 applications.

Restbed Restbed is a comprehensive and consistent programming model for building applications that require seamless and secure communication over HTTP

Corvusoft 1.6k Nov 29, 2021
A http/websocket server framework on linux.

The framework is a Web-Server on unix based system. Without using any third-party libraries, the framework writes from unix system calls and standard C library functions.

xingyuuchen 12 Dec 7, 2021
TreeFrog Framework : High-speed C++ MVC Framework for Web Application

Small but Powerful and Efficient TreeFrog Framework is a high-speed and full-stack web application framework based on C++ and Qt, which supports HTTP

TreeFrog Framework 977 Nov 29, 2021
🌱Light and powerful C++ web framework for highly scalable and resource-efficient web application. It's zero-dependency and easy-portable.

Oat++ News Hey, meet the new oatpp version 1.2.5! See the changelog for details. Check out the new oatpp ORM - read more here. Oat++ is a modern Web F

Oat++ 4.7k Dec 3, 2021
🌱Light and powerful C++ web framework for highly scalable and resource-efficient web application. It's zero-dependency and easy-portable.

Oat++ News Hey, meet the new oatpp version 1.2.5! See the changelog for details. Check out the new oatpp ORM - read more here. Oat++ is a modern Web F

Oat++ 4.7k Nov 28, 2021
High performance server-side application framework

Seastar Introduction SeaStar is an event-driven framework allowing you to write non-blocking, asynchronous code in a relatively straightforward manner

ScyllaDB 6.3k Nov 29, 2021
An eventing framework for building high performance and high scalability systems in C.

NOTE: THIS PROJECT HAS BEEN DEPRECATED AND IS NO LONGER ACTIVELY MAINTAINED As of 2019-03-08, this project will no longer be maintained and will be ar

Facebook Archive 1.7k Nov 23, 2021
Drogon: A C++14/17 based HTTP web application framework running on Linux/macOS/Unix/Windows

English | 简体中文 | 繁體中文 Overview Drogon is a C++14/17-based HTTP application framework. Drogon can be used to easily build various types of web applicat

An Tao 6.5k Dec 6, 2021
Drogon: A C++14/17 based HTTP web application framework running on Linux/macOS/Unix/Windows

English | 简体中文 | 繁體中文 Overview Drogon is a C++14/17-based HTTP application framework. Drogon can be used to easily build various types of web applicat

An Tao 6.5k Dec 3, 2021
BingBing 41 Dec 5, 2021
Deploy SCRFD, an efficient high accuracy face detection approach, in your web browser with ncnn and webassembly

ncnn-webassembly-scrfd open https://nihui.github.io/ncnn-webassembly-scrfd and enjoy build and deploy Install emscripten

null 30 Nov 15, 2021