A C++ Web Framework built on top of Qt, using the simple approach of Catalyst (Perl) framework.

Overview

Cutelyst - The Qt Web Framework Cutelyst logo

Build Status Windows Build status Codacy Badge Code Quality: Cpp Total Alerts

A Web Framework built on top of Qt, using the simple and elegant approach of Catalyst (Perl) framework.

Qt's meta object system is what powers the core of Cutelyst, it allows for introspecting controller's methods signatures and generate matching actions that can be invoked later.

BENCHMARKS

Don't trust us on being fast, check out the most comprehensive web framework benchmarks by TechEmpower http://www.techempower.com/benchmarks/

FEATURES:

  • Cross-platform
  • Stable API/ABI - v1 on v1.x.x branch and v2 on tagged from master
  • Pluggable Engines
    • Cutelyst-WSGI - A cross-platform and fast WSGI engine
      • HTTP/1.1 - Pipelining and Keep-Alive
      • HTTP/2 - Upgrade to H2, ALPN negotiation on HTTPS and direct H2C
      • FastCGI - Pipelining and Keep-Alive
    • uWSGI - Multiple protocols support (HTTP 1.0, FastCGI, uWSGI)
  • WebSockets
  • REST with ActionREST
  • Plugin based views
  • Dispatcher
    • Chained
    • Path
  • Plugins
    • Session
    • Authentication (with PBKDF2)
    • Authorization with RoleACL
    • StatusMessage
    • Validator (to validate user input)
    • CSRF protection
    • Memcached
    • UserAgent
  • Asynchronous processing (just don't use local QEventLoops or it will eventually crash)
    • Async SQL with ASql
  • Upload parser
  • JSON body as QJsonDocument when uploaded data is in JSON format
  • C++11
  • Chunked reponses (via QIODevice write API)
  • Request profiling/stats
  • Unit tested
  • QtCreator integration

DOCUMENTATION

Get started with our Tutorial or check the API.

COMMUNITY

The Cutelyst project IRC channel is #cutelyst on freenode.

Or you can use the Mailing List

REQUIREMENTS

  • CMake - for the build system (>= 3.1)
  • Qt - the core library of this framework (>= 5.6)

OPTIONAL

  • uWSGI - to receive and parse protocols requests (>= 1.9 recommended)

LICENSE

The library is under the LGPLv2+ and public header files, documentation and examples are under MIT license.

Issues
  • Implement a validation infrastracture.

    Implement a validation infrastracture.

    This can be used to validate input data. See the code documentation for further information. It's a bit inspired by the validator implementation of Laravel. :) (I never used catalyst)

    opened by buschmann23 40
  • SSE server

    SSE server

    I am trying to implement a SSE (Server Sent Event) in my cutelyst application following the steps in this example http://stefanfrings.de/qtwebapp/tutorial/sse_example.html , but I have some issues:

    1. while(response.isConnected()) isConnected is not implemented in cutelyst
    2. response.flush(); even not implemented

    Both methods are implemented in the demo app as:

    bool HttpResponse::isConnected() const { return socket->isOpen(); }

    void HttpResponse::flush() { socket->flush(); }

    How can I access the underlying socket from the c->response() ?

    opened by iastinf 24
  • Need help with starting HTTP/2 server

    Need help with starting HTTP/2 server

    Hi guys,

    I am new to Cutelyst and after having tough time to compile it on RHEL (had to compile QT5 Base from source as packages are archaic) I am unable to start CWSGI::WSGI server to listen for HTTP/2, because every time I do it just refuses to send reply. (curl: (52) Empty reply from server), for standard HTTP it works fine and sends HTTP/1.1 response. This is the code of my main program. What am I doing wrong?

    CWSGI::WSGI *wsgi = new CWSGI::WSGI();
      Cutelyst::Application *myapp = new Hello();
      QCoreApplication app(argc, argv);
      wsgi->setThreads("auto");
      wsgi->setProcesses("1");
      wsgi->setBufferSize(16393);
      // wsgi->setUpgradeH2c(true); -> tried also turning this on and off
      wsgi->setHttp2Socket({QStringLiteral("0.0.0.0:80")});
      wsgi->setSoKeepalive(true);
      wsgi->setReusePort(true);
      wsgi->setMaster(true);
      wsgi->exec(myapp);
    
    opened by brano543 16
  • Unable to serve static files via HTTP/2

    Unable to serve static files via HTTP/2

    Hi,

    it seems that this line https://github.com/cutelyst/cutelyst/blob/master/Cutelyst/Plugins/StaticSimple/staticsimple.cpp#L77 returns "/" at start when HTTP/2 over SSL is used (wsgi->setHttpsH2(true)) resulting in files not being able to be found.

    Way to replicate

    int main(int argc, char *argv[])
    {
      CWSGI::WSGI *wsgi = new CWSGI::WSGI();
      Cutelyst::Application *myapp = new Hello();
      QCoreApplication app(argc, argv);
      wsgi->setProcesses("1");
      wsgi->setThreads("4");
      wsgi->setHttpsSocket({{QStringLiteral("0.0.0.0:443,/etc/ssl/certs/certificate.crt,/etc/ssl/private/server.key")}});
      wsgi->setHttpsH2(true);
      wsgi->setBufferSize(16393);
      wsgi->setSoKeepalive(true);
      wsgi->setReusePort(true);
      wsgi->setMaster(true);
      wsgi->exec(myapp);
    }
    
    bool Hello::init()
    {
        //initialize controllers
        new Root(this);
    
        //initialize file serving plugin
        auto staticSimple = new StaticSimple(this);
        staticSimple->setDirs({"public"});
        staticSimple->setIncludePaths({QDir::currentPath()});
    
        //initialize templates plugin
        auto grantleeView = new GrantleeView(this);
        grantleeView->setCache(true);
        grantleeView->setIncludePaths({pathTo("views")});
    
        return true;
    }
    

    Even when I fix the line to const QString path = c->req()->path().mid(1); for this scenario and files can actually be found, I am getting net::ERR_SPDY_FRAME_SIZE_ERROR.

    opened by brano543 16
  • Upload files greater than 2Gb

    Upload files greater than 2Gb

    It seems to be a problem uploading files bigger than 2GB.

    Following code

    const auto uploads = c->request()->uploads(); for (Upload *upload : uploads) { upload->save("/tmp/" + upload->filename()); } produces this error message and the file is empty in /tmp/ QIODevice::read (Cutelyst::Upload): Called with maxSize < 0

    With files smaller than 2GB there is no problem except a warning

    Cannot create /tmp/ for output

    Although the file is created successfully

    opened by haralambop 14
  • install package cannot be used in a cross compile environment

    install package cannot be used in a cross compile environment

    I'm working on an embedded system and trying Cutelyst. I have successfully built Cutelyst and created an install package, but the package cannot be used in downstream cmake projects when it is installed into my sysroot. (I use a cmake toolchain file to find the sysroot and otherwise setup my enviornment)

    When cmake gets to the FIND_PACKAGE(CutelystQt5) line I get the following error.

    CMake Error at [sysroot]/usr/lib/cmake/Cutelyst2Qt5/Cutelyst2Qt5Targets.cmake:122 (message):
    -- Configuring incomplete, errors occurred!
    
    The imported target "Cutelyst::Core" references the file
    
         "/usr/lib/libCutelyst2Qt5.so.2.8.0"
    

    I depend on other cmake packages that work. So this is a problem with Cutelyst cmake packages, not cmake or my enviornment.

    opened by HenryMiller1 14
  • uriFor in Grantlee Template

    uriFor in Grantlee Template

    Hi! This is not really an issue but more like a question of best practice. In Catalyst or Flask/Jinja2 I can access the uri_for method directly for creating links for an action. Unfortunately in Grantlee there is no direct way of calling a function with a string parameter. E.g. {{c.uriFor("authen/logout")}} does not work. The Parser is choking on the parameter "Could not parse the remainder, (\"authen/logout\") from c.uriFor(\"authen/logout\")

    Right now, as a workaround, I created a two-level map so that I can access the routes via dot-lookup:

    QVariantHash controllers;
    for( Controller *controller: c->app()->controllers() ) {
      QVariantHash routes;
      for( Action *action: controller->actions() ) {
        routes[action->name()] = c->uriFor(action);
      }
      controllers[controller->objectName()] = routes;
    }
    c->setStash("controllers", controllers);
    

    Having this routes map on my stash I can do something like this in the template:

    <p> <a href="{{controllers.Authen.logout}}">Logout</a> </p>
    

    Sure, better have it in the init method to not have the map generated on every request.

    Or is there another (easier) way to do this? -- Besides creating a Grantlee Filter that appearently accepts string parameters.

    opened by ghost 13
  • Soft termination of user threads using slot for Application::shutdown signal

    Soft termination of user threads using slot for Application::shutdown signal

    Hello! I have a couple of threads which must be gently terminated in the Controller slot slotShutdown() linked with Application::shutdown. I have typical worker objects (QObject descendants) and corresponding QThreads. I emit finalize() signal within slotShutdown(). Then I periodically check worker object atomic bool flag isFinalized in a loop. I quit worker QThread after that. AFAIK, I cannot rely on other slots within Controller after Application::shutdown, that's why I have to check other workers state in a loop using synchronized flag. But I expect that eventloops of other threads are still working when I emit signal within Controller slotShutdown().
    Sometimes the signal is not catched within worker objects, so the loop is eternal. What can be done? I don't want to call methods of worker objects within Controller thread, because I've got Qt warnings about killing timers in the wrong threads etc. BTW, I've used single process (master), single REST Controller thread for this experiment.

    opened by arietto 12
  • [WIP] Prometheus Plugin

    [WIP] Prometheus Plugin

    This is an attempt to provide Prometheus compatible metrics in an easy manner. This plugin uses the existing statistics feature to calculate metrics.

    What do you think?

    opened by sibbi77 12
  • Parallel processing of requests

    Parallel processing of requests

    I am new here and recently I am dealing with Cutelyst. My englich is not gut ;). I have studied the tutorials and implemented. When I have many requests and the processing of one takes 2 seconds (waiting for response from embedded devices), the other requests wait. Is there a possibility in Cutelyst to process the requests in parallel. A simple example would be very helpful.

    opened by cppusta 11
  • Bootstrapping WebSockets with HTTP/2

    Bootstrapping WebSockets with HTTP/2

    Suppose a web page has a script to create a new websocket, then every tab that loads that page (at each time) will create a new websocket. In HTTP1.1, a websocket is in fact a TCP socket connection :-(. And browsers like chrome and firefox limit number of websocket connections.

    Bootstrapping WebSockets with HTTP/2, as specified by https://tools.ietf.org/html/rfc8441, allow multiple websockets to live in one Http2 connection, as a stream, and already gets supported by chrome and firefox.

    However the work to support Websocket in Cutelyst seems not easy. I noticed that the design of http2 is far different from http's, which stop my steps: For Http

    1. ProtoRequestHttp is ProtocolData and EngineRequest
    2. ProtocolHttp is Protocol
    3. ProtocolWebSocket is Protocol

    For Http2

    1. H2Stream is EngineRequest
    2. ProtoRequestHttp2 is ProtocolData
    3. ProtocolHttp2 is Protocol

    @dantti , I would greatly appreciate it if you have plan to support it. Thanks!

    opened by lyarbean 3
  • Error: could not load translations

    Error: could not load translations

    Running cutelyst3-qt5 prints the above error message to stdout.

    Responsible for this is the line https://github.com/cutelyst/cutelyst/blob/657893c9758d75b3a92c3dfdc258af60e2f616ae/cmd/main.cpp#L423

    QLatin1String("qt_") % QLocale::system().name() results on my machine in qt_en_US. There are nowhere files prefixed with that string.

    Cutelyst's translation files are installed to share/cutelyst3 and look like this:

    share
    │   ├── cutelyst3
    │   │   └── translations
    │   │       ├── cutelystcmd.de.qm
    │   │       ├── cutelystcmd.en.qm
    │   │       ├── cutelystcore.de.qm
    │   │       ├── cutelystcore.en.qm
    │   │       ├── cutelystwsgi.de.qm
    │   │       ├── cutelystwsgi.en.qm
    │   │       ├── plugin_csrfprotection.de.qm
    │   │       ├── plugin_csrfprotection.en.qm
    │   │       ├── plugin_memcached.de.qm
    │   │       ├── plugin_memcached.en.qm
    │   │       ├── plugin_utils_validator.de.qm
    │   │       ├── plugin_utils_validator.en.qm
    │   │       ├── plugin_view_cutelee.de.qm
    │   │       ├── plugin_view_cutelee.en.qm
    │   │       ├── plugin_view_grantlee.de.qm
    │   │       └── plugin_view_grantlee.en.qm
    

    Do I miss something?

    opened by neuroassault 2
  • Cutelyst built-in to other Qt app

    Cutelyst built-in to other Qt app

    I have standalone application written in Qt with some data inside. I need to represent that data in some web interface and give data through REST API. Is that possible to built-in the Cutelyst to another Qt/C++ application to make seamless single app with web server inside? If so, where I can get documentation/examples?

    opened by MikePooh 6
  • Trigger socket close when worker shuts down, resulting in faster server termination

    Trigger socket close when worker shuts down, resulting in faster server termination

    Closes #301

    Currently there is a disconnect between any actively established sockets and the Engine during a shutdown. The engine shutdown is triggered and currently just waits for the sockets to finish doing their thing. Testing on my machine results in the engine waiting for a very long timeout (30 seconds) before the child processes have to be forcibly killed in order to shut down the server.

    Instead, this fix invokes the appropriate methods to close the open sockets, result in the workers flushing their buffers and terminating rapidly, resulting in very fast shutdown (woohoo!).

    opened by nmaludy 2
  • Slow shutdown and not cleanly closing listening sockets

    Slow shutdown and not cleanly closing listening sockets

    I noticed two things when trying out Cutelyst:

    1. The server takes a long time to shut down (~30 seconds).

    Doing some investigation / debugging this only happens a user has initiated a connection to the server (example with the browser). In this case the TcpServer never closes its sockets, they stay open and after the timeout the master process has to to SIGKILL the worker children.

    Doing some testing at the fix for this is (i think, feedback appreciated) is adding a call to socket->connectionClose() here: https://github.com/cutelyst/cutelyst/blob/master/server/tcpserver.cpp#L87-L109

    Example:

    void TcpServer::shutdown()
    {
        if (isListening()) {
            pauseAccepting();
        }
    
        if (m_processing == 0) {
            m_engine->serverShutdown();
        } else {
            const auto childrenL = children();
            for (auto child : childrenL) {
                auto socket = qobject_cast<TcpSocket*>(child);
                if (socket) {
                    socket->protoData->headerConnection = ProtocolData::HeaderConnectionClose;
                    connect(socket, &TcpSocket::finished, this, [this] () {
                        if (!m_processing) {
                            m_engine->serverShutdown();
                        }
                    });
                   socket->connectionClose();
                }
            }
        }
    }
    

    2. The server is not properly closing the file descriptor for the socket

    Sometimes (only after a user has initiated a connection) and you shut down the server, then try to restart it, the TCP socket is unable to be opened with the error (notice i turned on native socket debugging #define):

    2118788:2118788 wsgi.tcp_server_balancer[debug] QNativeSocketEnginePrivate::createNewSocket(1, 2) == true
    2118788:2118788 wsgi.tcp_server_balancer[debug] QNativeSocketEnginePrivate::nativeBind(0.0.0.0, 3000) == false (Address already in use)
    2118788:2118788 wsgi.tcp_server_balancer[critical] Failed to bind to socket 8
    Failed to listen on TCP: :3000 : 
    

    I have yet to track down the cause of the issue, but my gut says that the TcpServer is not cleanly closing the listening socket, causing in a bind failure when you launch the application again. Eventually the kernel does something under the hood, cleaning up the socket, and you can launch the server once more.

    Some thoughts from reading/googleing, it might be necessary to:

    • pause accepting connections (dont' accept new connections)
    • read/write any outstanding buffers
    • close the file desriptor
    opened by nmaludy 4
  • Update in vpckg

    Update in vpckg

    This package is using an old version in vcpkg. It would be great to update it.

    opened by manugc 0
  • Setting the action name for chaining

    Setting the action name for chaining

    I'm implementing a REST API (code is here, and I successfully got these endpoints exposed:

    .-------------------+---------------------.
    | Path              | Private             |
    .-------------------+---------------------.
    | /...              | /defaultPage        |
    | /                 | /index              |
    | /api/v1/login     | /api/v1/login/index |
    | /api/v1/users/... | /api/v1/users/user  |
    | /api/v1/users     | /api/v1/users/index |
    .-------------------+---------------------.
    

    Now I want to add a new method, say on /api/v1/users/{id}/changePassword, but I haven't been able to figure out how to achieve that. I've been trying to use the :Chained attribute, but I cannot make the action appear at the desired path. I don't fully understand what the value of the :Chained attribute is; I'd like to be able to set an action ID on the base action, and then chain to that. For example,

        C_ATTR(user, :Path :CaptureArgs(1) :ActionClass(REST) :ActionId("user"))
        // this is the new attribute I wish existed ----------^^^^^^^^^^^^^^^^^
        void user(Context *c, const QString &userId);
    
        C_ATTR(changePassword, :Chained("user") :PathPart("changePassword") :CaptureArgs(1) :ActionClass(REST))
        void ChangePassword(Context *c);
    

    What is the way to achieve what I need? Does it involve playing with the Dispatcher classes, or is there an easier (and better) way?

    opened by mardy 6
  • Using the Session class in a REST application

    Using the Session class in a REST application

    Hi, I'm developing a server which should offer a REST API, most of which should be available only after the user has been authenticated. I was playing with the idea of using the Session class to store the authentication info, like this:

    1. When the user authenticates, I would repeatedly call Session::setValue() to store the information about the authenticated user (like his ID)
    2. Return the Session::id() to the client, аs an authentication token
    3. In the following calls, the client will set the ID we returned in the X-Authentication-Token header
    4. I read the token in the server from the header and set it as the session ID for the context, so that the proper session data gets loaded

    I'm not sure about point 4, because looking at the API I cannot find an obvious way to achieve what I need. Looking at the source code, it would appear that I could do something like:

    c->setStash("_c_session_id", authenticationToken);
    QString userId = Session::value(c, "userId");
    // ...and get any other useful info from the session...
    

    But indeed, the _c_session_id is a string defined in the cpp file, which is supposed to be private. So, I guess there must be some better way to achieve my goal, but I cannot find the right API for it. Any hints? :-)

    opened by mardy 1
  • REST api choice

    REST api choice

    Hi,

    After reading some issues related to REST I just want to be sure; Does Cutelyst is a good choice for building REST web services (just like DRF)?

    opened by mbnoimi 7
Releases(v3.2.0)
Owner
Cutelyst
Cutelyst an elegant C++/Qt Web Framework
Cutelyst
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
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
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
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
Your high performance web application C framework

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 c

Bo 1.5k Dec 2, 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
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
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
The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design. This project aims to help C++ developers connect to and interact with services.

Welcome! The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design

Microsoft 6.6k Dec 4, 2021
Query C++ codebases using SQLite

ClangQL: query C++ codebases using SQLite and clangd What is it? ClangQL is a proof-of-concept SQLite extension for querying C++ codebases that have b

Francesco Bertolaccini 149 Dec 7, 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
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
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
An asynchronous web framework for C++ built on top of Qt

!!! I can no longer maintain this project. If you're interessed, please contact me and I can move the projetct to you !!! Tufão - an asynchronous web

Vinícius dos Santos Oliveira 526 Nov 26, 2021
✔️The smallest header-only GUI library(4 KLOC) for all platforms

Welcome to GUI-lite The smallest header-only GUI library (4 KLOC) for all platforms. 中文 Lightweight ✂️ Small: 4,000+ lines of C++ code, zero dependenc

null 5.8k Nov 28, 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
Perl Incompatible Regular Expressions library

This is PIRE, Perl Incompatible Regular Expressions library. This library is aimed at checking a huge amount of text against relatively many regular

Yandex 302 Nov 3, 2021
RE2 is a fast, safe, thread-friendly alternative to backtracking regular expression engines like those used in PCRE, Perl, and Python. It is a C++ library.

This is the source code repository for RE2, a regular expression library. For documentation about how to install and use RE2, visit https://github.co

Google 6.3k Dec 7, 2021
A non-backtracking NFA/DFA-based Perl-compatible regex engine matching on large data streams

Name libsregex - A non-backtracking NFA/DFA-based Perl-compatible regex engine library for matching on large data streams Table of Contents Name Statu

OpenResty 575 Nov 23, 2021
C++ peer to peer library, built on the top of boost

Breep What is Breep? Breep is a c++ bridged peer to peer library. What does that mean? It means that even though the network is constructed as a peer

Lucas Lazare 102 Nov 11, 2021
HIBA is a system built on top of regular OpenSSH certificate-based authentication that allows to manage flexible authorization of principals on pools of target hosts without the need to push customized authorized_users files periodically.

HIBA is a system built on top of regular OpenSSH certificate-based authentication that allows to manage flexible authorization of principals on pools of target hosts without the need to push customized authorized_users files periodically.

Google 312 Nov 19, 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
A virtual network Differential GNSS server-client project using Precise Point Positioning (PPP). Global coverage. Without physical base station construction needed. An open-source virtual base station approach.

Virtual-Network-DGNSS-Project This project is the software implementation for a publicly available, open-source, client/server VN-DGNSS implementation

null 6 Oct 29, 2021
Mongoose Embedded Web Server Library - a multi-protocol embedded networking library with TCP/UDP, HTTP, WebSocket, MQTT built-in protocols, async DNS resolver, and non-blocking API.

Mongoose - Embedded Web Server / Embedded Networking Library Mongoose is a networking library for C/C++. It implements event-driven non-blocking APIs

Cesanta Software 7.7k Dec 4, 2021