summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRutger Broekhoff2026-08-29 14:36:36 +0200
committerRutger Broekhoff2026-08-29 14:36:36 +0200
commit999d77a9bcfa90f002b0107ea5fc7e6abc51dd9c (patch)
tree15f2154ba28139ab87602bcb53f1451e5b8bfd6b
parent783ec01cbe2007c2ccf723635166c08f6d26abee (diff)
downloadroutemon-999d77a9bcfa90f002b0107ea5fc7e6abc51dd9c.tar.gz
routemon-999d77a9bcfa90f002b0107ea5fc7e6abc51dd9c.zip
Deployment preparations
-rw-r--r--flake.nix24
-rw-r--r--server/CMakeLists.txt2
-rw-r--r--server/src/config.cpp3
-rw-r--r--server/src/config.cppm2
-rw-r--r--server/src/http_server.cppm43
-rw-r--r--server/src/main.cpp5
-rw-r--r--server/src/srv.cpp10
-rw-r--r--server/src/srv.cppm6
-rw-r--r--todo.org1
-rw-r--r--web/index.html2
-rw-r--r--web/index.js (renamed from web/script.js)6
11 files changed, 70 insertions, 34 deletions
diff --git a/flake.nix b/flake.nix
index 2320882..7629d56 100644
--- a/flake.nix
+++ b/flake.nix
@@ -21,8 +21,8 @@
21 }); 21 });
22 boost = pkgs."boost${toString boostVersion}"; 22 boost = pkgs."boost${toString boostVersion}";
23 23
24 routemon = stdenv.mkDerivation { 24 routemon-server = stdenv.mkDerivation {
25 name = "routemon"; 25 name = "routemon-server";
26 src = ./server; 26 src = ./server;
27 27
28 buildInputs = with pkgs; [ boost pugixml expat icu openssl sqlite ]; 28 buildInputs = with pkgs; [ boost pugixml expat icu openssl sqlite ];
@@ -48,13 +48,29 @@
48 "-DCMAKE_CXX_STDLIB_MODULES_JSON=${libstdcxxGcc}/lib/libstdc++.modules.json" 48 "-DCMAKE_CXX_STDLIB_MODULES_JSON=${libstdcxxGcc}/lib/libstdc++.modules.json"
49 ]; 49 ];
50 }; 50 };
51
52 routemon-web = pkgs.stdenvNoCC.mkDerivation {
53 name = "routemon-web";
54
55 src = ./web;
56
57 installPhase = ''
58 runHook preInstall
59
60 mkdir -p $out/usr/lib/routemon-web/htdocs
61 cp -rv index.html index.js style.css $out/usr/lib/routemon-web/htdocs
62
63 runHook postInstall
64 '';
65 };
51 in 66 in
52 { 67 {
53 packages.routemon = routemon; 68 packages.routemon-server = routemon-server;
69 packages.routemon-web = routemon-web;
54 70
55 devShells.default = pkgs.mkShell.override { inherit stdenv; } { 71 devShells.default = pkgs.mkShell.override { inherit stdenv; } {
56 buildInputs = [ pkgs.nix-index pkgs.nix-tree ]; 72 buildInputs = [ pkgs.nix-index pkgs.nix-tree ];
57 inputsFrom = [ routemon ]; 73 inputsFrom = [ routemon-server ];
58 }; 74 };
59 75
60 formatter = pkgs.nixpkgs-fmt; 76 formatter = pkgs.nixpkgs-fmt;
diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt
index 15ebfae..014ec7c 100644
--- a/server/CMakeLists.txt
+++ b/server/CMakeLists.txt
@@ -9,7 +9,7 @@ add_compile_options(
9 -fno-omit-frame-pointer 9 -fno-omit-frame-pointer
10 -Wall -Wextra -Wformat -Wformat=2 -Wconversion -Wimplicit-fallthrough 10 -Wall -Wextra -Wformat -Wformat=2 -Wconversion -Wimplicit-fallthrough
11 -Werror=format-security 11 -Werror=format-security
12 -U_FORTIFY_SOURCE # -D_FORTIFY_SOURCE=3 (unfortunately breaks the std module) 12 -U_FORTIFY_SOURCE # -D_FORTIFY_SOURCE=3 (unfortunately breaks the std module, see https://github.com/llvm/llvm-project/issues/121709)
13 -D_GLIBCXX_ASSERTIONS 13 -D_GLIBCXX_ASSERTIONS
14 -fstrict-flex-arrays=3 14 -fstrict-flex-arrays=3
15 -fstack-clash-protection -fstack-protector-strong 15 -fstack-clash-protection -fstack-protector-strong
diff --git a/server/src/config.cpp b/server/src/config.cpp
index 5c1a161..200b873 100644
--- a/server/src/config.cpp
+++ b/server/src/config.cpp
@@ -182,7 +182,8 @@ auto tag_invoke(
182 [](object_reader& r) -> http_server 182 [](object_reader& r) -> http_server
183 { 183 {
184 return { 184 return {
185 .lax_cors = r.expect_at<bool>("lax_cors"), 185 .allow_origins =
186 r.expect_at<std::vector<std::string>>("allow_origins"),
186 }; 187 };
187 }); 188 });
188} 189}
diff --git a/server/src/config.cppm b/server/src/config.cppm
index 358a961..ab9b137 100644
--- a/server/src/config.cppm
+++ b/server/src/config.cppm
@@ -23,7 +23,7 @@ export struct database
23 23
24export struct http_server 24export struct http_server
25{ 25{
26 bool lax_cors; 26 std::vector<std::string> allow_origins;
27}; 27};
28 28
29export struct logger 29export struct logger
diff --git a/server/src/http_server.cppm b/server/src/http_server.cppm
index dc8c183..b16f3a8 100644
--- a/server/src/http_server.cppm
+++ b/server/src/http_server.cppm
@@ -15,7 +15,7 @@ export module routemon:http.server;
15import std; 15import std;
16import :config; 16import :config;
17import :trace; 17import :trace;
18export import :http.common; 18import :http.common;
19import :problem; 19import :problem;
20 20
21namespace net = boost::asio; 21namespace net = boost::asio;
@@ -157,14 +157,33 @@ using middleware_t =
157 ->net::awaitable<presponse>>; 157 ->net::awaitable<presponse>>;
158 158
159template <class Ctx> 159template <class Ctx>
160auto lax_cors_middleware( 160auto id_middleware(
161 Ctx ctx, bhttp::request_header<bhttp::fields>& req_hdr, 161 Ctx ctx, bhttp::request_header<bhttp::fields>&, next_handler_t<Ctx> next)
162 next_handler_t<Ctx> next) -> net::awaitable<presponse> 162 -> net::awaitable<presponse>
163{ 163{
164 std::ignore = req_hdr; 164 co_return co_await next(std::move(ctx));
165 auto prersp = co_await next(ctx); 165}
166 prersp.header().set(bhttp::field::access_control_allow_origin, "*"); 166
167 co_return std::move(prersp); 167template <class Ctx>
168auto cors_middleware(std::vector<std::string> const& allow_origins)
169 -> middleware_t<Ctx, Ctx>
170{
171 if (allow_origins.empty())
172 return id_middleware<Ctx>;
173
174 auto header_str = allow_origins
175 | std::views::join_with(std::string_view{", "})
176 | std::ranges::to<std::string>();
177
178 return [header_str = std::move(header_str)](
179 Ctx ctx, bhttp::request_header<bhttp::fields>& req_hdr,
180 next_handler_t<Ctx> next) -> net::awaitable<presponse>
181 {
182 std::ignore = req_hdr;
183 auto prersp = co_await next(ctx);
184 prersp.header().set(bhttp::field::access_control_allow_origin, header_str);
185 co_return std::move(prersp);
186 };
168} 187}
169 188
170template <class InnerCtx> 189template <class InnerCtx>
@@ -310,14 +329,6 @@ auto default_options_handler(
310auto global_options_handler(base_ctx const& ctx, readable_request r) 329auto global_options_handler(base_ctx const& ctx, readable_request r)
311 -> net::awaitable<presponse>; 330 -> net::awaitable<presponse>;
312 331
313template <class Ctx>
314auto id_middleware(
315 Ctx ctx, bhttp::request_header<bhttp::fields>&, next_handler_t<Ctx> next)
316 -> net::awaitable<presponse>
317{
318 co_return co_await next(std::move(ctx));
319}
320
321template <class A, class B, class C> 332template <class A, class B, class C>
322auto middleware_compose(middleware_t<A, B> ab, middleware_t<B, C> bc) 333auto middleware_compose(middleware_t<A, B> ab, middleware_t<B, C> bc)
323 -> middleware_t<A, C> 334 -> middleware_t<A, C>
diff --git a/server/src/main.cpp b/server/src/main.cpp
index d5fcd42..b0a9938 100644
--- a/server/src/main.cpp
+++ b/server/src/main.cpp
@@ -105,8 +105,9 @@ auto real_main(std::span<char const*> args) -> exit_status
105 l.info("Loading situations finished in {}", dur_load); 105 l.info("Loading situations finished in {}", dur_load);
106 106
107 auto handler = routemon::api::handler{l, std::move(pub)}; 107 auto handler = routemon::api::handler{l, std::move(pub)};
108 auto http_server = 108 auto http_server = routemon::srv::server{
109 routemon::srv::server{l, std::move(lsel), std::move(handler)}; 109 l, config.http_server, std::move(lsel), std::move(handler)
110 };
110 http_server.spawn(ioc); 111 http_server.spawn(ioc);
111 ioc.run(); 112 ioc.run();
112 113
diff --git a/server/src/srv.cpp b/server/src/srv.cpp
index 00a2bb8..b70f05c 100644
--- a/server/src/srv.cpp
+++ b/server/src/srv.cpp
@@ -232,22 +232,24 @@ auto handler::make_routes() -> http::route_tree<http::routed_ctx<outer_ctx>>
232 }); 232 });
233} 233}
234 234
235auto server::make_global_middleware() 235auto server::make_global_middleware(config::http_server const& cfg)
236 -> http::middleware_t<http::base_ctx, handler::outer_ctx> 236 -> http::middleware_t<http::base_ctx, handler::outer_ctx>
237{ 237{
238 return http::middleware_compose< 238 return http::middleware_compose<
239 http::base_ctx, http::trace_id_ctx<http::base_ctx>, 239 http::base_ctx, http::trace_id_ctx<http::base_ctx>,
240 http::trace_id_ctx<http::base_ctx> 240 http::trace_id_ctx<http::base_ctx>
241 >(http::trace_id_middleware<http::base_ctx>, 241 >(http::trace_id_middleware<http::base_ctx>,
242 http::lax_cors_middleware<http::trace_id_ctx<http::base_ctx>>); 242 http::cors_middleware<http::trace_id_ctx<http::base_ctx>>(
243 cfg.allow_origins));
243} 244}
244 245
245server::server( 246server::server(
246 log::logger const& l, locale::selector&& lsel, api::handler&& inner) 247 log::logger const& l, config::http_server const& cfg,
248 locale::selector&& lsel, api::handler&& inner)
247 : handler_{std::move(inner)}, 249 : handler_{std::move(inner)},
248 srv_{ 250 srv_{
249 l, http::router{ 251 l, http::router{
250 std::move(lsel), make_global_middleware(), handler_.make_routes() 252 std::move(lsel), make_global_middleware(cfg), handler_.make_routes()
251 } 253 }
252 } 254 }
253{ 255{
diff --git a/server/src/srv.cppm b/server/src/srv.cppm
index 1d082fb..063617e 100644
--- a/server/src/srv.cppm
+++ b/server/src/srv.cppm
@@ -35,11 +35,13 @@ export class server
35 handler handler_; 35 handler handler_;
36 http::server srv_; 36 http::server srv_;
37 37
38 static auto make_global_middleware() 38 static auto make_global_middleware(config::http_server const& cfg)
39 -> http::middleware_t<http::base_ctx, handler::outer_ctx>; 39 -> http::middleware_t<http::base_ctx, handler::outer_ctx>;
40 40
41public: 41public:
42 server(log::logger const& l, locale::selector&& lsel, api::handler&& inner); 42 server(
43 log::logger const& l, config::http_server const& cfg,
44 locale::selector&& lsel, api::handler&& inner);
43 45
44 auto spawn(net::io_context& ioc) -> void; 46 auto spawn(net::io_context& ioc) -> void;
45}; 47};
diff --git a/todo.org b/todo.org
index ebddd19..91c02e3 100644
--- a/todo.org
+++ b/todo.org
@@ -1 +1,2 @@
1- [ ] Accept-Language negotation does not work as expected 1- [ ] Accept-Language negotation does not work as expected
2- [ ] Expect: 100-continue support in HTTP server?
diff --git a/web/index.html b/web/index.html
index f927d39..0fa0cea 100644
--- a/web/index.html
+++ b/web/index.html
@@ -47,6 +47,6 @@
47 </dialog> 47 </dialog>
48 48
49 <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.js" integrity="sha512-BwHfrr4c9kmRkLw6iXFdzcdWV/PGkVgiIyIWLLlTSXzWQzxuSg4DiQUCpauz/EWjgk5TYQqX/kvn9pG1NpYfqg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> 49 <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.js" integrity="sha512-BwHfrr4c9kmRkLw6iXFdzcdWV/PGkVgiIyIWLLlTSXzWQzxuSg4DiQUCpauz/EWjgk5TYQqX/kvn9pG1NpYfqg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
50 <script src="script.js"></script> 50 <script src="index.js"></script>
51 </body> 51 </body>
52</html> 52</html>
diff --git a/web/script.js b/web/index.js
index b3179b3..316e73f 100644
--- a/web/script.js
+++ b/web/index.js
@@ -1,3 +1,5 @@
1const apiBaseUrl = "https://api.routemon.fautchen.eu";
2
1const dialog = document.querySelector("dialog"); 3const dialog = document.querySelector("dialog");
2const closeButton = document.querySelector("dialog button"); 4const closeButton = document.querySelector("dialog button");
3closeButton.addEventListener("click", () => { 5closeButton.addEventListener("click", () => {
@@ -73,7 +75,7 @@ async function showProblem(rsp) {
73} 75}
74 76
75async function getSysinfo() { 77async function getSysinfo() {
76 const rsp = await fetch("http://localhost:8284/sysinfo", { 78 const rsp = await fetch(apiBaseUrl + "/sysinfo", {
77 method: "GET", 79 method: "GET",
78 headers: { 80 headers: {
79 "Accept-Language": "nl-NL", 81 "Accept-Language": "nl-NL",
@@ -89,7 +91,7 @@ async function getSysinfo() {
89} 91}
90 92
91async function load(gpxFile) { 93async function load(gpxFile) {
92 const rsp = await fetch("http://localhost:8284/gpx", { 94 const rsp = await fetch(apiBaseUrl + "/gpx", {
93 method: "POST", 95 method: "POST",
94 headers: { 96 headers: {
95 "Accept-Language": "nl-NL", 97 "Accept-Language": "nl-NL",