From f014fb289585bd196aae1473e943870d2414dfae Mon Sep 17 00:00:00 2001 From: Matthieu Gautier Date: Wed, 29 Jul 2020 11:31:17 +0200 Subject: [PATCH] Introduce a ContentResponse. This is only an "interface" for now as other type of response (entry) may be "transformed" to a ContentResponse. We cannot move all the code in the class. --- src/server/internalServer.cpp | 61 ++++++++++++++++++----------------- src/server/internalServer.h | 1 + src/server/response.cpp | 31 ++++++++++++++---- src/server/response.h | 8 ++++- 4 files changed, 64 insertions(+), 37 deletions(-) diff --git a/src/server/internalServer.cpp b/src/server/internalServer.cpp index bd0af5a9d..7c7d23386 100644 --- a/src/server/internalServer.cpp +++ b/src/server/internalServer.cpp @@ -232,10 +232,10 @@ MHD_Result InternalServer::handlerCallback(struct MHD_Connection* connection, std::unique_ptr InternalServer::build_304(const RequestContext& request, const ETag& etag) const { - auto response = Response::build(*this); + // This is just to set the m_mode. + auto response = ContentResponse::build(*this, "", ""); response->set_code(MHD_HTTP_NOT_MODIFIED); response->set_etag(etag); - response->set_content(""); return response; } @@ -410,9 +410,7 @@ std::unique_ptr InternalServer::handle_meta(const RequestContext& requ return build_404(request, bookName); } - auto response = Response::build(*this); - response->set_content(content); - response->set_mimeType(mimeType); + auto response = ContentResponse::build(*this, content, mimeType); response->set_compress(false); response->set_cacheable(); return response; @@ -489,17 +487,18 @@ std::unique_ptr InternalServer::handle_skin(const RequestContext& requ printf("** running handle_skin\n"); } - auto response = Response::build(*this); auto resourceName = request.get_url().substr(1); try { - response->set_content(getResource(resourceName)); + auto response = ContentResponse::build( + *this, + getResource(resourceName), + getMimeTypeForFile(resourceName)); + response->set_compress(true); + response->set_cacheable(); + return response; } catch (const ResourceNotFound& e) { return build_404(request, ""); } - response->set_mimeType(getMimeTypeForFile(resourceName)); - response->set_compress(true); - response->set_cacheable(); - return response; } std::unique_ptr InternalServer::handle_search(const RequestContext& request) @@ -563,15 +562,14 @@ std::unique_ptr InternalServer::handle_search(const RequestContext& re } /* Make the search */ - auto response = Response::build(*this); - response->set_mimeType("text/html; charset=utf-8"); - response->set_taskbar(bookName, reader ? reader->getTitle() : ""); - response->set_compress(true); - if ( (!reader && !bookName.empty()) || (patternString.empty() && ! has_geo_query) ) { auto data = get_default_data(); data.set("pattern", encodeDiples(patternString)); + auto response = Response::build(*this); + response->set_mimeType("text/html; charset=utf-8"); + response->set_taskbar(bookName, reader ? reader->getTitle() : ""); + response->set_compress(true); response->set_template(RESOURCE::templates::no_search_result_html, data); response->set_code(MHD_HTTP_NOT_FOUND); return response; @@ -622,18 +620,20 @@ std::unique_ptr InternalServer::handle_search(const RequestContext& re renderer.setProtocolPrefix(m_root + "/"); renderer.setSearchProtocolPrefix(m_root + "/search?"); renderer.setPageLength(pageLength); - response->set_content(renderer.getHtml()); + auto response = ContentResponse::build(*this, renderer.getHtml(), "text/html; charset=utf-8"); + response->set_taskbar(bookName, reader ? reader->getTitle() : ""); + response->set_compress(true); + //changing status code if no result obtained + if(searcher.getEstimatedResultCount() == 0) + { + response->set_code(MHD_HTTP_NO_CONTENT); + } + + return response; } catch (const std::exception& e) { std::cerr << e.what() << std::endl; + return build_500(e.what()); } - - //changing status code if no result obtained - if(searcher.getEstimatedResultCount() == 0) - { - response.set_code(MHD_HTTP_NO_CONTENT); - } - - return response; } std::unique_ptr InternalServer::handle_random(const RequestContext& request) @@ -703,9 +703,9 @@ std::unique_ptr InternalServer::handle_catalog(const RequestContext& r return build_404(request, ""); } - auto response = Response::build(*this); - response->set_compress(true); if (url == "searchdescription.xml") { + auto response = Response::build(*this); + response->set_compress(true); response->set_template(RESOURCE::opensearchdescription_xml, get_default_data()); response->set_mimeType("application/opensearchdescription+xml"); return response; @@ -716,7 +716,6 @@ std::unique_ptr InternalServer::handle_catalog(const RequestContext& r opdsDumper.setRootLocation(m_root); opdsDumper.setSearchDescriptionUrl("catalog/searchdescription.xml"); opdsDumper.setLibrary(mp_library); - response->set_mimeType("application/atom+xml; profile=opds-catalog; kind=acquisition; charset=utf-8"); std::vector bookIdsToDump; if (url == "root.xml") { opdsDumper.setTitle("All zims"); @@ -764,7 +763,11 @@ std::unique_ptr InternalServer::handle_catalog(const RequestContext& r } opdsDumper.setId(kiwix::to_string(uuid)); - response->set_content(opdsDumper.dumpOPDSFeed(bookIdsToDump)); + auto response = ContentResponse::build( + *this, + opdsDumper.dumpOPDSFeed(bookIdsToDump), + "application/atom+xml; profile=opds-catalog; kind=acquisition; charset=utf-8"); + response->set_compress(true); return response; } diff --git a/src/server/internalServer.h b/src/server/internalServer.h index 9ac9f4aae..ba34fd3d2 100644 --- a/src/server/internalServer.h +++ b/src/server/internalServer.h @@ -107,6 +107,7 @@ class InternalServer { friend std::unique_ptr Response::build(const InternalServer& server); friend std::unique_ptr RedirectionResponse::build(const InternalServer& server, const std::string& redirectionUrl); + friend std::unique_ptr ContentResponse::build(const InternalServer& server, const std::string& content, const std::string& mimetype); }; } diff --git a/src/server/response.cpp b/src/server/response.cpp index f40321aae..9fac355b2 100644 --- a/src/server/response.cpp +++ b/src/server/response.cpp @@ -320,11 +320,7 @@ MHD_Result Response::send(const RequestContext& request, MHD_Connection* connect } void Response::set_template(const std::string& template_str, kainjow::mustache::data data) { - set_content(render_template(template_str, data)); -} - -void Response::set_content(const std::string& content) { - m_content = content; + m_content = render_template(template_str, data); m_mode = ResponseMode::RAW_CONTENT; } @@ -342,11 +338,12 @@ void Response::set_entry(const Entry& entry, const RequestContext& request) { zim::Blob raw_content = entry.getBlob(); const std::string content = string(raw_content.data(), raw_content.size()); - set_content(content); + m_content = content; + m_mode = ResponseMode::RAW_CONTENT; set_compress(true); } else if ( m_byteRange.kind() == ByteRange::RESOLVED_UNSATISFIABLE ) { set_code(416); - set_content(""); + m_content = ""; m_mode = ResponseMode::ERROR_RESPONSE; } } @@ -383,6 +380,26 @@ MHD_Response* RedirectionResponse::create_mhd_response(const RequestContext& req return response; } +ContentResponse::ContentResponse(const std::string& root, bool verbose, bool withTaskbar, bool withLibraryButton, bool blockExternalLinks, const std::string& content, const std::string& mimetype) : + Response(root, verbose, withTaskbar, withLibraryButton, blockExternalLinks) +{ + m_content = content; + m_mimeType = mimetype; + m_mode = ResponseMode::RAW_CONTENT; +} + +std::unique_ptr ContentResponse::build(const InternalServer& server, const std::string& content, const std::string& mimetype) +{ + return std::unique_ptr(new ContentResponse( + server.m_root, + server.m_verbose.load(), + server.m_withTaskbar, + server.m_withLibraryButton, + server.m_blockExternalLinks, + content, + mimetype)); +} + } diff --git a/src/server/response.h b/src/server/response.h index 6b46b3be4..837de396b 100644 --- a/src/server/response.h +++ b/src/server/response.h @@ -53,7 +53,6 @@ class Response { MHD_Result send(const RequestContext& request, MHD_Connection* connection); void set_template(const std::string& template_str, kainjow::mustache::data data); - void set_content(const std::string& content); void set_entry(const Entry& entry, const RequestContext& request); @@ -112,6 +111,13 @@ class RedirectionResponse : public Response { std::string m_redirectionUrl; }; +class ContentResponse : public Response { + public: + ContentResponse(const std::string& root, bool verbose, bool withTaskbar, bool withLibraryButton, bool blockExternalLinks, const std::string& content, const std::string& mimetype); + + static std::unique_ptr build(const InternalServer& server, const std::string& content, const std::string& mimetype); +}; + } #endif //KIWIXLIB_SERVER_RESPONSE_H