[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.
This commit is contained in:
Matthieu Gautier 2019-08-11 11:27:54 +02:00
parent de819dff25
commit 7060afae66
4 changed files with 64 additions and 16 deletions

View File

@ -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<std::chrono::duration<double>>(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();

View File

@ -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:

View File

@ -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

16
static/templates/500.html Normal file
View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<meta content="text/html;charset=UTF-8" http-equiv="content-type" />
<title>Internal Server Error</title>
</head>
<body>
<h1>Internal Server Error</h1>
<p>
An internal server error occured. We are sorry about that :/
</p>
<p>
{{ error }}
</p>
</body>
</html>