aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--amalgamate/crow_all.h24
-rw-r--r--examples/example_chat.cpp1
-rw-r--r--include/routing.h20
-rw-r--r--include/utility.h4
-rw-r--r--tests/unittest.cpp78
5 files changed, 116 insertions, 11 deletions
diff --git a/amalgamate/crow_all.h b/amalgamate/crow_all.h
index a567b5a..43a3af4 100644
--- a/amalgamate/crow_all.h
+++ b/amalgamate/crow_all.h
@@ -67,7 +67,9 @@ namespace crow
constexpr bool is_equ_p(const char* a, const char* b, unsigned n)
{
return
- *a == 0 || *b == 0
+ *a == 0 && *b == 0 && n == 0
+ ? true :
+ (*a == 0 || *b == 0)
? false :
n == 0
? true :
@@ -6113,8 +6115,13 @@ namespace crow
virtual void handle(const request&, response&, const routing_params&) = 0;
- protected:
+ uint32_t methods()
+ {
+ return methods_;
+ }
+ protected:
+ uint32_t methods_{1<<(int)HTTPMethod::GET};
};
template <typename ... Args>
@@ -6234,6 +6241,7 @@ namespace crow
self_t& methods(HTTPMethod method)
{
methods_ = 1<<(int)method;
+ return *this;
}
template <typename ... MethodArgs>
@@ -6241,6 +6249,7 @@ namespace crow
{
methods(args_method...);
methods_ |= 1<<(int)method;
+ return *this;
}
void validate()
@@ -6344,7 +6353,6 @@ namespace crow
std::string rule_;
std::string name_;
- uint32_t methods_{1<<(int)HTTPMethod::GET};
template <typename T, int Pos>
struct call_pair
@@ -6725,7 +6733,15 @@ public:
if (rule_index >= rules_.size())
throw std::runtime_error("Trie internal structure corrupted!");
- CROW_LOG_DEBUG << "Matched rule '" << ((TaggedRule<>*)rules_[rule_index].get())->rule_ << "'";
+ if ((rules_[rule_index]->methods() & (1<<(uint32_t)req.method)) == 0)
+ {
+ CROW_LOG_DEBUG << "Rule found but method mismatch: " << req.url << " with " << method_name(req.method) << "(" << (uint32_t)req.method << ") / " << rules_[rule_index]->methods();
+ res = response(404);
+ res.end();
+ return;
+ }
+
+ CROW_LOG_DEBUG << "Matched rule '" << ((TaggedRule<>*)rules_[rule_index].get())->rule_ << "' " << (uint32_t)req.method << " / " << rules_[rule_index]->methods();
rules_[rule_index]->handle(req, res, found.second);
}
diff --git a/examples/example_chat.cpp b/examples/example_chat.cpp
index 31f16c5..aa7cc96 100644
--- a/examples/example_chat.cpp
+++ b/examples/example_chat.cpp
@@ -79,6 +79,7 @@ int main()
});
CROW_ROUTE(app, "/send")
+ .methods("GET"_method, "POST"_method)
([](const crow::request& req)
{
CROW_LOG_INFO << "msg from client: " << req.body;
diff --git a/include/routing.h b/include/routing.h
index ca88192..87d492b 100644
--- a/include/routing.h
+++ b/include/routing.h
@@ -26,8 +26,13 @@ namespace crow
virtual void handle(const request&, response&, const routing_params&) = 0;
- protected:
+ uint32_t methods()
+ {
+ return methods_;
+ }
+ protected:
+ uint32_t methods_{1<<(int)HTTPMethod::GET};
};
template <typename ... Args>
@@ -147,6 +152,7 @@ namespace crow
self_t& methods(HTTPMethod method)
{
methods_ = 1<<(int)method;
+ return *this;
}
template <typename ... MethodArgs>
@@ -154,6 +160,7 @@ namespace crow
{
methods(args_method...);
methods_ |= 1<<(int)method;
+ return *this;
}
void validate()
@@ -257,7 +264,6 @@ namespace crow
std::string rule_;
std::string name_;
- uint32_t methods_{1<<(int)HTTPMethod::GET};
template <typename T, int Pos>
struct call_pair
@@ -638,7 +644,15 @@ public:
if (rule_index >= rules_.size())
throw std::runtime_error("Trie internal structure corrupted!");
- CROW_LOG_DEBUG << "Matched rule '" << ((TaggedRule<>*)rules_[rule_index].get())->rule_ << "'";
+ if ((rules_[rule_index]->methods() & (1<<(uint32_t)req.method)) == 0)
+ {
+ CROW_LOG_DEBUG << "Rule found but method mismatch: " << req.url << " with " << method_name(req.method) << "(" << (uint32_t)req.method << ") / " << rules_[rule_index]->methods();
+ res = response(404);
+ res.end();
+ return;
+ }
+
+ CROW_LOG_DEBUG << "Matched rule '" << ((TaggedRule<>*)rules_[rule_index].get())->rule_ << "' " << (uint32_t)req.method << " / " << rules_[rule_index]->methods();
rules_[rule_index]->handle(req, res, found.second);
}
diff --git a/include/utility.h b/include/utility.h
index b2e61f1..c910eb2 100644
--- a/include/utility.h
+++ b/include/utility.h
@@ -67,7 +67,9 @@ namespace crow
constexpr bool is_equ_p(const char* a, const char* b, unsigned n)
{
return
- *a == 0 || *b == 0
+ *a == 0 && *b == 0 && n == 0
+ ? true :
+ (*a == 0 || *b == 0)
? false :
n == 0
? true :
diff --git a/tests/unittest.cpp b/tests/unittest.cpp
index 87acb52..1a15742 100644
--- a/tests/unittest.cpp
+++ b/tests/unittest.cpp
@@ -250,6 +250,79 @@ TEST(handler_with_response)
});
}
+TEST(http_method)
+{
+ SimpleApp app;
+
+ CROW_ROUTE(app, "/")
+ .methods("POST"_method, "GET"_method)
+ ([](const request& req){
+ if (req.method == "GET"_method)
+ return "2";
+ else
+ return "1";
+ });
+
+ CROW_ROUTE(app, "/get_only")
+ .methods("GET"_method)
+ ([](const request& req){
+ return "get";
+ });
+ CROW_ROUTE(app, "/post_only")
+ .methods("POST"_method)
+ ([](const request& req){
+ return "post";
+ });
+
+
+ // cannot have multiple handlers for the same url
+ //CROW_ROUTE(app, "/")
+ //.methods("GET"_method)
+ //([]{ return "2"; });
+
+ {
+ request req;
+ response res;
+
+ req.url = "/";
+ app.handle(req, res);
+
+ ASSERT_EQUAL("2", res.body);
+ }
+ {
+ request req;
+ response res;
+
+ req.url = "/";
+ req.method = "POST"_method;
+ app.handle(req, res);
+
+ ASSERT_EQUAL("1", res.body);
+ }
+
+ {
+ request req;
+ response res;
+
+ req.url = "/get_only";
+ app.handle(req, res);
+
+ ASSERT_EQUAL("get", res.body);
+ }
+
+ {
+ request req;
+ response res;
+
+ req.url = "/get_only";
+ req.method = "POST"_method;
+ app.handle(req, res);
+
+ ASSERT_NOTEQUAL("get", res.body);
+ }
+
+}
+
TEST(server_handling_error_request)
{
static char buf[2048];
@@ -283,8 +356,8 @@ TEST(multi_server)
{
static char buf[2048];
SimpleApp app1, app2;
- CROW_ROUTE(app1, "/")([]{return "A";});
- CROW_ROUTE(app2, "/")([]{return "B";});
+ CROW_ROUTE(app1, "/").methods("GET"_method, "POST"_method)([]{return "A";});
+ CROW_ROUTE(app2, "/").methods("GET"_method, "POST"_method)([]{return "B";});
Server<SimpleApp> server1(&app1, 45451);
Server<SimpleApp> server2(&app2, 45452);
@@ -298,7 +371,6 @@ TEST(multi_server)
asio::ip::tcp::socket c(is);
c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), 45451));
-
c.send(asio::buffer(sendmsg));
size_t recved = c.receive(asio::buffer(buf, 2048));