From 7060afae66fd8cf85f14f4ab9e49cee6806394c3 Mon Sep 17 00:00:00 2001 From: Matthieu Gautier Date: Sun, 11 Aug 2019 11:27:54 +0200 Subject: [PATCH] [SERVER] Catch any error and return a 500 response instead of crashing. The server will be running some code on the behalf of the calling code. We really don't what to crash the library (and the binary) because of a wrong request. --- src/server.cpp | 59 +++++++++++++++++++++++++++++---------- src/server/response.h | 2 ++ static/resources_list.txt | 3 +- static/templates/500.html | 16 +++++++++++ 4 files changed, 64 insertions(+), 16 deletions(-) create mode 100644 static/templates/500.html diff --git a/src/server.cpp b/src/server.cpp index 3a4e72ec7..fe9ebd85a 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -110,6 +110,7 @@ class InternalServer { private: Response handle_request(const RequestContext& request); + Response build_500(const std::string& msg); Response build_404(const RequestContext& request, const std::string& zimName); Response build_homepage(const RequestContext& request); Response handle_skin(const RequestContext& request); @@ -295,6 +296,15 @@ int InternalServer::handlerCallback(struct MHD_Connection* connection, auto response = handle_request(request); + if (response.getReturnCode() == MHD_HTTP_INTERNAL_SERVER_ERROR) { + printf("========== INTERNAL ERROR !! ============\n"); + if (!m_verbose.load()) { + printf("Requesting : \n"); + printf("full_url : %s\n", url); + request.print_debug_info(); + } + } + auto ret = response.send(request, connection); auto end_time = std::chrono::steady_clock::now(); auto time_span = std::chrono::duration_cast>(end_time - start_time); @@ -308,28 +318,36 @@ int InternalServer::handlerCallback(struct MHD_Connection* connection, Response InternalServer::handle_request(const RequestContext& request) { - if (! request.is_valid_url()) - return build_404(request, ""); + try { + if (! request.is_valid_url()) + return build_404(request, ""); - if (kiwix::startsWith(request.get_url(), "/skin/")) - return handle_skin(request); + if (kiwix::startsWith(request.get_url(), "/skin/")) + return handle_skin(request); - if (startsWith(request.get_url(), "/catalog")) - return handle_catalog(request); + if (startsWith(request.get_url(), "/catalog")) + return handle_catalog(request); - if (request.get_url() == "/meta") - return handle_meta(request); + if (request.get_url() == "/meta") + return handle_meta(request); - if (request.get_url() == "/search") - return handle_search(request); + if (request.get_url() == "/search") + return handle_search(request); - if (request.get_url() == "/suggest") - return handle_suggest(request); + if (request.get_url() == "/suggest") + return handle_suggest(request); - if (request.get_url() == "/random") - return handle_random(request); + if (request.get_url() == "/random") + return handle_random(request); - return handle_content(request); + return handle_content(request); + } catch (std::exception& e) { + fprintf(stderr, "===== Unhandled error : %s\n", e.what()); + return build_500(e.what()); + } catch (...) { + fprintf(stderr, "===== Unhandled unknown error\n"); + return build_500("Unknown error"); + } } kainjow::mustache::data InternalServer::get_default_data() @@ -361,6 +379,17 @@ Response InternalServer::build_404(const RequestContext& request, return response; } +Response InternalServer::build_500(const std::string& msg) +{ + kainjow::mustache::data data; + data.set("error", msg); + Response response(m_root, true, false, false); + response.set_template(RESOURCE::templates::_500_html, data); + response.set_mimeType("text/html"); + response.set_code(MHD_HTTP_INTERNAL_SERVER_ERROR); + return response; +} + Response InternalServer::build_homepage(const RequestContext& request) { auto data = get_default_data(); diff --git a/src/server/response.h b/src/server/response.h index f03f96f69..df372c25f 100644 --- a/src/server/response.h +++ b/src/server/response.h @@ -61,6 +61,8 @@ class Response { void set_range_first(uint64_t start) { m_startRange = start; } void set_range_len(uint64_t len) { m_lenRange = len; } + int getReturnCode() { return m_returnCode; } + void introduce_taskbar(); private: diff --git a/static/resources_list.txt b/static/resources_list.txt index 62cfe15de..607f30fe9 100644 --- a/static/resources_list.txt +++ b/static/resources_list.txt @@ -23,8 +23,9 @@ skin/taskbar.css templates/search_result.html templates/no_search_result.html templates/404.html +templates/500.html templates/index.html templates/suggestion.json -opensearchdescription.xml templates/head_part.html templates/taskbar_part.html +opensearchdescription.xml diff --git a/static/templates/500.html b/static/templates/500.html new file mode 100644 index 000000000..1b2692d5f --- /dev/null +++ b/static/templates/500.html @@ -0,0 +1,16 @@ + + + + + Internal Server Error + + +

Internal Server Error

+

+ An internal server error occured. We are sorry about that :/ +

+

+ {{ error }} +

+ +