drogon/examples/simple_example/main.cc

283 lines
9.4 KiB
C++
Raw Normal View History

#include "CustomCtrl.h"
#include "CustomHeaderFilter.h"
#include <drogon/config.h>
2018-10-18 07:54:57 +00:00
#include <drogon/drogon.h>
#include <vector>
#include <string>
#include <iostream>
2018-06-05 06:40:03 +00:00
2018-05-11 07:33:11 +00:00
using namespace drogon;
using namespace std::chrono_literals;
2018-10-13 13:49:37 +00:00
class A : public DrObjectBase
{
2019-05-18 12:39:57 +00:00
public:
2018-10-13 13:49:37 +00:00
void handle(const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback,
2019-05-18 12:39:57 +00:00
int p1,
const std::string &p2,
const std::string &p3,
int p4) const
{
2018-06-07 01:41:15 +00:00
HttpViewData data;
2018-10-13 13:49:37 +00:00
data.insert("title", std::string("ApiTest::get"));
std::map<std::string, std::string> para;
para["int p1"] = std::to_string(p1);
para["string p2"] = p2;
para["string p3"] = p3;
para["int p4"] = std::to_string(p4);
2018-06-07 01:41:15 +00:00
2018-10-13 13:49:37 +00:00
data.insert("parameters", para);
auto res = HttpResponse::newHttpViewResponse("ListParaView", data);
callback(res);
}
2019-05-18 12:39:57 +00:00
static void staticHandle(
const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback,
int p1,
const std::string &p2,
const std::string &p3,
int p4)
{
HttpViewData data;
2018-10-13 13:49:37 +00:00
data.insert("title", std::string("ApiTest::get"));
std::map<std::string, std::string> para;
para["int p1"] = std::to_string(p1);
para["string p2"] = p2;
para["string p3"] = p3;
para["int p4"] = std::to_string(p4);
2018-10-13 13:49:37 +00:00
data.insert("parameters", para);
auto res = HttpResponse::newHttpViewResponse("ListParaView", data);
2018-08-26 08:25:35 +00:00
callback(res);
}
};
2018-10-13 13:49:37 +00:00
class B : public DrObjectBase
2018-06-05 02:43:53 +00:00
{
2019-05-18 12:39:57 +00:00
public:
void operator()(const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback,
int p1,
int p2)
2018-06-05 02:43:53 +00:00
{
2018-06-07 01:41:15 +00:00
HttpViewData data;
2018-10-13 13:49:37 +00:00
data.insert("title", std::string("ApiTest::get"));
std::map<std::string, std::string> para;
para["p1"] = std::to_string(p1);
para["p2"] = std::to_string(p2);
data.insert("parameters", para);
auto res = HttpResponse::newHttpViewResponse("ListParaView", data);
2018-08-26 08:25:35 +00:00
callback(res);
2018-06-05 02:43:53 +00:00
}
};
2018-06-05 06:40:03 +00:00
namespace api
{
2018-10-13 13:49:37 +00:00
namespace v1
{
class Test : public HttpController<Test>
2018-10-13 13:49:37 +00:00
{
2019-05-18 12:39:57 +00:00
public:
2018-10-13 13:49:37 +00:00
METHOD_LIST_BEGIN
2019-05-18 12:39:57 +00:00
METHOD_ADD(Test::get,
"get/{2}/{1}",
Get); // path is /api/v1/test/get/{arg2}/{arg1}
METHOD_ADD(Test::list,
"/{2}/info",
Get); // path is /api/v1/test/{arg2}/info
2018-10-13 13:49:37 +00:00
METHOD_LIST_END
2019-05-18 12:39:57 +00:00
void get(const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback,
int p1,
int p2) const
2018-06-05 06:40:03 +00:00
{
2018-10-13 13:49:37 +00:00
HttpViewData data;
data.insert("title", std::string("ApiTest::get"));
std::map<std::string, std::string> para;
para["p1"] = std::to_string(p1);
para["p2"] = std::to_string(p2);
data.insert("parameters", para);
auto res = HttpResponse::newHttpViewResponse("ListParaView", data);
callback(res);
2018-06-05 06:40:03 +00:00
}
2019-05-18 12:39:57 +00:00
void list(const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback,
int p1,
int p2) const
2018-10-13 13:49:37 +00:00
{
HttpViewData data;
data.insert("title", std::string("ApiTest::get"));
std::map<std::string, std::string> para;
para["p1"] = std::to_string(p1);
para["p2"] = std::to_string(p2);
data.insert("parameters", para);
auto res = HttpResponse::newHttpViewResponse("ListParaView", data);
callback(res);
}
};
2019-05-18 12:39:57 +00:00
} // namespace v1
} // namespace api
using namespace std::placeholders;
using namespace drogon;
/// Some examples in the main function some common functions of drogon. In
/// practice, we don't need such a lengthy main function.
2018-05-11 01:25:17 +00:00
int main()
{
2018-10-13 13:49:37 +00:00
std::cout << banner << std::endl;
// app().addListener("::1", 8848); //ipv6
2019-03-25 15:28:22 +00:00
app().addListener("0.0.0.0", 8848);
#ifdef OpenSSL_FOUND
2019-05-18 12:39:57 +00:00
// https
drogon::app().setSSLFiles("server.pem", "server.pem");
drogon::app().addListener("0.0.0.0", 8849, true);
2019-01-19 05:44:24 +00:00
#endif
// Class function example
app().registerHandler("/api/v1/handle1/{1}/{2}/?p3={3}&p4={4}", &A::handle);
2019-05-18 12:39:57 +00:00
app().registerHandler("/api/v1/handle11/{1}/{2}/?p3={3}&p4={4}",
&A::staticHandle);
// Lambda example
2019-05-18 12:39:57 +00:00
app().registerHandler(
"/api/v1/handle2/{1}/{2}",
[](const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback,
int a,
float b) {
HttpViewData data;
data.insert("title", std::string("ApiTest::get"));
std::map<std::string, std::string> para;
para["a"] = std::to_string(a);
para["b"] = std::to_string(b);
data.insert("parameters", para);
auto res = HttpResponse::newHttpViewResponse("ListParaView", data);
callback(res);
});
2018-06-05 02:43:53 +00:00
// Functor example
2018-06-05 02:43:53 +00:00
B b;
app().registerHandler("/api/v1/handle3/{1}/{2}", b);
// API example for std::function
2018-06-05 02:43:53 +00:00
A tmp;
2019-05-18 12:39:57 +00:00
std::function<void(const HttpRequestPtr &,
std::function<void(const HttpResponsePtr &)> &&,
int,
const std::string &,
const std::string &,
int)>
2018-10-13 13:49:37 +00:00
func = std::bind(&A::handle, &tmp, _1, _2, _3, _4, _5, _6);
app().registerHandler("/api/v1/handle4/{4}/{3}/{1}", func);
2018-06-11 09:11:06 +00:00
app().setDocumentRoot("./");
app().enableSession(60);
// Load configuration
app().loadConfigFile("config.example.json");
auto &json = app().getCustomConfig();
if (json.empty())
{
std::cout << "empty custom config!" << std::endl;
}
2019-05-18 12:39:57 +00:00
// Install custom controller
auto ctrlPtr = std::make_shared<CustomCtrl>("Hi");
app().registerController(ctrlPtr);
2019-05-18 12:39:57 +00:00
// Install custom filter
auto filterPtr =
std::make_shared<CustomHeaderFilter>("custom_header", "yes");
app().registerFilter(filterPtr);
app().setIdleConnectionTimeout(30s);
// AOP example
2019-05-18 12:39:57 +00:00
app().registerBeginningAdvice(
[]() { LOG_DEBUG << "Event loop is running!"; });
app().registerNewConnectionAdvice([](const trantor::InetAddress &peer,
const trantor::InetAddress &local) {
LOG_DEBUG << "New connection: " << peer.toIpPort() << "-->"
<< local.toIpPort();
2019-04-18 10:37:31 +00:00
return true;
});
app().registerPreRoutingAdvice([](const drogon::HttpRequestPtr &req,
drogon::AdviceCallback &&acb,
drogon::AdviceChainCallback &&accb) {
2019-04-18 10:37:31 +00:00
LOG_DEBUG << "preRouting1";
accb();
});
app().registerPostRoutingAdvice([](const drogon::HttpRequestPtr &req,
drogon::AdviceCallback &&acb,
drogon::AdviceChainCallback &&accb) {
2019-04-18 10:37:31 +00:00
LOG_DEBUG << "postRouting1";
LOG_DEBUG << "Matched path=" << req->matchedPathPatternData();
2019-05-23 02:47:15 +00:00
for (auto &cookie : req->cookies())
{
LOG_DEBUG << "cookie: " << cookie.first << "=" << cookie.second;
}
2019-04-18 10:37:31 +00:00
accb();
});
app().registerPreHandlingAdvice([](const drogon::HttpRequestPtr &req,
drogon::AdviceCallback &&acb,
drogon::AdviceChainCallback &&accb) {
2019-04-18 10:37:31 +00:00
LOG_DEBUG << "preHandling1";
accb();
});
app().registerPostHandlingAdvice([](const drogon::HttpRequestPtr &,
const drogon::HttpResponsePtr &resp) {
LOG_DEBUG << "postHandling1";
resp->addHeader("Access-Control-Allow-Origin", "*");
});
2019-04-18 10:37:31 +00:00
app().registerPreRoutingAdvice([](const drogon::HttpRequestPtr &req) {
LOG_DEBUG << "preRouting observer";
});
app().registerPostRoutingAdvice([](const drogon::HttpRequestPtr &req) {
LOG_DEBUG << "postRouting observer";
});
app().registerPreHandlingAdvice([](const drogon::HttpRequestPtr &req) {
LOG_DEBUG << "preHanding observer";
});
app().registerSyncAdvice([](const HttpRequestPtr &req) -> HttpResponsePtr {
static const HttpResponsePtr nullResp;
if (req->path() == "/plaintext")
{
auto resp = HttpResponse::newHttpResponse();
resp->setBody("Hello, World!");
resp->setContentTypeCodeAndCustomString(
CT_TEXT_PLAIN, "Content-Type: text/plain\r\n");
return resp;
}
return nullResp;
});
// Output information of all handlers
2019-04-24 06:38:07 +00:00
auto handlerInfo = app().getHandlersInfo();
for (auto &info : handlerInfo)
{
std::cout << std::get<0>(info);
switch (std::get<1>(info))
{
2019-05-18 12:39:57 +00:00
case Get:
std::cout << " (GET) ";
break;
case Post:
std::cout << " (POST) ";
break;
case Delete:
std::cout << " (DELETE) ";
break;
case Put:
std::cout << " (PUT) ";
break;
case Options:
std::cout << " (OPTIONS) ";
break;
case Head:
std::cout << " (Head) ";
break;
default:
break;
2019-04-24 06:38:07 +00:00
}
std::cout << std::get<2>(info) << std::endl;
}
app().run();
2018-05-04 09:51:22 +00:00
}