Skip to content

Commit

Permalink
Made catchall work with 404 or 405 errors
Browse files Browse the repository at this point in the history
snuck in a fix for release.py where version name wouldn't change
also snuck in slight improvement in finding blueprint (removed extra if statement)
  • Loading branch information
The-EDev committed Aug 21, 2021
1 parent a3ef00f commit 576690b
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 42 deletions.
15 changes: 11 additions & 4 deletions examples/example_catchall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,17 @@ int main()

//Setting a custom route for any URL that isn't defined, instead of a simple 404.
CROW_CATCHALL_ROUTE(app)
([](crow::response& res) {
res.body = "The URL does not seem to be correct.";
res.end();
});
([](crow::response& res) {
if (res.code == 404)
{
res.body = "The URL does not seem to be correct.";
}
else if (res.code == 405)
{
res.body = "The HTTP method does not seem to be correct.";
}
res.end();
});

app.port(18080).run();
}
74 changes: 40 additions & 34 deletions include/crow/routing.h
Original file line number Diff line number Diff line change
Expand Up @@ -1496,16 +1496,15 @@ namespace crow
}
else
{
if (!found_bps.empty())
found_bps.pop_back();

if (found_bps.empty())
if (found_bps.size() < 2)
{
found_bps.clear();
found_bps.push_back(blueprints_[bp_i[index]]);
get_found_bp(bp_i, found_bps.back()->blueprints_, found_bps, ++index);
}
else
{
found_bps.pop_back();
Blueprint* last_element = found_bps.back();
found_bps.push_back(last_element->blueprints_[bp_i[index]]);
get_found_bp(bp_i, found_bps.back()->blueprints_, found_bps, ++index);
Expand All @@ -1514,6 +1513,37 @@ namespace crow
}
}

/// Is used to handle errors, you insert the error code, found route, request, and response. and it'll either call the appropriate catchall route (considering the blueprint system) and send you a status string (which is mainly used for debug messages), or just set the response code to the proper error code.
std::string get_error(unsigned short code, std::tuple<uint16_t, std::vector<uint16_t>, routing_params>& found, const request& req, response& res)
{
res.code = code;
std::vector<Blueprint*> bps_found;
get_found_bp(std::get<1>(found), blueprints_, bps_found);
for (int i = bps_found.size()-1; i > 0; i--)
{
std::vector<uint16_t> bpi = std::get<1>(found);
if (bps_found[i]->catchall_rule().has_handler())
{
bps_found[i]->catchall_rule().handler_(req, res);
#ifdef CROW_ENABLE_DEBUG
return std::string("Redirected to Blueprint \"" + bps_found[i]->prefix() + "\" Catchall rule");
#else
return std::string();
#endif
}
}
if (catchall_rule_.has_handler())
{
catchall_rule_.handler_(req, res);
#ifdef CROW_ENABLE_DEBUG
return std::string("Redirected to global Catchall rule");
#else
return std::string();
#endif
}
return std::string();
}

void handle(const request& req, response& res)
{
HTTPMethod method_actual = req.method;
Expand Down Expand Up @@ -1584,42 +1614,18 @@ namespace crow
{
for (auto& per_method: per_methods_)
{
if (std::get<0>(per_method.trie.find(req.url)))
if (std::get<0>(per_method.trie.find(req.url))) //Route found, but in another method
{
CROW_LOG_DEBUG << "Cannot match method " << req.url << " " << method_name(method_actual);
res = response(405);
std::string error_message(get_error(405, found, req, res));
CROW_LOG_DEBUG << "Cannot match method " << req.url << " " << method_name(method_actual) << ". " << error_message;
res.end();
return;
}
}
//Route does not exist anywhere

std::vector<Blueprint*> bps_found;
get_found_bp(std::get<1>(found), blueprints_, bps_found);
bool no_bp_catchall = true;
for (int i = bps_found.size()-1; i > 0; i--)
{
std::vector<uint16_t> bpi = std::get<1>(found);
if (bps_found[i]->catchall_rule().has_handler())
{
no_bp_catchall = false;
CROW_LOG_DEBUG << "Cannot match rules " << req.url << ". Redirecting to Blueprint \"" << bps_found[i]->prefix() << "\" Catchall rule";
bps_found[i]->catchall_rule().handler_(req, res);
break;
}
}
if (no_bp_catchall)
{
if (catchall_rule_.has_handler())
{
CROW_LOG_DEBUG << "Cannot match rules " << req.url << ". Redirecting to global Catchall rule";
catchall_rule_.handler_(req, res);
}
else
{
CROW_LOG_DEBUG << "Cannot match rules " << req.url;
res = response(404);
}
}
std::string error_message(get_error(404, found, req, res));
CROW_LOG_DEBUG << "Cannot match rules " << req.url << ". " << error_message;
res.end();
return;
}
Expand Down
4 changes: 2 additions & 2 deletions scripts/release.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@
os.mkdir(releasePath)
os.chdir(releasePath)
os.system("cmake -DBUILD_EXAMPLES=OFF -DBUILD_TESTING=OFF -DCPACK_PACKAGE_FILE_NAME=\"crow-{}\" .. && make -j5".format(version))
os.system("sed -i 's/constexpr char VERSION\\[\\] = \"master\";/constexpr char VERSION\\[\\] = \"{}\";/g' crow_all.h".format(version))
os.system("cpack")
os.system("sed -i 's/char VERSION\\[\\] = \"master\";/char VERSION\\[\\] = \"{}\";/g' crow_all.h".format(version))
os.system("cpack -R {}".format(version))
5 changes: 3 additions & 2 deletions tests/unittest.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#define CATCH_CONFIG_MAIN
#define CROW_ENABLE_COMPRESSION
#define CROW_ENABLE_DEBUG
#define CROW_LOG_LEVEL 0
#define CROW_MAIN
#include <sys/stat.h>
Expand Down Expand Up @@ -2094,7 +2095,7 @@ TEST_CASE("catchall")

CROW_ROUTE(app, "/place")([](){return "place";});

CROW_CATCHALL_ROUTE(app)([](){return "!place";});
CROW_CATCHALL_ROUTE(app)([](response& res){res.body = "!place";});

CROW_ROUTE(app2, "/place")([](){return "place";});

Expand All @@ -2120,7 +2121,7 @@ TEST_CASE("catchall")

app.handle(req, res);

CHECK(200 == res.code);
CHECK(404 == res.code);
CHECK("!place" == res.body);
}

Expand Down

0 comments on commit 576690b

Please sign in to comment.