From bbac676470bdb6091a9817d9a3d1a996a113c6a7 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Tue, 23 Dec 2025 15:00:55 +0100 Subject: [PATCH 01/11] feat: helmet middleware example in beast2 server. Signed-off-by: Amlal El Mahrouss --- example/server/main.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/example/server/main.cpp b/example/server/main.cpp index 9713599d..59eb17eb 100644 --- a/example/server/main.cpp +++ b/example/server/main.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -80,7 +81,16 @@ int server_main( int argc, char* argv[] ) { return http_proto::route::next; }); - srv.wwwroot.use("/", serve_static( argv[3] )); + + srv.wwwroot.use( + http_proto::helmet(), + [] ( http_proto::route_params& ) -> + http_proto::route_result + { + return http_proto::route::next; + }); + + srv.wwwroot.use("/", serve_static( argv[3] )); app.start(); srv.attach(); From 31ddfc86f212627908c15f50955e73c28beb62fe Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Wed, 24 Dec 2025 09:46:52 +0100 Subject: [PATCH 02/11] feat: update beast2 example. Signed-off-by: Amlal El Mahrouss --- example/server/main.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/example/server/main.cpp b/example/server/main.cpp index 59eb17eb..2fc27326 100644 --- a/example/server/main.cpp +++ b/example/server/main.cpp @@ -82,8 +82,13 @@ int server_main( int argc, char* argv[] ) return http_proto::route::next; }); + http_proto::helmet_options options; + + options.set(http_proto::x_download_options(http_proto::helmet_download_type::noopen)); + options.set(http_proto::x_frame_origin(http_proto::helmet_origin_type::deny)); + srv.wwwroot.use( - http_proto::helmet(), + http_proto::helmet(options), [] ( http_proto::route_params& ) -> http_proto::route_result { From 2505fd7d517f3aff7aabf4f435aed63099a01388 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Wed, 24 Dec 2025 10:22:37 +0100 Subject: [PATCH 03/11] feat: server/main.cpp: add sp API to example. Signed-off-by: Amlal El Mahrouss --- example/server/main.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/example/server/main.cpp b/example/server/main.cpp index 2fc27326..ba331468 100644 --- a/example/server/main.cpp +++ b/example/server/main.cpp @@ -87,6 +87,13 @@ int server_main( int argc, char* argv[] ) options.set(http_proto::x_download_options(http_proto::helmet_download_type::noopen)); options.set(http_proto::x_frame_origin(http_proto::helmet_origin_type::deny)); + std::vector allow_list; + + http_proto::sp::append(allow_list, "script-src", http_proto::sp::allow_type::self); + http_proto::sp::append(allow_list, "object-src", http_proto::sp::allow_type::none); + + options.set(http_proto::content_security_policy(allow_list)); + srv.wwwroot.use( http_proto::helmet(options), [] ( http_proto::route_params& ) -> From cca3322ed7da7f0fff4772fe25461ac2586f2f61 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Wed, 24 Dec 2025 12:38:44 +0100 Subject: [PATCH 04/11] feat: update server example with updated SP api. Signed-off-by: Amlal El Mahrouss --- example/server/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/example/server/main.cpp b/example/server/main.cpp index ba331468..61696b0b 100644 --- a/example/server/main.cpp +++ b/example/server/main.cpp @@ -87,10 +87,10 @@ int server_main( int argc, char* argv[] ) options.set(http_proto::x_download_options(http_proto::helmet_download_type::noopen)); options.set(http_proto::x_frame_origin(http_proto::helmet_origin_type::deny)); - std::vector allow_list; + http_proto::sp::allow_list allow_list; - http_proto::sp::append(allow_list, "script-src", http_proto::sp::allow_type::self); - http_proto::sp::append(allow_list, "object-src", http_proto::sp::allow_type::none); + http_proto::sp::push_back(allow_list, "script-src", http_proto::sp::allow_type::self); + http_proto::sp::push_back(allow_list, "object-src", http_proto::sp::allow_type::none); options.set(http_proto::content_security_policy(allow_list)); From 4efb08e12bb968ff27e8377d356b3953765ad4ab Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Wed, 24 Dec 2025 13:03:06 +0100 Subject: [PATCH 05/11] fix: main.cpp: use updated API. Signed-off-by: Amlal El Mahrouss --- example/server/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example/server/main.cpp b/example/server/main.cpp index 61696b0b..3bb5da39 100644 --- a/example/server/main.cpp +++ b/example/server/main.cpp @@ -89,8 +89,8 @@ int server_main( int argc, char* argv[] ) http_proto::sp::allow_list allow_list; - http_proto::sp::push_back(allow_list, "script-src", http_proto::sp::allow_type::self); - http_proto::sp::push_back(allow_list, "object-src", http_proto::sp::allow_type::none); + http_proto::sp::push_back(allow_list, "script-src", http_proto::sp::csp_type::self); + http_proto::sp::push_back(allow_list, "object-src", http_proto::sp::csp_type::none); options.set(http_proto::content_security_policy(allow_list)); From 35cd2fbb487bc037f653c47d08fe47e2bcf560a6 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Wed, 24 Dec 2025 16:00:49 +0100 Subject: [PATCH 06/11] feat: main.cpp: update helmet example. Signed-off-by: Amlal El Mahrouss --- example/server/main.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/example/server/main.cpp b/example/server/main.cpp index 3bb5da39..5f4f163b 100644 --- a/example/server/main.cpp +++ b/example/server/main.cpp @@ -87,12 +87,12 @@ int server_main( int argc, char* argv[] ) options.set(http_proto::x_download_options(http_proto::helmet_download_type::noopen)); options.set(http_proto::x_frame_origin(http_proto::helmet_origin_type::deny)); - http_proto::sp::allow_list allow_list; + http_proto::security_policy sp; - http_proto::sp::push_back(allow_list, "script-src", http_proto::sp::csp_type::self); - http_proto::sp::push_back(allow_list, "object-src", http_proto::sp::csp_type::none); + sp.append("script-src", http_proto::csp_type::self) + .append("object-src", http_proto::csp_type::none); - options.set(http_proto::content_security_policy(allow_list)); + options.set(http_proto::content_security_policy(sp)); srv.wwwroot.use( http_proto::helmet(options), From 18b18847d9144e234f56e4f79f60606a12ce1e91 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Wed, 24 Dec 2025 18:02:24 +0100 Subject: [PATCH 07/11] feat: update beast2 example. Signed-off-by: Amlal El Mahrouss --- example/server/main.cpp | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/example/server/main.cpp b/example/server/main.cpp index ee15db2e..b9f9cf08 100644 --- a/example/server/main.cpp +++ b/example/server/main.cpp @@ -189,24 +189,27 @@ int server_main( int argc, char* argv[] ) return http::route::next; }); - http_proto::helmet_options options; + http::helmet_options options; - options.set(http_proto::x_download_options(http_proto::helmet_download_type::noopen)); - options.set(http_proto::x_frame_origin(http_proto::helmet_origin_type::deny)); + options.set(http::x_download_options(http::helmet_download_type::noopen)); + options.set(http::x_frame_origin(http::helmet_origin_type::deny)); - http_proto::security_policy sp; + http::helmet::csp_policy sp; - sp.append("script-src", http_proto::csp_type::self) - .append("object-src", http_proto::csp_type::none); + sp.append("script-src", http::csp_type::self) + .append("object-src", http::csp_type::none) + .append("style-src", "https://example.com/index.css"); - options.set(http_proto::content_security_policy(sp)); + sp.remove("style-src"); + + options.set(http::content_security_policy(sp)); srv.wwwroot.use( - http_proto::helmet(options), - [] ( http_proto::route_params& ) -> - http_proto::route_result + http::helmet(options), + [] ( http::route_params& ) -> + http::route_result { - return http_proto::route::next; + return http::route::next; }); srv.wwwroot.use("/", serve_static( argv[3] )); From be92867133f33f2eb6c6ee4f8f1b6f50e89d7696 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Thu, 25 Dec 2025 10:50:48 +0100 Subject: [PATCH 08/11] feat: update helmet example. Signed-off-by: Amlal El Mahrouss --- example/server/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/example/server/main.cpp b/example/server/main.cpp index b9f9cf08..4d6e06d5 100644 --- a/example/server/main.cpp +++ b/example/server/main.cpp @@ -198,9 +198,9 @@ int server_main( int argc, char* argv[] ) sp.append("script-src", http::csp_type::self) .append("object-src", http::csp_type::none) - .append("style-src", "https://example.com/index.css"); - - sp.remove("style-src"); + .append("style-src", "https://example.com/index.css") + .append("style-src", "https://example.com/foo.css") + .append("style-src", http::csp_type::self); options.set(http::content_security_policy(sp)); From 734bbbcda602fcff9233e3117dab17e4e4ed75a8 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Thu, 25 Dec 2025 15:11:16 +0100 Subject: [PATCH 09/11] feat! server: update example according to new API. Signed-off-by: Amlal El Mahrouss --- example/server/main.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/example/server/main.cpp b/example/server/main.cpp index 4d6e06d5..4341afc7 100644 --- a/example/server/main.cpp +++ b/example/server/main.cpp @@ -196,11 +196,11 @@ int server_main( int argc, char* argv[] ) http::helmet::csp_policy sp; - sp.append("script-src", http::csp_type::self) - .append("object-src", http::csp_type::none) - .append("style-src", "https://example.com/index.css") - .append("style-src", "https://example.com/foo.css") - .append("style-src", http::csp_type::self); + sp.set("script-src", http::csp_type::self) + .set("object-src", http::csp_type::none) + .set("style-src", "https://example.com/index.css") + .set("style-src", "https://example.com/foo.css") + .set("style-src", http::csp_type::self); options.set(http::content_security_policy(sp)); From d6077232405bf98850c2174a6c5a05db150cdbc5 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Thu, 25 Dec 2025 15:36:22 +0100 Subject: [PATCH 10/11] feat: update server example. Signed-off-by: Amlal El Mahrouss --- example/server/main.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/example/server/main.cpp b/example/server/main.cpp index 4341afc7..54cf9a98 100644 --- a/example/server/main.cpp +++ b/example/server/main.cpp @@ -196,11 +196,11 @@ int server_main( int argc, char* argv[] ) http::helmet::csp_policy sp; - sp.set("script-src", http::csp_type::self) - .set("object-src", http::csp_type::none) - .set("style-src", "https://example.com/index.css") - .set("style-src", "https://example.com/foo.css") - .set("style-src", http::csp_type::self); + sp.allow("script-src", http::csp_type::self) + .allow("object-src", http::csp_type::none) + .allow("style-src", "https://example.com/index.css") + .allow("style-src", "https://example.com/foo.css") + .allow("style-src", http::csp_type::self); options.set(http::content_security_policy(sp)); From 228c49f65f67de6b570a73e03e670cdd0da11a8d Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Fri, 26 Dec 2025 17:17:25 +0100 Subject: [PATCH 11/11] feat: server: `serve_not_found` helper for beast2 servers. Signed-off-by: Amlal El Mahrouss --- example/server/main.cpp | 2 + .../boost/beast2/server/serve_not_found.hpp | 44 +++++++++ src/server/serve_not_found.cpp | 99 +++++++++++++++++++ 3 files changed, 145 insertions(+) create mode 100644 include/boost/beast2/server/serve_not_found.hpp create mode 100644 src/server/serve_not_found.cpp diff --git a/example/server/main.cpp b/example/server/main.cpp index 54cf9a98..501cb8ed 100644 --- a/example/server/main.cpp +++ b/example/server/main.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -212,6 +213,7 @@ int server_main( int argc, char* argv[] ) return http::route::next; }); + srv.wwwroot.use("/", serve_not_found( argv[3] )); srv.wwwroot.use("/", serve_static( argv[3] )); app.start(); diff --git a/include/boost/beast2/server/serve_not_found.hpp b/include/boost/beast2/server/serve_not_found.hpp new file mode 100644 index 00000000..c98556b1 --- /dev/null +++ b/include/boost/beast2/server/serve_not_found.hpp @@ -0,0 +1,44 @@ +// +// Copyright (c) 2025 Amlal El Mahrouss (amlal at nekernel dot org) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/cppalliance/beast2 +// + +#ifndef BOOST_BEAST2_SERVER_SERVE_REDIRECT_HPP +#define BOOST_BEAST2_SERVER_SERVE_REDIRECT_HPP + +#include +#include + +namespace boost { +namespace beast2 { + +struct serve_not_found +{ +private: + struct serve_impl; + serve_impl* impl_{}; + +public: + serve_not_found(const core::string_view&); + ~serve_not_found(); + + serve_not_found& operator=(serve_not_found&&) noexcept; + serve_not_found(serve_not_found&&) noexcept; + + /** Serves a 404.html when a resource isn't found. + @note if no 404.html is found the route will be ignored. + */ + BOOST_BEAST2_DECL + http::route_result + operator()( + http::route_params&) const; +}; + +} // beast2 +} // boost + +#endif diff --git a/src/server/serve_not_found.cpp b/src/server/serve_not_found.cpp new file mode 100644 index 00000000..fbb1ebe3 --- /dev/null +++ b/src/server/serve_not_found.cpp @@ -0,0 +1,99 @@ +// +// Copyright (c) 2025 Amlal El Mahrouss (amlal at nekernel dot org) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/cppalliance/beast2 +// + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace beast2 { + + struct serve_not_found::serve_impl + { + std::string path_; + }; + + serve_not_found::serve_not_found(const core::string_view& path) + : impl_(new serve_impl()) + { + impl_->path_ = path; + } + + serve_not_found::~serve_not_found() + { + if (impl_) + delete impl_; + + impl_ = nullptr; + } + + serve_not_found& serve_not_found::operator=(serve_not_found&& other) noexcept + { + delete impl_; + impl_ = other.impl_; + other.impl_ = nullptr; + + return *this; + } + + serve_not_found:: + serve_not_found(serve_not_found&& other) noexcept + : impl_(other.impl_) + { + other.impl_ = nullptr; + } + + http::route_result + serve_not_found::operator()( + http::route_params& p) const + { + std::string path{impl_->path_}; + path += p.path; + + system::error_code ec{}; + + capy::file f; + + f.open(path.c_str(), capy::file_mode::scan, ec); + + if (!ec.failed()) + return http::route::next; + + p.res.set_start_line(http::status::not_found); + p.res.append(http::field::content_type, "text/html"); + + std::string body; + std::ostringstream ss; + + ss << + "" + "" + "NOT FOUND" + "\n" + "" + "

NOT FOUND

" + "

THE FOLLOWING RESOURCE: " << p.path << ", WAS NOT FOUND.

" + "" + "" + ; + + body = ss.str(); + + // send 404 template to client + p.serializer.start(p.res, + http::string_body( std::move(body))); + + return http::route::send; + } + +} +} \ No newline at end of file