Make the HTTPErrorHtmlResponse not Html only.

This commit is contained in:
Matthieu Gautier 2022-05-11 12:15:57 +02:00
parent e51a5b9ebc
commit cadd2a5cbb
6 changed files with 89 additions and 83 deletions

View File

@ -499,7 +499,7 @@ std::unique_ptr<Response> InternalServer::handle_request(const RequestContext& r
{ {
try { try {
if (! request.is_valid_url()) { if (! request.is_valid_url()) {
return HTTP404HtmlResponse(*this, request) return HTTP404Response(*this, request)
+ urlNotFoundMsg; + urlNotFoundMsg;
} }
@ -539,11 +539,11 @@ std::unique_ptr<Response> InternalServer::handle_request(const RequestContext& r
return handle_content(request); return handle_content(request);
} catch (std::exception& e) { } catch (std::exception& e) {
fprintf(stderr, "===== Unhandled error : %s\n", e.what()); fprintf(stderr, "===== Unhandled error : %s\n", e.what());
return HTTP500HtmlResponse(*this, request) return HTTP500Response(*this, request)
+ e.what(); + e.what();
} catch (...) { } catch (...) {
fprintf(stderr, "===== Unhandled unknown error\n"); fprintf(stderr, "===== Unhandled unknown error\n");
return HTTP500HtmlResponse(*this, request) return HTTP500Response(*this, request)
+ "Unknown error"; + "Unknown error";
} }
} }
@ -636,7 +636,7 @@ std::unique_ptr<Response> InternalServer::handle_suggest(const RequestContext& r
} }
if (archive == nullptr) { if (archive == nullptr) {
return HTTP404HtmlResponse(*this, request) return HTTP404Response(*this, request)
+ noSuchBookErrorMsg(bookName) + noSuchBookErrorMsg(bookName)
+ TaskbarInfo(bookName); + TaskbarInfo(bookName);
} }
@ -709,7 +709,7 @@ std::unique_ptr<Response> InternalServer::handle_skin(const RequestContext& requ
response->set_cacheable(); response->set_cacheable();
return std::move(response); return std::move(response);
} catch (const ResourceNotFound& e) { } catch (const ResourceNotFound& e) {
return HTTP404HtmlResponse(*this, request) return HTTP404Response(*this, request)
+ urlNotFoundMsg; + urlNotFoundMsg;
} }
} }
@ -740,7 +740,7 @@ std::unique_ptr<Response> InternalServer::handle_search(const RequestContext& re
// Searcher->search will throw a runtime error if there is no valid xapian database to do the search. // Searcher->search will throw a runtime error if there is no valid xapian database to do the search.
// (in case of zim file not containing a index) // (in case of zim file not containing a index)
const auto cssUrl = renderUrl(m_root, RESOURCE::templates::url_of_search_results_css); const auto cssUrl = renderUrl(m_root, RESOURCE::templates::url_of_search_results_css);
HTTPErrorHtmlResponse response(*this, request, MHD_HTTP_NOT_FOUND, HTTPErrorResponse response(*this, request, MHD_HTTP_NOT_FOUND,
"fulltext-search-unavailable", "fulltext-search-unavailable",
"404-page-heading", "404-page-heading",
cssUrl); cssUrl);
@ -790,7 +790,7 @@ std::unique_ptr<Response> InternalServer::handle_search(const RequestContext& re
} }
return std::move(response); return std::move(response);
} catch (const Error& e) { } catch (const Error& e) {
return HTTP400HtmlResponse(*this, request) return HTTP400Response(*this, request)
+ invalidUrlMsg + invalidUrlMsg
+ e.message(); + e.message();
} }
@ -813,7 +813,7 @@ std::unique_ptr<Response> InternalServer::handle_random(const RequestContext& re
} }
if (archive == nullptr) { if (archive == nullptr) {
return HTTP404HtmlResponse(*this, request) return HTTP404Response(*this, request)
+ noSuchBookErrorMsg(bookName) + noSuchBookErrorMsg(bookName)
+ TaskbarInfo(bookName); + TaskbarInfo(bookName);
} }
@ -822,7 +822,7 @@ std::unique_ptr<Response> InternalServer::handle_random(const RequestContext& re
auto entry = archive->getRandomEntry(); auto entry = archive->getRandomEntry();
return build_redirect(bookName, getFinalItem(*archive, entry)); return build_redirect(bookName, getFinalItem(*archive, entry));
} catch(zim::EntryNotFound& e) { } catch(zim::EntryNotFound& e) {
return HTTP404HtmlResponse(*this, request) return HTTP404Response(*this, request)
+ nonParameterizedMessage("random-article-failure") + nonParameterizedMessage("random-article-failure")
+ TaskbarInfo(bookName, archive.get()); + TaskbarInfo(bookName, archive.get());
} }
@ -836,7 +836,7 @@ std::unique_ptr<Response> InternalServer::handle_captured_external(const Request
} catch (const std::out_of_range& e) {} } catch (const std::out_of_range& e) {}
if (source.empty()) { if (source.empty()) {
return HTTP404HtmlResponse(*this, request) return HTTP404Response(*this, request)
+ urlNotFoundMsg; + urlNotFoundMsg;
} }
@ -857,7 +857,7 @@ std::unique_ptr<Response> InternalServer::handle_catalog(const RequestContext& r
host = request.get_header("Host"); host = request.get_header("Host");
url = request.get_url_part(1); url = request.get_url_part(1);
} catch (const std::out_of_range&) { } catch (const std::out_of_range&) {
return HTTP404HtmlResponse(*this, request) return HTTP404Response(*this, request)
+ urlNotFoundMsg; + urlNotFoundMsg;
} }
@ -866,7 +866,7 @@ std::unique_ptr<Response> InternalServer::handle_catalog(const RequestContext& r
} }
if (url != "searchdescription.xml" && url != "root.xml" && url != "search") { if (url != "searchdescription.xml" && url != "root.xml" && url != "search") {
return HTTP404HtmlResponse(*this, request) return HTTP404Response(*this, request)
+ urlNotFoundMsg; + urlNotFoundMsg;
} }
@ -963,7 +963,7 @@ std::unique_ptr<Response> InternalServer::handle_content(const RequestContext& r
if (archive == nullptr) { if (archive == nullptr) {
const std::string searchURL = m_root + "/search?pattern=" + kiwix::urlEncode(pattern, true); const std::string searchURL = m_root + "/search?pattern=" + kiwix::urlEncode(pattern, true);
return HTTP404HtmlResponse(*this, request) return HTTP404Response(*this, request)
+ urlNotFoundMsg + urlNotFoundMsg
+ suggestSearchMsg(searchURL, kiwix::urlDecode(pattern)) + suggestSearchMsg(searchURL, kiwix::urlDecode(pattern))
+ TaskbarInfo(bookName); + TaskbarInfo(bookName);
@ -997,7 +997,7 @@ std::unique_ptr<Response> InternalServer::handle_content(const RequestContext& r
printf("Failed to find %s\n", urlStr.c_str()); printf("Failed to find %s\n", urlStr.c_str());
std::string searchURL = m_root + "/search?content=" + bookName + "&pattern=" + kiwix::urlEncode(pattern, true); std::string searchURL = m_root + "/search?content=" + bookName + "&pattern=" + kiwix::urlEncode(pattern, true);
return HTTP404HtmlResponse(*this, request) return HTTP404Response(*this, request)
+ urlNotFoundMsg + urlNotFoundMsg
+ suggestSearchMsg(searchURL, kiwix::urlDecode(pattern)) + suggestSearchMsg(searchURL, kiwix::urlDecode(pattern))
+ TaskbarInfo(bookName, archive.get()); + TaskbarInfo(bookName, archive.get());
@ -1017,12 +1017,12 @@ std::unique_ptr<Response> InternalServer::handle_raw(const RequestContext& reque
bookName = request.get_url_part(1); bookName = request.get_url_part(1);
kind = request.get_url_part(2); kind = request.get_url_part(2);
} catch (const std::out_of_range& e) { } catch (const std::out_of_range& e) {
return HTTP404HtmlResponse(*this, request) return HTTP404Response(*this, request)
+ urlNotFoundMsg; + urlNotFoundMsg;
} }
if (kind != "meta" && kind!= "content") { if (kind != "meta" && kind!= "content") {
return HTTP404HtmlResponse(*this, request) return HTTP404Response(*this, request)
+ urlNotFoundMsg + urlNotFoundMsg
+ invalidRawAccessMsg(kind); + invalidRawAccessMsg(kind);
} }
@ -1034,7 +1034,7 @@ std::unique_ptr<Response> InternalServer::handle_raw(const RequestContext& reque
} catch (const std::out_of_range& e) {} } catch (const std::out_of_range& e) {}
if (archive == nullptr) { if (archive == nullptr) {
return HTTP404HtmlResponse(*this, request) return HTTP404Response(*this, request)
+ urlNotFoundMsg + urlNotFoundMsg
+ noSuchBookErrorMsg(bookName); + noSuchBookErrorMsg(bookName);
} }
@ -1060,7 +1060,7 @@ std::unique_ptr<Response> InternalServer::handle_raw(const RequestContext& reque
if (m_verbose.load()) { if (m_verbose.load()) {
printf("Failed to find %s\n", itemPath.c_str()); printf("Failed to find %s\n", itemPath.c_str());
} }
return HTTP404HtmlResponse(*this, request) return HTTP404Response(*this, request)
+ urlNotFoundMsg + urlNotFoundMsg
+ rawEntryNotFoundMsg(kind, itemPath); + rawEntryNotFoundMsg(kind, itemPath);
} }

View File

@ -43,7 +43,7 @@ std::unique_ptr<Response> InternalServer::handle_catalog_v2(const RequestContext
try { try {
url = request.get_url_part(2); url = request.get_url_part(2);
} catch (const std::out_of_range&) { } catch (const std::out_of_range&) {
return HTTP404HtmlResponse(*this, request) return HTTP404Response(*this, request)
+ urlNotFoundMsg; + urlNotFoundMsg;
} }
@ -70,7 +70,7 @@ std::unique_ptr<Response> InternalServer::handle_catalog_v2(const RequestContext
} else if (url == "illustration") { } else if (url == "illustration") {
return handle_catalog_v2_illustration(request); return handle_catalog_v2_illustration(request);
} else { } else {
return HTTP404HtmlResponse(*this, request) return HTTP404Response(*this, request)
+ urlNotFoundMsg; + urlNotFoundMsg;
} }
} }
@ -112,7 +112,7 @@ std::unique_ptr<Response> InternalServer::handle_catalog_v2_complete_entry(const
try { try {
mp_library->getBookById(entryId); mp_library->getBookById(entryId);
} catch (const std::out_of_range&) { } catch (const std::out_of_range&) {
return HTTP404HtmlResponse(*this, request) return HTTP404Response(*this, request)
+ urlNotFoundMsg; + urlNotFoundMsg;
} }
@ -161,7 +161,7 @@ std::unique_ptr<Response> InternalServer::handle_catalog_v2_illustration(const R
auto illustration = book.getIllustration(size); auto illustration = book.getIllustration(size);
return ContentResponse::build(*this, illustration->getData(), illustration->mimeType); return ContentResponse::build(*this, illustration->getData(), illustration->mimeType);
} catch(...) { } catch(...) {
return HTTP404HtmlResponse(*this, request) return HTTP404Response(*this, request)
+ urlNotFoundMsg; + urlNotFoundMsg;
} }
} }

View File

@ -146,7 +146,7 @@ std::unique_ptr<ContentResponse> ContentResponseBlueprint::generateResponseObjec
return r; return r;
} }
HTTPErrorHtmlResponse::HTTPErrorHtmlResponse(const InternalServer& server, HTTPErrorResponse::HTTPErrorResponse(const InternalServer& server,
const RequestContext& request, const RequestContext& request,
int httpStatusCode, int httpStatusCode,
const std::string& pageTitleMsgId, const std::string& pageTitleMsgId,
@ -155,8 +155,8 @@ HTTPErrorHtmlResponse::HTTPErrorHtmlResponse(const InternalServer& server,
: ContentResponseBlueprint(&server, : ContentResponseBlueprint(&server,
&request, &request,
httpStatusCode, httpStatusCode,
"text/html; charset=utf-8", request.get_requested_format() == "html" ? "text/html; charset=utf-8" : "application/xml; charset=utf-8",
RESOURCE::templates::error_html) request.get_requested_format() == "html" ? RESOURCE::templates::error_html : RESOURCE::templates::error_xml)
{ {
kainjow::mustache::list emptyList; kainjow::mustache::list emptyList;
this->m_data = kainjow::mustache::object{ this->m_data = kainjow::mustache::object{
@ -167,9 +167,9 @@ HTTPErrorHtmlResponse::HTTPErrorHtmlResponse(const InternalServer& server,
}; };
} }
HTTP404HtmlResponse::HTTP404HtmlResponse(const InternalServer& server, HTTP404Response::HTTP404Response(const InternalServer& server,
const RequestContext& request) const RequestContext& request)
: HTTPErrorHtmlResponse(server, : HTTPErrorResponse(server,
request, request,
MHD_HTTP_NOT_FOUND, MHD_HTTP_NOT_FOUND,
"404-page-title", "404-page-title",
@ -177,33 +177,33 @@ HTTP404HtmlResponse::HTTP404HtmlResponse(const InternalServer& server,
{ {
} }
HTTPErrorHtmlResponse& HTTP404HtmlResponse::operator+(UrlNotFoundMsg /*unused*/) HTTPErrorResponse& HTTP404Response::operator+(UrlNotFoundMsg /*unused*/)
{ {
const std::string requestUrl = m_request.get_full_url(); const std::string requestUrl = m_request.get_full_url();
return *this + ParameterizedMessage("url-not-found", {{"url", requestUrl}}); return *this + ParameterizedMessage("url-not-found", {{"url", requestUrl}});
} }
HTTPErrorHtmlResponse& HTTPErrorHtmlResponse::operator+(const std::string& msg) HTTPErrorResponse& HTTPErrorResponse::operator+(const std::string& msg)
{ {
m_data["details"].push_back({"p", msg}); m_data["details"].push_back({"p", msg});
return *this; return *this;
} }
HTTPErrorHtmlResponse& HTTPErrorHtmlResponse::operator+(const ParameterizedMessage& details) HTTPErrorResponse& HTTPErrorResponse::operator+(const ParameterizedMessage& details)
{ {
return *this + details.getText(m_request.get_user_language()); return *this + details.getText(m_request.get_user_language());
} }
HTTPErrorHtmlResponse& HTTPErrorHtmlResponse::operator+=(const ParameterizedMessage& details) HTTPErrorResponse& HTTPErrorResponse::operator+=(const ParameterizedMessage& details)
{ {
// operator+() is already a state-modifying operator (akin to operator+=) // operator+() is already a state-modifying operator (akin to operator+=)
return *this + details; return *this + details;
} }
HTTP400HtmlResponse::HTTP400HtmlResponse(const InternalServer& server, HTTP400Response::HTTP400Response(const InternalServer& server,
const RequestContext& request) const RequestContext& request)
: HTTPErrorHtmlResponse(server, : HTTPErrorResponse(server,
request, request,
MHD_HTTP_BAD_REQUEST, MHD_HTTP_BAD_REQUEST,
"400-page-title", "400-page-title",
@ -211,7 +211,7 @@ HTTP400HtmlResponse::HTTP400HtmlResponse(const InternalServer& server,
{ {
} }
HTTPErrorHtmlResponse& HTTP400HtmlResponse::operator+(InvalidUrlMsg /*unused*/) HTTPErrorResponse& HTTP400Response::operator+(InvalidUrlMsg /*unused*/)
{ {
std::string requestUrl = m_request.get_full_url(); std::string requestUrl = m_request.get_full_url();
const auto query = m_request.get_query(); const auto query = m_request.get_query();
@ -222,9 +222,9 @@ HTTPErrorHtmlResponse& HTTP400HtmlResponse::operator+(InvalidUrlMsg /*unused*/)
return *this + msgTmpl.render({"url", requestUrl}); return *this + msgTmpl.render({"url", requestUrl});
} }
HTTP500HtmlResponse::HTTP500HtmlResponse(const InternalServer& server, HTTP500Response::HTTP500Response(const InternalServer& server,
const RequestContext& request) const RequestContext& request)
: HTTPErrorHtmlResponse(server, : HTTPErrorResponse(server,
request, request,
MHD_HTTP_INTERNAL_SERVER_ERROR, MHD_HTTP_INTERNAL_SERVER_ERROR,
"500-page-title", "500-page-title",
@ -234,7 +234,7 @@ HTTP500HtmlResponse::HTTP500HtmlResponse(const InternalServer& server,
*this + "An internal server error occured. We are sorry about that :/"; *this + "An internal server error occured. We are sorry about that :/";
} }
std::unique_ptr<ContentResponse> HTTP500HtmlResponse::generateResponseObject() const std::unique_ptr<ContentResponse> HTTP500Response::generateResponseObject() const
{ {
// We want a 500 response to be a minimalistic one (so that the server doesn't // We want a 500 response to be a minimalistic one (so that the server doesn't
// have to provide additional resources required for its proper rendering) // have to provide additional resources required for its proper rendering)

View File

@ -181,9 +181,9 @@ public: //data
std::unique_ptr<TaskbarInfo> m_taskbarInfo; std::unique_ptr<TaskbarInfo> m_taskbarInfo;
}; };
struct HTTPErrorHtmlResponse : ContentResponseBlueprint struct HTTPErrorResponse : ContentResponseBlueprint
{ {
HTTPErrorHtmlResponse(const InternalServer& server, HTTPErrorResponse(const InternalServer& server,
const RequestContext& request, const RequestContext& request,
int httpStatusCode, int httpStatusCode,
const std::string& pageTitleMsgId, const std::string& pageTitleMsgId,
@ -192,40 +192,40 @@ struct HTTPErrorHtmlResponse : ContentResponseBlueprint
using ContentResponseBlueprint::operator+; using ContentResponseBlueprint::operator+;
using ContentResponseBlueprint::operator+=; using ContentResponseBlueprint::operator+=;
HTTPErrorHtmlResponse& operator+(const std::string& msg); HTTPErrorResponse& operator+(const std::string& msg);
HTTPErrorHtmlResponse& operator+(const ParameterizedMessage& errorDetails); HTTPErrorResponse& operator+(const ParameterizedMessage& errorDetails);
HTTPErrorHtmlResponse& operator+=(const ParameterizedMessage& errorDetails); HTTPErrorResponse& operator+=(const ParameterizedMessage& errorDetails);
}; };
class UrlNotFoundMsg {}; class UrlNotFoundMsg {};
extern const UrlNotFoundMsg urlNotFoundMsg; extern const UrlNotFoundMsg urlNotFoundMsg;
struct HTTP404HtmlResponse : HTTPErrorHtmlResponse struct HTTP404Response : HTTPErrorResponse
{ {
HTTP404HtmlResponse(const InternalServer& server, HTTP404Response(const InternalServer& server,
const RequestContext& request); const RequestContext& request);
using HTTPErrorHtmlResponse::operator+; using HTTPErrorResponse::operator+;
HTTPErrorHtmlResponse& operator+(UrlNotFoundMsg /*unused*/); HTTPErrorResponse& operator+(UrlNotFoundMsg /*unused*/);
}; };
class InvalidUrlMsg {}; class InvalidUrlMsg {};
extern const InvalidUrlMsg invalidUrlMsg; extern const InvalidUrlMsg invalidUrlMsg;
struct HTTP400HtmlResponse : HTTPErrorHtmlResponse struct HTTP400Response : HTTPErrorResponse
{ {
HTTP400HtmlResponse(const InternalServer& server, HTTP400Response(const InternalServer& server,
const RequestContext& request); const RequestContext& request);
using HTTPErrorHtmlResponse::operator+; using HTTPErrorResponse::operator+;
HTTPErrorHtmlResponse& operator+(InvalidUrlMsg /*unused*/); HTTPErrorResponse& operator+(InvalidUrlMsg /*unused*/);
}; };
struct HTTP500HtmlResponse : HTTPErrorHtmlResponse struct HTTP500Response : HTTPErrorResponse
{ {
HTTP500HtmlResponse(const InternalServer& server, HTTP500Response(const InternalServer& server,
const RequestContext& request); const RequestContext& request);
private: // overrides private: // overrides

View File

@ -36,6 +36,7 @@ skin/search_results.css
templates/search_result.html templates/search_result.html
templates/search_result.xml templates/search_result.xml
templates/error.html templates/error.html
templates/error.xml
templates/index.html templates/index.html
templates/suggestion.json templates/suggestion.json
templates/head_taskbar.html templates/head_taskbar.html

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8">
<error>{{PAGE_TITLE}}</error>
{{#details}}
<detail>{{{p}}}</detail>
{{/details}}