/udho

C++ HTTP server library based on boost beast

Primary LanguageC++BSD 2-Clause "Simplified" LicenseBSD-2-Clause

Udho (উধো)

udho is a tiny http library based on Boost.Beast.

Boost.Beast is based on Boost.Asio which provides low level asynchronous I/O. udho was originally created to add HTTP functionality to an existing application that is using Boost.Asio.

License pipeline status develop pipeline status master Codacy Badge Total alerts Language grade: C/C++

std::string world(udho::contexts::stateless ctx){
    return "{'planet': 'Earth'}";
}
std::string planet(udho::contexts::stateless ctx, std::string name){
    return "Hello "+name;
}
int main(){
    boost::asio::io_service io;
    udho::servers::ostreamed::stateless server(io, std::cout);
    server[udho::configs::server::document_root] = "/path/to/static/files";
    auto urls = udho::router() | "/world"          >> udho::get(&world).json() 
                               | "/planet/(\\w+)"  >> udho::get(&planet).plain();

    server.serve(urls, 9198);

    io.run();
    return 0;
}

Dependencies:

boost depend on boost-beast library. As boost-beast is only available on boost >= 1.66, udho requires a boost version at least 1.66. udho may optionally use ICU library for unicode regex functionality. In that case ICU library may be required.

  • boost > 1.66
  • pugixml
  • icu [optional]

Features:

  • regular expression based url routing to callables (functions / function objects)
  • compile time binding of routing rule with callables
  • compile time travarsable url router
  • response mime type specification in routing rule
  • any default constructible can be used as callable argument type that can be parsed from std::string
  • any ostreamable can be used as return type of callables
  • automatic type coersion for url based method calling
  • throwable http error messages
  • serving static content from disk document root if no rule matched
  • urlencoded/multipart form parsing
  • on memory session for stateful web applications (no globals) and no session for stateless applications
  • strictly typed on memory session storage
  • compile time pluggable logging
  • customizable logging
  • typesafe configuration

Example

std::string login(udho::contexts::stateful<user> ctx){ /// < strictly typed stateful context
    const static username = "derp";
    const static password = "derp123";

    if(ctx.session().exists<user>()){
        user data;
        ctx.session() >> data;  /// < extract session data
        return "already logged in";
    }else{
        if(ctx.form().has("user") && ctx.form().has("pass")){
            std::string usr = ctx.form().field<std::string>("user"); /// < form field value from post request
            std::string psw = ctx.form().field<std::string>("pass"); /// < form field value from post request
            if(usr == username && psw == password){
                ctx.session() << user(usr); /// < put data in session
                return "successful";
            }
        }
    }
    return "failed";
}

std::string echo(udho::contexts::stateful<user> ctx, int num){
    if(ctx.session().exists<user>()){
        user data;
        ctx.session() >> data;
        return boost::format("{'name': '%1%', 'num': %2%}") % data.name % num;
    }
    return "{}";
}

int main(){
    boost::asio::io_service io;
    udho::servers::ostreamed::stateful<user> server(io, std::cout);
    server[udho::configs::server::document_root] = "/path/to/static/files";
    auto router = udho::router()
        | (udho::post(&login).plain() = "^/login$")
        | (udho::get(&echo).json()    = "^/echo/(\\d+)$");

    server.serve(router, 9198);
        
    io.run();
    
    return 0;
}