aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/crow/http_connection.h1
-rw-r--r--include/crow/http_server.h17
-rw-r--r--include/crow/json.h17
-rw-r--r--include/crow/query_string.h58
-rw-r--r--include/crow/routing.h28
-rw-r--r--include/crow/websocket.h1
6 files changed, 109 insertions, 13 deletions
diff --git a/include/crow/http_connection.h b/include/crow/http_connection.h
index 96f2d14..3ef8089 100644
--- a/include/crow/http_connection.h
+++ b/include/crow/http_connection.h
@@ -374,6 +374,7 @@ namespace crow
{401, "HTTP/1.1 401 Unauthorized\r\n"},
{403, "HTTP/1.1 403 Forbidden\r\n"},
{404, "HTTP/1.1 404 Not Found\r\n"},
+ {422, "HTTP/1.1 422 Unprocessable Entity\r\n"},
{500, "HTTP/1.1 500 Internal Server Error\r\n"},
{501, "HTTP/1.1 501 Not Implemented\r\n"},
diff --git a/include/crow/http_server.h b/include/crow/http_server.h
index d5abb11..a247b12 100644
--- a/include/crow/http_server.h
+++ b/include/crow/http_server.h
@@ -121,12 +121,19 @@ namespace crow
timer.async_wait(handler);
init_count ++;
- try
+ while(1)
{
- io_service_pool_[i]->run();
- } catch(std::exception& e)
- {
- CROW_LOG_ERROR << "Worker Crash: An uncaught exception occurred: " << e.what();
+ try
+ {
+ if (io_service_pool_[i]->run() == 0)
+ {
+ // when io_service.run returns 0, there are no more works to do.
+ break;
+ }
+ } catch(std::exception& e)
+ {
+ CROW_LOG_ERROR << "Worker Crash: An uncaught exception occurred: " << e.what();
+ }
}
}));
diff --git a/include/crow/json.h b/include/crow/json.h
index 891fedf..8b58180 100644
--- a/include/crow/json.h
+++ b/include/crow/json.h
@@ -1264,6 +1264,23 @@ namespace crow
return *this;
}
+ wvalue& operator=(std::vector<wvalue>&& v)
+ {
+ if (t_ != type::List)
+ reset();
+ t_ = type::List;
+ if (!l)
+ l = std::unique_ptr<std::vector<wvalue>>(new std::vector<wvalue>{});
+ l->clear();
+ l->resize(v.size());
+ size_t idx = 0;
+ for(auto& x:v)
+ {
+ (*l)[idx++] = std::move(x);
+ }
+ return *this;
+ }
+
template <typename T>
wvalue& operator=(const std::vector<T>& v)
{
diff --git a/include/crow/query_string.h b/include/crow/query_string.h
index 3f8bffe..78ccc67 100644
--- a/include/crow/query_string.h
+++ b/include/crow/query_string.h
@@ -4,7 +4,9 @@
#include <string.h>
#include <string>
#include <vector>
+#include <unordered_map>
#include <iostream>
+#include <boost/optional.hpp>
namespace crow
{
@@ -197,6 +199,48 @@ inline char * qs_k2v(const char * key, char * const * qs_kv, int qs_kv_size, int
return NULL;
}
+inline boost::optional<std::pair<std::string, std::string>> qs_dict_name2kv(const char * dict_name, char * const * qs_kv, int qs_kv_size, int nth = 0)
+{
+ int i;
+ size_t name_len, skip_to_eq, skip_to_brace_open, skip_to_brace_close;
+
+ name_len = strlen(dict_name);
+
+#ifdef _qsSORTING
+// TODO: binary search for key in the sorted qs_kv
+#else // _qsSORTING
+ for(i=0; i<qs_kv_size; i++)
+ {
+ if ( strncmp(dict_name, qs_kv[i], name_len) == 0 )
+ {
+ skip_to_eq = strcspn(qs_kv[i], "=");
+ if ( qs_kv[i][skip_to_eq] == '=' )
+ skip_to_eq++;
+ skip_to_brace_open = strcspn(qs_kv[i], "[");
+ if ( qs_kv[i][skip_to_brace_open] == '[' )
+ skip_to_brace_open++;
+ skip_to_brace_close = strcspn(qs_kv[i], "]");
+
+ if ( skip_to_brace_open <= skip_to_brace_close &&
+ skip_to_brace_open > 0 &&
+ skip_to_brace_close > 0 &&
+ nth == 0 )
+ {
+ auto key = std::string(qs_kv[i] + skip_to_brace_open, skip_to_brace_close - skip_to_brace_open);
+ auto value = std::string(qs_kv[i] + skip_to_eq);
+ return boost::make_optional(std::make_pair(key, value));
+ }
+ else
+ {
+ --nth;
+ }
+ }
+ }
+#endif // _qsSORTING
+
+ return boost::none;
+}
+
inline char * qs_scanvalue(const char * key, const char * qs, char * val, size_t val_len)
{
@@ -336,6 +380,20 @@ namespace crow
return ret;
}
+ std::unordered_map<std::string, std::string> get_dict (const std::string& name) const
+ {
+ std::unordered_map<std::string, std::string> ret;
+
+ int count = 0;
+ while(1)
+ {
+ if (auto element = qs_dict_name2kv(name.c_str(), key_value_pairs_.data(), key_value_pairs_.size(), count++))
+ ret.insert(*element);
+ else
+ break;
+ }
+ return ret;
+ }
private:
std::string url_;
diff --git a/include/crow/routing.h b/include/crow/routing.h
index 95fe354..cdfa480 100644
--- a/include/crow/routing.h
+++ b/include/crow/routing.h
@@ -156,7 +156,7 @@ namespace crow
struct Wrapped
{
template <typename ... Args>
- void set(Func f, typename std::enable_if<
+ void set_(Func f, typename std::enable_if<
!std::is_same<typename std::tuple_element<0, std::tuple<Args..., void>>::type, const request&>::value
, int>::type = 0)
{
@@ -190,7 +190,7 @@ namespace crow
};
template <typename ... Args>
- void set(Func f, typename std::enable_if<
+ void set_(Func f, typename std::enable_if<
std::is_same<typename std::tuple_element<0, std::tuple<Args..., void>>::type, const request&>::value &&
!std::is_same<typename std::tuple_element<1, std::tuple<Args..., void, void>>::type, response&>::value
, int>::type = 0)
@@ -205,7 +205,7 @@ namespace crow
}
template <typename ... Args>
- void set(Func f, typename std::enable_if<
+ void set_(Func f, typename std::enable_if<
std::is_same<typename std::tuple_element<0, std::tuple<Args..., void>>::type, const request&>::value &&
std::is_same<typename std::tuple_element<1, std::tuple<Args..., void, void>>::type, response&>::value
, int>::type = 0)
@@ -418,7 +418,7 @@ namespace crow
throw std::runtime_error("route_dynamic: Handler type is mismatched with URL parameters: " + rule_);
}
auto ret = detail::routing_handler_call_helper::Wrapped<Func, typename function_t::template arg<Indices>...>();
- ret.template set<
+ ret.template set_<
typename function_t::template arg<Indices>...
>(std::move(f));
return ret;
@@ -464,10 +464,16 @@ namespace crow
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");
- handler_ = [f = std::move(f)](const request&, response& res, Args ... args){
+ handler_ = (
+#ifdef CROW_CAN_USE_CPP14
+ [f = std::move(f)]
+#else
+ [f]
+#endif
+ (const request&, response& res, Args ... args){
res = response(f(args...));
res.end();
- };
+ });
}
template <typename Func>
@@ -483,10 +489,16 @@ namespace crow
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_ = [f = std::move(f)](const crow::request& req, crow::response& res, Args ... args){
+ handler_ = (
+#ifdef CROW_CAN_USE_CPP14
+ [f = std::move(f)]
+#else
+ [f]
+#endif
+ (const crow::request& req, crow::response& res, Args ... args){
res = response(f(req, args...));
res.end();
- };
+ });
}
template <typename Func>
diff --git a/include/crow/websocket.h b/include/crow/websocket.h
index fa45d1b..efcf834 100644
--- a/include/crow/websocket.h
+++ b/include/crow/websocket.h
@@ -1,5 +1,6 @@
#pragma once
#include <boost/algorithm/string/predicate.hpp>
+#include <boost/array.hpp>
#include "crow/socket_adaptors.h"
#include "crow/http_request.h"
#include "crow/TinySHA1.hpp"