diff --git a/src/meson.build b/src/meson.build index 21486bc4..818eb4f9 100644 --- a/src/meson.build +++ b/src/meson.build @@ -26,7 +26,7 @@ kiwix_sources = [ 'server/request_context.cpp', 'server/response.cpp', 'server/internalServer.cpp', - 'server/internalServer_catalog_v2.cpp', + 'server/internalServer_catalog.cpp', 'server/i18n.cpp', 'opds_catalog.cpp', 'version.cpp' diff --git a/src/server/internalServer.cpp b/src/server/internalServer.cpp index 67ddb987..4896cd5d 100644 --- a/src/server/internalServer.cpp +++ b/src/server/internalServer.cpp @@ -1046,56 +1046,6 @@ std::unique_ptr InternalServer::handle_catch(const RequestContext& req + urlNotFoundMsg; } -std::unique_ptr InternalServer::handle_catalog(const RequestContext& request) -{ - if (m_verbose.load()) { - printf("** running handle_catalog"); - } - - std::string host; - std::string url; - try { - host = request.get_header("Host"); - url = request.get_url_part(1); - } catch (const std::out_of_range&) { - return HTTP404Response(*this, request) - + urlNotFoundMsg; - } - - if (url == "v2") { - return handle_catalog_v2(request); - } - - if (url != "searchdescription.xml" && url != "root.xml" && url != "search") { - return HTTP404Response(*this, request) - + urlNotFoundMsg; - } - - if (url == "searchdescription.xml") { - auto response = ContentResponse::build(*this, RESOURCE::opensearchdescription_xml, get_default_data(), "application/opensearchdescription+xml"); - return std::move(response); - } - - zim::Uuid uuid; - kiwix::OPDSDumper opdsDumper(mp_library, mp_nameMapper); - opdsDumper.setRootLocation(m_root); - opdsDumper.setLibraryId(getLibraryId()); - std::vector bookIdsToDump; - if (url == "root.xml") { - uuid = zim::Uuid::generate(host); - bookIdsToDump = mp_library->filter(kiwix::Filter().valid(true).local(true).remote(true)); - } else if (url == "search") { - bookIdsToDump = search_catalog(request, opdsDumper); - uuid = zim::Uuid::generate(); - } - - auto response = ContentResponse::build( - *this, - opdsDumper.dumpOPDSFeed(bookIdsToDump, request.get_query()), - "application/atom+xml; profile=opds-catalog; kind=acquisition; charset=utf-8"); - return std::move(response); -} - std::vector InternalServer::search_catalog(const RequestContext& request, kiwix::OPDSDumper& opdsDumper) diff --git a/src/server/internalServer_catalog_v2.cpp b/src/server/internalServer_catalog.cpp similarity index 72% rename from src/server/internalServer_catalog_v2.cpp rename to src/server/internalServer_catalog.cpp index c0cb69ec..a43d968e 100644 --- a/src/server/internalServer_catalog_v2.cpp +++ b/src/server/internalServer_catalog.cpp @@ -33,6 +33,74 @@ namespace kiwix { +namespace +{ + +enum OPDSResponseKind +{ + OPDS_ENTRY, + OPDS_NAVIGATION_FEED, + OPDS_ACQUISITION_FEED +}; + +const std::string opdsMimeType[] = { + "application/atom+xml;type=entry;profile=opds-catalog;charset=utf-8", + "application/atom+xml;profile=opds-catalog;kind=navigation;charset=utf-8", + "application/atom+xml;profile=opds-catalog;kind=acquisition;charset=utf-8" +}; + +} // unnamed namespace + +std::unique_ptr InternalServer::handle_catalog(const RequestContext& request) +{ + if (m_verbose.load()) { + printf("** running handle_catalog"); + } + + std::string host; + std::string url; + try { + host = request.get_header("Host"); + url = request.get_url_part(1); + } catch (const std::out_of_range&) { + return HTTP404Response(*this, request) + + urlNotFoundMsg; + } + + if (url == "v2") { + return handle_catalog_v2(request); + } + + if (url != "searchdescription.xml" && url != "root.xml" && url != "search") { + return HTTP404Response(*this, request) + + urlNotFoundMsg; + } + + if (url == "searchdescription.xml") { + auto response = ContentResponse::build(*this, RESOURCE::opensearchdescription_xml, get_default_data(), "application/opensearchdescription+xml"); + return std::move(response); + } + + zim::Uuid uuid; + kiwix::OPDSDumper opdsDumper(mp_library, mp_nameMapper); + opdsDumper.setRootLocation(m_root); + opdsDumper.setLibraryId(getLibraryId()); + std::vector bookIdsToDump; + if (url == "root.xml") { + uuid = zim::Uuid::generate(host); + bookIdsToDump = mp_library->filter(kiwix::Filter().valid(true).local(true).remote(true)); + } else if (url == "search") { + bookIdsToDump = search_catalog(request, opdsDumper); + uuid = zim::Uuid::generate(); + } + + auto response = ContentResponse::build( + *this, + opdsDumper.dumpOPDSFeed(bookIdsToDump, request.get_query()), + opdsMimeType[OPDS_ACQUISITION_FEED]); + return std::move(response); +} + std::unique_ptr InternalServer::handle_catalog_v2(const RequestContext& request) { if (m_verbose.load()) { @@ -90,7 +158,7 @@ std::unique_ptr InternalServer::handle_catalog_v2_root(const RequestCo {"category_list_feed_id", gen_uuid(libraryId + "/categories")}, {"language_list_feed_id", gen_uuid(libraryId + "/languages")} }, - "application/atom+xml;profile=opds-catalog;kind=navigation" + opdsMimeType[OPDS_NAVIGATION_FEED] ); } @@ -104,7 +172,7 @@ std::unique_ptr InternalServer::handle_catalog_v2_entries(const Reques return ContentResponse::build( *this, opdsFeed, - "application/atom+xml;profile=opds-catalog;kind=acquisition" + opdsMimeType[OPDS_ACQUISITION_FEED] ); } @@ -124,7 +192,7 @@ std::unique_ptr InternalServer::handle_catalog_v2_complete_entry(const return ContentResponse::build( *this, opdsFeed, - "application/atom+xml;type=entry;profile=opds-catalog" + opdsMimeType[OPDS_ENTRY] ); } @@ -136,7 +204,7 @@ std::unique_ptr InternalServer::handle_catalog_v2_categories(const Req return ContentResponse::build( *this, opdsDumper.categoriesOPDSFeed(), - "application/atom+xml;profile=opds-catalog;kind=navigation" + opdsMimeType[OPDS_NAVIGATION_FEED] ); } @@ -148,7 +216,7 @@ std::unique_ptr InternalServer::handle_catalog_v2_languages(const Requ return ContentResponse::build( *this, opdsDumper.languagesOPDSFeed(), - "application/atom+xml;profile=opds-catalog;kind=navigation" + opdsMimeType[OPDS_NAVIGATION_FEED] ); } diff --git a/test/server.cpp b/test/server.cpp index b7cfa8d6..961ef9a0 100644 --- a/test/server.cpp +++ b/test/server.cpp @@ -497,8 +497,13 @@ TEST_F(ServerTest, MimeTypes) { "/skin/blank.html", "text/html" }, { "/skin/index.css", "text/css" }, { "/skin/index.js", "application/javascript" }, + { "/catalog/root.xml", "application/atom+xml;profile=opds-catalog;kind=acquisition;charset=utf-8" }, { "/catalog/v2/searchdescription.xml", "application/opensearchdescription+xml" }, - { "/catalog/v2/root.xml", "application/atom+xml;profile=opds-catalog;kind=navigation" }, + { "/catalog/v2/root.xml", "application/atom+xml;profile=opds-catalog;kind=navigation;charset=utf-8" }, + { "/catalog/v2/languages", "application/atom+xml;profile=opds-catalog;kind=navigation;charset=utf-8" }, + { "/catalog/v2/categories", "application/atom+xml;profile=opds-catalog;kind=navigation;charset=utf-8" }, + { "/catalog/v2/entries", "application/atom+xml;profile=opds-catalog;kind=acquisition;charset=utf-8" }, + { "/catalog/v2/entry/6f1d19d0-633f-087b-fb55-7ac324ff9baf", "application/atom+xml;type=entry;profile=opds-catalog;charset=utf-8" }, { "/skin/search-icon.svg", "image/svg+xml" }, { "/skin/bittorrent.png", "image/png" }, { "/skin/favicon/favicon.ico", "image/x-icon" },