Skip to content

Commit b9c0ec7

Browse files
committed
web: remove doc_root / -dir static file serving
Assets are now embedded in the binary, so the on-disk fallback path and the doc_root parameter threaded through Listener → DetectSession → HttpSession → handle_request are dead code. Remove them and deprecate the -dir flag in the Tcl command. Also tighten -web_port parsing with std::from_chars and range validation. Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
1 parent a025f80 commit b9c0ec7

6 files changed

Lines changed: 21 additions & 71 deletions

File tree

src/Main.cc

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <strings.h>
66

77
#include <array>
8+
#include <charconv>
89
#include <climits>
910
#include <clocale>
1011
#include <csignal>
@@ -397,8 +398,17 @@ static int tclAppInit(int& argc,
397398
// Start the web server before sourcing the script so the user can
398399
// watch execution in real-time (analogous to -gui).
399400
if (web_enabled) {
400-
int port = web_port_arg ? std::atoi(web_port_arg) : 0;
401-
ord::OpenRoad::openRoad()->getWebServer()->serve(port, "");
401+
int port = 0;
402+
if (web_port_arg) {
403+
const char* end = web_port_arg + std::strlen(web_port_arg);
404+
auto [ptr, ec] = std::from_chars(web_port_arg, end, port);
405+
if (ec != std::errc{} || ptr != end || port < 0 || port > 65535) {
406+
fprintf(
407+
stderr, "Error: invalid -web_port value '%s'\n", web_port_arg);
408+
exit(EXIT_FAILURE);
409+
}
410+
}
411+
ord::OpenRoad::openRoad()->getWebServer()->serve(port);
402412
}
403413

404414
// gui::Gui::enabled() is true when a HeadlessViewer is installed

src/web/include/web/web.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ ListenerHandle createAndRunListener(
5353
std::shared_ptr<TclEvaluator> tcl_eval,
5454
std::shared_ptr<TimingReport> timing_report,
5555
std::shared_ptr<ClockTreeReport> clock_report,
56-
const std::string& doc_root,
5756
utl::Logger* logger,
5857
WebViewerHook* viewer_hook);
5958

@@ -74,7 +73,7 @@ class WebServer
7473
// Start the web server on the given port. Launches background
7574
// I/O threads and returns immediately. A second call is a no-op if
7675
// the server is already running.
77-
void serve(int port, const std::string& doc_root);
76+
void serve(int port);
7877

7978
// True after serve() returns and before stop/destructor.
8079
bool isRunning() const { return ioc_ != nullptr; }

src/web/src/web.cpp

Lines changed: 3 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,9 @@
1010
#include <cstdlib>
1111
#include <cstring>
1212
#include <deque>
13-
#include <filesystem>
1413
#include <fstream>
1514
#include <functional>
1615
#include <ios>
17-
#include <iterator>
1816
#include <limits>
1917
#include <memory>
2018
#include <mutex>
@@ -225,31 +223,9 @@ static std::vector<unsigned char> serialize_response(
225223
// HTTP request handler (wraps dispatch_request for HTTP transport)
226224
//------------------------------------------------------------------------------
227225

228-
static std::string content_type_for(const std::string& path)
229-
{
230-
auto ext = std::filesystem::path(path).extension().string();
231-
if (ext == ".html") {
232-
return "text/html";
233-
}
234-
if (ext == ".js") {
235-
return "application/javascript";
236-
}
237-
if (ext == ".css") {
238-
return "text/css";
239-
}
240-
if (ext == ".png") {
241-
return "image/png";
242-
}
243-
if (ext == ".json") {
244-
return "application/json";
245-
}
246-
return "application/octet-stream";
247-
}
248-
249226
static http::response<http::string_body> handle_request(
250227
http::request<http::string_body>&& req,
251-
const TileGenerator& generator,
252-
const std::string& doc_root)
228+
const TileGenerator& generator)
253229
{
254230
http::response<http::string_body> res{http::status::ok, req.version()};
255231
res.set(http::field::server, "Boost.Beast Server (C++17)");
@@ -297,24 +273,10 @@ static http::response<http::string_body> handle_request(
297273
if (file_path == "/") {
298274
file_path = "/index.html";
299275
}
300-
// Try embedded assets first (compiled into the binary).
301276
const auto* asset = findEmbeddedAsset(file_path);
302277
if (asset) {
303278
res.set(http::field::content_type, asset->content_type);
304279
res.body() = std::string(asset->content());
305-
} else if (!doc_root.empty() && file_path.find("..") == std::string::npos) {
306-
// Fall back to on-disk files for development override.
307-
auto full_path = std::filesystem::path(doc_root) / file_path.substr(1);
308-
std::ifstream file(full_path, std::ios::binary);
309-
if (file) {
310-
std::string content((std::istreambuf_iterator<char>(file)),
311-
std::istreambuf_iterator<char>());
312-
res.set(http::field::content_type, content_type_for(file_path));
313-
res.body() = std::move(content);
314-
} else {
315-
res.result(http::status::not_found);
316-
res.body() = "File not found.";
317-
}
318280
} else {
319281
res.result(http::status::not_found);
320282
res.body() = "Resource not found.";
@@ -864,13 +826,11 @@ class HttpSession : public std::enable_shared_from_this<HttpSession>
864826
std::shared_ptr<TileGenerator> generator_;
865827
std::shared_ptr<http::response<http::string_body>> res_;
866828
http::request<http::string_body> req_;
867-
std::string doc_root_;
868829
utl::Logger* logger_;
869830

870831
public:
871832
HttpSession(Tcp::socket&& socket,
872833
std::shared_ptr<TileGenerator> generator,
873-
std::string doc_root,
874834
utl::Logger* logger);
875835

876836
void run() { do_read(); }
@@ -888,11 +848,9 @@ class HttpSession : public std::enable_shared_from_this<HttpSession>
888848

889849
HttpSession::HttpSession(Tcp::socket&& socket,
890850
std::shared_ptr<TileGenerator> generator,
891-
std::string doc_root,
892851
utl::Logger* logger)
893852
: stream_(std::move(socket)),
894853
generator_(std::move(generator)),
895-
doc_root_(std::move(doc_root)),
896854
logger_(logger)
897855
{
898856
}
@@ -930,7 +888,7 @@ void HttpSession::on_read(beast::error_code ec)
930888
}
931889

932890
res_ = std::make_shared<http::response<http::string_body>>(
933-
handle_request(std::move(req_), *generator_, doc_root_));
891+
handle_request(std::move(req_), *generator_));
934892
do_write();
935893
}
936894

@@ -981,7 +939,6 @@ class DetectSession : public std::enable_shared_from_this<DetectSession>
981939
std::shared_ptr<TimingReport> timing_report_;
982940
std::shared_ptr<ClockTreeReport> clock_report_;
983941
http::request<http::string_body> req_;
984-
std::string doc_root_;
985942
utl::Logger* logger_;
986943
WebViewerHook* viewer_hook_ = nullptr;
987944

@@ -991,7 +948,6 @@ class DetectSession : public std::enable_shared_from_this<DetectSession>
991948
std::shared_ptr<TclEvaluator> tcl_eval,
992949
std::shared_ptr<TimingReport> timing_report,
993950
std::shared_ptr<ClockTreeReport> clock_report,
994-
std::string doc_root,
995951
utl::Logger* logger,
996952
WebViewerHook* viewer_hook);
997953

@@ -1006,15 +962,13 @@ DetectSession::DetectSession(Tcp::socket&& socket,
1006962
std::shared_ptr<TclEvaluator> tcl_eval,
1007963
std::shared_ptr<TimingReport> timing_report,
1008964
std::shared_ptr<ClockTreeReport> clock_report,
1009-
std::string doc_root,
1010965
utl::Logger* logger,
1011966
WebViewerHook* viewer_hook)
1012967
: stream_(std::move(socket)),
1013968
generator_(std::move(generator)),
1014969
tcl_eval_(std::move(tcl_eval)),
1015970
timing_report_(std::move(timing_report)),
1016971
clock_report_(std::move(clock_report)),
1017-
doc_root_(std::move(doc_root)),
1018972
logger_(logger),
1019973
viewer_hook_(viewer_hook)
1020974
{
@@ -1053,7 +1007,7 @@ void DetectSession::on_read(beast::error_code ec)
10531007
} else {
10541008
// Regular HTTP - hand off to session with already-read request
10551009
auto s = std::make_shared<HttpSession>(
1056-
stream_.release_socket(), generator_, doc_root_, logger_);
1010+
stream_.release_socket(), generator_, logger_);
10571011
s->run_with_request(std::move(req_), std::move(buffer_));
10581012
}
10591013
}
@@ -1070,7 +1024,6 @@ class Listener : public std::enable_shared_from_this<Listener>
10701024
std::shared_ptr<TclEvaluator> tcl_eval_;
10711025
std::shared_ptr<TimingReport> timing_report_;
10721026
std::shared_ptr<ClockTreeReport> clock_report_;
1073-
std::string doc_root_;
10741027
utl::Logger* logger_;
10751028
WebViewerHook* viewer_hook_ = nullptr;
10761029

@@ -1081,7 +1034,6 @@ class Listener : public std::enable_shared_from_this<Listener>
10811034
std::shared_ptr<TclEvaluator> tcl_eval,
10821035
std::shared_ptr<TimingReport> timing_report,
10831036
std::shared_ptr<ClockTreeReport> clock_report,
1084-
std::string doc_root,
10851037
utl::Logger* logger,
10861038
WebViewerHook* viewer_hook);
10871039

@@ -1110,7 +1062,6 @@ Listener::Listener(net::io_context& ioc,
11101062
std::shared_ptr<TclEvaluator> tcl_eval,
11111063
std::shared_ptr<TimingReport> timing_report,
11121064
std::shared_ptr<ClockTreeReport> clock_report,
1113-
std::string doc_root,
11141065
utl::Logger* logger,
11151066
WebViewerHook* viewer_hook)
11161067
: ioc_(ioc),
@@ -1119,7 +1070,6 @@ Listener::Listener(net::io_context& ioc,
11191070
tcl_eval_(std::move(tcl_eval)),
11201071
timing_report_(std::move(timing_report)),
11211072
clock_report_(std::move(clock_report)),
1122-
doc_root_(std::move(doc_root)),
11231073
logger_(logger),
11241074
viewer_hook_(viewer_hook)
11251075
{
@@ -1171,7 +1121,6 @@ void Listener::on_accept(beast::error_code ec, Tcp::socket socket)
11711121
tcl_eval_,
11721122
timing_report_,
11731123
clock_report_,
1174-
doc_root_,
11751124
logger_,
11761125
viewer_hook_)
11771126
->run();
@@ -1529,7 +1478,6 @@ ListenerHandle createAndRunListener(
15291478
std::shared_ptr<TclEvaluator> tcl_eval,
15301479
std::shared_ptr<TimingReport> timing_report,
15311480
std::shared_ptr<ClockTreeReport> clock_report,
1532-
const std::string& doc_root,
15331481
utl::Logger* logger,
15341482
WebViewerHook* viewer_hook)
15351483
{
@@ -1539,7 +1487,6 @@ ListenerHandle createAndRunListener(
15391487
std::move(tcl_eval),
15401488
std::move(timing_report),
15411489
std::move(clock_report),
1542-
doc_root,
15431490
logger,
15441491
viewer_hook);
15451492
listener->run();

src/web/src/web.i

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@
1313
namespace web {
1414

1515
void
16-
web_server_cmd(int port, const char* doc_root)
16+
web_server_cmd(int port)
1717
{
1818
web::WebServer *server = ord::OpenRoad::openRoad()->getWebServer();
19-
server->serve(port, doc_root);
19+
server->serve(port);
2020
}
2121

2222
void

src/web/src/web.tcl

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,11 @@ proc web_server { args } {
1919
set port $keys(-port)
2020
}
2121

22-
set dir ""
2322
if { [info exists keys(-dir)] } {
24-
set dir $keys(-dir)
23+
utl::warn WEB 37 "-dir is deprecated and ignored; assets are embedded in the binary."
2524
}
2625

27-
web::web_server_cmd $port $dir
26+
web::web_server_cmd $port
2827
web::web_server_wait_cmd
2928
}
3029

src/web/src/web_serve.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ class WebLogSink : public spdlog::sinks::base_sink<std::mutex>
102102
std::string pending_;
103103
};
104104

105-
void WebServer::serve(int port, const std::string& doc_root)
105+
void WebServer::serve(int port)
106106
{
107107
if (ioc_) {
108108
logger_->warn(utl::WEB, 6, "Web server is already running.");
@@ -165,10 +165,6 @@ void WebServer::serve(int port, const std::string& doc_root)
165165
uint16_t const u_port = port;
166166
int const num_threads = num_threads_;
167167

168-
if (!doc_root.empty()) {
169-
logger_->info(utl::WEB, 4, "Serving static files from {}", doc_root);
170-
}
171-
172168
ioc_ = std::make_unique<net::io_context>(num_threads);
173169

174170
auto handle = createAndRunListener(*ioc_,
@@ -177,7 +173,6 @@ void WebServer::serve(int port, const std::string& doc_root)
177173
tcl_eval,
178174
timing_report,
179175
clock_report,
180-
doc_root,
181176
logger_,
182177
viewer_hook_.get());
183178
shutdown_listener_ = std::move(handle.shutdown);

0 commit comments

Comments
 (0)