From cadd2a5cbbe5ab7d8459dbc55da9d6556fe970e7 Mon Sep 17 00:00:00 2001 From: Matthieu Gautier Date: Wed, 11 May 2022 12:15:57 +0200 Subject: [PATCH] Make the HTTPErrorHtmlResponse not Html only. --- src/server/internalServer.cpp | 42 +++++++------- src/server/internalServer_catalog_v2.cpp | 8 +-- src/server/response.cpp | 70 ++++++++++++------------ src/server/response.h | 46 ++++++++-------- static/resources_list.txt | 1 + static/templates/error.xml | 5 ++ 6 files changed, 89 insertions(+), 83 deletions(-) create mode 100644 static/templates/error.xml diff --git a/src/server/internalServer.cpp b/src/server/internalServer.cpp index 3346747e6..75af18066 100644 --- a/src/server/internalServer.cpp +++ b/src/server/internalServer.cpp @@ -499,7 +499,7 @@ std::unique_ptr 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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); } diff --git a/src/server/internalServer_catalog_v2.cpp b/src/server/internalServer_catalog_v2.cpp index a5c9f49c8..79504e5de 100644 --- a/src/server/internalServer_catalog_v2.cpp +++ b/src/server/internalServer_catalog_v2.cpp @@ -43,7 +43,7 @@ std::unique_ptr 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 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 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 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; } } diff --git a/src/server/response.cpp b/src/server/response.cpp index 5543499fd..37f12fca4 100644 --- a/src/server/response.cpp +++ b/src/server/response.cpp @@ -146,17 +146,17 @@ std::unique_ptr 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 HTTP500HtmlResponse::generateResponseObject() const +std::unique_ptr 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) diff --git a/src/server/response.h b/src/server/response.h index 5c14e7786..afdbd336d 100644 --- a/src/server/response.h +++ b/src/server/response.h @@ -181,52 +181,52 @@ public: //data std::unique_ptr 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 diff --git a/static/resources_list.txt b/static/resources_list.txt index e14e604c9..c3b9c0d56 100644 --- a/static/resources_list.txt +++ b/static/resources_list.txt @@ -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 diff --git a/static/templates/error.xml b/static/templates/error.xml new file mode 100644 index 000000000..9d6eea7dc --- /dev/null +++ b/static/templates/error.xml @@ -0,0 +1,5 @@ + +{{PAGE_TITLE}} +{{#details}} +{{{p}}} +{{/details}}