Skip to content

Commit f095996

Browse files
fix: loading error pages after building shared config
files for testing route specific error_pages
1 parent c6dd403 commit f095996

File tree

5 files changed

+73
-48
lines changed

5 files changed

+73
-48
lines changed

config/vitepress.conf

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,18 @@ server {
44
root www/vitepress_docs;
55

66
index index.html index.htm;
7+
error_page 404 /404.html;
8+
error_page 403 /404.html;
79

810
location / {
9-
error_page 404 /404.html;
10-
error_page 403 /404.html;
11+
error_page 404 /404_route_specific1.html;
1112
}
13+
14+
location /override/ {
15+
error_page 404 /404_route_specific2.html;
16+
}
17+
18+
location /nooverride/ {
19+
20+
}
1221
}

src/config/config_builder.cpp

Lines changed: 59 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,61 @@
1313
#include <cstdlib>
1414
#include <stdexcept>
1515

16+
static bool file_readable(const std::string& path)
17+
{
18+
struct stat sb;
19+
return (stat(path.c_str(), &sb) == 0 && S_ISREG(sb.st_mode));
20+
}
21+
22+
static bool read_error_page(const std::string& path, std::string& error_page_content)
23+
{
24+
if (!file_readable(path)) {
25+
LOG(DEBUG) << "error page not readable : " << path;
26+
return false;
27+
}
28+
29+
int fd = 0;
30+
char buf[4096];
31+
ssize_t bytes = 1;
32+
fd = open(path.c_str(), O_RDONLY);
33+
if (fd == -1) {
34+
return false;
35+
}
36+
37+
while (bytes) {
38+
bytes = read(fd, buf, sizeof(buf));
39+
if (bytes == 0) {
40+
break;
41+
}
42+
if (bytes < 0) {
43+
close(fd);
44+
return false;
45+
}
46+
error_page_content.append(buf, bytes);
47+
}
48+
close(fd);
49+
return true;
50+
}
51+
52+
static void update_error_pages(SharedConfig& shared)
53+
{
54+
for (std::map<HttpResponse::Status, std::string>::iterator it = shared.error_pages.begin();
55+
it != shared.error_pages.end();
56+
++it) {
57+
HttpResponse::Status status = it->first;
58+
const std::string& url = it->second;
59+
std::string path = shared.document_root + url;
60+
std::string error_page = "";
61+
if (read_error_page(path, error_page)) {
62+
LOG(DEBUG) << "ERROR page loaded : " << static_cast<int>(status) << " " << url;
63+
it->second = error_page;
64+
}
65+
else {
66+
it->second = "";
67+
}
68+
}
69+
}
70+
1671
static void config_error(const std::string& msg, int line = -1)
1772
{
1873
if (line == -1)
@@ -254,42 +309,6 @@ static void parse_client_max_body_size(const AstNode& node, SharedConfig& config
254309
config.max_body_size = size;
255310
}
256311

257-
static bool file_readable(const std::string& path)
258-
{
259-
struct stat sb;
260-
return (stat(path.c_str(), &sb) == 0 && S_ISREG(sb.st_mode));
261-
}
262-
263-
static bool read_error_page(const std::string& path, std::string& error_page_content)
264-
{
265-
if (!file_readable(path)) {
266-
LOG(DEBUG) << "error page not readable : " << path;
267-
return false;
268-
}
269-
270-
int fd = 0;
271-
char buf[4096];
272-
ssize_t bytes = 1;
273-
fd = open(path.c_str(), O_RDONLY);
274-
if (fd == -1) {
275-
return false;
276-
}
277-
278-
while (bytes) {
279-
bytes = read(fd, buf, sizeof(buf));
280-
if (bytes == 0) {
281-
break;
282-
}
283-
if (bytes < 0) {
284-
close(fd);
285-
return false;
286-
}
287-
error_page_content.append(buf, bytes);
288-
}
289-
close(fd);
290-
return true;
291-
}
292-
293312
static void parse_error_pages(const AstNode& node, SharedConfig& config)
294313
{
295314
expect_min_argc(node, 2);
@@ -301,15 +320,7 @@ static void parse_error_pages(const AstNode& node, SharedConfig& config)
301320

302321
if (status == HttpResponse::kStatusNone)
303322
config_error("'error_page' unsupported status code '" + node.args[i] + "'", node.line);
304-
305-
std::string error_page;
306-
std::string path =
307-
config.document_root +
308-
url; // potentially unsave ? if file cannot be loaded, default error pages are used
309-
if (read_error_page(path, error_page) == true) {
310-
LOG(DEBUG) << "ERROR page loaded : " << status << " " << url;
311-
config.error_pages[status] = error_page;
312-
}
323+
config.error_pages[status] = url;
313324
}
314325
}
315326

@@ -431,6 +442,9 @@ RouteConfig ConfigBuilder::build_route_config(const AstNode& node, const SharedC
431442
}
432443

433444
SharedConfig shared = build_shared_config(shared_nodes, &parent);
445+
446+
update_error_pages(shared); // loading the error pages
447+
434448
route.shared = shared;
435449

436450
return route;

src/router/router.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ Handler* Router::handle_request(const HttpRequest& request) const
123123
assert(!request.path.empty() && "Request URI can never be empty in the router");
124124

125125
const RouteConfig& best_route = find_best_route(request.path);
126-
126+
LOG(DEBUG) << "best_route.path = " << best_route.path;
127127
if (!best_route.shared.redirect.url.empty()) {
128128
return new RedirectHandler(best_route, request);
129129
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<h1>ROUTE1 404</h1>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<h1>ROUTE2 404</h1>

0 commit comments

Comments
 (0)