Skip to content

Modern C++ Http Server event-driven I/O implementation without any dependencies.

License

Notifications You must be signed in to change notification settings

WoozChucky/cpp-webserver-eventdriven

Repository files navigation

CPP WebServer EventDriven

DISCLAIMER: Still a work in progress

Introduction

...todo

The code is a tentative to implement one approach mentioned in this article.

Serve many clients with each thread, and use nonblocking I/O and readiness change notification.

...todo

Build Status

Linux x64

Build Status

Code Quality

CodeQL

Coverity

Modules

Very conceptual diagram of the project architecture

Abstractions

  • Responsible for most cross-platform support code.
    • IO
    • Threads
    • Memory

EventEngine

  • Responsible for implementing the an engine that listens and reacts to kernel IO notifications
    • File descriptors
    • Pipes
    • Directories

SocketServer

  • Responsible for operations of sockets that listen to incoming connections.

HttpServer

  • Responsible for implementing the HTTP Protocol (at least some of it...) with a SERVER role.

SocketClient

  • Responsible for operations of sockets that connect to other sockets that are listening for connections.

HttpClient

  • Responsible for implementing the HTTP Protocol (at least some of it...) with a CLIENT role.

Features

  • Non Blocking Sockets (Server AND Clients)
  • Event Engine to handle multiple concurrent connections using kernel notifications (epoll, kevent)
    • Non-blocking I/O operations
    • Edge-triggered readiness notifications
    • 1 Connection Accept Thread
    • 1 Optional(can be a blocking call) WebServer Listen Thread
  • Built-in support for TLS using LibreSSL (allows for OpenSSL or any other openssl based fork.)
  • Cross-platform support
    • Linux (usable)
    • Windows (work-in-progress)
    • MacOS (work-in-progress)

Roadmap

  • Improve Abstractions module
    • Remove if defs and create separate implementation files
  • Improve Cross-platform Support
    • Windows
      • EventEngine: There is no out-of-the-box kernel notifications solution
    • MacOS
      • EventEngine: Implement with kqueue (90% done)
  • Improve general Memory Pool usage
  • HTTP
    • Improve request parser algorithm
    • Improve response data structure
    • Add support for HTTP2
    • Add support for compression
      • Maybe zlib or GZIP ?
    • Add support for http uploads
    • Improve support for Connection header: KeepAlive and Close
    • Add support for Cache header
  • Develop WebSocket module
    • With support for TLS
  • Improve TLS module to be a compilation option and not mandatory
  • Improve socket message buffering
  • Develop shutdown (fatal/gracefully) of sockets
  • Develop the Client modules
    • SocketClient
    • HttpClient
    • WebSocketClient
  • Refactor Channel module to use C++ "interfaces - pure virtual methods" allowing other Transports to be used.
  • Refactor TLS connect/accept to use callbacks for async operations
  • Improve support to dynamically load plugins, such as new route handlers.

Http WebServer Code Example

int main(int argc, char **argv) {

    auto options = (new SocketOptionBuilder())
            ->WithReuseAddress()
            ->WithReusePort()
            ->WithKeepAlive()
            ->WithMaxQueuedConnection(100)
            ->WithServerPort(21000)
            ->WithSSL(true)
            ->WithCertificate("cert.pem")
            ->WithPrivateKey("key.pem")
            ->Build();

    auto http = new HttpServer(options);

    http->Handle("/", HandleBaseRoute); // defaults to GET

    http->Handle("/register", HttpMethod::POST, HandleRegisterRoute);

    try {
        http->Boot(); // blocking
    } catch (std::exception& e) {
        TRACE("%s", e.what());
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}

// Response is written to address of *request.
void HandleBaseRoute(HttpRequest* request, HttpResponse* response) {
    // do stuff
    TRACE("%s", request->GetHeader("Content-Length").data());
    TRACE("%s", request->GetBody().data());
    
    response->SetStatusCode(HttpStatusCode::OK);
    response->SetProtocol(HttpProtocol::V1_1);
    response->SetBody("{\"obj\": true}");
    response->AddHeader(HttpHeader("Connection", "Keep-Alive"));
    response->AddHeader(HttpHeader("Content-Type", "application/json"));
}

void HandleRegisterRoute(HttpRequest* request, HttpResponse* response) {
    // do stuff
}

About

Modern C++ Http Server event-driven I/O implementation without any dependencies.

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published