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

View File

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

View File

@ -146,17 +146,17 @@ std::unique_ptr<ContentResponse> ContentResponseBlueprint::generateResponseObjec
return r;
}
HTTPErrorHtmlResponse::HTTPErrorHtmlResponse(const InternalServer& server,
const RequestContext& request,
int httpStatusCode,
const std::string& pageTitleMsgId,
const std::string& headingMsgId,
const std::string& cssUrl)
HTTPErrorResponse::HTTPErrorResponse(const InternalServer& server,
const RequestContext& request,
int httpStatusCode,
const std::string& pageTitleMsgId,
const std::string& headingMsgId,
const std::string& cssUrl)
: ContentResponseBlueprint(&server,
&request,
httpStatusCode,
"text/html; charset=utf-8",
RESOURCE::templates::error_html)
request.get_requested_format() == "html" ? "text/html; charset=utf-8" : "application/xml; charset=utf-8",
request.get_requested_format() == "html" ? RESOURCE::templates::error_html : RESOURCE::templates::error_xml)
{
kainjow::mustache::list emptyList;
this->m_data = kainjow::mustache::object{
@ -167,51 +167,51 @@ HTTPErrorHtmlResponse::HTTPErrorHtmlResponse(const InternalServer& server,
};
}
HTTP404HtmlResponse::HTTP404HtmlResponse(const InternalServer& server,
const RequestContext& request)
: HTTPErrorHtmlResponse(server,
request,
MHD_HTTP_NOT_FOUND,
"404-page-title",
"404-page-heading")
HTTP404Response::HTTP404Response(const InternalServer& server,
const RequestContext& request)
: HTTPErrorResponse(server,
request,
MHD_HTTP_NOT_FOUND,
"404-page-title",
"404-page-heading")
{
}
HTTPErrorHtmlResponse& HTTP404HtmlResponse::operator+(UrlNotFoundMsg /*unused*/)
HTTPErrorResponse& HTTP404Response::operator+(UrlNotFoundMsg /*unused*/)
{
const std::string requestUrl = m_request.get_full_url();
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});
return *this;
}
HTTPErrorHtmlResponse& HTTPErrorHtmlResponse::operator+(const ParameterizedMessage& details)
HTTPErrorResponse& HTTPErrorResponse::operator+(const ParameterizedMessage& details)
{
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+=)
return *this + details;
}
HTTP400HtmlResponse::HTTP400HtmlResponse(const InternalServer& server,
const RequestContext& request)
: HTTPErrorHtmlResponse(server,
request,
MHD_HTTP_BAD_REQUEST,
"400-page-title",
"400-page-heading")
HTTP400Response::HTTP400Response(const InternalServer& server,
const RequestContext& request)
: HTTPErrorResponse(server,
request,
MHD_HTTP_BAD_REQUEST,
"400-page-title",
"400-page-heading")
{
}
HTTPErrorHtmlResponse& HTTP400HtmlResponse::operator+(InvalidUrlMsg /*unused*/)
HTTPErrorResponse& HTTP400Response::operator+(InvalidUrlMsg /*unused*/)
{
std::string requestUrl = m_request.get_full_url();
const auto query = m_request.get_query();
@ -222,19 +222,19 @@ HTTPErrorHtmlResponse& HTTP400HtmlResponse::operator+(InvalidUrlMsg /*unused*/)
return *this + msgTmpl.render({"url", requestUrl});
}
HTTP500HtmlResponse::HTTP500HtmlResponse(const InternalServer& server,
const RequestContext& request)
: HTTPErrorHtmlResponse(server,
request,
MHD_HTTP_INTERNAL_SERVER_ERROR,
"500-page-title",
"500-page-heading")
HTTP500Response::HTTP500Response(const InternalServer& server,
const RequestContext& request)
: HTTPErrorResponse(server,
request,
MHD_HTTP_INTERNAL_SERVER_ERROR,
"500-page-title",
"500-page-heading")
{
// operator+() is a state-modifying operator (akin to operator+=)
*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
// have to provide additional resources required for its proper rendering)

View File

@ -181,52 +181,52 @@ public: //data
std::unique_ptr<TaskbarInfo> m_taskbarInfo;
};
struct HTTPErrorHtmlResponse : ContentResponseBlueprint
struct HTTPErrorResponse : ContentResponseBlueprint
{
HTTPErrorHtmlResponse(const InternalServer& server,
const RequestContext& request,
int httpStatusCode,
const std::string& pageTitleMsgId,
const std::string& headingMsgId,
const std::string& cssUrl = "");
HTTPErrorResponse(const InternalServer& server,
const RequestContext& request,
int httpStatusCode,
const std::string& pageTitleMsgId,
const std::string& headingMsgId,
const std::string& cssUrl = "");
using ContentResponseBlueprint::operator+;
using ContentResponseBlueprint::operator+=;
HTTPErrorHtmlResponse& operator+(const std::string& msg);
HTTPErrorHtmlResponse& operator+(const ParameterizedMessage& errorDetails);
HTTPErrorHtmlResponse& operator+=(const ParameterizedMessage& errorDetails);
HTTPErrorResponse& operator+(const std::string& msg);
HTTPErrorResponse& operator+(const ParameterizedMessage& errorDetails);
HTTPErrorResponse& operator+=(const ParameterizedMessage& errorDetails);
};
class UrlNotFoundMsg {};
extern const UrlNotFoundMsg urlNotFoundMsg;
struct HTTP404HtmlResponse : HTTPErrorHtmlResponse
struct HTTP404Response : HTTPErrorResponse
{
HTTP404HtmlResponse(const InternalServer& server,
const RequestContext& request);
HTTP404Response(const InternalServer& server,
const RequestContext& request);
using HTTPErrorHtmlResponse::operator+;
HTTPErrorHtmlResponse& operator+(UrlNotFoundMsg /*unused*/);
using HTTPErrorResponse::operator+;
HTTPErrorResponse& operator+(UrlNotFoundMsg /*unused*/);
};
class InvalidUrlMsg {};
extern const InvalidUrlMsg invalidUrlMsg;
struct HTTP400HtmlResponse : HTTPErrorHtmlResponse
struct HTTP400Response : HTTPErrorResponse
{
HTTP400HtmlResponse(const InternalServer& server,
const RequestContext& request);
HTTP400Response(const InternalServer& server,
const RequestContext& request);
using HTTPErrorHtmlResponse::operator+;
HTTPErrorHtmlResponse& operator+(InvalidUrlMsg /*unused*/);
using HTTPErrorResponse::operator+;
HTTPErrorResponse& operator+(InvalidUrlMsg /*unused*/);
};
struct HTTP500HtmlResponse : HTTPErrorHtmlResponse
struct HTTP500Response : HTTPErrorResponse
{
HTTP500HtmlResponse(const InternalServer& server,
const RequestContext& request);
HTTP500Response(const InternalServer& server,
const RequestContext& request);
private: // overrides
// generateResponseObject() is overriden in order to produce a minimal

View File

@ -36,6 +36,7 @@ skin/search_results.css
templates/search_result.html
templates/search_result.xml
templates/error.html
templates/error.xml
templates/index.html
templates/suggestion.json
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}}