aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--example.cpp8
-rw-r--r--http_response.h18
-rw-r--r--routing.h66
-rw-r--r--test.py1
-rw-r--r--unittest.cpp8
5 files changed, 88 insertions, 13 deletions
diff --git a/example.cpp b/example.cpp
index 5491ba2..57f8e09 100644
--- a/example.cpp
+++ b/example.cpp
@@ -42,6 +42,14 @@ int main()
return crow::response(os.str());
});
+ CROW_ROUTE(app,"/add/<int>/<int>")
+ ([](const crow::request& req, crow::response& res, int a, int b){
+ std::ostringstream os;
+ os << a+b;
+ res.send(os.str());
+ res.end();
+ });
+
// Compile error with message "Handler type is mismatched with URL paramters"
//CROW_ROUTE(app,"/another/<int>")
//([](int a, int b){
diff --git a/http_response.h b/http_response.h
index 392fe9c..eff1d0f 100644
--- a/http_response.h
+++ b/http_response.h
@@ -11,16 +11,19 @@ namespace crow
json::wvalue json_value;
int code{200};
std::unordered_map<std::string, std::string> headers;
+
response() {}
explicit response(int code) : code(code) {}
response(std::string body) : body(std::move(body)) {}
response(json::wvalue&& json_value) : json_value(std::move(json_value)) {}
response(const json::wvalue& json_value) : body(json::dump(json_value)) {}
response(int code, std::string body) : body(std::move(body)), code(code) {}
+
response(response&& r)
{
*this = std::move(r);
}
+
response& operator = (response&& r)
{
body = std::move(r.body);
@@ -29,5 +32,20 @@ namespace crow
headers = std::move(r.headers);
return *this;
}
+
+ void send(const std::string& body_part)
+ {
+ body += body_part;
+ }
+
+ void end()
+ {
+ }
+
+ void end(const std::string& body_part)
+ {
+ body += body_part;
+ end();
+ }
};
}
diff --git a/routing.h b/routing.h
index 3a8b7ab..36891f1 100644
--- a/routing.h
+++ b/routing.h
@@ -34,11 +34,12 @@ namespace crow
class TaggedRule : public BaseRule
{
private:
- template <typename H1, typename H2>
+ template <typename H1, typename H2, typename H3>
struct call_params
{
H1& handler;
H2& handler_with_req;
+ H3& handler_with_req_res;
const routing_params& params;
const request& req;
};
@@ -106,6 +107,16 @@ namespace crow
cparams.req,
cparams.params.template get<typename Args1::type>(Args1::pos)...
);
+ if (cparams.handler_with_req_res)
+ {
+ crow::response res;
+ cparams.handler_with_req_res(
+ cparams.req,
+ res,
+ cparams.params.template get<typename Args1::type>(Args1::pos)...
+ );
+ return res;
+ }
#ifdef CROW_ENABLE_LOGGING
std::cerr << "ERROR cannot find handler" << std::endl;
#endif
@@ -139,7 +150,7 @@ namespace crow
void validate()
{
- if (!handler_ && !handler_with_req_)
+ if (!handler_ && !handler_with_req_ && !handler_with_req_res_)
{
throw std::runtime_error(name_ + (!name_.empty() ? ": " : "") + "no handler for url " + rule_);
}
@@ -150,8 +161,7 @@ namespace crow
operator()(Func&& f)
{
static_assert(black_magic::CallHelper<Func, black_magic::S<Args...>>::value ||
- black_magic::CallHelper<Func, black_magic::S<crow::request, Args...>>::value
- ,
+ black_magic::CallHelper<Func, black_magic::S<crow::request, Args...>>::value ,
"Handler type is mismatched with URL paramters");
static_assert(!std::is_same<void, decltype(f(std::declval<Args>()...))>::value,
"Handler function cannot have void return type; valid return types: string, int, crow::resposne, crow::json::wvalue");
@@ -160,23 +170,50 @@ namespace crow
return response(f(args...));
};
handler_with_req_ = nullptr;
+ handler_with_req_res_ = nullptr;
}
template <typename Func>
- typename std::enable_if<!black_magic::CallHelper<Func, black_magic::S<Args...>>::value, void>::type
+ typename std::enable_if<
+ !black_magic::CallHelper<Func, black_magic::S<Args...>>::value &&
+ black_magic::CallHelper<Func, black_magic::S<crow::request, Args...>>::value,
+ void>::type
operator()(Func&& f)
{
static_assert(black_magic::CallHelper<Func, black_magic::S<Args...>>::value ||
- black_magic::CallHelper<Func, black_magic::S<crow::request, Args...>>::value
- ,
+ black_magic::CallHelper<Func, black_magic::S<crow::request, Args...>>::value,
"Handler type is mismatched with URL paramters");
static_assert(!std::is_same<void, decltype(f(std::declval<crow::request>(), std::declval<Args>()...))>::value,
"Handler function cannot have void return type; valid return types: string, int, crow::resposne, crow::json::wvalue");
- handler_with_req_ = [f = std::move(f)](const crow::request& request, Args ... args){
- return response(f(request, args...));
+ handler_with_req_ = [f = std::move(f)](const crow::request& req, Args ... args){
+ return response(f(req, args...));
};
handler_ = nullptr;
+ handler_with_req_res_ = nullptr;
+ }
+
+ template <typename Func>
+ typename std::enable_if<
+ !black_magic::CallHelper<Func, black_magic::S<Args...>>::value &&
+ !black_magic::CallHelper<Func, black_magic::S<crow::request, Args...>>::value,
+ void>::type
+ operator()(Func&& f)
+ {
+ static_assert(black_magic::CallHelper<Func, black_magic::S<Args...>>::value ||
+ black_magic::CallHelper<Func, black_magic::S<crow::request, Args...>>::value ||
+ black_magic::CallHelper<Func, black_magic::S<crow::request, crow::response&, Args...>>::value
+ ,
+ "Handler type is mismatched with URL paramters");
+ static_assert(std::is_same<void, decltype(f(std::declval<crow::request>(), std::declval<crow::response&>(), std::declval<Args>()...))>::value,
+ "Handler function with response argument should have void return type");
+
+ handler_with_req_res_ = std::move(f);
+ //[f = std::move(f)](const crow::request& req, crow::response& res, Args ... args){
+ // f(req, response, args...);
+ //};
+ handler_ = nullptr;
+ handler_with_req_ = nullptr;
}
template <typename Func>
@@ -192,21 +229,24 @@ namespace crow
call<
call_params<
decltype(handler_),
- decltype(handler_with_req_)>,
+ decltype(handler_with_req_),
+ decltype(handler_with_req_res_)>,
0, 0, 0, 0,
black_magic::S<Args...>,
black_magic::S<>
>()(
call_params<
decltype(handler_),
- decltype(handler_with_req_)>
- {handler_, handler_with_req_, params, req}
+ decltype(handler_with_req_),
+ decltype(handler_with_req_res_)>
+ {handler_, handler_with_req_, handler_with_req_res_, params, req}
);
}
private:
std::function<response(Args...)> handler_;
- std::function<response(crow::request, Args...)> handler_with_req_;
+ std::function<response(const crow::request&, Args...)> handler_with_req_;
+ std::function<void(const crow::request&, crow::response&, Args...)> handler_with_req_res_;
std::string rule_;
std::string name_;
diff --git a/test.py b/test.py
index 09d7a42..e2bf651 100644
--- a/test.py
+++ b/test.py
@@ -6,6 +6,7 @@ assert "3 bottles of beer!" == urllib.urlopen('http://localhost:18080/hello/3').
assert "100 bottles of beer!" == urllib.urlopen('http://localhost:18080/hello/100').read()
assert 400 == urllib.urlopen('http://localhost:18080/hello/500').getcode()
assert "3" == urllib.urlopen('http://localhost:18080/add_json', data='{"a":1,"b":2}').read()
+assert "3" == urllib.urlopen('http://localhost:18080/add/1/2').read()
# test persistent connection
import socket
diff --git a/unittest.cpp b/unittest.cpp
index eec119e..e4f8105 100644
--- a/unittest.cpp
+++ b/unittest.cpp
@@ -220,6 +220,14 @@ TEST(simple_response_routing_params)
ASSERT_EQUAL("hello", rp.get<string>(0));
}
+TEST(handler_with_response)
+{
+ Crow app;
+ CROW_ROUTE(app, "/")([](const crow::request&, crow::response&)
+ {
+ });
+}
+
TEST(server_handling_error_request)
{
static char buf[2048];