improved lambda bracing by inlining only empty lambdas.

Signed-off-by: Luca Schlecker <luca.schlecker@hotmail.com>
This commit is contained in:
Luca Schlecker 2021-11-27 18:44:51 +01:00
parent ef396a7c88
commit 7e4f1494d2
23 changed files with 579 additions and 377 deletions

View File

@ -1,4 +1,4 @@
---
---
BasedOnStyle: Mozilla
AccessModifierOffset: '-4'
AlignAfterOpenBracket: Align
@ -10,7 +10,7 @@ AllowShortBlocksOnASingleLine: 'true'
AllowShortCaseLabelsOnASingleLine: 'true'
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: 'true'
AllowShortLambdasOnASingleLine: All
AllowShortLambdasOnASingleLine: Empty
AllowShortLoopsOnASingleLine: 'false'
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None

View File

@ -46,14 +46,20 @@ int main()
app.get_middleware<ExampleMiddleware>().setMessage("hello");
CROW_ROUTE(app, "/")
.name("hello")([] { return "Hello World!"; });
.name("hello")([] {
return "Hello World!";
});
CROW_ROUTE(app, "/about")
([]() { return "About Crow example."; });
([]() {
return "About Crow example.";
});
// a request to /path should be forwarded to /path/
CROW_ROUTE(app, "/path/")
([]() { return "Trailing slash test case.."; });
([]() {
return "Trailing slash test case..";
});
// simple json response
@ -61,27 +67,31 @@ int main()
([] {
crow::json::wvalue x({{"message", "Hello, World!"}});
x["message2"] = "Hello, World.. Again!";
return x; });
return x;
});
CROW_ROUTE(app, "/json-initializer-list-constructor")
([] { return crow::json::wvalue({
{"first", "Hello world!"}, /* stores a char const* hence a json::type::String */
{"second", std::string("How are you today?")}, /* stores a std::string hence a json::type::String. */
{"third", std::int64_t(54)}, /* stores a 64-bit int hence a std::int64_t. */
{"fourth", std::uint64_t(54)}, /* stores a 64-bit unsigned int hence a std::uint64_t. */
{"fifth", 54}, /* stores an int (as 54 is an int literal) hence a std::int64_t. */
{"sixth", 54u}, /* stores an unsigned int (as 54u is a unsigned int literal) hence a std::uint64_t. */
{"seventh", 2.f}, /* stores a float (as 2.f is a float literal) hence a double. */
{"eighth", 2.}, /* stores a double (as 2. is a double literal) hence a double. */
{"ninth", nullptr}, /* stores a std::nullptr hence json::type::Null . */
{"tenth", true} /* stores a bool hence json::type::True . */
}); });
([] {
return crow::json::wvalue({
{"first", "Hello world!"}, /* stores a char const* hence a json::type::String */
{"second", std::string("How are you today?")}, /* stores a std::string hence a json::type::String. */
{"third", std::int64_t(54)}, /* stores a 64-bit int hence a std::int64_t. */
{"fourth", std::uint64_t(54)}, /* stores a 64-bit unsigned int hence a std::uint64_t. */
{"fifth", 54}, /* stores an int (as 54 is an int literal) hence a std::int64_t. */
{"sixth", 54u}, /* stores an unsigned int (as 54u is a unsigned int literal) hence a std::uint64_t. */
{"seventh", 2.f}, /* stores a float (as 2.f is a float literal) hence a double. */
{"eighth", 2.}, /* stores a double (as 2. is a double literal) hence a double. */
{"ninth", nullptr}, /* stores a std::nullptr hence json::type::Null . */
{"tenth", true} /* stores a bool hence json::type::True . */
});
});
// json list response
CROW_ROUTE(app, "/json_list")
([] {
crow::json::wvalue x(crow::json::wvalue::list({1,2,3}));
return x; });
crow::json::wvalue x(crow::json::wvalue::list({1, 2, 3}));
return x;
});
// To see it in action enter {ip}:18080/hello/{integer_between -2^32 and 100} and you should receive
// {integer_between -2^31 and 100} bottles of beer!
@ -91,7 +101,8 @@ int main()
return crow::response(400);
std::ostringstream os;
os << count << " bottles of beer!";
return crow::response(os.str()); });
return crow::response(os.str());
});
// Same as above, but using crow::status
CROW_ROUTE(app, "/hello_status/<int>")
@ -100,15 +111,17 @@ int main()
return crow::response(crow::status::BAD_REQUEST);
std::ostringstream os;
os << count << " bottles of beer!";
return crow::response(os.str()); });
return crow::response(os.str());
});
// To see it in action submit {ip}:18080/add/1/2 and you should receive 3 (exciting, isn't it)
CROW_ROUTE(app, "/add/<int>/<int>")
([](crow::response& res, int a, int b) {
std::ostringstream os;
os << a+b;
os << a + b;
res.write(os.str());
res.end(); });
res.end();
});
// Compile error with message "Handler type is mismatched with URL paramters"
//CROW_ROUTE(app,"/another/<int>")
@ -129,13 +142,14 @@ int main()
// * curl -d '{"a":1,"b":2}' {ip}:18080/add_json
CROW_ROUTE(app, "/add_json")
.methods("POST"_method)([](const crow::request& req) {
auto x = crow::json::load(req.body);
if (!x)
return crow::response(400);
int sum = x["a"].i()+x["b"].i();
std::ostringstream os;
os << sum;
return crow::response{os.str()}; });
auto x = crow::json::load(req.body);
if (!x)
return crow::response(400);
int sum = x["a"].i() + x["b"].i();
std::ostringstream os;
os << sum;
return crow::response{os.str()};
});
// Example of a request taking URL parameters
// If you want to activate all the functions just query
@ -151,16 +165,18 @@ int main()
// To get a double from the request
// To see in action submit something like '/params?pew=42'
if(req.url_params.get("pew") != nullptr) {
if (req.url_params.get("pew") != nullptr)
{
double countD = boost::lexical_cast<double>(req.url_params.get("pew"));
os << "The value of 'pew' is " << countD << '\n';
os << "The value of 'pew' is " << countD << '\n';
}
// To get a list from the request
// You have to submit something like '/params?count[]=a&count[]=b' to have a list with two values (a and b)
auto count = req.url_params.get_list("count");
os << "The key 'count' contains " << count.size() << " value(s).\n";
for(const auto& countVal : count) {
for (const auto& countVal : count)
{
os << " - " << countVal << '\n';
}
@ -168,21 +184,26 @@ int main()
// You have to submit something like '/params?mydict[a]=b&mydict[abcd]=42' to have a list of pairs ((a, b) and (abcd, 42))
auto mydict = req.url_params.get_dict("mydict");
os << "The key 'dict' contains " << mydict.size() << " value(s).\n";
for(const auto& mydictVal : mydict) {
for (const auto& mydictVal : mydict)
{
os << " - " << mydictVal.first << " -> " << mydictVal.second << '\n';
}
return crow::response{os.str()}; });
return crow::response{os.str()};
});
CROW_ROUTE(app, "/large")
([] { return std::string(512 * 1024, ' '); });
([] {
return std::string(512 * 1024, ' ');
});
// Take a multipart/form-data request and print out its body
CROW_ROUTE(app, "/multipart")
([](const crow::request& req) {
crow::multipart::message msg(req);
CROW_LOG_INFO << "body of the first part " << msg.parts[0].body;
return "it works!"; });
return "it works!";
});
// enables all log
app.loglevel(crow::LogLevel::Debug);

View File

@ -10,7 +10,9 @@ int main()
crow::Blueprint sub_bp("bp2", "csstat", "cstemplate");
CROW_BP_ROUTE(sub_bp, "/")
([]() { return "Hello world!"; });
([]() {
return "Hello world!";
});
/* CROW_BP_ROUTE(bp, "/templatt")
([]() {
@ -23,7 +25,9 @@ int main()
});
*/
CROW_BP_CATCHALL_ROUTE(sub_bp)
([]() { return "WRONG!!"; });
([]() {
return "WRONG!!";
});
bp.register_blueprint(sub_bp);

View File

@ -7,7 +7,9 @@ int main()
crow::SimpleApp app;
CROW_ROUTE(app, "/")
([]() { return "Hello"; });
([]() {
return "Hello";
});
//Setting a custom route for any URL that isn't defined, instead of a simple 404.
CROW_CATCHALL_ROUTE(app)
@ -20,7 +22,8 @@ int main()
{
res.body = "The HTTP method does not seem to be correct.";
}
res.end(); });
res.end();
});
app.port(18080).run();
}

View File

@ -32,18 +32,20 @@ int main()
CROW_ROUTE(app, "/")
([] {
crow::mustache::context ctx;
return crow::mustache::load("example_chat.html").render(); });
return crow::mustache::load("example_chat.html").render();
});
CROW_ROUTE(app, "/logs")
([] {
CROW_LOG_INFO << "logs requested";
crow::json::wvalue x;
int start = max(0, (int)msgs.size()-100);
for(int i = start; i < (int)msgs.size(); i++)
x["msgs"][i-start] = msgs[i];
int start = max(0, (int)msgs.size() - 100);
for (int i = start; i < (int)msgs.size(); i++)
x["msgs"][i - start] = msgs[i];
x["last"] = msgs.size();
CROW_LOG_INFO << "logs completed";
return x; });
return x;
});
CROW_ROUTE(app, "/logs/<int>")
([](const crow::request& /*req*/, crow::response& res, int after) {
@ -51,8 +53,8 @@ int main()
if (after < (int)msgs.size())
{
crow::json::wvalue x;
for(int i = after; i < (int)msgs.size(); i ++)
x["msgs"][i-after] = msgs[i];
for (int i = after; i < (int)msgs.size(); i++)
x["msgs"][i - after] = msgs[i];
x["last"] = msgs.size();
res.write(x.dump());
@ -61,7 +63,7 @@ int main()
else
{
vector<pair<crow::response*, decltype(chrono::steady_clock::now())>> filtered;
for(auto p : ress)
for (auto p : ress)
{
if (p.first->is_alive() && chrono::steady_clock::now() - p.second < chrono::seconds(30))
filtered.push_back(p);
@ -71,13 +73,15 @@ int main()
ress.swap(filtered);
ress.push_back({&res, chrono::steady_clock::now()});
CROW_LOG_DEBUG << &res << " stored " << ress.size();
} });
}
});
CROW_ROUTE(app, "/send")
.methods("GET"_method, "POST"_method)([](const crow::request& req) {
CROW_LOG_INFO << "msg from client: " << req.body;
broadcast(req.body);
return ""; });
CROW_LOG_INFO << "msg from client: " << req.body;
broadcast(req.body);
return "";
});
app.port(40080)
//.multithreaded()

View File

@ -11,10 +11,13 @@ int main()
res.compressed = false;
res.body = "Hello World! This is uncompressed!";
res.end(); });
res.end();
});
CROW_ROUTE(app, "/hello_compressed")
([]() { return "Hello World! This is compressed by default!"; });
([]() {
return "Hello World! This is compressed by default!";
});
app.port(18080)

View File

@ -10,9 +10,10 @@ int main()
// it shoud show amessage before zmessage despite adding zmessage first.
CROW_ROUTE(app, "/json")
([] {
crow::json::wvalue x({{"zmessage", "Hello, World!"},
{"amessage", "Hello, World2!"}});
return x; });
crow::json::wvalue x({{"zmessage", "Hello, World!"},
{"amessage", "Hello, World2!"}});
return x;
});
app.port(18080)
.multithreaded()

View File

@ -12,9 +12,10 @@ int main()
//
CROW_ROUTE(app, "/")
([](const crow::request&, crow::response& res) {
//replace cat.jpg with your file path
res.set_static_file_info("cat.jpg");
res.end(); });
//replace cat.jpg with your file path
res.set_static_file_info("cat.jpg");
res.end();
});
app.port(18080).run();

View File

@ -46,21 +46,28 @@ int main()
app.get_middleware<ExampleMiddleware>().setMessage("hello");
CROW_ROUTE(app, "/")
.name("hello")([] { return "Hello World!"; });
.name("hello")([] {
return "Hello World!";
});
CROW_ROUTE(app, "/about")
([]() { return "About Crow example."; });
([]() {
return "About Crow example.";
});
// a request to /path should be forwarded to /path/
CROW_ROUTE(app, "/path/")
([]() { return "Trailing slash test case.."; });
([]() {
return "Trailing slash test case..";
});
// simple json response
CROW_ROUTE(app, "/json")
([] {
crow::json::wvalue x;
x["message"] = "Hello, World!";
return x; });
return x;
});
CROW_ROUTE(app, "/hello/<int>")
([](int count) {
@ -68,14 +75,16 @@ int main()
return crow::response(400);
std::ostringstream os;
os << count << " bottles of beer!";
return crow::response(os.str()); });
return crow::response(os.str());
});
CROW_ROUTE(app, "/add/<int>/<int>")
([](crow::response& res, int a, int b) {
std::ostringstream os;
os << a+b;
os << a + b;
res.write(os.str());
res.end(); });
res.end();
});
// Compile error with message "Handler type is mismatched with URL paramters"
//CROW_ROUTE(app,"/another/<int>")
@ -86,28 +95,32 @@ int main()
// more json example
CROW_ROUTE(app, "/add_json")
.methods(crow::HTTPMethod::Post)([](const crow::request& req) {
auto x = crow::json::load(req.body);
if (!x)
return crow::response(400);
auto sum = x["a"].i()+x["b"].i();
std::ostringstream os;
os << sum;
return crow::response{os.str()}; });
auto x = crow::json::load(req.body);
if (!x)
return crow::response(400);
auto sum = x["a"].i() + x["b"].i();
std::ostringstream os;
os << sum;
return crow::response{os.str()};
});
app.route_dynamic("/params")([](const crow::request& req) {
std::ostringstream os;
os << "Params: " << req.url_params << "\n\n";
os << "The key 'foo' was " << (req.url_params.get("foo") == nullptr ? "not " : "") << "found.\n";
if(req.url_params.get("pew") != nullptr) {
if (req.url_params.get("pew") != nullptr)
{
double countD = boost::lexical_cast<double>(req.url_params.get("pew"));
os << "The value of 'pew' is " << countD << '\n';
os << "The value of 'pew' is " << countD << '\n';
}
auto count = req.url_params.get_list("count");
os << "The key 'count' contains " << count.size() << " value(s).\n";
for(const auto& countVal : count) {
for (const auto& countVal : count)
{
os << " - " << countVal << '\n';
}
return crow::response{os.str()}; });
return crow::response{os.str()};
});
// ignore all log
crow::logger::setLogLevel(crow::LogLevel::Debug);

View File

@ -16,37 +16,45 @@ int main()
crow::SimpleApp app;
CROW_ROUTE(app, "/")
.name("hello")([] { return "Hello World!"; });
.name("hello")([] {
return "Hello World!";
});
CROW_ROUTE(app, "/about")
([]() { return "About Crow example."; });
([]() {
return "About Crow example.";
});
// simple json response
CROW_ROUTE(app, "/json")
([] {
crow::json::wvalue x({{"message", "Hello, World!"}});
x["message2"] = "Hello, World.. Again!";
return x; });
return x;
});
CROW_ROUTE(app, "/json-initializer-list-constructor")
([] { return crow::json::wvalue({
{"first", "Hello world!"}, /* stores a char const* hence a json::type::String */
{"second", std::string("How are you today?")}, /* stores a std::string hence a json::type::String. */
{"third", 54}, /* stores an int (as 54 is an int literal) hence a std::int64_t. */
{"fourth", 54l}, /* stores a long (as 54l is a long literal) hence a std::int64_t. */
{"fifth", 54u}, /* stores an unsigned int (as 54u is a unsigned int literal) hence a std::uint64_t. */
{"sixth", 54ul}, /* stores an unsigned long (as 54ul is an unsigned long literal) hence a std::uint64_t. */
{"seventh", 2.f}, /* stores a float (as 2.f is a float literal) hence a double. */
{"eighth", 2.}, /* stores a double (as 2. is a double literal) hence a double. */
{"ninth", nullptr}, /* stores a std::nullptr hence json::type::Null . */
{"tenth", true} /* stores a bool hence json::type::True . */
}); });
([] {
return crow::json::wvalue({
{"first", "Hello world!"}, /* stores a char const* hence a json::type::String */
{"second", std::string("How are you today?")}, /* stores a std::string hence a json::type::String. */
{"third", 54}, /* stores an int (as 54 is an int literal) hence a std::int64_t. */
{"fourth", 54l}, /* stores a long (as 54l is a long literal) hence a std::int64_t. */
{"fifth", 54u}, /* stores an unsigned int (as 54u is a unsigned int literal) hence a std::uint64_t. */
{"sixth", 54ul}, /* stores an unsigned long (as 54ul is an unsigned long literal) hence a std::uint64_t. */
{"seventh", 2.f}, /* stores a float (as 2.f is a float literal) hence a double. */
{"eighth", 2.}, /* stores a double (as 2. is a double literal) hence a double. */
{"ninth", nullptr}, /* stores a std::nullptr hence json::type::Null . */
{"tenth", true} /* stores a bool hence json::type::True . */
});
});
// json list response
CROW_ROUTE(app, "/json_list")
([] {
crow::json::wvalue x(crow::json::wvalue::list({1,2,3}));
return x; });
crow::json::wvalue x(crow::json::wvalue::list({1, 2, 3}));
return x;
});
CROW_ROUTE(app, "/hello/<int>")
([](int count) {
@ -54,16 +62,18 @@ int main()
return crow::response(400);
std::ostringstream os;
os << count << " bottles of beer!";
return crow::response(os.str()); });
return crow::response(os.str());
});
// example which uses only response as a paramter without
// request being a parameter.
CROW_ROUTE(app, "/add/<int>/<int>")
([](crow::response& res, int a, int b) {
std::ostringstream os;
os << a+b;
os << a + b;
res.write(os.str());
res.end(); });
res.end();
});
// Compile error with message "Handler type is mismatched with URL paramters"
//CROW_ROUTE(app,"/another/<int>")
@ -77,26 +87,30 @@ int main()
auto x = crow::json::load(req.body);
if (!x)
return crow::response(400);
int sum = x["a"].i()+x["b"].i();
int sum = x["a"].i() + x["b"].i();
std::ostringstream os;
os << sum;
return crow::response{os.str()}; });
return crow::response{os.str()};
});
CROW_ROUTE(app, "/params")
([](const crow::request& req) {
std::ostringstream os;
os << "Params: " << req.url_params << "\n\n";
os << "The key 'foo' was " << (req.url_params.get("foo") == nullptr ? "not " : "") << "found.\n";
if(req.url_params.get("pew") != nullptr) {
if (req.url_params.get("pew") != nullptr)
{
double countD = boost::lexical_cast<double>(req.url_params.get("pew"));
os << "The value of 'pew' is " << countD << '\n';
os << "The value of 'pew' is " << countD << '\n';
}
auto count = req.url_params.get_list("count");
os << "The key 'count' contains " << count.size() << " value(s).\n";
for(const auto& countVal : count) {
for (const auto& countVal : count)
{
os << " - " << countVal << '\n';
}
return crow::response{os.str()}; });
return crow::response{os.str()};
});
// ignore all log
crow::logger::setLogLevel(crow::LogLevel::Debug);

View File

@ -5,7 +5,9 @@ int main()
crow::SimpleApp app;
CROW_ROUTE(app, "/")
([]() { return "Hello, world!"; });
([]() {
return "Hello, world!";
});
app.port(18080).run();
}

View File

@ -5,8 +5,9 @@ int main()
crow::SimpleApp app;
CROW_ROUTE(app, "/")
([]()
{ return "Hello world!"; });
([]() {
return "Hello world!";
});
app.port(18080).ssl_file("test.crt", "test.key").run();

View File

@ -12,35 +12,35 @@ int main()
CROW_ROUTE(app, "/ws")
.websocket()
.onopen([&](crow::websocket::connection& conn)
{
CROW_LOG_INFO << "new websocket connection from " << conn.get_remote_ip();
std::lock_guard<std::mutex> _(mtx);
users.insert(&conn); })
.onclose([&](crow::websocket::connection& conn, const std::string& reason)
{
CROW_LOG_INFO << "websocket connection closed: " << reason;
std::lock_guard<std::mutex> _(mtx);
users.erase(&conn); })
.onmessage([&](crow::websocket::connection& /*conn*/, const std::string& data, bool is_binary)
{
std::lock_guard<std::mutex> _(mtx);
for(auto u:users)
if (is_binary)
u->send_binary(data);
else
u->send_text(data); });
.onopen([&](crow::websocket::connection& conn) {
CROW_LOG_INFO << "new websocket connection from " << conn.get_remote_ip();
std::lock_guard<std::mutex> _(mtx);
users.insert(&conn);
})
.onclose([&](crow::websocket::connection& conn, const std::string& reason) {
CROW_LOG_INFO << "websocket connection closed: " << reason;
std::lock_guard<std::mutex> _(mtx);
users.erase(&conn);
})
.onmessage([&](crow::websocket::connection& /*conn*/, const std::string& data, bool is_binary) {
std::lock_guard<std::mutex> _(mtx);
for (auto u : users)
if (is_binary)
u->send_binary(data);
else
u->send_text(data);
});
CROW_ROUTE(app, "/")
([]
{
([] {
char name[256];
gethostname(name, 256);
crow::mustache::context x;
x["servername"] = name;
auto page = crow::mustache::load("ws.html");
return page.render(x); });
return page.render(x);
});
app.port(40080)
.multithreaded()

View File

@ -227,8 +227,9 @@ namespace crow
#ifndef CROW_DISABLE_STATIC_DIR
route<crow::black_magic::get_parameter_tag(CROW_STATIC_ENDPOINT)>(CROW_STATIC_ENDPOINT)([](crow::response& res, std::string file_path_partial) {
res.set_static_file_info(CROW_STATIC_DIRECTORY + file_path_partial);
res.end(); });
res.set_static_file_info(CROW_STATIC_DIRECTORY + file_path_partial);
res.end();
});
#if defined(__APPLE__) || defined(__MACH__)
if (!router_.blueprints().empty())
@ -239,8 +240,9 @@ namespace crow
if (!bp->static_dir().empty())
{
bp->new_rule_tagged<crow::black_magic::get_parameter_tag(CROW_STATIC_ENDPOINT)>(CROW_STATIC_ENDPOINT)([bp](crow::response& res, std::string file_path_partial) {
res.set_static_file_info(bp->static_dir() + '/' + file_path_partial);
res.end(); });
res.set_static_file_info(bp->static_dir() + '/' + file_path_partial);
res.end();
});
}
}
}

View File

@ -231,7 +231,8 @@ namespace crow
{
CROW_LOG_ERROR << "Could not start adaptor: " << ec.message();
check_destroy();
} });
}
});
}
void handle_header()
@ -307,7 +308,9 @@ namespace crow
if (!is_invalid_request)
{
res.complete_request_handler_ = [] {};
res.is_alive_helper_ = [this]() -> bool { return adaptor_.is_open(); };
res.is_alive_helper_ = [this]() -> bool {
return adaptor_.is_open();
};
ctx_ = detail::context<Middlewares...>();
req.middleware_context = static_cast<void*>(&ctx_);
@ -316,7 +319,9 @@ namespace crow
if (!res.completed_)
{
res.complete_request_handler_ = [this] { this->complete_request(); };
res.complete_request_handler_ = [this] {
this->complete_request();
};
need_to_call_after_handlers_ = true;
handler_->handle(req, res);
if (add_keep_alive_)
@ -656,7 +661,8 @@ namespace crow
return;
}
adaptor_.shutdown_readwrite();
adaptor_.close(); });
adaptor_.close();
});
CROW_LOG_DEBUG << this << " timer added: " << &task_timer_ << ' ' << task_id_;
}

View File

@ -314,16 +314,17 @@ namespace crow
inline void write_buffer_list(std::vector<asio::const_buffer>& buffers, Adaptor& adaptor)
{
boost::asio::write(adaptor.socket(), buffers, [this](std::error_code ec, std::size_t) {
if (!ec)
{
return false;
}
else
{
CROW_LOG_ERROR << ec << " - happened while sending buffers";
this->end();
return true;
} });
if (!ec)
{
return false;
}
else
{
CROW_LOG_ERROR << ec << " - happened while sending buffers";
this->end();
return true;
}
});
}
};
} // namespace crow

View File

@ -51,9 +51,10 @@ namespace crow
tick_function_();
tick_timer_.expires_from_now(boost::posix_time::milliseconds(tick_interval_.count()));
tick_timer_.async_wait([this](const boost::system::error_code& ec) {
if (ec)
return;
on_tick(); });
if (ec)
return;
on_tick();
});
}
void run()
@ -69,13 +70,11 @@ namespace crow
v.push_back(
std::async(
std::launch::async, [this, i, &init_count] {
// thread local date string get function
auto last = std::chrono::steady_clock::now();
std::string date_str;
auto update_date_str = [&]
{
auto update_date_str = [&] {
auto last_time_t = time(0);
tm my_tm;
@ -89,8 +88,7 @@ namespace crow
date_str.resize(date_str_sz);
};
update_date_str();
get_cached_date_str_pool_[i] = [&]()->std::string
{
get_cached_date_str_pool_[i] = [&]() -> std::string {
if (std::chrono::steady_clock::now() - last >= std::chrono::seconds(1))
{
last = std::chrono::steady_clock::now();
@ -104,8 +102,8 @@ namespace crow
task_timer.set_default_timeout(timeout_);
task_timer_pool_[i] = &task_timer;
init_count ++;
while(1)
init_count++;
while (1)
{
try
{
@ -114,11 +112,13 @@ namespace crow
// when io_service.run returns 0, there are no more works to do.
break;
}
} catch(std::exception& e)
}
catch (std::exception& e)
{
CROW_LOG_ERROR << "Worker Crash: An uncaught exception occurred: " << e.what();
}
} }));
}
}));
if (tick_function_ && tick_interval_.count() > 0)
{
@ -196,7 +196,9 @@ namespace crow
if (!ec)
{
is.post(
[p] { p->start(); });
[p] {
p->start();
});
}
else
{

View File

@ -87,7 +87,7 @@ namespace crow
public:
logger(LogLevel level):
level_(level)
{}
{}
~logger()
{
#ifdef CROW_ENABLE_LOGGING

View File

@ -705,7 +705,9 @@ namespace crow
blueprint_index == INVALID_BP_ID &&
children.size() < 2 &&
param == ParamType::MAX &&
std::all_of(std::begin(children), std::end(children), [](Node* x) { return x->param == ParamType::MAX; });
std::all_of(std::begin(children), std::end(children), [](Node* x) {
return x->param == ParamType::MAX;
});
}
};
@ -1259,15 +1261,16 @@ namespace crow
}
ruleObject->foreach_method([&](int method) {
per_methods_[method].rules.emplace_back(ruleObject);
per_methods_[method].trie.add(rule, per_methods_[method].rules.size() - 1, BP_index != INVALID_BP_ID ? blueprints[BP_index]->prefix().length() : 0, BP_index);
per_methods_[method].rules.emplace_back(ruleObject);
per_methods_[method].trie.add(rule, per_methods_[method].rules.size() - 1, BP_index != INVALID_BP_ID ? blueprints[BP_index]->prefix().length() : 0, BP_index);
// directory case:
// request to '/about' url matches '/about/' rule
if (has_trailing_slash)
{
per_methods_[method].trie.add(rule_without_trailing_slash, RULE_SPECIAL_REDIRECT_SLASH, BP_index != INVALID_BP_ID ? blueprints_[BP_index]->prefix().length() : 0, BP_index);
} });
// directory case:
// request to '/about' url matches '/about/' rule
if (has_trailing_slash)
{
per_methods_[method].trie.add(rule_without_trailing_slash, RULE_SPECIAL_REDIRECT_SLASH, BP_index != INVALID_BP_ID ? blueprints_[BP_index]->prefix().length() : 0, BP_index);
}
});
}
void register_blueprint(Blueprint& blueprint)
@ -1297,7 +1300,8 @@ namespace crow
rule->foreach_method([&methods](unsigned method) {
HTTPMethod method_final = static_cast<HTTPMethod>(method);
if (std::find(methods.begin(), methods.end(), method_final) == methods.end())
methods.emplace_back(method_final); });
methods.emplace_back(method_final);
});
}
}

View File

@ -128,10 +128,11 @@ namespace crow
void send_ping(const std::string& msg) override
{
dispatch([this, msg] {
auto header = build_header(0x9, msg.size());
write_buffers_.emplace_back(std::move(header));
write_buffers_.emplace_back(msg);
do_write(); });
auto header = build_header(0x9, msg.size());
write_buffers_.emplace_back(std::move(header));
write_buffers_.emplace_back(msg);
do_write();
});
}
///
@ -142,30 +143,33 @@ namespace crow
void send_pong(const std::string& msg) override
{
dispatch([this, msg] {
auto header = build_header(0xA, msg.size());
write_buffers_.emplace_back(std::move(header));
write_buffers_.emplace_back(msg);
do_write(); });
auto header = build_header(0xA, msg.size());
write_buffers_.emplace_back(std::move(header));
write_buffers_.emplace_back(msg);
do_write();
});
}
/// Send a binary encoded message.
void send_binary(const std::string& msg) override
{
dispatch([this, msg] {
auto header = build_header(2, msg.size());
write_buffers_.emplace_back(std::move(header));
write_buffers_.emplace_back(msg);
do_write(); });
auto header = build_header(2, msg.size());
write_buffers_.emplace_back(std::move(header));
write_buffers_.emplace_back(msg);
do_write();
});
}
/// Send a plaintext message.
void send_text(const std::string& msg) override
{
dispatch([this, msg] {
auto header = build_header(1, msg.size());
write_buffers_.emplace_back(std::move(header));
write_buffers_.emplace_back(msg);
do_write(); });
auto header = build_header(1, msg.size());
write_buffers_.emplace_back(std::move(header));
write_buffers_.emplace_back(msg);
do_write();
});
}
///
@ -176,17 +180,18 @@ namespace crow
void close(const std::string& msg) override
{
dispatch([this, msg] {
has_sent_close_ = true;
if (has_recv_close_ && !is_close_handler_called_)
{
is_close_handler_called_ = true;
if (close_handler_)
close_handler_(*this, msg);
}
auto header = build_header(0x8, msg.size());
write_buffers_.emplace_back(std::move(header));
write_buffers_.emplace_back(msg);
do_write(); });
has_sent_close_ = true;
if (has_recv_close_ && !is_close_handler_called_)
{
is_close_handler_called_ = true;
if (close_handler_)
close_handler_(*this, msg);
}
auto header = build_header(0x8, msg.size());
write_buffers_.emplace_back(std::move(header));
write_buffers_.emplace_back(msg);
do_write();
});
}
std::string get_remote_ip() override

View File

@ -24,14 +24,18 @@ TEST_CASE("SSL")
//crow::SimpleApp app2;
CROW_ROUTE(app, "/")
([]() { return "Hello world, I'm keycrt."; });
([]() {
return "Hello world, I'm keycrt.";
});
/*
CROW_ROUTE(app2, "/")
([]() {
return "Hello world, I'm pem.";
});
*/
auto _ = async(std::launch::async, [&] { app.bindaddr(LOCALHOST_ADDRESS).port(45460).ssl_file("test.crt", "test.key").run(); });
auto _ = async(std::launch::async, [&] {
app.bindaddr(LOCALHOST_ADDRESS).port(45460).ssl_file("test.crt", "test.key").run();
});
//auto _1 = async(std::launch::async,[&] { app2.bindaddr(LOCALHOST_ADDRESS).port(45461).ssl_file("test.pem").run(); });
app.wait_for_server_start();

View File

@ -22,10 +22,12 @@ int main()
auto templ = compile(read_all("template"));
auto partials = json::load(read_all("partials"));
set_loader([&](std::string name) -> std::string {
if (partials.count(name)) {
return partials[name].s();
}
return ""; });
if (partials.count(name))
{
return partials[name].s();
}
return "";
});
context ctx(data);
cout << templ.render(ctx);
return 0;

View File

@ -37,8 +37,9 @@ TEST_CASE("Rule")
// registering handler
r([&x] {
x = 1;
return ""; });
x = 1;
return "";
});
r.validate();
@ -51,8 +52,9 @@ TEST_CASE("Rule")
// registering handler with request argument
r([&x](const crow::request&) {
x = 2;
return ""; });
x = 2;
return "";
});
r.validate();
@ -92,10 +94,14 @@ TEST_CASE("PathRouting")
SimpleApp app;
CROW_ROUTE(app, "/file")
([] { return "file"; });
([] {
return "file";
});
CROW_ROUTE(app, "/path/")
([] { return "path"; });
([] {
return "path";
});
app.validate();
@ -149,31 +155,35 @@ TEST_CASE("RoutingTest")
CROW_ROUTE(app, "/0/<uint>")
([&](uint32_t b) {
B = b;
return "OK"; });
B = b;
return "OK";
});
CROW_ROUTE(app, "/1/<int>/<uint>")
([&](int a, uint32_t b) {
A = a;
B = b;
return "OK"; });
A = a;
B = b;
return "OK";
});
CROW_ROUTE(app, "/4/<int>/<uint>/<double>/<string>")
([&](int a, uint32_t b, double c, string d) {
A = a;
B = b;
C = c;
D = d;
return "OK"; });
A = a;
B = b;
C = c;
D = d;
return "OK";
});
CROW_ROUTE(app, "/5/<int>/<uint>/<double>/<string>/<path>")
([&](int a, uint32_t b, double c, string d, string e) {
A = a;
B = b;
C = c;
D = d;
E = e;
return "OK"; });
A = a;
B = b;
C = c;
D = d;
E = e;
return "OK";
});
app.validate();
// app.debug_print();
@ -288,19 +298,28 @@ TEST_CASE("http_method")
CROW_ROUTE(app, "/").methods("POST"_method,
"GET"_method)([](const request& req) {
if (req.method == "GET"_method)
return "2";
else
return "1"; });
if (req.method == "GET"_method)
return "2";
else
return "1";
});
CROW_ROUTE(app, "/get_only")
.methods("GET"_method)([](const request& /*req*/) { return "get"; });
.methods("GET"_method)([](const request& /*req*/) {
return "get";
});
CROW_ROUTE(app, "/post_only")
.methods("POST"_method)([](const request& /*req*/) { return "post"; });
.methods("POST"_method)([](const request& /*req*/) {
return "post";
});
CROW_ROUTE(app, "/patch_only")
.methods("PATCH"_method)([](const request& /*req*/) { return "patch"; });
.methods("PATCH"_method)([](const request& /*req*/) {
return "patch";
});
CROW_ROUTE(app, "/purge_only")
.methods("PURGE"_method)([](const request& /*req*/) { return "purge"; });
.methods("PURGE"_method)([](const request& /*req*/) {
return "purge";
});
app.validate();
app.debug_print();
@ -437,11 +456,15 @@ TEST_CASE("server_handling_error_request")
static char buf[2048];
SimpleApp app;
CROW_ROUTE(app, "/")
([] { return "A"; });
([] {
return "A";
});
// Server<SimpleApp> server(&app, LOCALHOST_ADDRESS, 45451);
// auto _ = async(launch::async, [&]{server.run();});
auto _ = async(launch::async,
[&] { app.bindaddr(LOCALHOST_ADDRESS).port(45451).run(); });
[&] {
app.bindaddr(LOCALHOST_ADDRESS).port(45451).run();
});
app.wait_for_server_start();
std::string sendmsg = "POX";
asio::io_service is;
@ -470,9 +493,13 @@ TEST_CASE("server_handling_error_request_http_version")
static char buf[2048];
SimpleApp app;
CROW_ROUTE(app, "/")
([] { return "A"; });
([] {
return "A";
});
auto _ = async(launch::async,
[&] { app.bindaddr(LOCALHOST_ADDRESS).port(45451).run(); });
[&] {
app.bindaddr(LOCALHOST_ADDRESS).port(45451).run();
});
app.wait_for_server_start();
std::string sendmsg = "POST /\r\nContent-Length:3\r\nX-HeaderTest: 123\r\n\r\nA=B\r\n";
asio::io_service is;
@ -501,14 +528,22 @@ TEST_CASE("multi_server")
static char buf[2048];
SimpleApp app1, app2;
CROW_ROUTE(app1, "/").methods("GET"_method,
"POST"_method)([] { return "A"; });
"POST"_method)([] {
return "A";
});
CROW_ROUTE(app2, "/").methods("GET"_method,
"POST"_method)([] { return "B"; });
"POST"_method)([] {
return "B";
});
auto _ = async(launch::async,
[&] { app1.bindaddr(LOCALHOST_ADDRESS).port(45451).run(); });
[&] {
app1.bindaddr(LOCALHOST_ADDRESS).port(45451).run();
});
auto _2 = async(launch::async,
[&] { app2.bindaddr(LOCALHOST_ADDRESS).port(45452).run(); });
[&] {
app2.bindaddr(LOCALHOST_ADDRESS).port(45452).run();
});
app1.wait_for_server_start();
app2.wait_for_server_start();
@ -1161,9 +1196,10 @@ TEST_CASE("middleware_simple")
decltype(app)::server_t server(&app, LOCALHOST_ADDRESS, 45451);
CROW_ROUTE(app, "/")
([&](const crow::request& req) {
app.get_context<NullMiddleware>(req);
app.get_context<NullSimpleMiddleware>(req);
return ""; });
app.get_context<NullMiddleware>(req);
app.get_context<NullSimpleMiddleware>(req);
return "";
});
}
struct IntSettingMiddleware
@ -1256,27 +1292,31 @@ TEST_CASE("middleware_context")
int x{};
CROW_ROUTE(app, "/")
([&](const request& req) {
{
auto& ctx = app.get_context<IntSettingMiddleware>(req);
x = ctx.val;
}
{
auto& ctx = app.get_context<FirstMW>(req);
ctx.v.push_back("handle");
}
{
auto& ctx = app.get_context<IntSettingMiddleware>(req);
x = ctx.val;
}
{
auto& ctx = app.get_context<FirstMW>(req);
ctx.v.push_back("handle");
}
return ""; });
return "";
});
CROW_ROUTE(app, "/break")
([&](const request& req) {
{
auto& ctx = app.get_context<FirstMW>(req);
ctx.v.push_back("handle");
}
{
auto& ctx = app.get_context<FirstMW>(req);
ctx.v.push_back("handle");
}
return ""; });
return "";
});
auto _ = async(launch::async,
[&] { app.bindaddr(LOCALHOST_ADDRESS).port(45451).run(); });
[&] {
app.bindaddr(LOCALHOST_ADDRESS).port(45451).run();
});
app.wait_for_server_start();
std::string sendmsg = "GET /\r\n\r\n";
asio::io_service is;
@ -1337,18 +1377,21 @@ TEST_CASE("middleware_cookieparser")
CROW_ROUTE(app, "/")
([&](const request& req) {
{
auto& ctx = app.get_context<CookieParser>(req);
value1 = ctx.get_cookie("key1");
value2 = ctx.get_cookie("key2");
value3 = ctx.get_cookie("key3");
value4 = ctx.get_cookie("key4");
}
{
auto& ctx = app.get_context<CookieParser>(req);
value1 = ctx.get_cookie("key1");
value2 = ctx.get_cookie("key2");
value3 = ctx.get_cookie("key3");
value4 = ctx.get_cookie("key4");
}
return ""; });
return "";
});
auto _ = async(launch::async,
[&] { app.bindaddr(LOCALHOST_ADDRESS).port(45451).run(); });
[&] {
app.bindaddr(LOCALHOST_ADDRESS).port(45451).run();
});
app.wait_for_server_start();
std::string sendmsg =
"GET /\r\nCookie: key1=value1; key2=\"val=ue2\"; key3=\"val\"ue3\"; "
@ -1380,10 +1423,14 @@ TEST_CASE("bug_quick_repeated_request")
SimpleApp app;
CROW_ROUTE(app, "/")
([&] { return "hello"; });
([&] {
return "hello";
});
auto _ = async(launch::async,
[&] { app.bindaddr(LOCALHOST_ADDRESS).port(45451).run(); });
[&] {
app.bindaddr(LOCALHOST_ADDRESS).port(45451).run();
});
app.wait_for_server_start();
std::string sendmsg = "GET / HTTP/1.1\r\nHost: localhost\r\n\r\n";
asio::io_service is;
@ -1392,17 +1439,19 @@ TEST_CASE("bug_quick_repeated_request")
for (int i = 0; i < 5; i++)
{
v.push_back(async(launch::async, [&] {
asio::ip::tcp::socket c(is);
c.connect(asio::ip::tcp::endpoint(
asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
asio::ip::tcp::socket c(is);
c.connect(asio::ip::tcp::endpoint(
asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
for (int j = 0; j < 5; j++) {
c.send(asio::buffer(sendmsg));
for (int j = 0; j < 5; j++)
{
c.send(asio::buffer(sendmsg));
size_t received = c.receive(asio::buffer(buf, 2048));
CHECK("hello" == std::string(buf + received - 5, buf + received));
}
c.close(); }));
size_t received = c.receive(asio::buffer(buf, 2048));
CHECK("hello" == std::string(buf + received - 5, buf + received));
}
c.close();
}));
}
}
app.stop();
@ -1418,13 +1467,16 @@ TEST_CASE("simple_url_params")
CROW_ROUTE(app, "/params")
([&last_url_params](const crow::request& req) {
last_url_params = std::move(req.url_params);
return "OK"; });
last_url_params = std::move(req.url_params);
return "OK";
});
/// params?h=1&foo=bar&lol&count[]=1&count[]=4&pew=5.2
auto _ = async(launch::async,
[&] { app.bindaddr(LOCALHOST_ADDRESS).port(45451).run(); });
[&] {
app.bindaddr(LOCALHOST_ADDRESS).port(45451).run();
});
app.wait_for_server_start();
asio::io_service is;
std::string sendmsg;
@ -1578,23 +1630,29 @@ TEST_CASE("route_dynamic")
SimpleApp app;
int x = 1;
app.route_dynamic("/")([&] {
x = 2;
return ""; });
x = 2;
return "";
});
app.route_dynamic("/set4")([&](const request&) {
x = 4;
return ""; });
x = 4;
return "";
});
app.route_dynamic("/set5")([&](const request&, response& res) {
x = 5;
res.end(); });
x = 5;
res.end();
});
app.route_dynamic("/set_int/<int>")([&](int y) {
x = y;
return ""; });
x = y;
return "";
});
try
{
app.route_dynamic("/invalid_test/<double>/<path>")([]() { return ""; });
app.route_dynamic("/invalid_test/<double>/<path>")([]() {
return "";
});
FAIL_CHECK();
}
catch (std::exception&)
@ -1647,10 +1705,11 @@ TEST_CASE("multipart")
CROW_ROUTE(app, "/multipart")
([](const crow::request& req, crow::response& res) {
multipart::message msg(req);
res.add_header("Content-Type", "multipart/form-data; boundary=CROW-BOUNDARY");
res.body = msg.dump();
res.end(); });
multipart::message msg(req);
res.add_header("Content-Type", "multipart/form-data; boundary=CROW-BOUNDARY");
res.body = msg.dump();
res.end();
});
app.validate();
@ -1678,14 +1737,16 @@ TEST_CASE("send_file")
CROW_ROUTE(app, "/jpg")
([](const crow::request&, crow::response& res) {
res.set_static_file_info("tests/img/cat.jpg");
res.end(); });
res.set_static_file_info("tests/img/cat.jpg");
res.end();
});
CROW_ROUTE(app, "/jpg2")
([](const crow::request&, crow::response& res) {
res.set_static_file_info(
"tests/img/cat2.jpg"); // This file is nonexistent on purpose
res.end(); });
res.set_static_file_info(
"tests/img/cat2.jpg"); // This file is nonexistent on purpose
res.end();
});
app.validate();
@ -1736,61 +1797,63 @@ TEST_CASE("stream_response")
CROW_ROUTE(app, "/test")
([&key_response](const crow::request&, crow::response& res) {
res.body = key_response;
res.end(); });
res.body = key_response;
res.end();
});
app.validate();
//running the test on a separate thread to allow the client to sleep
std::thread runTest([&app, &key_response, key_response_size]() {
auto _ = async(launch::async,
[&] {
app.bindaddr(LOCALHOST_ADDRESS).port(45451).run();
});
app.wait_for_server_start();
asio::io_service is;
std::string sendmsg;
auto _ = async(launch::async,
[&] { app.bindaddr(LOCALHOST_ADDRESS).port(45451).run(); });
app.wait_for_server_start();
asio::io_service is;
std::string sendmsg;
//Total bytes received
unsigned int received = 0;
sendmsg = "GET /test\r\n\r\n";
{
asio::streambuf b;
//Total bytes received
unsigned int received = 0;
sendmsg = "GET /test\r\n\r\n";
{
asio::streambuf b;
asio::ip::tcp::socket c(is);
c.connect(asio::ip::tcp::endpoint(
asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
c.send(asio::buffer(sendmsg));
asio::ip::tcp::socket c(is);
c.connect(asio::ip::tcp::endpoint(
asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
c.send(asio::buffer(sendmsg));
//consuming the headers, since we don't need those for the test
static char buf[2048];
size_t received_headers_bytes = 0;
//consuming the headers, since we don't need those for the test
static char buf[2048];
size_t received_headers_bytes = 0;
// magic number is 102 (it's the size of the headers, which is how much this line below needs to read)
const size_t headers_bytes = 102;
while (received_headers_bytes < headers_bytes)
received_headers_bytes += c.receive(asio::buffer(buf, 2048));
received += received_headers_bytes - headers_bytes; //add any extra that might have been received to the proper received count
// magic number is 102 (it's the size of the headers, which is how much this line below needs to read)
const size_t headers_bytes = 102;
while (received_headers_bytes < headers_bytes)
received_headers_bytes += c.receive(asio::buffer(buf, 2048));
received += received_headers_bytes - headers_bytes; //add any extra that might have been received to the proper received count
while (received < key_response_size)
{
asio::streambuf::mutable_buffers_type bufs = b.prepare(16384);
while (received < key_response_size)
{
asio::streambuf::mutable_buffers_type bufs = b.prepare(16384);
size_t n = c.receive(bufs);
b.commit(n);
received += n;
size_t n = c.receive(bufs);
b.commit(n);
received += n;
std::istream is(&b);
std::string s;
is >> s;
std::istream is(&b);
std::string s;
is >> s;
CHECK(key_response.substr(received-n, n) == s);
CHECK(key_response.substr(received - n, n) == s);
std::this_thread::sleep_for(std::chrono::milliseconds(20));
}
}
app.stop(); });
std::this_thread::sleep_for(std::chrono::milliseconds(20));
}
}
app.stop();
});
runTest.join();
} // stream_response
@ -1803,20 +1866,28 @@ TEST_CASE("websocket")
SimpleApp app;
CROW_ROUTE(app, "/ws").websocket().onopen([&](websocket::connection&) {
connected = true;
CROW_LOG_INFO << "Connected websocket and value is " << connected; }).onmessage([&](websocket::connection& conn, const std::string& message, bool isbin) {
CROW_LOG_INFO << "Message is \"" << message << '\"';
if (!isbin && message == "PINGME")
conn.send_ping("");
else if (!isbin && message == "Hello")
conn.send_text("Hello back");
else if (isbin && message == "Hello bin")
conn.send_binary("Hello back bin"); }).onclose([&](websocket::connection&, const std::string&) { CROW_LOG_INFO << "Closing websocket"; });
connected = true;
CROW_LOG_INFO << "Connected websocket and value is " << connected;
})
.onmessage([&](websocket::connection& conn, const std::string& message, bool isbin) {
CROW_LOG_INFO << "Message is \"" << message << '\"';
if (!isbin && message == "PINGME")
conn.send_ping("");
else if (!isbin && message == "Hello")
conn.send_text("Hello back");
else if (isbin && message == "Hello bin")
conn.send_binary("Hello back bin");
})
.onclose([&](websocket::connection&, const std::string&) {
CROW_LOG_INFO << "Closing websocket";
});
app.validate();
auto _ = async(launch::async,
[&] { app.bindaddr(LOCALHOST_ADDRESS).port(45451).run(); });
[&] {
app.bindaddr(LOCALHOST_ADDRESS).port(45451).run();
});
app.wait_for_server_start();
asio::io_service is;
@ -1962,28 +2033,38 @@ TEST_CASE("zlib_compression")
// test deflate
CROW_ROUTE(app_deflate, "/test_compress")
([&]() { return expected_string; });
([&]() {
return expected_string;
});
CROW_ROUTE(app_deflate, "/test")
([&](const request&, response& res) {
res.compressed = false;
res.body = expected_string;
res.end(); });
res.end();
});
// test gzip
CROW_ROUTE(app_gzip, "/test_compress")
([&]() { return expected_string; });
([&]() {
return expected_string;
});
CROW_ROUTE(app_gzip, "/test")
([&](const request&, response& res) {
res.compressed = false;
res.body = expected_string;
res.end(); });
res.end();
});
auto t1 = async(launch::async, [&] { app_deflate.bindaddr(LOCALHOST_ADDRESS).port(45451).use_compression(compression::algorithm::DEFLATE).run(); });
auto t2 = async(launch::async, [&] { app_gzip.bindaddr(LOCALHOST_ADDRESS).port(45452).use_compression(compression::algorithm::GZIP).run(); });
auto t1 = async(launch::async, [&] {
app_deflate.bindaddr(LOCALHOST_ADDRESS).port(45451).use_compression(compression::algorithm::DEFLATE).run();
});
auto t2 = async(launch::async, [&] {
app_gzip.bindaddr(LOCALHOST_ADDRESS).port(45452).use_compression(compression::algorithm::GZIP).run();
});
app_deflate.wait_for_server_start();
app_gzip.wait_for_server_start();
@ -2146,13 +2227,19 @@ TEST_CASE("catchall")
SimpleApp app2;
CROW_ROUTE(app, "/place")
([]() { return "place"; });
([]() {
return "place";
});
CROW_CATCHALL_ROUTE(app)
([](response& res) { res.body = "!place"; });
([](response& res) {
res.body = "!place";
});
CROW_ROUTE(app2, "/place")
([]() { return "place"; });
([]() {
return "place";
});
app.validate();
app2.validate();
@ -2212,16 +2299,24 @@ TEST_CASE("blueprint")
crow::Blueprint sub_sub_bp("bp3");
CROW_BP_ROUTE(sub_bp, "/hello")
([]() { return "Hello world!"; });
([]() {
return "Hello world!";
});
CROW_BP_ROUTE(bp_not_sub, "/hello")
([]() { return "Hello world!"; });
([]() {
return "Hello world!";
});
CROW_BP_ROUTE(sub_sub_bp, "/hi")
([]() { return "Hi world!"; });
([]() {
return "Hi world!";
});
CROW_BP_CATCHALL_ROUTE(sub_bp)
([]() { return response(200, "WRONG!!"); });
([]() {
return response(200, "WRONG!!");
});
app.register_blueprint(bp);
app.register_blueprint(bp_not_sub);
@ -2347,7 +2442,9 @@ TEST_CASE("get_port")
const std::uint16_t port = 12345;
std::thread runTest([&]() { app.port(port).run(); });
std::thread runTest([&]() {
app.port(port).run();
});
app.wait_for_server_start();
CHECK(app.port() == port);
@ -2364,9 +2461,13 @@ TEST_CASE("timeout")
SimpleApp app;
CROW_ROUTE(app, "/")
([]() { return "hello"; });
([]() {
return "hello";
});
auto _ = async(launch::async, [&] { app.bindaddr(LOCALHOST_ADDRESS).timeout(timeout).port(45451).run(); });
auto _ = async(launch::async, [&] {
app.bindaddr(LOCALHOST_ADDRESS).timeout(timeout).port(45451).run();
});
app.wait_for_server_start();
asio::io_service is;
std::string sendmsg = "GET /\r\n\r\n";
@ -2378,9 +2479,10 @@ TEST_CASE("timeout")
asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
auto receive_future = async(launch::async, [&]() {
boost::system::error_code ec;
c.receive(asio::buffer(buf, 2048), 0, ec);
return ec; });
boost::system::error_code ec;
c.receive(asio::buffer(buf, 2048), 0, ec);
return ec;
});
status = receive_future.wait_for(std::chrono::seconds(timeout - 1));
CHECK(status == future_status::timeout);
@ -2397,9 +2499,10 @@ TEST_CASE("timeout")
size_t received;
auto receive_future = async(launch::async, [&]() {
boost::system::error_code ec;
received = c.receive(asio::buffer(buf, 2048), 0, ec);
return ec; });
boost::system::error_code ec;
received = c.receive(asio::buffer(buf, 2048), 0, ec);
return ec;
});
status = receive_future.wait_for(std::chrono::seconds(timeout - 1));
CHECK(status == future_status::timeout);
@ -2426,7 +2529,9 @@ TEST_CASE("task_timer")
boost::asio::io_service io_service;
work_guard_type work_guard(io_service.get_executor());
thread io_thread([&io_service]() { io_service.run(); });
thread io_thread([&io_service]() {
io_service.run();
});
bool a = false;
bool b = false;
@ -2436,9 +2541,13 @@ TEST_CASE("task_timer")
timer.set_default_timeout(7);
CHECK(timer.get_default_timeout() == 7);
timer.schedule([&a]() { a = true; },
timer.schedule([&a]() {
a = true;
},
5);
timer.schedule([&b]() { b = true; });
timer.schedule([&b]() {
b = true;
});
this_thread::sleep_for(chrono::seconds(4));
CHECK(a == false);