summaryrefslogtreecommitdiff
path: root/http
diff options
context:
space:
mode:
Diffstat (limited to 'http')
-rw-r--r--http/app.h51
-rw-r--r--http/http_connection.h227
-rw-r--r--http/http_request.h3
-rw-r--r--http/http_response.h4
-rw-r--r--http/http_server.h31
-rw-r--r--http/middleware_context.h72
-rw-r--r--http/websocket.h2
7 files changed, 43 insertions, 347 deletions
diff --git a/http/app.h b/http/app.h
index ca871dcead..dfd5304543 100644
--- a/http/app.h
+++ b/http/app.h
@@ -3,7 +3,6 @@
#include "http_request.h"
#include "http_server.h"
#include "logging.h"
-#include "middleware_context.h"
#include "routing.h"
#include "utility.h"
@@ -25,25 +24,24 @@ namespace crow
#ifdef BMCWEB_ENABLE_SSL
using ssl_context_t = boost::asio::ssl::context;
#endif
-template <typename... Middlewares>
-class Crow
+class App
{
public:
- using self_t = Crow;
+ using self_t = App;
#ifdef BMCWEB_ENABLE_SSL
using ssl_socket_t = boost::beast::ssl_stream<boost::asio::ip::tcp::socket>;
- using ssl_server_t = Server<Crow, ssl_socket_t, Middlewares...>;
+ using ssl_server_t = Server<App, ssl_socket_t>;
#else
using socket_t = boost::asio::ip::tcp::socket;
- using server_t = Server<Crow, socket_t, Middlewares...>;
+ using server_t = Server<App, socket_t>;
#endif
- explicit Crow(std::shared_ptr<boost::asio::io_context> ioIn =
- std::make_shared<boost::asio::io_context>()) :
+ explicit App(std::shared_ptr<boost::asio::io_context> ioIn =
+ std::make_shared<boost::asio::io_context>()) :
io(std::move(ioIn))
{}
- ~Crow()
+ ~App()
{
this->stop();
}
@@ -100,12 +98,12 @@ class Crow
if (-1 == socketFd)
{
sslServer = std::move(std::make_unique<ssl_server_t>(
- this, bindaddrStr, portUint, sslContext, &middlewares, io));
+ this, bindaddrStr, portUint, sslContext, io));
}
else
{
- sslServer = std::move(std::make_unique<ssl_server_t>(
- this, socketFd, sslContext, &middlewares, io));
+ sslServer = std::move(
+ std::make_unique<ssl_server_t>(this, socketFd, sslContext, io));
}
sslServer->setTickFunction(tickInterval, tickFunction);
sslServer->run();
@@ -115,12 +113,12 @@ class Crow
if (-1 == socketFd)
{
server = std::move(std::make_unique<server_t>(
- this, bindaddrStr, portUint, nullptr, &middlewares, io));
+ this, bindaddrStr, portUint, nullptr, io));
}
else
{
- server = std::move(std::make_unique<server_t>(
- this, socketFd, nullptr, &middlewares, io));
+ server = std::move(
+ std::make_unique<server_t>(this, socketFd, nullptr, io));
}
server->setTickFunction(tickInterval, tickFunction);
server->run();
@@ -216,23 +214,6 @@ class Crow
}
#endif
- // middleware
- using context_t = detail::Context<Middlewares...>;
- template <typename T>
- typename T::Context& getContext(const Request& req)
- {
- static_assert(black_magic::Contains<T, Middlewares...>::value,
- "App doesn't have the specified middleware type.");
- auto& ctx = *reinterpret_cast<context_t*>(req.middlewareContext);
- return ctx.template get<T>();
- }
-
- template <typename T>
- T& getMiddleware()
- {
- return utility::getElementByType<T, Middlewares...>(middlewares);
- }
-
template <typename Duration, typename Func>
self_t& tick(Duration d, Func f)
{
@@ -255,15 +236,11 @@ class Crow
std::chrono::milliseconds tickInterval{};
std::function<void()> tickFunction;
- std::tuple<Middlewares...> middlewares;
-
#ifdef BMCWEB_ENABLE_SSL
std::unique_ptr<ssl_server_t> sslServer;
#else
std::unique_ptr<server_t> server;
#endif
};
-template <typename... Middlewares>
-using App = Crow<Middlewares...>;
-using SimpleApp = Crow<>;
} // namespace crow
+using App = crow::App;
diff --git a/http/http_connection.h b/http/http_connection.h
index 8dba3d6b59..609d4a10b1 100644
--- a/http/http_connection.h
+++ b/http/http_connection.h
@@ -3,7 +3,6 @@
#include "http_response.h"
#include "logging.h"
-#include "middleware_context.h"
#include "timer_queue.h"
#include "utility.h"
@@ -19,6 +18,7 @@
#include <boost/beast/http.hpp>
#include <boost/beast/ssl/ssl_stream.hpp>
#include <boost/beast/websocket.hpp>
+#include <security_headers.hpp>
#include <ssl_key_handler.hpp>
#include <atomic>
@@ -61,186 +61,6 @@ inline void prettyPrintJson(crow::Response& res)
using namespace boost;
using tcp = asio::ip::tcp;
-namespace detail
-{
-template <typename MW>
-struct CheckBeforeHandleArity3Const
-{
- template <typename T,
- void (T::*)(Request&, Response&, typename MW::Context&) const =
- &T::beforeHandle>
- struct Get
- {};
-};
-
-template <typename MW>
-struct CheckBeforeHandleArity3
-{
- template <typename T, void (T::*)(Request&, Response&,
- typename MW::Context&) = &T::beforeHandle>
- struct Get
- {};
-};
-
-template <typename MW>
-struct CheckAfterHandleArity3Const
-{
- template <typename T,
- void (T::*)(Request&, Response&, typename MW::Context&) const =
- &T::afterHandle>
- struct Get
- {};
-};
-
-template <typename MW>
-struct CheckAfterHandleArity3
-{
- template <typename T, void (T::*)(Request&, Response&,
- typename MW::Context&) = &T::afterHandle>
- struct Get
- {};
-};
-
-template <typename T>
-struct IsBeforeHandleArity3Impl
-{
- template <typename C>
- static std::true_type
- f(typename CheckBeforeHandleArity3Const<T>::template Get<C>*);
-
- template <typename C>
- static std::true_type
- f(typename CheckBeforeHandleArity3<T>::template Get<C>*);
-
- template <typename C>
- static std::false_type f(...);
-
- public:
- static constexpr bool value = decltype(f<T>(nullptr))::value;
-};
-
-template <typename T>
-struct IsAfterHandleArity3Impl
-{
- template <typename C>
- static std::true_type
- f(typename CheckAfterHandleArity3Const<T>::template Get<C>*);
-
- template <typename C>
- static std::true_type
- f(typename CheckAfterHandleArity3<T>::template Get<C>*);
-
- template <typename C>
- static std::false_type f(...);
-
- public:
- static constexpr bool value = decltype(f<T>(nullptr))::value;
-};
-
-template <typename MW, typename Context, typename ParentContext>
-typename std::enable_if<!IsBeforeHandleArity3Impl<MW>::value>::type
- beforeHandlerCall(MW& mw, Request& req, Response& res, Context& ctx,
- ParentContext& /*parent_ctx*/)
-{
- mw.beforeHandle(req, res, ctx.template get<MW>(), ctx);
-}
-
-template <typename MW, typename Context, typename ParentContext>
-typename std::enable_if<IsBeforeHandleArity3Impl<MW>::value>::type
- beforeHandlerCall(MW& mw, Request& req, Response& res, Context& ctx,
- ParentContext& /*parent_ctx*/)
-{
- mw.beforeHandle(req, res, ctx.template get<MW>());
-}
-
-template <typename MW, typename Context, typename ParentContext>
-typename std::enable_if<!IsAfterHandleArity3Impl<MW>::value>::type
- afterHandlerCall(MW& mw, Request& req, Response& res, Context& ctx,
- ParentContext& /*parent_ctx*/)
-{
- mw.afterHandle(req, res, ctx.template get<MW>(), ctx);
-}
-
-template <typename MW, typename Context, typename ParentContext>
-typename std::enable_if<IsAfterHandleArity3Impl<MW>::value>::type
- afterHandlerCall(MW& mw, Request& req, Response& res, Context& ctx,
- ParentContext& /*parent_ctx*/)
-{
- mw.afterHandle(req, res, ctx.template get<MW>());
-}
-
-template <size_t N, typename Context, typename Container, typename CurrentMW,
- typename... Middlewares>
-bool middlewareCallHelper(Container& middlewares, Request& req, Response& res,
- Context& ctx)
-{
- using parent_context_t = typename Context::template partial<N - 1>;
- beforeHandlerCall<CurrentMW, Context, parent_context_t>(
- std::get<N>(middlewares), req, res, ctx,
- static_cast<parent_context_t&>(ctx));
-
- if (res.isCompleted())
- {
- afterHandlerCall<CurrentMW, Context, parent_context_t>(
- std::get<N>(middlewares), req, res, ctx,
- static_cast<parent_context_t&>(ctx));
- return true;
- }
-
- if (middlewareCallHelper<N + 1, Context, Container, Middlewares...>(
- middlewares, req, res, ctx))
- {
- afterHandlerCall<CurrentMW, Context, parent_context_t>(
- std::get<N>(middlewares), req, res, ctx,
- static_cast<parent_context_t&>(ctx));
- return true;
- }
-
- return false;
-}
-
-template <size_t N, typename Context, typename Container>
-bool middlewareCallHelper(Container& /*middlewares*/, Request& /*req*/,
- Response& /*res*/, Context& /*ctx*/)
-{
- return false;
-}
-
-template <size_t N, typename Context, typename Container>
-typename std::enable_if<(N < 0)>::type
- afterHandlersCallHelper(Container& /*middlewares*/, Context& /*Context*/,
- Request& /*req*/, Response& /*res*/)
-{}
-
-template <size_t N, typename Context, typename Container>
-typename std::enable_if<(N == 0)>::type
- afterHandlersCallHelper(Container& middlewares, Context& ctx, Request& req,
- Response& res)
-{
- using parent_context_t = typename Context::template partial<N - 1>;
- using CurrentMW = typename std::tuple_element<
- N, typename std::remove_reference<Container>::type>::type;
- afterHandlerCall<CurrentMW, Context, parent_context_t>(
- std::get<N>(middlewares), req, res, ctx,
- static_cast<parent_context_t&>(ctx));
-}
-
-template <size_t N, typename Context, typename Container>
-typename std::enable_if<(N > 0)>::type
- afterHandlersCallHelper(Container& middlewares, Context& ctx, Request& req,
- Response& res)
-{
- using parent_context_t = typename Context::template partial<N - 1>;
- using CurrentMW = typename std::tuple_element<
- N, typename std::remove_reference<Container>::type>::type;
- afterHandlerCall<CurrentMW, Context, parent_context_t>(
- std::get<N>(middlewares), req, res, ctx,
- static_cast<parent_context_t&>(ctx));
- afterHandlersCallHelper<N - 1, Context, Container>(middlewares, ctx, req,
- res);
-}
-} // namespace detail
-
#ifdef BMCWEB_ENABLE_DEBUG
static std::atomic<int> connectionCount;
#endif
@@ -261,21 +81,18 @@ static constexpr const size_t loggedInAttempts =
static constexpr const size_t loggedOutAttempts =
(15 / timerQueueTimeoutSeconds);
-template <typename Adaptor, typename Handler, typename... Middlewares>
+template <typename Adaptor, typename Handler>
class Connection :
- public std::enable_shared_from_this<
- Connection<Adaptor, Handler, Middlewares...>>
+ public std::enable_shared_from_this<Connection<Adaptor, Handler>>
{
public:
Connection(boost::asio::io_context& ioService, Handler* handlerIn,
const std::string& ServerNameIn,
- std::tuple<Middlewares...>* middlewaresIn,
std::function<std::string()>& get_cached_date_str_f,
detail::TimerQueue& timerQueueIn, Adaptor adaptorIn) :
adaptor(std::move(adaptorIn)),
handler(handlerIn), serverName(ServerNameIn),
- middlewares(middlewaresIn), getCachedDateStr(get_cached_date_str_f),
- timerQueue(timerQueueIn)
+ getCachedDateStr(get_cached_date_str_f), timerQueue(timerQueueIn)
{
parser.emplace(std::piecewise_construct, std::make_tuple());
parser->body_limit(httpReqBodyLimit);
@@ -285,7 +102,7 @@ class Connection :
#ifdef BMCWEB_ENABLE_MUTUAL_TLS_AUTHENTICATION
auto ca_available = !std::filesystem::is_empty(
std::filesystem::path(ensuressl::trustStorePath));
- if (ca_available && crow::persistent_data::SessionStore::getInstance()
+ if (ca_available && persistent_data::SessionStore::getInstance()
.getAuthMethodsConfig()
.tls)
{
@@ -301,7 +118,7 @@ class Connection :
bool preverified,
boost::asio::ssl::verify_context& ctx) {
// do nothing if TLS is disabled
- if (!crow::persistent_data::SessionStore::getInstance()
+ if (!persistent_data::SessionStore::getInstance()
.getAuthMethodsConfig()
.tls)
{
@@ -444,10 +261,10 @@ class Connection :
}
sslUser.resize(lastChar);
- session = persistent_data::SessionStore::getInstance()
- .generateUserSession(
- sslUser,
- crow::persistent_data::PersistenceType::TIMEOUT);
+ session =
+ persistent_data::SessionStore::getInstance()
+ .generateUserSession(
+ sslUser, persistent_data::PersistenceType::TIMEOUT);
if (auto sp = session.lock())
{
BMCWEB_LOG_DEBUG << this
@@ -538,15 +355,9 @@ class Connection :
res.completeRequestHandler = [] {};
res.isAliveHelper = [this]() -> bool { return isAlive(); };
- ctx = detail::Context<Middlewares...>();
- req->middlewareContext = static_cast<void*>(&ctx);
req->ioService = static_cast<decltype(req->ioService)>(
&adaptor.get_executor().context());
- detail::middlewareCallHelper<
- 0U, decltype(ctx), decltype(*middlewares), Middlewares...>(
- *middlewares, *req, res, ctx);
-
if (!res.completed)
{
needToCallAfterHandlers = true;
@@ -618,16 +429,10 @@ class Connection :
BMCWEB_LOG_INFO << "Response: " << this << ' ' << req->url << ' '
<< res.resultInt() << " keepalive=" << req->keepAlive();
+ addSecurityHeaders(res);
+
if (needToCallAfterHandlers)
{
- needToCallAfterHandlers = false;
-
- // call all afterHandler of middlewares
- detail::afterHandlersCallHelper<sizeof...(Middlewares) - 1,
- decltype(ctx),
- decltype(*middlewares)>(
- *middlewares, ctx, *req, res);
-
crow::authorization::cleanupTempSession(*req);
}
@@ -949,7 +754,8 @@ class Connection :
std::optional<crow::Request> req;
crow::Response res;
- std::weak_ptr<crow::persistent_data::UserSession> session;
+
+ std::weak_ptr<persistent_data::UserSession> session;
const std::string& serverName;
@@ -958,13 +764,10 @@ class Connection :
bool needToCallAfterHandlers{};
bool needToStartReadAfterComplete{};
- std::tuple<Middlewares...>* middlewares;
- detail::Context<Middlewares...> ctx;
-
std::function<std::string()>& getCachedDateStr;
detail::TimerQueue& timerQueue;
using std::enable_shared_from_this<
- Connection<Adaptor, Handler, Middlewares...>>::shared_from_this;
+ Connection<Adaptor, Handler>>::shared_from_this;
};
} // namespace crow
diff --git a/http/http_request.h b/http/http_request.h
index 95f88c735d..fa60f60ba2 100644
--- a/http/http_request.h
+++ b/http/http_request.h
@@ -30,10 +30,9 @@ struct Request
const std::string& body;
- void* middlewareContext{};
boost::asio::io_context* ioService{};
- std::shared_ptr<crow::persistent_data::UserSession> session;
+ std::shared_ptr<persistent_data::UserSession> session;
std::string userRole{};
std::function<Adaptor&()> socket;
diff --git a/http/http_response.h b/http/http_response.h
index d5d1e4b03f..7be6b0914c 100644
--- a/http/http_response.h
+++ b/http/http_response.h
@@ -11,12 +11,12 @@
namespace crow
{
-template <typename Adaptor, typename Handler, typename... Middlewares>
+template <typename Adaptor, typename Handler>
class Connection;
struct Response
{
- template <typename Adaptor, typename Handler, typename... Middlewares>
+ template <typename Adaptor, typename Handler>
friend class crow::Connection;
using response_type =
boost::beast::http::response<boost::beast::http::string_body>;
diff --git a/http/http_server.h b/http/http_server.h
index 0e8a702ec2..c87ddd428c 100644
--- a/http/http_server.h
+++ b/http/http_server.h
@@ -27,44 +27,39 @@ namespace crow
using namespace boost;
using tcp = asio::ip::tcp;
-template <typename Handler, typename Adaptor = boost::asio::ip::tcp::socket,
- typename... Middlewares>
+template <typename Handler, typename Adaptor = boost::asio::ip::tcp::socket>
class Server
{
public:
Server(Handler* handler, std::unique_ptr<tcp::acceptor>&& acceptor,
std::shared_ptr<boost::asio::ssl::context> adaptor_ctx,
- std::tuple<Middlewares...>* middlewares = nullptr,
std::shared_ptr<boost::asio::io_context> io =
std::make_shared<boost::asio::io_context>()) :
ioService(std::move(io)),
acceptor(std::move(acceptor)),
signals(*ioService, SIGINT, SIGTERM, SIGHUP), tickTimer(*ioService),
- timer(*ioService), handler(handler), middlewares(middlewares),
- adaptorCtx(adaptor_ctx)
+ timer(*ioService), handler(handler), adaptorCtx(adaptor_ctx)
{}
Server(Handler* handler, const std::string& bindaddr, uint16_t port,
std::shared_ptr<boost::asio::ssl::context> adaptor_ctx,
- std::tuple<Middlewares...>* middlewares = nullptr,
std::shared_ptr<boost::asio::io_context> io =
std::make_shared<boost::asio::io_context>()) :
Server(handler,
std::make_unique<tcp::acceptor>(
*io, tcp::endpoint(boost::asio::ip::make_address(bindaddr),
port)),
- adaptor_ctx, middlewares, io)
+ adaptor_ctx, io)
{}
Server(Handler* handler, int existing_socket,
std::shared_ptr<boost::asio::ssl::context> adaptor_ctx,
- std::tuple<Middlewares...>* middlewares = nullptr,
std::shared_ptr<boost::asio::io_context> io =
std::make_shared<boost::asio::io_context>()) :
Server(handler,
std::make_unique<tcp::acceptor>(*io, boost::asio::ip::tcp::v6(),
existing_socket),
- adaptor_ctx, middlewares, io)
+ adaptor_ctx, io)
{}
void setTickFunction(std::chrono::milliseconds d, std::function<void()> f)
@@ -223,11 +218,9 @@ class Server
boost::asio::ip::tcp::socket>>::value)
{
adaptorTemp = Adaptor(*ioService, *adaptorCtx);
- auto p =
- std::make_shared<Connection<Adaptor, Handler, Middlewares...>>(
- *ioService, handler, serverName, middlewares,
- getCachedDateStr, timerQueue,
- std::move(adaptorTemp.value()));
+ auto p = std::make_shared<Connection<Adaptor, Handler>>(
+ *ioService, handler, serverName, getCachedDateStr, timerQueue,
+ std::move(adaptorTemp.value()));
acceptor->async_accept(p->socket().next_layer(),
[this, p](boost::system::error_code ec) {
@@ -243,11 +236,9 @@ class Server
else
{
adaptorTemp = Adaptor(*ioService);
- auto p =
- std::make_shared<Connection<Adaptor, Handler, Middlewares...>>(
- *ioService, handler, serverName, middlewares,
- getCachedDateStr, timerQueue,
- std::move(adaptorTemp.value()));
+ auto p = std::make_shared<Connection<Adaptor, Handler>>(
+ *ioService, handler, serverName, getCachedDateStr, timerQueue,
+ std::move(adaptorTemp.value()));
acceptor->async_accept(
p->socket(), [this, p](boost::system::error_code ec) {
@@ -279,8 +270,6 @@ class Server
std::function<void()> tickFunction;
std::function<void(const boost::system::error_code& ec)> timerHandler;
- std::tuple<Middlewares...>* middlewares;
-
#ifdef BMCWEB_ENABLE_SSL
bool useSsl{false};
#endif
diff --git a/http/middleware_context.h b/http/middleware_context.h
deleted file mode 100644
index fa399d62d3..0000000000
--- a/http/middleware_context.h
+++ /dev/null
@@ -1,72 +0,0 @@
-#pragma once
-
-#include "http_request.h"
-#include "http_response.h"
-#include "utility.h"
-
-namespace crow
-{
-namespace detail
-{
-template <typename... Middlewares>
-struct PartialContext :
- public black_magic::PopBack<Middlewares...>::template rebind<
- PartialContext>,
- public black_magic::LastElementType<Middlewares...>::type::Context
-{
- using parent_context = typename black_magic::PopBack<
- Middlewares...>::template rebind<::crow::detail::PartialContext>;
- template <size_t N>
- using partial = typename std::conditional<
- N == sizeof...(Middlewares) - 1, PartialContext,
- typename parent_context::template partial<N>>::type;
-
- template <typename T>
- typename T::Context& get()
- {
- return static_cast<typename T::Context&>(*this);
- }
-};
-
-template <>
-struct PartialContext<>
-{
- template <size_t>
- using partial = PartialContext;
-};
-
-template <size_t N, typename Context, typename Container, typename CurrentMW,
- typename... Middlewares>
-bool middlewareCallHelper(Container& middlewares, Request& req, Response& res,
- Context& ctx);
-
-template <typename... Middlewares>
-struct Context : private PartialContext<Middlewares...>
-// struct Context : private Middlewares::context... // simple but less type-safe
-{
- template <size_t N, typename Context, typename Container>
- friend typename std::enable_if<(N == 0)>::type
- afterHandlersCallHelper(Container& middlewares, Context& ctx,
- Request& req, Response& res);
- template <size_t N, typename Context, typename Container>
- friend typename std::enable_if<(N > 0)>::type
- afterHandlersCallHelper(Container& middlewares, Context& ctx,
- Request& req, Response& res);
-
- template <size_t N, typename Context, typename Container,
- typename CurrentMW, typename... Middlewares2>
- friend bool middlewareCallHelper(Container& middlewares, Request& req,
- Response& res, Context& ctx);
-
- template <typename T>
- typename T::Context& get()
- {
- return static_cast<typename T::Context&>(*this);
- }
-
- template <size_t N>
- using partial =
- typename PartialContext<Middlewares...>::template partial<N>;
-};
-} // namespace detail
-} // namespace crow
diff --git a/http/websocket.h b/http/websocket.h
index 91b537b7d1..7670196521 100644
--- a/http/websocket.h
+++ b/http/websocket.h
@@ -276,7 +276,7 @@ class ConnectionImpl : public Connection
std::function<void(Connection&, const std::string&, bool)> messageHandler;
std::function<void(Connection&, const std::string&)> closeHandler;
std::function<void(Connection&)> errorHandler;
- std::shared_ptr<crow::persistent_data::UserSession> session;
+ std::shared_ptr<persistent_data::UserSession> session;
};
} // namespace websocket
} // namespace crow