diff --git a/src/server/kiwix-serve.cpp b/src/server/kiwix-serve.cpp index 1828c24..1750c2f 100644 --- a/src/server/kiwix-serve.cpp +++ b/src/server/kiwix-serve.cpp @@ -93,13 +93,14 @@ using namespace std; static bool noLibraryButtonFlag = false; static bool noSearchBarFlag = false; static string welcomeHTML; +static string catalogOpenSearchDescription; static std::atomic_bool isVerbose(false); static std::string rootLocation = ""; static std::map extMimeTypes; static std::map readers; static std::map searchers; static kiwix::Searcher* globalSearcher = nullptr; -static kiwix::OPDSDumper* opdsDumper = nullptr; +static kiwix::Manager libraryManager; static pthread_mutex_t searchLock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t compressorLock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t regexLock = PTHREAD_MUTEX_INITIALIZER; @@ -646,21 +647,53 @@ static struct MHD_Response* handle_catalog(RequestContext* request) } 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 build_404(request, ""); } - { - auto uuid = zim::Uuid::generate(host); - std::stringstream ss; - ss << uuid; - opdsDumper->setId(ss.str()); - } - std::string content = opdsDumper->dumpOPDSFeed(); + std::string content; + std::string mimeType; + + if (url == "searchdescription.xml") { + content = catalogOpenSearchDescription; + mimeType = "application/opensearchdescription+xml"; + } else { + zim::Uuid uuid; + kiwix::OPDSDumper opdsDumper; + opdsDumper.setRootLocation(rootLocation); + opdsDumper.setSearchDescriptionUrl("catalog/searchdescription.xml"); + mimeType = "application/atom+xml;profile=opds-catalog;kind=acquisition; charset=utf-8"; + kiwix::Library library_to_dump; + if (url == "root.xml") { + opdsDumper.setTitle("All zims"); + uuid = zim::Uuid::generate(host); + library_to_dump = libraryManager.cloneLibrary(); + } else if (url == "search") { + std::string query; + try { + query = request->get_argument("q"); + } catch (const std::out_of_range&) { + return build_404(request, ""); + } + opdsDumper.setTitle("Search result for " + query); + uuid = zim::Uuid::generate(); + library_to_dump = libraryManager.filter(query); + } else { + return build_404(request, ""); + } - std::string mimeType = "application/atom+xml;profile=opds-catalog;kind=acquisition; charset=utf-8"; + { + std::stringstream ss; + ss << uuid; + opdsDumper.setId(ss.str()); + } + opdsDumper.setLibrary(library_to_dump); + content = opdsDumper.dumpOPDSFeed(); + } bool deflated = request->can_compress() && compress_content(content, mimeType); return build_response( @@ -867,7 +900,6 @@ int main(int argc, char** argv) string PPIDString; unsigned int PPID = 0; unsigned int nb_threads = std::thread::hardware_concurrency(); - kiwix::Manager libraryManager; static struct option long_options[] = {{"daemon", no_argument, 0, 'd'}, @@ -1107,10 +1139,10 @@ int main(int argc, char** argv) introduceTaskbar(welcomeHTML, ""); - /* Compute the OPDS feed */ - opdsDumper = new kiwix::OPDSDumper(libraryManager.cloneLibrary()); - opdsDumper->setTitle("All zims"); - opdsDumper->setRootLocation(rootLocation); + /* Compute the OpenSearch description */ + catalogOpenSearchDescription = RESOURCE::opensearchdescription_xml; + catalogOpenSearchDescription = replaceRegex(catalogOpenSearchDescription, rootLocation, "__ROOT_LOCATION__"); + #ifndef _WIN32 /* Fork if necessary */ @@ -1272,7 +1304,6 @@ int main(int argc, char** argv) } while (waiting); delete globalSearcher; - delete opdsDumper; /* Stop the daemon */ MHD_stop_daemon(daemon); diff --git a/static/server/opensearchdescription.xml b/static/server/opensearchdescription.xml new file mode 100644 index 0000000..27c67e9 --- /dev/null +++ b/static/server/opensearchdescription.xml @@ -0,0 +1,8 @@ + + + Zim catalog search + Search zim files in the catalog. + + diff --git a/static/server/resources_list.txt b/static/server/resources_list.txt index 97a741f..9df07e1 100644 --- a/static/server/resources_list.txt +++ b/static/server/resources_list.txt @@ -22,3 +22,4 @@ include.html.part taskbar.css taskbar.html.part global_taskbar.html.part +opensearchdescription.xml