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+
1671static 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-
293312static 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;
0 commit comments