Drogon: A C++14/17 based HTTP web application framework running on Linux/macOS/Unix/Windows

Overview

Build Status Build Status Build status Total alerts Join the chat at https://gitter.im/drogon-web/community Docker image

English | 简体中文 | 繁體中文

Overview

Drogon is a C++14/17-based HTTP application framework. Drogon can be used to easily build various types of web application server programs using C++. Drogon is the name of a dragon in the American TV series "Game of Thrones" that I really like.

Drogon is a cross-platform framework, It supports Linux, macOS, FreeBSD, OpenBSD, and Windows. Its main features are as follows:

  • Use a non-blocking I/O network lib based on epoll (kqueue under macOS/FreeBSD) to provide high-concurrency, high-performance network IO, please visit the TFB Tests Results for more details;
  • Provide a completely asynchronous programming mode;
  • Support Http1.0/1.1 (server side and client side);
  • Based on template, a simple reflection mechanism is implemented to completely decouple the main program framework, controllers and views.
  • Support cookies and built-in sessions;
  • Support back-end rendering, the controller generates the data to the view to generate the Html page. Views are described by CSP template files, C++ codes are embedded into Html pages through CSP tags. And the drogon command-line tool automatically generates the C++ code files for compilation;
  • Support view page dynamic loading (dynamic compilation and loading at runtime);
  • Provide a convenient and flexible routing solution from the path to the controller handler;
  • Support filter chains to facilitate the execution of unified logic (such as login verification, Http Method constraint verification, etc.) before handling HTTP requests;
  • Support https (based on OpenSSL);
  • Support WebSocket (server side and client side);
  • Support JSON format request and response, very friendly to the Restful API application development;
  • Support file download and upload;
  • Support gzip, brotli compression transmission;
  • Support pipelining;
  • Provide a lightweight command line tool, drogon_ctl, to simplify the creation of various classes in Drogon and the generation of view code;
  • Support non-blocking I/O based asynchronously reading and writing database (PostgreSQL and MySQL(MariaDB) database);
  • Support asynchronously reading and writing sqlite3 database based on thread pool;
  • Support ARM Architecture;
  • Provide a convenient lightweight ORM implementation that supports for regular object-to-database bidirectional mapping;
  • Support plugins which can be installed by the configuration file at load time;
  • Support AOP with build-in joinpoints.
  • Support C++ coroutines

A very simple example

Unlike most C++ frameworks, the main program of the drogon application can be kept clean and simple. Drogon uses a few tricks to decouple controllers from the main program. The routing settings of controllers can be done through macros or configuration file.

Below is the main program of a typical drogon application:

#include <drogon/drogon.h>
using namespace drogon;
int main()
{
    app().setLogPath("./")
         .setLogLevel(trantor::Logger::kWarn)
         .addListener("0.0.0.0", 80)
         .setThreadNum(16)
         .enableRunAsDaemon()
         .run();
}

It can be further simplified by using configuration file as follows:

#include <drogon/drogon.h>
using namespace drogon;
int main()
{
    app().loadConfigFile("./config.json").run();
}

Drogon provides some interfaces for adding controller logic directly in the main() function, for example, user can register a handler like this in Drogon:

app().registerHandler("/test?username={name}",
                    [](const HttpRequestPtr& req,
                       std::function<void (const HttpResponsePtr &)> &&callback,
                       const std::string &name)
                    {
                        Json::Value json;
                        json["result"]="ok";
                        json["message"]=std::string("hello,")+name;
                        auto resp=HttpResponse::newHttpJsonResponse(json);
                        callback(resp);
                    },
                    {Get,"LoginFilter"});

While such interfaces look intuitive, they are not suitable for complex business logic scenarios. Assuming there are tens or even hundreds of handlers that need to be registered in the framework, isn't it a better practice to implement them separately in their respective classes? So unless your logic is very simple, we don't recommend using above interfaces. Instead, we can create an HttpSimpleController as follows:

/// The TestCtrl.h file
#pragma once
#include <drogon/HttpSimpleController.h>
using namespace drogon;
class TestCtrl:public drogon::HttpSimpleController<TestCtrl>
{
public:
    virtual void asyncHandleHttpRequest(const HttpRequestPtr& req, std::function<void (const HttpResponsePtr &)> &&callback) override;
    PATH_LIST_BEGIN
    PATH_ADD("/test",Get);
    PATH_LIST_END
};

/// The TestCtrl.cc file
#include "TestCtrl.h"
void TestCtrl::asyncHandleHttpRequest(const HttpRequestPtr& req,
                                      std::function<void (const HttpResponsePtr &)> &&callback)
{
    //write your application logic here
    auto resp = HttpResponse::newHttpResponse();
    resp->setBody("<p>Hello, world!</p>");
    resp->setExpiredTime(0);
    callback(resp);
}

Most of the above programs can be automatically generated by the command line tool drogon_ctl provided by drogon (The command is drogon_ctl create controller TestCtrl). All the user needs to do is add their own business logic. In the example, the controller returns a Hello, world! string when the client accesses the http://ip/test URL.

For JSON format response, we create the controller as follows:

/// The header file
#pragma once
#include <drogon/HttpSimpleController.h>
using namespace drogon;
class JsonCtrl : public drogon::HttpSimpleController<JsonCtrl>
{
  public:
    virtual void asyncHandleHttpRequest(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback) override;
    PATH_LIST_BEGIN
    //list path definitions here;
    PATH_ADD("/json", Get);
    PATH_LIST_END
};

/// The source file
#include "JsonCtrl.h"
void JsonCtrl::asyncHandleHttpRequest(const HttpRequestPtr &req,
                                      std::function<void(const HttpResponsePtr &)> &&callback)
{
    Json::Value ret;
    ret["message"] = "Hello, World!";
    auto resp = HttpResponse::newHttpJsonResponse(ret);
    callback(resp);
}

Let's go a step further and create a demo RESTful API with the HttpController class, as shown below (Omit the source file):

/// The header file
#pragma once
#include <drogon/HttpController.h>
using namespace drogon;
namespace api
{
namespace v1
{
class User : public drogon::HttpController<User>
{
  public:
    METHOD_LIST_BEGIN
    //use METHOD_ADD to add your custom processing function here;
    METHOD_ADD(User::getInfo, "/{id}", Get);                  //path is /api/v1/User/{arg1}
    METHOD_ADD(User::getDetailInfo, "/{id}/detailinfo", Get);  //path is /api/v1/User/{arg1}/detailinfo
    METHOD_ADD(User::newUser, "/{name}", Post);                 //path is /api/v1/User/{arg1}
    METHOD_LIST_END
    //your declaration of processing function maybe like this:
    void getInfo(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback, int userId) const;
    void getDetailInfo(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback, int userId) const;
    void newUser(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback, std::string &&userName);
  public:
    User()
    {
        LOG_DEBUG << "User constructor!";
    }
};
} // namespace v1
} // namespace api

As you can see, users can use the HttpController to map paths and parameters at the same time. This is a very convenient way to create a RESTful API application.

In addition, you can also find that all handler interfaces are in asynchronous mode, where the response is returned by a callback object. This design is for performance reasons because in asynchronous mode the drogon application can handle a large number of concurrent requests with a small number of threads.

After compiling all of the above source files, we get a very simple web application. This is a good start. For more information, please visit the wiki or DocsForge

Contributions

Every contribution is welcome. Please refer to the contribution guidelines for more information.

Comments
  • MariaDB connection issue

    MariaDB connection issue

    Describe the bug Fail on the connection to MariaDB when testing the model create ctl. Copied the default model.json into a folder named /models/testModel and run the following command.

    drogon_ctl create model testModel
    
    Create model
    mysql
    Connect to server...
    Source files in the eshop folder will be overwritten, continue(y/n)?
    20200202 17:04:55.725077 UTC 3864 ERROR Failed to mysql_real_connect() - MysqlConnection.cc:229
    20200202 17:04:56.725637 UTC 3864 ERROR Failed to mysql_real_connect() - MysqlConnection.cc:229
    20200202 17:04:57.725777 UTC 3864 ERROR Failed to mysql_real_connect() - MysqlConnection.cc:229
    ...
    

    The database is running which I can use PhpMyAdmin to access it. Created a database name "cppwebserver" and some other credentials for testing. I tried different ports (failed) and thought there was a bug in the model.json ( "passwd" to "password" ) still failed.

    Capture

    BTW, THANKS for the good works to the C++ community. I would like to take deeper understanding on this web-framework and compare with the Cutelyst and Wt. Are there some examples for the ORM part? Say, using the default model in the model.json.

    To Reproduce Steps to reproduce the behavior:

    1. Go to '/models' directory
    2. mkdir testModel && cp model.json testModel/
    3. edit the parameters "rdbms": mysql, "port":3306, "host":"127.0.0.1", "dbname":"cppwebserver".......
    4. drogon_ctl create model testModel and see error

    Expected behavior ERROR Failed to mysql_real_connect() - MysqlConnection.cc:229 Desktop (please complete the following information):

    • OS: Linux
    opened by ihmc3jn09hk 36
  • Put generated views in a namespace to avoid name conflicts

    Put generated views in a namespace to avoid name conflicts

    Describe the bug Using the same name of a view in the global namespace cause conflicts.

    To Reproduce

    1. Create a view search.csp named "search"
    2. Create a controller named "search" (in the global namespace)
    3. Controller will be ignored

    It could be useful to be able to choose in wich namespace the views will be generated.

    enhancement 
    opened by arkena00 28
  • Can't connect to database (M1 MacOS)

    Can't connect to database (M1 MacOS)

    main.cpp

    #include <drogon/drogon.h>
    
    int main()
    {
      drogon::app().addListener("127.0.0.1", 8848);
      // Load config file
      // drogon::app().loadConfigFile("../config.json");
      drogon::app().createDbClient("mysql", "127.0.0.1", 3306, "database_test", "root", "******").run();
    
      return 0;
    }
    
    

    When I start the project, I get an unknown error. image

    drogon_ctl -v

    A utility for drogon
    Version: 1.7.5
    Git commit: f017b09947badc2e0516355358c8eb7843b44e19
    Compilation: 
      Compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++
      Compiler ID: AppleClang
      Compilation flags: -std=c++17 -I/opt/homebrew/include -I/usr/local/include
    Libraries: 
      postgresql: no  (batch mode: no)
      mariadb: yes
      sqlite3: yes
      openssl: no
      brotli: no
      boost: no
      hiredis: yes
      c-ares: no
    

    brew ls

    ca-certificates	glew		hiredis		mariadb		msgpack		pcre2		ruby
    cmake		glfw		jsoncpp		mecab		[email protected]	readline	sqlite
    cocoapods	groonga		libyaml		mecab-ipadic	pcre		redis		zstd
    

    I can connect to MariaDB by DBeaver: image

    FAQ 
    opened by 1111mp 25
  • Question: how to use the resolver class

    Question: how to use the resolver class

    Hi everyone, I need to resolve smtp.gmail.com to an ip, I'd like to use the mail plugin which only accept ip.

    //Send an email
    auto *smtpmailPtr = app().getPlugin<SMTPMail>();
    auto id = smtpmailPtr->sendEmail(
             "127.0.0.1",                  //The server IP, dns not support by drogon tcp-socket at the moment
             587,                          //The port
             "[email protected]",       //Who send the email
             "[email protected]",    //Send to whom
             "Testing SMTPMail Function",  //Email Subject/Title
             "Hello from drogon plugin",   //Content
             "[email protected]",       //Login user
             "123456"                      //User password
             );
    

    in the readme it says dns not supported by drogon tcp-socket, but I see in trantor the Resolver.h and in the inner folder more of Resolver. I've tried

                            auto callbackPtr = std::make_shared<
                                std::function<void(const HttpResponsePtr &)>>(
                                std::move(callback));
                            auto &loopApp = trantor::EventLoop(app().getLoop(10));
    
                            std::shared_ptr<trantor::Resolver> resolvePtr =
                                trantor::Resolver::newResolver(*loopApp, 600);
                            auto resolve = resolvePtr.resolve(
                                "smpt.gmail.com",
                                [data,
                                 callbackPtr](const trantor::InetAddress &addr) {
                                    LOG_DEBUG << "****IIII " << addr.toIpPort();
                                });
    

    but with no success. I'm new to c++ grammar, btw I would thank you for this great project, much appreciated work.

    question 
    opened by seiichi-yoshimune 22
  • Websocket not connected to server in native

    Websocket not connected to server in native

    #include <drogon/WebSocketClient.h>
    #include <drogon/WebSocketController.h>
    #include <drogon/HttpAppFramework.h>
    #include <trantor/net/EventLoopThread.h>
    
    #include <iostream>
    
    using namespace drogon;
    using namespace std::chrono_literals;
    
    class WebSocketTest : public drogon::WebSocketController<WebSocketTest> {
    public:
        virtual void handleNewMessage(const WebSocketConnectionPtr &,
                                      std::string &&,
                                      const WebSocketMessageType &) override;
    
        virtual void handleConnectionClosed(
                const WebSocketConnectionPtr &) override;
    
        virtual void handleNewConnection(const HttpRequestPtr &,
                                         const WebSocketConnectionPtr &) override;
    
        WS_PATH_LIST_BEGIN
        WS_PATH_ADD("/chat", "drogon::LocalHostFilter", Get);
        WS_PATH_LIST_END
    };
    
    
    void WebSocketTest::handleNewMessage(const WebSocketConnectionPtr &wsConnPtr,
                                         std::string &&message,
                                         const WebSocketMessageType &type) {
        // write your application logic here
        LOG_DEBUG << "new websocket message:" << message;
        if (type == WebSocketMessageType::Ping) {
            LOG_DEBUG << "recv a ping";
        }
    }
    
    void WebSocketTest::handleConnectionClosed(const WebSocketConnectionPtr &) {
        LOG_DEBUG << "websocket closed!";
    }
    
    void WebSocketTest::handleNewConnection(const HttpRequestPtr &,
                                            const WebSocketConnectionPtr &conn) {
        LOG_DEBUG << "new websocket connection!";
        conn->send("haha!!!");
    }
    
    
    int main(int argc, char *argv[]) {
    
        std::string host("0.0.0.0");
        int port(8848);
        app()
        .setLogLevel(trantor::Logger::kDebug)
        .addListener(host, port);
    
        auto wsPtr = WebSocketClient::newWebSocketClient(host, port);
        auto req = HttpRequest::newHttpRequest();
        req->setPath("/chat");
        wsPtr->setMessageHandler([](const std::string &message,
                                               const WebSocketClientPtr &wsPtr,
                                               const WebSocketMessageType &type) {
            std::cout << "new message:" << message << std::endl;
            if (type == WebSocketMessageType::Pong) {
                std::cout << "recv a pong" << std::endl;
            }
        });
        wsPtr->setConnectionClosedHandler([](const WebSocketClientPtr &wsPtr) {
            std::cout << "ws closed!" << std::endl;
        });
        wsPtr->connectToServer(req,
                               [](ReqResult r,
                                             const HttpResponsePtr &resp,
                                             const WebSocketClientPtr &wsPtr) {
                                   if (r == ReqResult::Ok) {
                                       std::cout << "ws connected!" << std::endl;
                                       wsPtr->getConnection()->setPingMessage("",
                                                                              2s);
                                       wsPtr->getConnection()->send("hello!");
                                   } else {
                                       std::cout << "ws failed!" << std::endl;
                                   }
                               });
        app().run();
    }
    

    Output:

    ws failed!
    

    But with:

    <!DOCTYPE html>
    <pre id="log"></pre>
    <script>
      // helper function: log message to screen
      function log(msg) {
        document.getElementById('log').textContent += msg + '\n';
      }
    
      // setup websocket with callbacks
      var ws = new WebSocket("ws://0.0.0.0:8848/chat");
      ws.onopen = function() {
        log('CONNECT');
        ws.send("hello!!!");
      };
      ws.onclose = function() {
        log('DISCONNECT');
      };
      ws.onmessage = function(event) {
        log('MESSAGE: ' + event.data);
        ws.send(event.data);
        ws.send(event.data);
      };
    </script>
    

    Works totaly fine;

    CONNECT
    MESSAGE: haha!!!
    

    Please explain this behavior.

    Regards.

    question 
    opened by SviatoslavKomkov 22
  • Async transaction execution failure

    Async transaction execution failure

    Describe the bug With DbFastClient, apply query with newTransactionAsync() keeps reporting error.

    To Reproduce

    ...
      const uint64_t id = 1;
      const ushort age = 16;
      auto clientPtr = drogon::app().getFastDbClient("FOO");
    
      clientPtr->newTransactionAsync([id=std::move(id),age=std::move(age)](const std::shared_ptr<Transaction> &transPtr) {
          assert(transPtr);
          transPtr->execSqlAsync( "select * from foo where id=$1",
            [=](const Result &r) {
                if ( 0 < r.size() )
                {
                    *transPtr << "update foo set age=$1 where id=$2"
                              << age          //Does it required to be std::string ?
                              << r[0]["id"].as<uint64_t>()
                              >> [](const Result &r)
                                 {
                                    LOG_INFO << "Updated!";
                                    //... do something about the task;
                                 }
                              >> [](const DrogonDbException &e)
                                 {
                                    LOG_ERROR << "err:" << e.base().what();
                                 };
                }
                else
                {
                    LOG_ERROR << "No new tasks found!";
                }
            },
            [](const DrogonDbException &e) {
                LOG_ERROR << "err:" << e.base().what();
            },
          id);   //Does it required to be std::string ?
        });
    
      return;
    ...
    

    Sometimes crashes but always returns the following

    20200313 04:24:41.332853 UTC 16597 ERROR error - MysqlConnection.cc:427
    20200313 04:24:41.332891 UTC 16597 ERROR Error(0) [00000] "" - MysqlConnection.cc:443
    20200313 04:24:41.349522 UTC 16597 ERROR Error occurred in transaction begin - TransactionImpl.cc:287
    20200313 04:24:41.349666 UTC 16597 ERROR err:The transaction has been rolled back - api_v0_foo.cc:163
    
    

    and sometimes with these

    20200313 04:35:36.383567 UTC 16676 ERROR error:1 status:1 - MysqlConnection.cc:258
    20200313 04:35:36.383629 UTC 16676 ERROR Error(1054) [42S22] "Unknown column '$1' in 'where clause'" - MysqlConnection.cc:443
    20200313 04:35:36.414844 UTC 16676 ERROR err:Unknown column '$1' in 'where clause' - api_v0_foo.cc:163
    20200313 04:35:36.415163 UTC 16676 DEBUG [operator()] Transaction roll back! - TransactionImpl.cc:159
    
    

    Expected behavior The record with id=1 in foo, the age field set to 16.

    Additional context Am I misunderstand the usage? Actually, I was trying to reference your example with the for update but failed with blocking call with newTransaction(). Then, I amended it with newTransactionAsync() but failed again even with the for update removed.

    opened by ihmc3jn09hk 20
  • Cannot capture returned value of second sql query in transaction

    Cannot capture returned value of second sql query in transaction

    Consider following code:

    auto clientPtr = drogon::app().getFastDbClient("default");
            clientPtr->newTransactionAsync([=, this](const std::shared_ptr<Transaction> &transPtr) mutable {
                assert(transPtr);
    
                transPtr->execSqlAsync(
                    "select t.id, t.visible, t.title, t.created_at , t.posted_by, t.updated_at, t.votes, t.slug, "
                    "users.username, users.id as uid, array_agg(topic_tags.tag_id) as tag_id, array_agg(tags.name) as tags from topics t left "
                    "join users on t.posted_by=users.id left join topic_tags on topic_tags.topic_id=t.id left join "
                    "tags on topic_tags.tag_id = tags.id where t.op_id=0 group by t.id, users.id order by "
                    "t.updated_at limit $1 offset $2",
                    [=, this](const Result &rows) mutable {
                        if (rows.size() == 0)
                        {
                            return;
                        }
                        else
                        {
                            ret["topics"] = Json::arrayValue;
                            for (auto &r : rows)
                            {
                                Json::Value topic;
                                std::string answers;
    
                                topic["id"] = r["id"].as<std::string>();
                                topic["visible"] = r["visible"].as<bool>();
                                topic["title"] = r["title"].as<std::string>();
                                topic["created_at"] = r["created_at"].as<std::string>();
                                topic["updated_at"] = r["updated_at"].as<std::string>();
                                topic["votes"] = r["votes"].as<std::string>();
                                topic["slug"] = r["slug"].as<std::string>();
                                topic["username"] = r["username"].as<std::string>();
                                topic["uid"] = r["uid"].as<std::string>();
                                topic["tid"] = r["tag_id"].as<std::string>();
                                topic["tags"] = r["tags"].as<std::string>();
                                transPtr->execSqlAsync(
                                    "select count(1) from topics where op_id is not null and op_id=$1",
                                    [=, &answers](const Result &rows1) mutable {
                                        for (auto &r1 : rows1)
                                        {
                                            answers = r1["count"].as<std::string>();
                                            // topic["answers"] = r1["count"].as<std::string>();
                                            // ret["topics"].append(topic);
                                        }
                                    },
                                    [=](const DrogonDbException &e) mutable {
                                        LOG_DEBUG << e.base().what();
                                        ret["error"] = (std::string)e.base().what();
                                        callback(HttpResponse::newHttpJsonResponse(std::move(ret)));
                                    },
                                    r["id"].as<int64_t>());
                                LOG_DEBUG << answers;
                                ret["topics"].append(topic);
                            }
                        }
    
                        callback(jsonResponse(std::move(ret)));
                        return;
                    },
                    [=](const DrogonDbException &e) mutable {
                        LOG_DEBUG << e.base().what();
                        ret["error"] = (std::string)e.base().what();
                        callback(HttpResponse::newHttpJsonResponse(std::move(ret)));
                    },
                    (long)limit, (long)limit * (page_no - 1));
            });
    

    The string answers is still empty after the second sql query.

    opened by shivshankardayal 18
  • Should Drogon have built-in cryptographic functions?

    Should Drogon have built-in cryptographic functions?

    Happy new year!

    #646 suggested to add security guidelines. I think that's a great idea. Especially if we could make Drogon secure by default. As of now. Drogon currently doesn't come with "security features" per se. Contrast to PHP have a built-in password_hash.

    I've password hashing/verification and secure number/string generation upstream-able in my webapp. But I'm not sure if it should be upstreamed. They pull in extra dependencies that the core framework don't need and is trivial to write. And languages like Go and Rust asks user to pull in their own library.

    I guess the question is:

    • Should Drogon provide cryptographic functions? Or is it the user's job?
    • How much security could we provide without extra dependencies?
    • If yes, To what extent should Drogon assist users?
      • I don't expect drogon to support full-on SRP and GPG. That's bloat.
      • In the mean while, I want to avoid users storing password in the database.

    What are your thoughts? Thanks.

    opened by marty1885 18
  • Allow thread to process other requests when waiting for asyncrinous HTTP requests

    Allow thread to process other requests when waiting for asyncrinous HTTP requests

    Hi, this issue is mostly related to the maximum throughput of an application. Currently Drogon have to wait if it makes a HTTP request inside a request handler. This may be a performance bottleneck when the request takes a while to response (ex: to a server across the globe, long RTT, etc...). It would be nice to be able to process other other requests while we're waiting for response.

    Now, sending requests within a handler looks like so

    app().registerHandler("/foo",[](const HttpRequestPtr& req, auto &&callback) {
    	// some API things
    	auto client = HttpClient::newHttpClient("http://my.api.endpoint.com");
    	auto req = HttpRequest::newHttpRequest();
    	std::promise<bool> valid;
    	req->setPath("/do_something");
    	client->sendRequest(req, [&](ReqResult result, const HttpResponsePtr &response) {
    		if(response == nullptr) // If no server responce
    			valid.set_value(false);
    		valid.set_value(true);
    	});
    	bool api_ok = valid.get_future().get(); // Wait for HTTP to response. Have to wait here otherwise crash the entire application
    	if(api_ok == false)
    		api_failed();
    	
    	// Keep doing our stuff
    });
    

    It would be great to do something like this.

    client->sendRequest(validation_req, [&](ReqResult result, const HttpResponsePtr &response) {
    	...});
    drogon::handleOtherRequest(valid); // Do other stuff until `valid` have been set. Don't waist time waiting
    

    Alternatively, it would be great to let HttpClient::sendRequest itself to do everything. So HttpClient::sendRequest looks to be a blocking call from the caller's perspective but in reality it only returns when it got an response or timeouts (and handle other requests in the mean time).

    bool api_ok = false;
    client->sendRequestSync(req, ...); // This looks like a blocking call from the caller
    // Since sendRequestSync only rerun when it have a response. The control flow is a lot easier
    if(api_ok == false)
    	api_failed();
    

    Thanks

    opened by marty1885 17
  • Even after installing hiredis, getting

    Even after installing hiredis, getting "Redis is not supported by Drogon...."

    Describe the bug Even after installing hiredis, getting "Redis is not supported by Drogon...."

    Expected behavior It should have worked properly

    Screenshots If applicable, add screenshots to help explain your problem.

    Desktop (please complete the following information):

    • OS: Kubuntu 22.04
    opened by MohammadArik 16
  • Add exports macro to allow Shared Library with hidden symbols by default (e.g. Windows)

    Add exports macro to allow Shared Library with hidden symbols by default (e.g. Windows)

    If you build drogon as a shared library with CMAKE_CXX_VISIBILITY_PRESET set to hidden and CMAKE_VISIBILITY_INLINES_HIDDEN to 1 all the symbols are hidden, thus linking a project with the drogon shared library will fail.

    On Windows, the symbols are hidden by default and you need to export them explicitely.

    This PR enable building trantor as a shared library on Windows.

    An abort() is raised when closing the project, I need to check if it is related to my work or not. In the meantime, I am interested in your feedback.

    This is Work In Progress as it points to my fork of trantor. I will update when https://github.com/an-tao/trantor/pull/127 is merged

    opened by BertrandD 16
  • trying to convert mysql rows to json array

    trying to convert mysql rows to json array

    `auto usersQuery = dbClient->execSqlAsyncFuture("SELECT id,name from users");

    try{ auto users = usersQuery.get(); //how to convert users (drogon::orm::Result) to json::Value array ? auto resp=HttpResponse::newHttpJsonResponse(ret); callback(resp); return; } catch (const drogon::orm::DrogonDbException &e) { std::cerr << "gameinfo error:" << e.base().what() << std::endl; }`

    opened by msmahesh91 1
  • Build : Update FindSQLite3.cmake to newer version

    Build : Update FindSQLite3.cmake to newer version

    Hi!

    This is not an actual feature request, but I post this as "feature" as it is definitely not_a_bug (drogon works fine for me ;-)

    You could update cmake_modules/FindSQLite3.cmake. The current file is 6 months old, and there are newer versions, moreover with the new cmake-3.25.0. Maybe it's not even necessary to have a local FindSQLite3.cmake.

    enhancement 
    opened by olivier-fs 0
  • support upsert in orm-lib

    support upsert in orm-lib

    Is it possible to add interfaces in orm-lib to support upsert in MySQL and PostgreSQL.

    In MySQL INSERT ... ON DUPLICATE KEY UPDATE

    In Postgresql https://wiki.postgresql.org/wiki/UPSERT

    enhancement 
    opened by atalia 0
  • VS2019 编译出错

    VS2019 编译出错

    使用 vcpkg.exe install drogon:x64-windows 安装,

    只是编译如下代码运行(使用 std:c++17 X64) int main() { printf("hello world");

    const std::string ipString = std::string("127.0.0.1");
    //Set HTTP listener address and port
    drogon::app().addListener(ipString, 8000);
    //Load config file
    //drogon::app().loadConfigFile("../config.json");
    //Run HTTP framework,the method will block in the internal event loop
    drogon::app().run();
    

    }

    在 ListenerManager.h 中运行时报错

    struct ListenerInfo
    {
        ListenerInfo(
            const std::string &ip,
            uint16_t port,
            bool useSSL,
            const std::string &certFile,
            const std::string &keyFile,
            bool useOldTLS,
            const std::vector<std::pair<std::string, std::string>> &sslConfCmds)
            : ip_(ip),   -------------------------->> 这行报错
              port_(port),
              useSSL_(useSSL),
              certFile_(certFile),
              keyFile_(keyFile),
              useOldTLS_(useOldTLS),
              sslConfCmds_(sslConfCmds)
        {
        }
    

    0x00007FFFA249428C 处(位于 diopterNativeServer.exe 中)有未经处理的异常: Microsoft C++ 异常: std::bad_alloc,位于内存位置 0x00000063D11AF560 处。

    opened by cocobar 1
  • vcpkg : building openssl:x64-windows failed with: BUILD_FAILED

    vcpkg : building openssl:x64-windows failed with: BUILD_FAILED

    Operator System: Windows11 Visual Studio version Visual Studio 2022 Community vcpkg version: https://github.com/microsoft/vcpkg/releases/tag/2022.10.19

    I tryed

    ./vcpkg install drogon
    ./vcpkg install drogon:x64-windows
    ./vcpkg install drogon:x64-windows-static
    
    

    but the same error ocurred.

    -- Build x64-windows-rel
    CMake Error at scripts/cmake/vcpkg_execute_required_process.cmake:96 (message):
        Command failed: "D:/Program Files/vcpkg/downloads/tools/jom/jom-1.1.3/jom.exe" -j 1 -f makefile install_sw install_ssldirs
        Working Directory: D:/Program Files/vcpkg/buildtrees/openssl/x64-windows-rel
        Error code: 2
        See logs for more information:
          D:\Program Files\vcpkg\buildtrees\openssl\build-x64-windows-rel-1-out.log
          D:\Program Files\vcpkg\buildtrees\openssl\build-x64-windows-rel-1-err.log
    
    Call Stack (most recent call first):
      ports/openssl/windows/portfile.cmake:104 (vcpkg_execute_required_process)
      ports/openssl/portfile.cmake:35 (include)
      scripts/ports.cmake:147 (include)
    
    
    error: building openssl:x64-windows failed with: BUILD_FAILED
    error: Please ensure you're using the latest port files with `git pull` and `vcpkg update`.
    Then check for known issues at:
        https://github.com/microsoft/vcpkg/issues?q=is%3Aissue+is%3Aopen+in%3Atitle+openssl
    You can submit a new issue at:
        https://github.com/microsoft/vcpkg/issues/new?template=report-package-build-failure.md&title=[openssl]+Build+error
    Include '[openssl] Build error' in your bug report title, the following version information in your bug description, and attach any relevant failure logs from above.
        vcpkg-tool version: 2022-10-17-3247920fbdd47d08f36cbd480addd9890d3c2435
        vcpkg-scripts version: 68ad399d5 2022-11-04 (20 hours ago)
    
    
    Please use the prefilled template from D:\Program Files\vcpkg\installed\vcpkg\issue_body.md when reporting your issue.
    

    build-x64-windows-rel-1-out.log:

    	"D:\Program Files\vcpkg\downloads\tools\jom\jom-1.1.3\jom.exe" /j1 depend
    	"D:\Program Files\vcpkg\downloads\tools\jom\jom-1.1.3\jom.exe" /j1 _build_libs
    	"D:/Program Files/Visual Studio Community 2022/VC/Tools/MSVC/14.33.31629/bin/Hostx64/x64/cl.exe"  /Zi /Fdossl_static.pdb /Gs0 /GF /Gy /MD -nologo -DWIN32 -D_WINDOWS -W3 -utf-8 -MP  -MD -O2 -Oi -Gy -DNDEBUG -Z7   -FS -I"." -I"include" -I"apps\include" -D"L_ENDIAN" -D"OPENSSL_PIC" -D"OPENSSLDIR=\"D:\\Program Files\\vcpkg\\packages\\openssl_x64-windows\"" -D"ENGINESDIR=\"D:\\Program Files\\vcpkg\\packages\\openssl_x64-windows\\lib\\engines-3\"" -D"MODULESDIR=\"D:\\Program Files\\vcpkg\\packages\\openssl_x64-windows\\lib\\ossl-modules\"" -D"OPENSSL_BUILDING_OPENSSL" -D"OPENSSL_SYS_WIN32" -D"WIN32_LEAN_AND_MEAN" -D"UNICODE" -D"_UNICODE" -D"_CRT_SECURE_NO_DEPRECATE" -D"_WINSOCK_DEPRECATED_NO_WARNINGS" -D"NDEBUG"   -c /Foapps\lib\libapps-lib-app_libctx.obj "apps\lib\app_libctx.c"
    app_libctx.c
    cl : Command line error D8050 : cannot execute 'D:\Program Files\Visual Studio Community 2022\VC\Tools\MSVC\14.33.31629\bin\Hostx64\x64\c1.dll': failed to get command line into debug records
    

    build-x64-windows-rel-1-err.log:

    
    jom 1.1.3 - empower your cores
    
    cl : Command line warning D9025 : overriding '/Zi' with '/Z7'
    jom: D:\Program Files\vcpkg\buildtrees\openssl\x64-windows-rel\Makefile [apps\lib\libapps-lib-app_libctx.obj] Error 2
    jom: D:\Program Files\vcpkg\buildtrees\openssl\x64-windows-rel\makefile [build_libs] Error 2
    

    build-x64-windows-rel-0-err.log

    
    jom 1.1.3 - empower your cores
    
    cl : Command line warning D9025 : overriding '/Zi' with '/Z7'
    jom: D:\Program Files\vcpkg\buildtrees\openssl\x64-windows-rel\Makefile [apps\lib\libapps-lib-app_libctx.obj] Error 2
    jom: Option /K specified. Continuing.
    cl : Command line warning D9025 : overriding '/Zi' with '/Z7'
    jom: D:\Program Files\vcpkg\buildtrees\openssl\x64-windows-rel\Makefile [apps\lib\libapps-lib-app_params.obj] Error 2
    jom: Option /K specified. Continuing.
    cl : Command line warning D9025 : overriding '/Zi' with '/Z7'
    cl : Command line warning D9025 : overriding '/Zi' with '/Z7'
    jom: D:\Program Files\vcpkg\buildtrees\openssl\x64-windows-rel\Makefile [apps\lib\libapps-lib-app_rand.obj] Error 2
    jom: Option /K specified. Continuing.
    jom: D:\Program Files\vcpkg\buildtrees\openssl\x64-windows-rel\Makefile [apps\lib\libapps-lib-app_provider.obj] Error 2
    jom: Option /K specified. Continuing.
    cl : Command line warning D9025 : overriding '/Zi' with '/Z7'
    .......
    
    opened by dying084 0
Releases(v1.8.2)
  • v1.8.2(Nov 11, 2022)

    API changes list

    • Add the queueInLoopCoro function.

    • Avoid HashDoS attacks via random per-session hash initial state.

    Changed

    • Support the mediumint column when generate the mysql model.

    • Set Hiredis_FOUND to true when finding Hiredis library.

    • Add rate limiter.

    • Add some test cases for the sqlite datetime type.

    Fixed

    • Fix typo in drogon_test.h.

    • Fix a date race in drogon_test.

    • Fix a deadlock bug when closing all database connections.

    Source code(tar.gz)
    Source code(zip)
  • v1.8.1(Sep 25, 2022)

    API changes list

    • Support redis subscription.

    Changed

    • Remove redundant member functions of drogon::Task.

    • Small patches on orm_lib.

    • Add support for the string_view type to SqlBinder in orm.

    Fixed

    • Fix a conflict of ssize_t type with hiredis.

    • Fix a test bug when clients start before servers.

    • Fix model template file Unreachable code.

    • Use the mysql_library_end() function to avoid memory leaks.

    Source code(tar.gz)
    Source code(zip)
  • v1.8.0(Aug 31, 2022)

    API changes list

    • Add ‘not like‘ criteria.

    • Add HttpResponse::newStreamResponse().

    • Add the same site option for session cookie.

    • Add support for custom SQL query.

    Changed

    • Update issue templates.

    • Enable automatic reconnect in mysql.

    • Add typename for clang-14.

    • A workaround for redis sync exec.

    • Resolve redis server hostname from config file.

    • Add username option to redis databases.

    • Return nullptr if a plugin is not loaded when getting it.

    • Support controller registration in plugin.

    • Check mysql-optionsv support in cmake.

    • Check if host header is set before setting.

    • Clear all database connections before quitting.

    • Add namespace to views when using drogon_ctl.

    • Support pipeline mode on PostgreSQL 14+.

    • Add content type to multipart file upload.

    • Make orm::Result compatible with C++ STL container concepts.

    • Throw exceptions instead of exiting when loading configuration fails.

    • Rename BUILD_TRANTOR_SHARED to BUILD_SHARED_LIBS.

    • Support compressed request.

    • Prevent sending multiple responses for a single request.

    • Remove the virtual specifier from functions marked with override.

    • Remove redundancies from the CMake action.

    • Ensure requiring a semi-colon after macros.

    • Omit redundant virtual specifiers.

    • Refactor orm::SqlBinder.

    • Implement toJson to convert std::vector to Json::Value.

    • Resolve real ip from HttpRequest.

    • Delete the unmaintained test script.

    • Change the listener port of the cookie test.

    • Use a raw string literal for the drogon banner.

    • Change timeout of pipeline test for the CI environment.

    • Accept "postgres" for DbClient type as well.

    • Log remote real address in AccessLogger.

    • Support coroutine filter.

    • Refactor db_test.cc.

    • Use nullopt instead of the no-argument constructor.

    • Set the running flag to false after calling the quit() method.

    • Fix doc link in README files.

    Fixed

    • Fix XXXControllers created on MSVC even if specified not to do so.

    • To avoid accessing a null point, make sure result == OK before accessing the response ptr.

    • Fix a bug when stopping redis service.

    • Fix mutex lock missing.

    • Fix tolower with cfi sanitizer.

    • Add move constructor to fix clang-14 compile error.

    • Fix HttpClient dns cache.

    • Fix bug when resolving redis server hostname.

    • Reset timer afters relaunching on Linux.

    • Fix some configuration file issues.

    • Fix HttpFile unittest error on Windows.

    • Fix core dump causing by logging in destructor.

    • Fixing link error when linking with static c-ares.

    • Remove redundant resource release.

    • Install missing header file apply.h.

    • Fix deleteFutureByPrimaryKey compile fail.

    • Fix compilation failure without database support.

    • Fix Mapper::updateBy() async api.

    • Fix no BUILD_CTL with tests.

    • Fix some bugs in RedisClient.

    • Fix a misuse of std::move.

    • Fix a bug when creating models with composite keys in sqlite3.

    • Fix a bug when converting the content-length string to size_t.

    • Fix a bug when parsing multipart/form-data.

    • Export the getVersion method for Windows.

    • Add a pre-compilation macro in the pg pipeline test code.

    Source code(tar.gz)
    Source code(zip)
  • v1.7.5(Feb 19, 2022)

    API changes list

    • Add toString for drogon::ReqResult.

    • Add max-age, samesite options to Cookie.

    • Enable setup output of logs to files at any time.

    Changed

    • Use operator<< to convert ReqResult to string.

    • Remove sudo from build.sh.

    • Remove sudo from dependencies in Dockerfile.

    • Avoid attempt linking to std::fs when target does not exist.

    • Destroy fastdb client on quit.

    • Check HTTP client is not sending requests in sync mode on the same event loop.

    • Start listening after beginning advices.

    • Allow using json_cpp in other sublibraries.

    • Accept system lib for uuid on macOS.

    • Add Not In to ORM Criteria.

    Fixed

    • Fix WS test potentially can get stuck.

    • Fix a bug in model generation.

    • Prevent malformed upload path causing arbitrary write.

    • Fix missing "using namespace drogon::orm;" at autogenerated restful controllers.

    Source code(tar.gz)
    Source code(zip)
  • v1.7.4(Dec 11, 2021)

    API Change List

    • Support setting client certificate and SSL options on HTTP client

    • Add more method for mapper

    • Add overloads for SqlBinder::operator<< with non-const ref parameter

    Changes

    • Use decay_t instead of remove_cvref_t

    • Prevent drogon_ctl create_view appending empty new lines to resulting

    • Add an example for using coroutines of redis clients

    • Export some symbols for Windows

    • Mark all awaiters as nodiscard

    • Handle SIGINT too

    • Support CoroMapper method chaining

    • Remove setting c++17 in FindFilesystem

    Fixed

    • Fix Drogon not building caused by FindFilesystem

    • Fix deprecated warning when using openssl 3

    • Fix coroutine object destructing before coroutine ends in async_run

    • Fix build fail on CentOS8

    • Fix some compiler warnings

    • Fix the error with multiple results when calling a procedure in mysql

    • Fix an error when binding a function pointer to SqlBinder

    • Fix orm tests

    • Fix CI to actually build in C++14

    • Fix a race condition when resetting ws

    • Fix an error of std::bad_function_call

    • Update Trantor (fix sending partial files)

    Source code(tar.gz)
    Source code(zip)
  • v1.7.3(Oct 17, 2021)

    API Change List

    • Support sending files by range

    • Allow outside access to the file path of an HTTP response

    • Support custom MIME types and extensions

    • Add the getOptionalParameter method

    • Add async_run

    Changes

    • Experimental HaikuOS Support

    • Improve AccessLogger

    • Add Alpine Dockerfile

    • Add option to disable brotli if desired by the builder

    Fixed

    • Fix a bug in the getIOLoop method

    • Return on redis connection errors

    • Fix(MutliPart): Does not respect quotes in Content-Disposition header

    • Fix(cmake): error in FindFilesystem

    • Fix(style): Change the NotFound page text color

    • Fix a race condition in testing

    Source code(tar.gz)
    Source code(zip)
  • v1.7.2(Aug 24, 2021)

    @an-tao Is busy so I'm making the release in place of him.

    API Change List

    • Add port() and host() to HttpClient

    • Add stop() method to the WebSocketClient class

    Changes

    • Enables higher level of warnings when building on UNIX with GCC

    • Generic optimizations

    • Add redis example

    • Added support for paths containing unicode characters on Windows

    • Load ParseAndAddDrogonTests in DrogonConfig

    • Add BUILD_DOC to cmake options

    • Add websocket server example

    • CMake: Add CPack for .deb and .rpm package generation

    • cmake: Use GNUInstallDirs to figure out install dirs.

    Fixed

    • Fix WS client example not working with integration_test

    • Fix WS client example error when encountering bad IP addresses

    • CacheFile supports >2GB files on 64-bit Windows

    • drogon_ctl now emits error on failing to create view from CSP

    • Added the make program to Ubuntu docker environment

    • Correctly check the case-insensitive value of the upgrade header of responses in websocket connections

    • Fix incorrect MD5 hash when using internal MD5 implementation when input size == block size+1

    • Fix test success message incorrectly shown for a failed test when -s is flag present

    • Force using boost::filesystem when building for Android

    • Escape connection string in drogon_ctl create model

    • Fix some memory leak and race conditions in WebSocketClient

    Source code(tar.gz)
    Source code(zip)
  • v1.7.1(Jun 24, 2021)

    Changes

    • Updated Dockerfile to Ubuntu 20.04 & Fixed Timezone Hangup.

    • Add jsonstore example.

    • Fix some typos.

    Fixed

    • Fix single layer directory traversal in StaticFileRouter.
    Source code(tar.gz)
    Source code(zip)
  • v1.7.0(Jun 18, 2021)

    API changes list

    • Add the PreSendingAdvice to AOP.

    • Make Json::Value as a SQL parameters type.

    • Add the int type for the Row index parameter.

    • Add SSL_CONF_cmd support.

    • Add the setCustomStatusCode method.

    Changes

    • Fix sync_wait/co_future use-after-free.

    • Add the AccessLogger plugin.

    • Make AsyncTask only destruct when the coroutine reaches end of executions.

    • Add Drogon test framework.

    • Improve WebSocket mask handling.

    • Add minimal server side examples.

    • Optimize HttpControllersRouter for cases where regex is not needed.

    • Create controller instances after running instead of after being called.

    Fixed

    • Move resolverPtr when destroying an HttpClientImpl object.

    • Modify the way to create sqlite3 client.

    • Fix a bug when a network failure occurs on Redis connections.

    • Fix a bug of string_view for MSVC.

    • Fix 'build.sh -tshared'.

    • Fix compiler warnings.

    • Fix CacheMap crash in CI tests.

    Source code(tar.gz)
    Source code(zip)
  • v1.6.0(May 15, 2021)

    API changes list

    • Add option to set default handler.

    • Add the setTimeout() method to the DbClient class and the RedisClient class.

    • Add the validateCert parameter to the newWebSocketClient method.

    Changed

    • A few mini changes to drogon_ctl command.

    • Improve the MultiPartParser class.

    • Add GNU -Werror & fix warnings.

    • Enhancements on files part.

    • Add version/soversion to shared library.

    • Disallow coroutines to be resolved as plain subroutine handlers.

    • Send the content-length header even if the body(POST,PUT,OPTIONS,PATCH) is empty.

    • Use make_exception_ptr instead of throw/catch when possible.

    • Remove duplicated inclusion.

    • Print error before terminating in AsyncTask.

    • Allow users to override drogon Find modules.

    • Use two-phase construction for the DbClientImpl and the RedisClientImpl.

    • Add support 'select ' for redis.

    Fixed

    • Fix a bug of the Transaction class.

    • Copy CoroMapper.h to installation location.

    • Remove the related request from the buffer if it's not sent after the timeout.

    • Fix ORM with SQLite3 not compiling on Arch Linux.

    • Fix an error when constructing RedisClientImpl objects.

    • Fix coroutine frame leak upon assigning to awaitable.

    • Set running flag to true before installing plugins.

    • Fix double free in coroutine exception handling.

    Source code(tar.gz)
    Source code(zip)
  • v1.5.1(Apr 10, 2021)

  • v1.5.0(Apr 10, 2021)

    API changes list

    • Add option to disable signal handling.

    • Added newFileResponse Support for buffers in memory.

    • Add a method to HttpRequest to set the user_agent header.

    • Catch exceptions thrown by handlers.

    Changed

    • Add convert method to models.

    • Add Arch Dockerfile.

    • Add Redis support.

    • Print error and exit when IP parsing failed in server startup.

    • Use a canonical way of calling max() function on Windows.

    • Remove an assertion statement in the HttpClientImpl class.

    • Send ping messages by default for WebSockets.

    • Use canonical cmake logic for cross-compilation.

    • set make job count to the number of threads in GitHub Actions workflow.

    • Use lambda instead of std::bind in HttpServer.

    • Add exports macro to allow Shared Library with hidden symbols by default.

    • Remove repeated class names on relationships from the model generator.

    Fixed

    • Fix compile warnings in SQL client.

    • Fix compilation errors for the TimeFilter example.

    • Fix build.sh missing nproc error in build for macOS.

    • Fix a bug when creating sqlite3 models.

    • Fix two building corner cases, CMake quality of life improvements.

    • Add CoroMapper to models' friends.

    Source code(tar.gz)
    Source code(zip)
  • v1.4.1(Mar 7, 2021)

  • v1.4.0(Mar 6, 2021)

    API change list

    • Add coroutine support.

    • Add default value interface to SqlBinder for MySQL and PostgreSQL.

    • Support SNI in the HttpClient class.

    • Validate certificate in HttpClient.

    • HttpRequest: add a feature to avoid URL encoding of the path.

    Changed

    • Handle cross-compiling properly.

    • Lowercase all HTTP headers, add webp and avif types.

    • Modify FindMySQL.cmake

    Fixed

    • Fix an error in the HttpClient class when a response has no content-length.

    • Return 404 or 405 responses correctly.

    • Fix compilation errors on vs2019.

    • Fix stack use after scope error in client_example.

    • Fix the error when the SSL handshake fails.

    Note: an-tao is still the author. But marty1885 starts the draft and didn't expect it's his name.

    Source code(tar.gz)
    Source code(zip)
  • v1.3.0(Jan 17, 2021)

    API change list

    • Add an option for setting float precision in Json string.

    Fixed

    • Fix brotli link order.

    • Fix cmake with drogonctl cross-compilation.

    • sqlite3: Insert into stmtsMap_ as string_view.

    • Fix some bugs when creating models via drogon_ctl.

    • Fix an error in sqlite3 ORM generator.

    • Fix an error with missing composite key to sqlite3 ORM generator.

    Changed

    • Remove the use of std::filesystem to adapt to old compilers.

    • Add github actions.

    • Serve wasm files with the correct MIME type.

    Source code(tar.gz)
    Source code(zip)
  • v1.2.0(Dec 12, 2020)

    Fixed

    • Fix error when receiving response without content-length header.

    • Fix a stack-overflow error when high concurrency happening on sqlite3.

    • Fix MinGW ORM building by enabling htonll and ntohll.

    Changed

    • Modify the WebSocketTest controller to create a simple chat room.

    • Add support for OpenBSD.

    • Return 400 if the content-length is invalid.

    • Don't send content type in a 304 response.

    • Add the reuse_port option to app() interface.

    • Add the 'std::optional' support in the SqlBinder class and the Session class.

    • Add implicit page resolving capability.

    Source code(tar.gz)
    Source code(zip)
  • v1.1.0(Oct 31, 2020)

    Fixed

    • Fix failing to connect to DB if parameters contains spaces.

    • Fix a CMAKE bug when SHARED and EXAMPLES are on.

    • Fix the HttpServer::isWebSocket method.

    • Find mariadb client library correctly on Ubuntu 20.04.

    • Fix a bug when creating sqlite3 database models.

    • Fix a bug in the Mapper::insertFuture method.

    Changed

    • Disable TLS1.0/1.1 on HTTPS by default.

    • Use explicit lambda capture lists.

    • Modify the procedure of the app().run() method.

    • Support namespaces when creating view source files.

    • Add --path-to-namespace option to drogon_ctl for creating views.

    • Add the Host and Sec-WebSocket-Version headers when connecting to a websocket server.

    Source code(tar.gz)
    Source code(zip)
  • v1.0.0(Sep 27, 2020)

    Fixed

    • Fix an issue of simple_reverse_proxy when handling chunked transfer-encoding.

    • Fix a bug when losting connection to MySQL server during query.

    • Remove the expired std::iterator template.

    • Fix a bug when creating models in some special cases.

    API changes list

    • Modify methods related to headers.

    • Remove the expired std::iterator template.

    • Add getListeners() method to the HttpAppFramework class.

    • Remove the useless method stat() from the PluginBase class.

    • Add ConfigLoader::ConfigLoader(const Json::Value &data).

    Changed

    • Add support for status code 418.

    • Modify session handling.

    • Modify the FileUpload.csp in simple_example to avoid CORS.

    • remove execution permission on /tmp/drogon.lock.

    Source code(tar.gz)
    Source code(zip)
  • v1.0.0-beta21(Aug 19, 2020)

  • v1.0.0-beta20(Aug 15, 2020)

    API change list

    • Provide users with a method to change the session ID of a session.

    Changed

    • Modify parseContentType function.

    • Modify the docker file to build release version in docker.

    • Set session to requests for websockets.

    • Modify parseContentType function.

    • Change the return value type of the mktime() function in models.

    • Fix compilation warning of sprintf function.

    Fixed

    • Fix a bug when saving uploaded files on Windows.

    • Fix a mysql issue when connections are lost.

    • Resolve an issue when sending big files (>=2gB) on Windows.

    • Fix boost::string_view compilation error of MysqlConnection class.

    • Set the response Access-Control-Allow-Headers header correctly for CORS.

    • Fix a bug in drogon_ctl when creating a model, that causes to write source files multiple times.

    Source code(tar.gz)
    Source code(zip)
  • v1.0.0-beta19(Jul 16, 2020)

    API change list

    • Add a method to disable unicode escaping in json string.

    • Add a timeout parameter when sending HTTP requests.

    • Add the getJsonError method.

    Changed

    • Remove the restriction on the location of layout tags in views.

    • Add a way to set the character set when creating DbClient objects.

    • Make GET as the only method for accessing static files.

    • Modify the 404 pages generator.

    • Modify the DbClient class.

    • Optimize the HttpResponse class.

    Fixed

    • Properly handle chunked encoding requests.

    • Destroy DNS resolver of HttpClient in the correct thread.

    • Add the header to resolve build errors in VS2017.

    Source code(tar.gz)
    Source code(zip)
  • v1.0.0-beta18(Jun 14, 2020)

    API change list

    • Add a new joinpoint of AOP for modification on each HTTP response.

    • Add a method for the TERM signal handling.

    • Add getContextRef method to the WebSocketConnection class.

    Changed

    • Create a class template for publish subscribe pattern.

    • Add contribution recommendations.

    • Send a close message when closing a web socket connection.

    • Add additional formats for getHttpDate function.

    • Make app().run() method callable on a non-main thread.

    • Add digest filter in examples.

    • Use string_view to parse multipart/form-data requests.

    Fixed

    • Fix building of ORM on FreeBSD.

    • Fix a Mysql connection error on Windows.

    • Fix a bug in ListenerManager::getIOLoop().

    • Fix the count() method of Mysql ORM.

    • Fix a compilation issue on windows.

    • Fix model generation for PostgreSQL primary keys.

    • Fix a bug with quoted column names in sqlite3 databases.

    Source code(tar.gz)
    Source code(zip)
  • v1.0.0-beta17(May 22, 2020)

    API change list

    • Add methods to get DbClient connection status

    Changed

    • Add causal profiling with coz

    • Add filters on static file locations

    • Pass data from view to its layout container

    • Add additional HttpStatusCodes and implement a custom error handler

    • Modify drogon_ctl to show more compilation information

    Fixed

    • Fix a bug in drogon_ctl (when size of a line is larger than buffer size)

    • Fix a connection bug of mariadb clients

    Source code(tar.gz)
    Source code(zip)
  • v1.0.0-beta16(Apr 27, 2020)

    API change list

    • Standardize Row and Result api in ORM

    Changed

    • Add support for brotli compression

    • Parse content-type of HTTP requests

    • Remove non standard macros

    • Support url safe base64 codec

    Source code(tar.gz)
    Source code(zip)
  • v1.0.0-beta15(Mar 28, 2020)

    API change list

    • Modify the Attributes interface of the HttpRequest class

    • Add the getHomePage() method to HttpAppFramework

    Changed

    • Support br compression files

    • Update Content-Type support for PDF

    • Add support for MSVC 2015

    • Optimize the rendering of HTTP responses

    • Update the Dynamic Views Loading, add the layout tag

    • Graceful shutdown

    Fixed

    • Fix error when finding the jsoncpp library

    • Fix the 'many to many' relationship in ORM

    • Fix a bug when creating json responses

    • Fix a bug on filters with WebSocketControllers

    • Fix a fatal bug in the MysqlConnection class

    • Fix crash with partial matched url

    • Fix null jsonObject from newHttpJsonRequest

    Source code(tar.gz)
    Source code(zip)
  • v1.0.0-beta14(Feb 17, 2020)

    API change list

    • None

    Added

    • Add IOLoop access function

    Changed

    • Add support for regular expressions when routing

    • Add location configuration for static resources

    • Port drogon to Windows

    • Support 'password' keyword in configuration files

    • Remove get_version.sh

    • Modify dynamic view loading algorithm, add 'layout' tag for view generation.

    Fixed

    • Fix an issue of out-of-range (#334)

    • Fix a bug in views generation (#341)

    Source code(tar.gz)
    Source code(zip)
  • v1.0.0-beta13(Jan 4, 2020)

    API change list

    • None

    Changed

    • Add some unit tests (based on gtest)

    • Add a reverse proxy example

    • Make a patch to support the ossp UUID library

    • Make shared linking possible

    • Add the drogon::OStringStream class

    • Optimize ORM

    • Modify singleton logic of DrClassMap

    Fixed

    • Fix an error in the batch mode of libpq

    • Fix an error when clients use HTTP1.0

    Source code(tar.gz)
    Source code(zip)
  • v1.0.0-beta12(Nov 30, 2019)

    Changed

    • Make dg_ctl a symlink

    • Modify some code styles

    • Explicitly set path to '/' for JSESSIONID cookie

    • Handle gzip errors safely

    • Add the SecureSSLRedirector plugin

    Fixed

    • Fix a bug in dg_ctl for creating models of sqlite3

    • Reset the flag used to parse json to false before recycling HttpRequest objects

    Source code(tar.gz)
    Source code(zip)
  • v1.0.0-beta11(Nov 6, 2019)

  • v1.0.0-beta10(Nov 4, 2019)

    API change list

    • None

    Changed

    • Add the headers configuration option for static files

    Fixed

    • Fix(compilation on alpine): Replace u_short alias.
    Source code(tar.gz)
    Source code(zip)
Owner
An Tao
Drogon QQ群: 1137909452
An Tao
Dolphin is an emulator for running GameCube and Wii games on Windows, Linux, macOS, and recent Android devices.

Dolphin is a GameCube / Wii emulator, allowing you to play games for these two platforms on PC with improvements.

Dolphin Emulator 9.3k Nov 29, 2022
Graphical small-internet client for windows, linux, MacOS X and BSDs. Supports gemini, http, https, gopher, finger.

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

Felix Queißner 566 Nov 26, 2022
H2O - the optimized HTTP/1, HTTP/2, HTTP/3 server

H2O - an optimized HTTP server with support for HTTP/1.x, HTTP/2 and HTTP/3 (experimental) Copyright (c) 2014-2019 DeNA Co., Ltd., Kazuho Oku, Tatsuhi

H2O 10.2k Nov 27, 2022
ESP-IDF is the development framework for Espressif SoCs supported on Windows, Linux and macOS.

Espressif IoT Development Framework 中文版 ESP-IDF is the development framework for Espressif SoCs supported on Windows, Linux and macOS. ESP-IDF Release

Espressif Systems 9.5k Dec 3, 2022
cuehttp is a modern c++ middleware framework for http(http/https)/websocket(ws/wss).

cuehttp 简介 cuehttp是一个使用Modern C++(C++17)编写的跨平台、高性能、易用的HTTP/WebSocket框架。基于中间件模式可以方便、高效、优雅的增加功能。cuehttp基于boost.asio开发,使用picohttpparser进行HTTP协议解析。内部依赖了nl

xcyl 28 Nov 18, 2022
Asynchronous, Header-only C++ HTTP-over-(TCP|UNIX Socket|STDIO) Library

CXXHTTP A C++ library implementing an asynchronous HTTP server and client. To clone this library, make sure you also clone the submodules. The --recur

null 25 Mar 19, 2021
Header-only C++14 library for getting network addresses associated with network interface without name lookups on Windows, macOS, Linux, and FreeBSD

NetIF Get addresses associated with network interfaces on a system without using name lookups. Header-only, requires C++14. Usage Add the header file

GMLC-TDC 9 Oct 17, 2022
Netif - Header-only C++14 library for getting network addresses associated with network interface without name lookups on Windows, macOS, Linux, and FreeBSD

NetIF Get addresses associated with network interfaces on a system without using name lookups. Header-only, requires C++14. Usage Add the header file

GMLC-TDC 9 Oct 17, 2022
Cross-platform, single .h file HTTP server (Windows, Linux, Mac OS X)

EWS - Single .h File C Embeddable Web Server Latest Version: 1.1.4 released September 9, 2021 Supported platforms: Linux, Mac OS X, Windows License: B

Forrest Heller 81 Nov 18, 2022
Source-code based coverage for eBPF programs actually running in the Linux kernel

bpfcov Source-code based coverage for eBPF programs actually running in the Linux kernel This project provides 2 main components: libBPFCov.so - an ou

elastic 113 Nov 23, 2022
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 9k Dec 2, 2022
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.9k Nov 27, 2022
tiny HTTP parser written in C (used in HTTP::Parser::XS et al.)

PicoHTTPParser Copyright (c) 2009-2014 Kazuho Oku, Tokuhiro Matsuno, Daisuke Murase, Shigeo Mitsunari PicoHTTPParser is a tiny, primitive, fast HTTP r

H2O 1.6k Dec 4, 2022
A collection of C++ HTTP libraries including an easy to use HTTP server.

Proxygen: Facebook's C++ HTTP Libraries This project comprises the core C++ HTTP abstractions used at Facebook. Internally, it is used as the basis fo

Facebook 7.7k Dec 4, 2022
Pushpin is a reverse proxy server written in C++ that makes it easy to implement WebSocket, HTTP streaming, and HTTP long-polling services.

Pushpin is a reverse proxy server written in C++ that makes it easy to implement WebSocket, HTTP streaming, and HTTP long-polling services. The project is unique among realtime push solutions in that it is designed to address the needs of API creators. Pushpin is transparent to clients and integrates easily into an API stack.

Fanout 3.2k Nov 24, 2022
Gromox - Groupware server backend with MAPI/HTTP, RPC/HTTP, IMAP, POP3 and PHP-MAPI support for grommunio

Gromox is the central groupware server component of grommunio. It is capable of serving as a replacement for Microsoft Exchange and compatibles. Conne

grommunio 130 Nov 26, 2022
Wrapper for linux TCP/UDP/unix/USB socket connections

Socket Connection wrapper shared library Shared library that realize sockets connections and could transfer data-packages. Navigation Navigation Insta

Dmitry Golgovsky 7 Dec 21, 2021
BingBing 60 Nov 4, 2022
Linux Application Level Firewall based on eBPF and NFQUEUE.

eBPFSnitch eBPFSnitch is a Linux Application Level Firewall based on eBPF and NFQUEUE. It is inspired by OpenSnitch, and Douane, but utilizing modern

Harpo Roeder 664 Nov 19, 2022