diff --git a/src/server/internalServer.cpp b/src/server/internalServer.cpp index 1513f95a8..42cfa7f3e 100644 --- a/src/server/internalServer.cpp +++ b/src/server/internalServer.cpp @@ -430,7 +430,9 @@ InternalServer::InternalServer(Library* library, searchCache(getEnvVar("KIWIX_SEARCH_CACHE_SIZE", DEFAULT_CACHE_SIZE)), suggestionSearcherCache(getEnvVar("KIWIX_SUGGESTION_SEARCHER_CACHE_SIZE", std::max((unsigned int) (mp_library->getBookCount(true, true)*0.1), 1U))), m_customizedResources(new CustomizedResources) -{} +{ + m_root = urlEncode(m_root); +} InternalServer::~InternalServer() = default; @@ -621,7 +623,7 @@ std::unique_ptr InternalServer::handle_request(const RequestContext& r if (isEndpointUrl(url, "catch")) return handle_catch(request); - std::string contentUrl = urlEncode(m_root + "/content" + url); + std::string contentUrl = m_root + "/content" + urlEncode(url); const std::string query = request.get_query(); if ( ! query.empty() ) contentUrl += "?" + query; @@ -1044,8 +1046,9 @@ ParameterizedMessage suggestSearchMsg(const std::string& searchURL, const std::s std::unique_ptr InternalServer::build_redirect(const std::string& bookName, const zim::Item& item) const { - const auto absPath = m_root + "/content/" + bookName + "/" + item.getPath(); - return Response::build_redirect(*this, kiwix::urlEncode(absPath)); + const auto contentPath = "/content/" + bookName + "/" + item.getPath(); + const auto url = m_root + kiwix::urlEncode(contentPath); + return Response::build_redirect(*this, url); } std::unique_ptr InternalServer::handle_content(const RequestContext& request) diff --git a/src/server/internalServer.h b/src/server/internalServer.h index f00dfe8fb..aaa642cd0 100644 --- a/src/server/internalServer.h +++ b/src/server/internalServer.h @@ -163,8 +163,8 @@ class InternalServer { private: // data std::string m_addr; int m_port; - std::string m_root; - std::string m_rootWithSeparator; + std::string m_root; // URI-encoded + std::string m_rootWithSeparator; // URI-decoded int m_nbThreads; unsigned int m_multizimSearchLimit; std::atomic_bool m_verbose; diff --git a/src/server/request_context.cpp b/src/server/request_context.cpp index 4002671fc..9ae3de1a2 100644 --- a/src/server/request_context.cpp +++ b/src/server/request_context.cpp @@ -52,12 +52,12 @@ RequestMethod str2RequestMethod(const std::string& method) { } // unnamed namespace RequestContext::RequestContext(struct MHD_Connection* connection, - const std::string& _rootLocation, - const std::string& unrootedUrl, + const std::string& _rootLocation, // URI-encoded + const std::string& unrootedUrl, // URI-decoded const std::string& _method, const std::string& version) : rootLocation(_rootLocation), - full_url(_rootLocation + unrootedUrl), + full_url(_rootLocation + urlEncode(unrootedUrl)), url(unrootedUrl), method(str2RequestMethod(_method)), version(version), diff --git a/src/server/request_context.h b/src/server/request_context.h index bea0ff804..03ea271b3 100644 --- a/src/server/request_context.h +++ b/src/server/request_context.h @@ -57,8 +57,8 @@ class IndexError: public std::runtime_error {}; class RequestContext { public: // functions RequestContext(struct MHD_Connection* connection, - const std::string& rootLocation, - const std::string& unrootedUrl, + const std::string& rootLocation, // URI-encoded + const std::string& unrootedUrl, // URI-decoded const std::string& method, const std::string& version); ~RequestContext(); diff --git a/src/server/response.cpp b/src/server/response.cpp index 3ec50b8ca..db20a2fb4 100644 --- a/src/server/response.cpp +++ b/src/server/response.cpp @@ -200,7 +200,7 @@ HTTP404Response::HTTP404Response(const InternalServer& server, HTTPErrorResponse& HTTP404Response::operator+(UrlNotFoundMsg /*unused*/) { - const std::string requestUrl = m_request.get_full_url(); + const std::string requestUrl = urlDecode(m_request.get_full_url(), false); return *this + ParameterizedMessage("url-not-found", {{"url", requestUrl}}); } @@ -234,7 +234,7 @@ HTTP400Response::HTTP400Response(const InternalServer& server, HTTPErrorResponse& HTTP400Response::operator+(InvalidUrlMsg /*unused*/) { - std::string requestUrl = m_request.get_full_url(); + std::string requestUrl = urlDecode(m_request.get_full_url(), false); const auto query = m_request.get_query(); if (!query.empty()) { requestUrl += "?" + encodeDiples(query); diff --git a/test/library_server.cpp b/test/library_server.cpp index a8f349ef0..5c0d65b1f 100644 --- a/test/library_server.cpp +++ b/test/library_server.cpp @@ -73,7 +73,7 @@ std::string maskVariableOPDSFeedData(std::string s) " \n" \ " \n" + " href=\"/ROOT%23%3F/catalog/searchdescription.xml\" />\n" #define CATALOG_ENTRY(UUID, TITLE, SUMMARY, LANG, NAME, CATEGORY, TAGS, EXTRA_LINK, CONTENT_NAME, FILE_NAME, LENGTH) \ " \n" \ @@ -88,7 +88,7 @@ std::string maskVariableOPDSFeedData(std::string s) " " TAGS "\n" \ " 284\n" \ " 2\n" \ - " " EXTRA_LINK "\n" \ + " " EXTRA_LINK "\n" \ " \n" \ " Wikipedia\n" \ " \n" \ @@ -126,7 +126,7 @@ std::string maskVariableOPDSFeedData(std::string s) "wikipedia",\ "public_tag_without_a_value;_private_tag_without_a_value;wikipedia;_category:wikipedia;_pictures:no;_videos:no;_details:no;_ftindex:yes",\ "\n ", \ CONTENT_NAME, \ "zimfile", \ @@ -152,7 +152,7 @@ std::string maskVariableOPDSFeedData(std::string s) TEST_F(LibraryServerTest, catalog_root_xml) { - const auto r = zfs1_->GET("/ROOT/catalog/root.xml"); + const auto r = zfs1_->GET("/ROOT%23%3F/catalog/root.xml"); EXPECT_EQ(r->status, 200); EXPECT_EQ(maskVariableOPDSFeedData(r->body), OPDS_FEED_TAG @@ -170,7 +170,7 @@ TEST_F(LibraryServerTest, catalog_root_xml) TEST_F(LibraryServerTest, catalog_searchdescription_xml) { - const auto r = zfs1_->GET("/ROOT/catalog/searchdescription.xml"); + const auto r = zfs1_->GET("/ROOT%23%3F/catalog/searchdescription.xml"); EXPECT_EQ(r->status, 200); EXPECT_EQ(r->body, "\n" @@ -181,14 +181,14 @@ TEST_F(LibraryServerTest, catalog_searchdescription_xml) " xmlns:atom=\"http://www.w3.org/2005/Atom\"\n" " xmlns:k=\"http://kiwix.org/opensearchextension/1.0\"\n" " indexOffset=\"0\"\n" - " template=\"/ROOT/catalog/search?q={searchTerms?}&lang={language?}&name={k:name?}&tag={k:tag?}¬ag={k:notag?}&maxsize={k:maxsize?}&count={count?}&start={startIndex?}\"/>\n" + " template=\"/ROOT%23%3F/catalog/search?q={searchTerms?}&lang={language?}&name={k:name?}&tag={k:tag?}¬ag={k:notag?}&maxsize={k:maxsize?}&count={count?}&start={startIndex?}\"/>\n" "\n" ); } TEST_F(LibraryServerTest, catalog_search_by_phrase) { - const auto r = zfs1_->GET("/ROOT/catalog/search?q=\"ray%20charles\""); + const auto r = zfs1_->GET("/ROOT%23%3F/catalog/search?q=\"ray%20charles\""); EXPECT_EQ(r->status, 200); EXPECT_EQ(maskVariableOPDSFeedData(r->body), OPDS_FEED_TAG @@ -207,7 +207,7 @@ TEST_F(LibraryServerTest, catalog_search_by_phrase) TEST_F(LibraryServerTest, catalog_search_by_words) { - const auto r = zfs1_->GET("/ROOT/catalog/search?q=ray%20charles"); + const auto r = zfs1_->GET("/ROOT%23%3F/catalog/search?q=ray%20charles"); EXPECT_EQ(r->status, 200); EXPECT_EQ(maskVariableOPDSFeedData(r->body), OPDS_FEED_TAG @@ -228,7 +228,7 @@ TEST_F(LibraryServerTest, catalog_search_by_words) TEST_F(LibraryServerTest, catalog_prefix_search) { { - const auto r = zfs1_->GET("/ROOT/catalog/search?q=description:ray%20description:charles"); + const auto r = zfs1_->GET("/ROOT%23%3F/catalog/search?q=description:ray%20description:charles"); EXPECT_EQ(r->status, 200); EXPECT_EQ(maskVariableOPDSFeedData(r->body), OPDS_FEED_TAG @@ -245,7 +245,7 @@ TEST_F(LibraryServerTest, catalog_prefix_search) ); } { - const auto r = zfs1_->GET("/ROOT/catalog/search?q=title:\"ray%20charles\""); + const auto r = zfs1_->GET("/ROOT%23%3F/catalog/search?q=title:\"ray%20charles\""); EXPECT_EQ(r->status, 200); EXPECT_EQ(maskVariableOPDSFeedData(r->body), OPDS_FEED_TAG @@ -264,7 +264,7 @@ TEST_F(LibraryServerTest, catalog_prefix_search) TEST_F(LibraryServerTest, catalog_search_with_word_exclusion) { - const auto r = zfs1_->GET("/ROOT/catalog/search?q=ray%20-uncategorized"); + const auto r = zfs1_->GET("/ROOT%23%3F/catalog/search?q=ray%20-uncategorized"); EXPECT_EQ(r->status, 200); EXPECT_EQ(maskVariableOPDSFeedData(r->body), OPDS_FEED_TAG @@ -283,7 +283,7 @@ TEST_F(LibraryServerTest, catalog_search_with_word_exclusion) TEST_F(LibraryServerTest, catalog_search_by_tag) { - const auto r = zfs1_->GET("/ROOT/catalog/search?tag=_category:jazz"); + const auto r = zfs1_->GET("/ROOT%23%3F/catalog/search?tag=_category:jazz"); EXPECT_EQ(r->status, 200); EXPECT_EQ(maskVariableOPDSFeedData(r->body), OPDS_FEED_TAG @@ -301,7 +301,7 @@ TEST_F(LibraryServerTest, catalog_search_by_tag) TEST_F(LibraryServerTest, catalog_search_by_category) { - const auto r = zfs1_->GET("/ROOT/catalog/search?category=jazz"); + const auto r = zfs1_->GET("/ROOT%23%3F/catalog/search?category=jazz"); EXPECT_EQ(r->status, 200); EXPECT_EQ(maskVariableOPDSFeedData(r->body), OPDS_FEED_TAG @@ -320,7 +320,7 @@ TEST_F(LibraryServerTest, catalog_search_by_category) TEST_F(LibraryServerTest, catalog_search_by_language) { { - const auto r = zfs1_->GET("/ROOT/catalog/search?lang=eng"); + const auto r = zfs1_->GET("/ROOT%23%3F/catalog/search?lang=eng"); EXPECT_EQ(r->status, 200); EXPECT_EQ(maskVariableOPDSFeedData(r->body), OPDS_FEED_TAG @@ -337,7 +337,7 @@ TEST_F(LibraryServerTest, catalog_search_by_language) } { - const auto r = zfs1_->GET("/ROOT/catalog/search?lang=eng,fra"); + const auto r = zfs1_->GET("/ROOT%23%3F/catalog/search?lang=eng,fra"); EXPECT_EQ(r->status, 200); EXPECT_EQ(maskVariableOPDSFeedData(r->body), OPDS_FEED_TAG @@ -358,7 +358,7 @@ TEST_F(LibraryServerTest, catalog_search_by_language) TEST_F(LibraryServerTest, catalog_search_results_pagination) { { - const auto r = zfs1_->GET("/ROOT/catalog/search?count=0"); + const auto r = zfs1_->GET("/ROOT%23%3F/catalog/search?count=0"); EXPECT_EQ(r->status, 200); EXPECT_EQ(maskVariableOPDSFeedData(r->body), OPDS_FEED_TAG @@ -376,7 +376,7 @@ TEST_F(LibraryServerTest, catalog_search_results_pagination) ); } { - const auto r = zfs1_->GET("/ROOT/catalog/search?count=1"); + const auto r = zfs1_->GET("/ROOT%23%3F/catalog/search?count=1"); EXPECT_EQ(r->status, 200); EXPECT_EQ(maskVariableOPDSFeedData(r->body), OPDS_FEED_TAG @@ -392,7 +392,7 @@ TEST_F(LibraryServerTest, catalog_search_results_pagination) ); } { - const auto r = zfs1_->GET("/ROOT/catalog/search?start=1&count=1"); + const auto r = zfs1_->GET("/ROOT%23%3F/catalog/search?start=1&count=1"); EXPECT_EQ(r->status, 200); EXPECT_EQ(maskVariableOPDSFeedData(r->body), OPDS_FEED_TAG @@ -408,7 +408,7 @@ TEST_F(LibraryServerTest, catalog_search_results_pagination) ); } { - const auto r = zfs1_->GET("/ROOT/catalog/search?start=100&count=10"); + const auto r = zfs1_->GET("/ROOT%23%3F/catalog/search?start=100&count=10"); EXPECT_EQ(r->status, 200); EXPECT_EQ(maskVariableOPDSFeedData(r->body), OPDS_FEED_TAG @@ -426,20 +426,20 @@ TEST_F(LibraryServerTest, catalog_search_results_pagination) TEST_F(LibraryServerTest, catalog_v2_root) { - const auto r = zfs1_->GET("/ROOT/catalog/v2/root.xml"); + const auto r = zfs1_->GET("/ROOT%23%3F/catalog/v2/root.xml"); EXPECT_EQ(r->status, 200); const char expected_output[] = R"( 12345678-90ab-cdef-1234-567890abcdef OPDS Catalog Root YYYY-MM-DDThh:mm:ssZ @@ -447,7 +447,7 @@ TEST_F(LibraryServerTest, catalog_v2_root) All entries YYYY-MM-DDThh:mm:ssZ 12345678-90ab-cdef-1234-567890abcdef @@ -456,7 +456,7 @@ TEST_F(LibraryServerTest, catalog_v2_root) All entries (partial) YYYY-MM-DDThh:mm:ssZ 12345678-90ab-cdef-1234-567890abcdef @@ -465,7 +465,7 @@ TEST_F(LibraryServerTest, catalog_v2_root) List of categories YYYY-MM-DDThh:mm:ssZ 12345678-90ab-cdef-1234-567890abcdef @@ -474,7 +474,7 @@ TEST_F(LibraryServerTest, catalog_v2_root) List of languages YYYY-MM-DDThh:mm:ssZ 12345678-90ab-cdef-1234-567890abcdef @@ -487,7 +487,7 @@ TEST_F(LibraryServerTest, catalog_v2_root) TEST_F(LibraryServerTest, catalog_v2_searchdescription_xml) { - const auto r = zfs1_->GET("/ROOT/catalog/v2/searchdescription.xml"); + const auto r = zfs1_->GET("/ROOT%23%3F/catalog/v2/searchdescription.xml"); EXPECT_EQ(r->status, 200); EXPECT_EQ(r->body, "\n" @@ -498,24 +498,24 @@ TEST_F(LibraryServerTest, catalog_v2_searchdescription_xml) " xmlns:atom=\"http://www.w3.org/2005/Atom\"\n" " xmlns:k=\"http://kiwix.org/opensearchextension/1.0\"\n" " indexOffset=\"0\"\n" - " template=\"/ROOT/catalog/v2/entries?q={searchTerms?}&lang={language?}&name={k:name?}&tag={k:tag?}&maxsize={k:maxsize?}&count={count?}&start={startIndex?}\"/>\n" + " template=\"/ROOT%23%3F/catalog/v2/entries?q={searchTerms?}&lang={language?}&name={k:name?}&tag={k:tag?}&maxsize={k:maxsize?}&count={count?}&start={startIndex?}\"/>\n" "\n" ); } TEST_F(LibraryServerTest, catalog_v2_categories) { - const auto r = zfs1_->GET("/ROOT/catalog/v2/categories"); + const auto r = zfs1_->GET("/ROOT%23%3F/catalog/v2/categories"); EXPECT_EQ(r->status, 200); const char expected_output[] = R"( 12345678-90ab-cdef-1234-567890abcdef List of categories YYYY-MM-DDThh:mm:ssZ @@ -523,7 +523,7 @@ TEST_F(LibraryServerTest, catalog_v2_categories) jazz YYYY-MM-DDThh:mm:ssZ 12345678-90ab-cdef-1234-567890abcdef @@ -532,7 +532,7 @@ TEST_F(LibraryServerTest, catalog_v2_categories) wikipedia YYYY-MM-DDThh:mm:ssZ 12345678-90ab-cdef-1234-567890abcdef @@ -545,7 +545,7 @@ TEST_F(LibraryServerTest, catalog_v2_categories) TEST_F(LibraryServerTest, catalog_v2_languages) { - const auto r = zfs1_->GET("/ROOT/catalog/v2/languages"); + const auto r = zfs1_->GET("/ROOT%23%3F/catalog/v2/languages"); EXPECT_EQ(r->status, 200); const char expected_output[] = R"( 12345678-90ab-cdef-1234-567890abcdef List of languages YYYY-MM-DDThh:mm:ssZ @@ -567,7 +567,7 @@ TEST_F(LibraryServerTest, catalog_v2_languages) eng 1 YYYY-MM-DDThh:mm:ssZ 12345678-90ab-cdef-1234-567890abcdef @@ -577,7 +577,7 @@ TEST_F(LibraryServerTest, catalog_v2_languages) fra 1 YYYY-MM-DDThh:mm:ssZ 12345678-90ab-cdef-1234-567890abcdef @@ -587,7 +587,7 @@ TEST_F(LibraryServerTest, catalog_v2_languages) rus 1 YYYY-MM-DDThh:mm:ssZ 12345678-90ab-cdef-1234-567890abcdef @@ -606,13 +606,13 @@ TEST_F(LibraryServerTest, catalog_v2_languages) " 12345678-90ab-cdef-1234-567890abcdef\n" \ "\n" \ " \n" \ " \n" \ " \n" \ "\n" \ @@ -624,7 +624,7 @@ TEST_F(LibraryServerTest, catalog_v2_languages) TEST_F(LibraryServerTest, catalog_v2_entries) { - const auto r = zfs1_->GET("/ROOT/catalog/v2/entries"); + const auto r = zfs1_->GET("/ROOT%23%3F/catalog/v2/entries"); EXPECT_EQ(r->status, 200); EXPECT_EQ(maskVariableOPDSFeedData(r->body), CATALOG_V2_ENTRIES_PREAMBLE("") @@ -641,7 +641,7 @@ TEST_F(LibraryServerTest, catalog_v2_entries) TEST_F(LibraryServerTest, catalog_v2_entries_filtered_by_range) { { - const auto r = zfs1_->GET("/ROOT/catalog/v2/entries?start=1"); + const auto r = zfs1_->GET("/ROOT%23%3F/catalog/v2/entries?start=1"); EXPECT_EQ(r->status, 200); EXPECT_EQ(maskVariableOPDSFeedData(r->body), CATALOG_V2_ENTRIES_PREAMBLE("?start=1") @@ -657,7 +657,7 @@ TEST_F(LibraryServerTest, catalog_v2_entries_filtered_by_range) } { - const auto r = zfs1_->GET("/ROOT/catalog/v2/entries?count=2"); + const auto r = zfs1_->GET("/ROOT%23%3F/catalog/v2/entries?count=2"); EXPECT_EQ(r->status, 200); EXPECT_EQ(maskVariableOPDSFeedData(r->body), CATALOG_V2_ENTRIES_PREAMBLE("?count=2") @@ -673,7 +673,7 @@ TEST_F(LibraryServerTest, catalog_v2_entries_filtered_by_range) } { - const auto r = zfs1_->GET("/ROOT/catalog/v2/entries?start=1&count=1"); + const auto r = zfs1_->GET("/ROOT%23%3F/catalog/v2/entries?start=1&count=1"); EXPECT_EQ(r->status, 200); EXPECT_EQ(maskVariableOPDSFeedData(r->body), CATALOG_V2_ENTRIES_PREAMBLE("?start=1&count=1") @@ -690,7 +690,7 @@ TEST_F(LibraryServerTest, catalog_v2_entries_filtered_by_range) TEST_F(LibraryServerTest, catalog_v2_entries_filtered_by_search_terms) { - const auto r = zfs1_->GET("/ROOT/catalog/v2/entries?q=\"ray%20charles\""); + const auto r = zfs1_->GET("/ROOT%23%3F/catalog/v2/entries?q=\"ray%20charles\""); EXPECT_EQ(r->status, 200); EXPECT_EQ(maskVariableOPDSFeedData(r->body), CATALOG_V2_ENTRIES_PREAMBLE("?q=%22ray%20charles%22") @@ -708,7 +708,7 @@ TEST_F(LibraryServerTest, catalog_v2_entries_filtered_by_search_terms) TEST_F(LibraryServerTest, catalog_v2_entries_filtered_by_language) { { - const auto r = zfs1_->GET("/ROOT/catalog/v2/entries?lang=eng"); + const auto r = zfs1_->GET("/ROOT%23%3F/catalog/v2/entries?lang=eng"); EXPECT_EQ(r->status, 200); EXPECT_EQ(maskVariableOPDSFeedData(r->body), CATALOG_V2_ENTRIES_PREAMBLE("?lang=eng") @@ -723,7 +723,7 @@ TEST_F(LibraryServerTest, catalog_v2_entries_filtered_by_language) } { - const auto r = zfs1_->GET("/ROOT/catalog/v2/entries?lang=eng,fra"); + const auto r = zfs1_->GET("/ROOT%23%3F/catalog/v2/entries?lang=eng,fra"); EXPECT_EQ(r->status, 200); EXPECT_EQ(maskVariableOPDSFeedData(r->body), CATALOG_V2_ENTRIES_PREAMBLE("?lang=eng%2Cfra") @@ -741,20 +741,20 @@ TEST_F(LibraryServerTest, catalog_v2_entries_filtered_by_language) TEST_F(LibraryServerTest, catalog_v2_individual_entry_access) { - const auto r = zfs1_->GET("/ROOT/catalog/v2/entry/raycharles"); + const auto r = zfs1_->GET("/ROOT%23%3F/catalog/v2/entry/raycharles"); EXPECT_EQ(r->status, 200); EXPECT_EQ(maskVariableOPDSFeedData(r->body), "\n" RAY_CHARLES_CATALOG_ENTRY ); - const auto r1 = zfs1_->GET("/ROOT/catalog/v2/entry/non-existent-entry"); + const auto r1 = zfs1_->GET("/ROOT%23%3F/catalog/v2/entry/non-existent-entry"); EXPECT_EQ(r1->status, 404); } TEST_F(LibraryServerTest, catalog_v2_partial_entries) { - const auto r = zfs1_->GET("/ROOT/catalog/v2/partial_entries"); + const auto r = zfs1_->GET("/ROOT%23%3F/catalog/v2/partial_entries"); EXPECT_EQ(r->status, 200); EXPECT_EQ(maskVariableOPDSFeedData(r->body), CATALOG_V2_PARTIAL_ENTRIES_PREAMBLE("") @@ -766,7 +766,7 @@ TEST_F(LibraryServerTest, catalog_v2_partial_entries) " Charles, Ray\n" " YYYY-MM-DDThh:mm:ssZ\n" " \n" " \n" " \n" @@ -774,7 +774,7 @@ TEST_F(LibraryServerTest, catalog_v2_partial_entries) " Ray Charles\n" " YYYY-MM-DDThh:mm:ssZ\n" " \n" " \n" " \n" @@ -782,7 +782,7 @@ TEST_F(LibraryServerTest, catalog_v2_partial_entries) " Ray (uncategorized) Charles\n" " YYYY-MM-DDThh:mm:ssZ\n" " \n" " \n" "\n" @@ -791,7 +791,7 @@ TEST_F(LibraryServerTest, catalog_v2_partial_entries) #define EXPECT_SEARCH_RESULTS(SEARCH_TERM, RESULT_COUNT, OPDS_ENTRIES) \ { \ - const auto r = zfs1_->GET("/ROOT/catalog/search?q=" SEARCH_TERM); \ + const auto r = zfs1_->GET("/ROOT%23%3F/catalog/search?q=" SEARCH_TERM); \ EXPECT_EQ(r->status, 200); \ EXPECT_EQ(maskVariableOPDSFeedData(r->body), \ OPDS_FEED_TAG \ @@ -860,7 +860,7 @@ TEST_F(LibraryServerTest, catalog_search_excludes_hidden_tags) TEST_F(LibraryServerTest, no_name_mapper_returned_catalog_use_uuid_in_link) { resetServer(ZimFileServer::NO_NAME_MAPPER); - const auto r = zfs1_->GET("/ROOT/catalog/search?tag=_category:jazz"); + const auto r = zfs1_->GET("/ROOT%23%3F/catalog/search?tag=_category:jazz"); EXPECT_EQ(r->status, 200); EXPECT_EQ(maskVariableOPDSFeedData(r->body), OPDS_FEED_TAG @@ -880,14 +880,14 @@ TEST_F(LibraryServerTest, no_name_mapper_returned_catalog_use_uuid_in_link) TEST_F(LibraryServerTest, no_name_mapper_catalog_v2_individual_entry_access) { resetServer(ZimFileServer::NO_NAME_MAPPER); - const auto r = zfs1_->GET("/ROOT/catalog/v2/entry/raycharles"); + const auto r = zfs1_->GET("/ROOT%23%3F/catalog/v2/entry/raycharles"); EXPECT_EQ(r->status, 200); EXPECT_EQ(maskVariableOPDSFeedData(r->body), "\n" RAY_CHARLES_CATALOG_ENTRY_NO_MAPPER ); - const auto r1 = zfs1_->GET("/ROOT/catalog/v2/entry/non-existent-entry"); + const auto r1 = zfs1_->GET("/ROOT%23%3F/catalog/v2/entry/non-existent-entry"); EXPECT_EQ(r1->status, 404); } diff --git a/test/server.cpp b/test/server.cpp index ce89b45bc..420c89864 100644 --- a/test/server.cpp +++ b/test/server.cpp @@ -47,136 +47,136 @@ std::ostream& operator<<(std::ostream& out, const Resource& r) typedef std::vector ResourceCollection; const ResourceCollection resources200Compressible{ - { DYNAMIC_CONTENT, "/ROOT/" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/" }, - { DYNAMIC_CONTENT, "/ROOT/viewer" }, - { DYNAMIC_CONTENT, "/ROOT/viewer?cacheid=whatever" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/viewer" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/viewer?cacheid=whatever" }, - { DYNAMIC_CONTENT, "/ROOT/skin/autoComplete.min.js" }, - { STATIC_CONTENT, "/ROOT/skin/autoComplete.min.js?cacheid=1191aaaf" }, - { DYNAMIC_CONTENT, "/ROOT/skin/css/autoComplete.css" }, - { STATIC_CONTENT, "/ROOT/skin/css/autoComplete.css?cacheid=08951e06" }, - { DYNAMIC_CONTENT, "/ROOT/skin/favicon/favicon.ico" }, - { STATIC_CONTENT, "/ROOT/skin/favicon/favicon.ico?cacheid=fba03a27" }, - { DYNAMIC_CONTENT, "/ROOT/skin/i18n.js" }, - { STATIC_CONTENT, "/ROOT/skin/i18n.js?cacheid=6da2bca0" }, - { DYNAMIC_CONTENT, "/ROOT/skin/index.css" }, - { STATIC_CONTENT, "/ROOT/skin/index.css?cacheid=0f9ba34e" }, - { DYNAMIC_CONTENT, "/ROOT/skin/index.js" }, - { STATIC_CONTENT, "/ROOT/skin/index.js?cacheid=2f5a81ac" }, - { DYNAMIC_CONTENT, "/ROOT/skin/iso6391To3.js" }, - { STATIC_CONTENT, "/ROOT/skin/iso6391To3.js?cacheid=ecde2bb3" }, - { DYNAMIC_CONTENT, "/ROOT/skin/isotope.pkgd.min.js" }, - { STATIC_CONTENT, "/ROOT/skin/isotope.pkgd.min.js?cacheid=2e48d392" }, - { DYNAMIC_CONTENT, "/ROOT/skin/mustache.min.js" }, - { STATIC_CONTENT, "/ROOT/skin/mustache.min.js?cacheid=bd23c4fb" }, - { DYNAMIC_CONTENT, "/ROOT/skin/taskbar.css" }, - { STATIC_CONTENT, "/ROOT/skin/taskbar.css?cacheid=eb3bec90" }, - { DYNAMIC_CONTENT, "/ROOT/skin/viewer.js" }, - { STATIC_CONTENT, "/ROOT/skin/viewer.js?cacheid=03fd97ee" }, - { DYNAMIC_CONTENT, "/ROOT/skin/fonts/Poppins.ttf" }, - { STATIC_CONTENT, "/ROOT/skin/fonts/Poppins.ttf?cacheid=af705837" }, - { DYNAMIC_CONTENT, "/ROOT/skin/fonts/Roboto.ttf" }, - { STATIC_CONTENT, "/ROOT/skin/fonts/Roboto.ttf?cacheid=84d10248" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/autoComplete.min.js" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/autoComplete.min.js?cacheid=1191aaaf" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/css/autoComplete.css" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/css/autoComplete.css?cacheid=08951e06" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/favicon/favicon.ico" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/favicon/favicon.ico?cacheid=fba03a27" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/i18n.js" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/i18n.js?cacheid=6da2bca0" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/index.css" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/index.css?cacheid=0f9ba34e" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/index.js" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/index.js?cacheid=2f5a81ac" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/iso6391To3.js" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/iso6391To3.js?cacheid=ecde2bb3" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/isotope.pkgd.min.js" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/isotope.pkgd.min.js?cacheid=2e48d392" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/mustache.min.js" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/mustache.min.js?cacheid=bd23c4fb" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/taskbar.css" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/taskbar.css?cacheid=eb3bec90" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/viewer.js" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/viewer.js?cacheid=03fd97ee" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/fonts/Poppins.ttf" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/fonts/Poppins.ttf?cacheid=af705837" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/fonts/Roboto.ttf" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/fonts/Roboto.ttf?cacheid=84d10248" }, - { DYNAMIC_CONTENT, "/ROOT/catalog/search" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/catalog/search" }, - { DYNAMIC_CONTENT, "/ROOT/catalog/v2/root.xml" }, - { DYNAMIC_CONTENT, "/ROOT/catalog/v2/entries" }, - { DYNAMIC_CONTENT, "/ROOT/catalog/v2/partial_entries" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/catalog/v2/root.xml" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/catalog/v2/entries" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/catalog/v2/partial_entries" }, - { DYNAMIC_CONTENT, "/ROOT/search?content=zimfile&pattern=a" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/search?content=zimfile&pattern=a" }, - { DYNAMIC_CONTENT, "/ROOT/suggest?content=zimfile&term=ray" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/suggest?content=zimfile&term=ray" }, - { ZIM_CONTENT, "/ROOT/content/zimfile/A/index" }, - { ZIM_CONTENT, "/ROOT/content/zimfile/A/Ray_Charles" }, + { ZIM_CONTENT, "/ROOT%23%3F/content/zimfile/A/index" }, + { ZIM_CONTENT, "/ROOT%23%3F/content/zimfile/A/Ray_Charles" }, - { ZIM_CONTENT, "/ROOT/raw/zimfile/content/A/index" }, - { ZIM_CONTENT, "/ROOT/raw/zimfile/content/A/Ray_Charles" }, + { ZIM_CONTENT, "/ROOT%23%3F/raw/zimfile/content/A/index" }, + { ZIM_CONTENT, "/ROOT%23%3F/raw/zimfile/content/A/Ray_Charles" }, }; const ResourceCollection resources200Uncompressible{ - { DYNAMIC_CONTENT, "/ROOT/skin/bittorrent.png" }, - { STATIC_CONTENT, "/ROOT/skin/bittorrent.png?cacheid=4f5c6882" }, - { DYNAMIC_CONTENT, "/ROOT/skin/blank.html" }, - { STATIC_CONTENT, "/ROOT/skin/blank.html?cacheid=6b1fa032" }, - { DYNAMIC_CONTENT, "/ROOT/skin/caret.png" }, - { STATIC_CONTENT, "/ROOT/skin/caret.png?cacheid=22b942b4" }, - { DYNAMIC_CONTENT, "/ROOT/skin/download.png" }, - { STATIC_CONTENT, "/ROOT/skin/download.png?cacheid=a39aa502" }, - { DYNAMIC_CONTENT, "/ROOT/skin/favicon/android-chrome-192x192.png" }, - { STATIC_CONTENT, "/ROOT/skin/favicon/android-chrome-192x192.png?cacheid=bfac158b" }, - { DYNAMIC_CONTENT, "/ROOT/skin/favicon/android-chrome-512x512.png" }, - { STATIC_CONTENT, "/ROOT/skin/favicon/android-chrome-512x512.png?cacheid=380c3653" }, - { DYNAMIC_CONTENT, "/ROOT/skin/favicon/apple-touch-icon.png" }, - { STATIC_CONTENT, "/ROOT/skin/favicon/apple-touch-icon.png?cacheid=f86f8df3" }, - { DYNAMIC_CONTENT, "/ROOT/skin/favicon/browserconfig.xml" }, - { STATIC_CONTENT, "/ROOT/skin/favicon/browserconfig.xml?cacheid=f29a7c4a" }, - { DYNAMIC_CONTENT, "/ROOT/skin/favicon/favicon-16x16.png" }, - { STATIC_CONTENT, "/ROOT/skin/favicon/favicon-16x16.png?cacheid=a986fedc" }, - { DYNAMIC_CONTENT, "/ROOT/skin/favicon/favicon-32x32.png" }, - { STATIC_CONTENT, "/ROOT/skin/favicon/favicon-32x32.png?cacheid=79ded625" }, - { DYNAMIC_CONTENT, "/ROOT/skin/favicon/mstile-144x144.png" }, - { STATIC_CONTENT, "/ROOT/skin/favicon/mstile-144x144.png?cacheid=c25a7641" }, - { DYNAMIC_CONTENT, "/ROOT/skin/favicon/mstile-150x150.png" }, - { STATIC_CONTENT, "/ROOT/skin/favicon/mstile-150x150.png?cacheid=6fa6f467" }, - { DYNAMIC_CONTENT, "/ROOT/skin/favicon/mstile-310x150.png" }, - { STATIC_CONTENT, "/ROOT/skin/favicon/mstile-310x150.png?cacheid=e0ed9032" }, - { DYNAMIC_CONTENT, "/ROOT/skin/favicon/mstile-310x310.png" }, - { STATIC_CONTENT, "/ROOT/skin/favicon/mstile-310x310.png?cacheid=26b20530" }, - { DYNAMIC_CONTENT, "/ROOT/skin/favicon/mstile-70x70.png" }, - { STATIC_CONTENT, "/ROOT/skin/favicon/mstile-70x70.png?cacheid=64ffd9dc" }, - { DYNAMIC_CONTENT, "/ROOT/skin/favicon/safari-pinned-tab.svg" }, - { STATIC_CONTENT, "/ROOT/skin/favicon/safari-pinned-tab.svg?cacheid=8d487e95" }, - { DYNAMIC_CONTENT, "/ROOT/skin/favicon/site.webmanifest" }, - { STATIC_CONTENT, "/ROOT/skin/favicon/site.webmanifest?cacheid=bc396efb" }, - { DYNAMIC_CONTENT, "/ROOT/skin/hash.png" }, - { STATIC_CONTENT, "/ROOT/skin/hash.png?cacheid=f836e872" }, - { DYNAMIC_CONTENT, "/ROOT/skin/magnet.png" }, - { STATIC_CONTENT, "/ROOT/skin/magnet.png?cacheid=73b6bddf" }, - { DYNAMIC_CONTENT, "/ROOT/skin/search-icon.svg" }, - { STATIC_CONTENT, "/ROOT/skin/search-icon.svg?cacheid=b10ae7ed" }, - { DYNAMIC_CONTENT, "/ROOT/skin/search_results.css" }, - { STATIC_CONTENT, "/ROOT/skin/search_results.css?cacheid=76d39c84" }, - { DYNAMIC_CONTENT, "/ROOT/skin/i18n/test.json" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/bittorrent.png" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/bittorrent.png?cacheid=4f5c6882" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/blank.html" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/blank.html?cacheid=6b1fa032" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/caret.png" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/caret.png?cacheid=22b942b4" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/download.png" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/download.png?cacheid=a39aa502" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/favicon/android-chrome-192x192.png" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/favicon/android-chrome-192x192.png?cacheid=bfac158b" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/favicon/android-chrome-512x512.png" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/favicon/android-chrome-512x512.png?cacheid=380c3653" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/favicon/apple-touch-icon.png" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/favicon/apple-touch-icon.png?cacheid=f86f8df3" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/favicon/browserconfig.xml" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/favicon/browserconfig.xml?cacheid=f29a7c4a" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/favicon/favicon-16x16.png" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/favicon/favicon-16x16.png?cacheid=a986fedc" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/favicon/favicon-32x32.png" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/favicon/favicon-32x32.png?cacheid=79ded625" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/favicon/mstile-144x144.png" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/favicon/mstile-144x144.png?cacheid=c25a7641" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/favicon/mstile-150x150.png" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/favicon/mstile-150x150.png?cacheid=6fa6f467" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/favicon/mstile-310x150.png" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/favicon/mstile-310x150.png?cacheid=e0ed9032" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/favicon/mstile-310x310.png" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/favicon/mstile-310x310.png?cacheid=26b20530" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/favicon/mstile-70x70.png" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/favicon/mstile-70x70.png?cacheid=64ffd9dc" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/favicon/safari-pinned-tab.svg" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/favicon/safari-pinned-tab.svg?cacheid=8d487e95" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/favicon/site.webmanifest" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/favicon/site.webmanifest?cacheid=bc396efb" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/hash.png" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/hash.png?cacheid=f836e872" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/magnet.png" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/magnet.png?cacheid=73b6bddf" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/search-icon.svg" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/search-icon.svg?cacheid=b10ae7ed" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/search_results.css" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/search_results.css?cacheid=76d39c84" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/i18n/test.json" }, // TODO: implement cache management of i18n resources - //{ STATIC_CONTENT, "/ROOT/skin/i18n/test.json?cacheid=unknown" }, - { DYNAMIC_CONTENT, "/ROOT/skin/languages.js" }, - { STATIC_CONTENT, "/ROOT/skin/languages.js?cacheid=fe100348" }, + //{ STATIC_CONTENT, "/ROOT%23%3F/skin/i18n/test.json?cacheid=unknown" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/languages.js" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/languages.js?cacheid=fe100348" }, - { ZIM_CONTENT, "/ROOT/raw/zimfile/meta/Title" }, - { ZIM_CONTENT, "/ROOT/raw/zimfile/meta/Description" }, - { ZIM_CONTENT, "/ROOT/raw/zimfile/meta/Language" }, - { ZIM_CONTENT, "/ROOT/raw/zimfile/meta/Name" }, - { ZIM_CONTENT, "/ROOT/raw/zimfile/meta/Tags" }, - { ZIM_CONTENT, "/ROOT/raw/zimfile/meta/Date" }, - { ZIM_CONTENT, "/ROOT/raw/zimfile/meta/Creator" }, - { ZIM_CONTENT, "/ROOT/raw/zimfile/meta/Publisher" }, + { ZIM_CONTENT, "/ROOT%23%3F/raw/zimfile/meta/Title" }, + { ZIM_CONTENT, "/ROOT%23%3F/raw/zimfile/meta/Description" }, + { ZIM_CONTENT, "/ROOT%23%3F/raw/zimfile/meta/Language" }, + { ZIM_CONTENT, "/ROOT%23%3F/raw/zimfile/meta/Name" }, + { ZIM_CONTENT, "/ROOT%23%3F/raw/zimfile/meta/Tags" }, + { ZIM_CONTENT, "/ROOT%23%3F/raw/zimfile/meta/Date" }, + { ZIM_CONTENT, "/ROOT%23%3F/raw/zimfile/meta/Creator" }, + { ZIM_CONTENT, "/ROOT%23%3F/raw/zimfile/meta/Publisher" }, - { DYNAMIC_CONTENT, "/ROOT/catalog/root.xml" }, - { DYNAMIC_CONTENT, "/ROOT/catalog/searchdescription.xml" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/catalog/root.xml" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/catalog/searchdescription.xml" }, - { DYNAMIC_CONTENT, "/ROOT/catalog/v2/categories" }, - { DYNAMIC_CONTENT, "/ROOT/catalog/v2/languages" }, - { DYNAMIC_CONTENT, "/ROOT/catalog/v2/searchdescription.xml" }, - { DYNAMIC_CONTENT, "/ROOT/catalog/v2/illustration/6f1d19d0-633f-087b-fb55-7ac324ff9baf?size=48" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/catalog/v2/categories" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/catalog/v2/languages" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/catalog/v2/searchdescription.xml" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/catalog/v2/illustration/6f1d19d0-633f-087b-fb55-7ac324ff9baf?size=48" }, - { DYNAMIC_CONTENT, "/ROOT/catch/external?source=www.example.com" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/catch/external?source=www.example.com" }, - { ZIM_CONTENT, "/ROOT/content/zimfile/I/m/Ray_Charles_classic_piano_pose.jpg" }, + { ZIM_CONTENT, "/ROOT%23%3F/content/zimfile/I/m/Ray_Charles_classic_piano_pose.jpg" }, - { ZIM_CONTENT, "/ROOT/content/corner_cases%23%26/empty.html" }, - { ZIM_CONTENT, "/ROOT/content/corner_cases%23%26/empty.css" }, - { ZIM_CONTENT, "/ROOT/content/corner_cases%23%26/empty.js" }, + { ZIM_CONTENT, "/ROOT%23%3F/content/corner_cases%23%26/empty.html" }, + { ZIM_CONTENT, "/ROOT%23%3F/content/corner_cases%23%26/empty.css" }, + { ZIM_CONTENT, "/ROOT%23%3F/content/corner_cases%23%26/empty.js" }, // The following url's responses are too small to be compressed - { DYNAMIC_CONTENT, "/ROOT/catalog/root.xml" }, - { DYNAMIC_CONTENT, "/ROOT/catalog/searchdescription.xml" }, - { DYNAMIC_CONTENT, "/ROOT/suggest?content=zimfile" }, - { ZIM_CONTENT, "/ROOT/raw/zimfile/meta/Creator" }, - { ZIM_CONTENT, "/ROOT/raw/zimfile/meta/Title" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/catalog/root.xml" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/catalog/searchdescription.xml" }, + { DYNAMIC_CONTENT, "/ROOT%23%3F/suggest?content=zimfile" }, + { ZIM_CONTENT, "/ROOT%23%3F/raw/zimfile/meta/Creator" }, + { ZIM_CONTENT, "/ROOT%23%3F/raw/zimfile/meta/Title" }, }; ResourceCollection all200Resources() @@ -192,7 +192,7 @@ TEST(indexTemplateStringTest, emptyIndexTemplate) { }; ZimFileServer zfs(PORT, ZimFileServer::DEFAULT_OPTIONS, ZIMFILES, ""); - EXPECT_EQ(200, zfs.GET("/ROOT/")->status); + EXPECT_EQ(200, zfs.GET("/ROOT%23%3F/")->status); } TEST(indexTemplateStringTest, indexTemplateCheck) { @@ -209,7 +209,7 @@ TEST(indexTemplateStringTest, indexTemplateCheck) { EXPECT_EQ("" "Welcome to kiwix library" "" - "", zfs.GET("/ROOT/")->body); + "", zfs.GET("/ROOT%23%3F/")->body); } TEST_F(ServerTest, 200) @@ -220,11 +220,11 @@ TEST_F(ServerTest, 200) TEST_F(ServerTest, 200_IdNameMapper) { - EXPECT_EQ(404, zfs1_->GET("/ROOT/content/6f1d19d0-633f-087b-fb55-7ac324ff9baf/A/index")->status); - EXPECT_EQ(200, zfs1_->GET("/ROOT/content/zimfile/A/index")->status); + EXPECT_EQ(404, zfs1_->GET("/ROOT%23%3F/content/6f1d19d0-633f-087b-fb55-7ac324ff9baf/A/index")->status); + EXPECT_EQ(200, zfs1_->GET("/ROOT%23%3F/content/zimfile/A/index")->status); resetServer(ZimFileServer::NO_NAME_MAPPER); - EXPECT_EQ(200, zfs1_->GET("/ROOT/content/6f1d19d0-633f-087b-fb55-7ac324ff9baf/A/index")->status); - EXPECT_EQ(404, zfs1_->GET("/ROOT/content/zimfile/A/index")->status); + EXPECT_EQ(200, zfs1_->GET("/ROOT%23%3F/content/6f1d19d0-633f-087b-fb55-7ac324ff9baf/A/index")->status); + EXPECT_EQ(404, zfs1_->GET("/ROOT%23%3F/content/zimfile/A/index")->status); } TEST_F(ServerTest, CompressibleContentIsCompressedIfAcceptable) @@ -267,29 +267,29 @@ TEST_F(ServerTest, CacheIdsOfStaticResources) typedef std::pair UrlAndExpectedResult; const std::vector testData{ { - /* url */ "/ROOT/", -R"EXPECTEDRESULT( href="/ROOT/skin/index.css?cacheid=0f9ba34e" - - - - - - - - src: url("/ROOT/skin/fonts/Poppins.ttf?cacheid=af705837") format("truetype"); - src: url("/ROOT/skin/fonts/Roboto.ttf?cacheid=84d10248") format("truetype"); - - - + /* url */ "/ROOT%23%3F/", +R"EXPECTEDRESULT( href="/ROOT%23%3F/skin/index.css?cacheid=0f9ba34e" + + + + + + + + src: url("/ROOT%23%3F/skin/fonts/Poppins.ttf?cacheid=af705837") format("truetype"); + src: url("/ROOT%23%3F/skin/fonts/Roboto.ttf?cacheid=84d10248") format("truetype"); + + + )EXPECTEDRESULT" }, { - /* url */ "/ROOT/skin/index.css", + /* url */ "/ROOT%23%3F/skin/index.css", R"EXPECTEDRESULT( background-image: url('../skin/search-icon.svg?cacheid=b10ae7ed'); )EXPECTEDRESULT" }, { - /* url */ "/ROOT/skin/index.js", + /* url */ "/ROOT%23%3F/skin/index.js", R"EXPECTEDRESULT( direct download download hash download magnet @@ -297,7 +297,7 @@ R"EXPECTEDRESULT( @@ -310,14 +310,14 @@ R"EXPECTEDRESULT( + /* url */ "/ROOT%23%3F/search?content=poor&pattern=whatever", +R"EXPECTEDRESULT( )EXPECTEDRESULT" }, }; @@ -333,15 +333,15 @@ R"EXPECTEDRESULT( GET("/ROOT/non-existent-item"); + // ServerTest.404 verifies that "/ROOT%23%3F/non-existent-item" doesn't exist + const auto r = zfs1_->GET("/ROOT%23%3F/non-existent-item"); EXPECT_EQ(r->status, 200); EXPECT_EQ(getHeaderValue(r->headers, "Content-Type"), "text/plain"); EXPECT_EQ(r->body, "Hello world!\n"); @@ -432,35 +432,35 @@ TEST_F(CustomizedServerTest, NewResourcesCanBeAdded) TEST_F(CustomizedServerTest, ContentOfAnyServableUrlCanBeOverriden) { { - const auto r = zfs1_->GET("/ROOT/"); + const auto r = zfs1_->GET("/ROOT%23%3F/"); EXPECT_EQ(r->status, 200); EXPECT_EQ(getHeaderValue(r->headers, "Content-Type"), "text/html"); EXPECT_EQ(r->body, "Welcome\n"); } { - const auto r = zfs1_->GET("/ROOT/skin/index.css"); + const auto r = zfs1_->GET("/ROOT%23%3F/skin/index.css"); EXPECT_EQ(r->status, 200); EXPECT_EQ(getHeaderValue(r->headers, "Content-Type"), "application/json"); EXPECT_EQ(r->body, "Hello world!\n"); } { - const auto r = zfs1_->GET("/ROOT/zimfile/A/Ray_Charles"); + const auto r = zfs1_->GET("/ROOT%23%3F/zimfile/A/Ray_Charles"); EXPECT_EQ(r->status, 200); EXPECT_EQ(getHeaderValue(r->headers, "Content-Type"), "ray/charles"); EXPECT_EQ(r->body, "Welcome\n"); } { - const auto r = zfs1_->GET("/ROOT/content/zimfile/A/Ray_Charles"); + const auto r = zfs1_->GET("/ROOT%23%3F/content/zimfile/A/Ray_Charles"); EXPECT_EQ(r->status, 200); EXPECT_EQ(getHeaderValue(r->headers, "Content-Type"), "charles/ray"); EXPECT_EQ(r->body, "Welcome\n"); } { - const auto r = zfs1_->GET("/ROOT/search?pattern=la+femme"); + const auto r = zfs1_->GET("/ROOT%23%3F/search?pattern=la+femme"); EXPECT_EQ(r->status, 200); EXPECT_EQ(getHeaderValue(r->headers, "Content-Type"), "text/html"); EXPECT_EQ(r->body, "Hello world!\n"); @@ -614,7 +614,7 @@ TEST_F(ServerTest, Http404HtmlError) { using namespace TestingOfHtmlResponses; const std::vector testData{ - { /* url */ "/ROOT/random?content=non-existent-book", + { /* url */ "/ROOT%23%3F/random?content=non-existent-book", expected_body==R"(

Not Found

@@ -622,7 +622,7 @@ TEST_F(ServerTest, Http404HtmlError)

)" }, - { /* url */ "/ROOT/random?content=non-existent-book&userlang=test", + { /* url */ "/ROOT%23%3F/random?content=non-existent-book&userlang=test", expected_page_title=="[I18N TESTING] Not Found - Try Again" && expected_body==R"(

[I18N TESTING] Content not found, but at least the server is alive

@@ -631,7 +631,7 @@ TEST_F(ServerTest, Http404HtmlError)

)" }, - { /* url */ "/ROOT/suggest?content=no-such-book&term=whatever", + { /* url */ "/ROOT%23%3F/suggest?content=no-such-book&term=whatever", expected_body==R"(

Not Found

@@ -639,149 +639,149 @@ TEST_F(ServerTest, Http404HtmlError)

)" }, - { /* url */ "/ROOT/catalog/", + { /* url */ "/ROOT%23%3F/catalog/", expected_body==R"(

Not Found

- The requested URL "/ROOT/catalog/" was not found on this server. + The requested URL "/ROOT%23%3F/catalog/" was not found on this server.

)" }, - { /* url */ "/ROOT/catalog/?userlang=test", + { /* url */ "/ROOT%23%3F/catalog/?userlang=test", expected_page_title=="[I18N TESTING] Not Found - Try Again" && expected_body==R"(

[I18N TESTING] Content not found, but at least the server is alive

- [I18N TESTING] URL not found: /ROOT/catalog/ + [I18N TESTING] URL not found: /ROOT%23%3F/catalog/

)" }, - { /* url */ "/ROOT/catalog/invalid_endpoint", + { /* url */ "/ROOT%23%3F/catalog/invalid_endpoint", expected_body==R"(

Not Found

- The requested URL "/ROOT/catalog/invalid_endpoint" was not found on this server. + The requested URL "/ROOT%23%3F/catalog/invalid_endpoint" was not found on this server.

)" }, - { /* url */ "/ROOT/catalog/invalid_endpoint?userlang=test", + { /* url */ "/ROOT%23%3F/catalog/invalid_endpoint?userlang=test", expected_page_title=="[I18N TESTING] Not Found - Try Again" && expected_body==R"(

[I18N TESTING] Content not found, but at least the server is alive

- [I18N TESTING] URL not found: /ROOT/catalog/invalid_endpoint + [I18N TESTING] URL not found: /ROOT%23%3F/catalog/invalid_endpoint

)" }, - { /* url */ "/ROOT/content/invalid-book/whatever", + { /* url */ "/ROOT%23%3F/content/invalid-book/whatever", expected_body==R"(

Not Found

- The requested URL "/ROOT/content/invalid-book/whatever" was not found on this server. + The requested URL "/ROOT%23%3F/content/invalid-book/whatever" was not found on this server.

- Make a full text search for whatever + Make a full text search for whatever

)" }, - { /* url */ "/ROOT/content/zimfile/invalid-article", + { /* url */ "/ROOT%23%3F/content/zimfile/invalid-article", book_name=="zimfile" && book_title=="Ray Charles" && expected_body==R"(

Not Found

- The requested URL "/ROOT/content/zimfile/invalid-article" was not found on this server. + The requested URL "/ROOT%23%3F/content/zimfile/invalid-article" was not found on this server.

- Make a full text search for invalid-article + Make a full text search for invalid-article

)" }, - { /* url */ R"(/ROOT/content/">)", + { /* url */ R"(/ROOT%23%3F/content/">)", expected_body==R"(

Not Found

- The requested URL "/ROOT/content/"><svg onload=alert(1)>" was not found on this server. + The requested URL "/ROOT%23%3F/content/"><svg onload%3Dalert(1)>" was not found on this server.

- Make a full text search for "><svg onload=alert(1)> + Make a full text search for "><svg onload=alert(1)>

)" }, - { /* url */ R"(/ROOT/content/zimfile/">)", + { /* url */ R"(/ROOT%23%3F/content/zimfile/">)", book_name=="zimfile" && book_title=="Ray Charles" && expected_body==R"(

Not Found

- The requested URL "/ROOT/content/zimfile/"><svg onload=alert(1)>" was not found on this server. + The requested URL "/ROOT%23%3F/content/zimfile/"><svg onload%3Dalert(1)>" was not found on this server.

- Make a full text search for "><svg onload=alert(1)> + Make a full text search for "><svg onload=alert(1)>

)" }, - { /* url */ "/ROOT/content/zimfile/invalid-article?userlang=test", + { /* url */ "/ROOT%23%3F/content/zimfile/invalid-article?userlang=test", expected_page_title=="[I18N TESTING] Not Found - Try Again" && book_name=="zimfile" && book_title=="Ray Charles" && expected_body==R"(

[I18N TESTING] Content not found, but at least the server is alive

- [I18N TESTING] URL not found: /ROOT/content/zimfile/invalid-article + [I18N TESTING] URL not found: /ROOT%23%3F/content/zimfile/invalid-article

- [I18N TESTING] Make a full text search for invalid-article + [I18N TESTING] Make a full text search for invalid-article

)" }, - { /* url */ "/ROOT/raw/no-such-book/meta/Title", + { /* url */ "/ROOT%23%3F/raw/no-such-book/meta/Title", expected_body==R"(

Not Found

- The requested URL "/ROOT/raw/no-such-book/meta/Title" was not found on this server. + The requested URL "/ROOT%23%3F/raw/no-such-book/meta/Title" was not found on this server.

No such book: no-such-book

)" }, - { /* url */ "/ROOT/raw/zimfile/XYZ", + { /* url */ "/ROOT%23%3F/raw/zimfile/XYZ", expected_body==R"(

Not Found

- The requested URL "/ROOT/raw/zimfile/XYZ" was not found on this server. + The requested URL "/ROOT%23%3F/raw/zimfile/XYZ" was not found on this server.

XYZ is not a valid request for raw content.

)" }, - { /* url */ "/ROOT/raw/zimfile/meta/invalid-metadata", + { /* url */ "/ROOT%23%3F/raw/zimfile/meta/invalid-metadata", expected_body==R"(

Not Found

- The requested URL "/ROOT/raw/zimfile/meta/invalid-metadata" was not found on this server. + The requested URL "/ROOT%23%3F/raw/zimfile/meta/invalid-metadata" was not found on this server.

Cannot find meta entry invalid-metadata

)" }, - { /* url */ "/ROOT/raw/zimfile/content/invalid-article", + { /* url */ "/ROOT%23%3F/raw/zimfile/content/invalid-article", expected_body==R"(

Not Found

- The requested URL "/ROOT/raw/zimfile/content/invalid-article" was not found on this server. + The requested URL "/ROOT%23%3F/raw/zimfile/content/invalid-article" was not found on this server.

Cannot find content entry invalid-article

)" }, - { /* url */ "/ROOT/search?content=poor&pattern=whatever", + { /* url */ "/ROOT%23%3F/search?content=poor&pattern=whatever", expected_page_title=="Fulltext search unavailable" && - expected_css_url=="/ROOT/skin/search_results.css?cacheid=76d39c84" && + expected_css_url=="/ROOT%23%3F/skin/search_results.css?cacheid=76d39c84" && book_name=="poor" && book_title=="poor" && expected_body==R"( @@ -804,41 +804,41 @@ TEST_F(ServerTest, Http400HtmlError) { using namespace TestingOfHtmlResponses; const std::vector testData{ - { /* url */ "/ROOT/search", + { /* url */ "/ROOT%23%3F/search", expected_body== R"(

Invalid request

- The requested URL "/ROOT/search" is not a valid request. + The requested URL "/ROOT%23%3F/search" is not a valid request.

Too many books requested (4) where limit is 3

)" }, - { /* url */ "/ROOT/search?content=zimfile", + { /* url */ "/ROOT%23%3F/search?content=zimfile", expected_body==R"(

Invalid request

- The requested URL "/ROOT/search?content=zimfile" is not a valid request. + The requested URL "/ROOT%23%3F/search?content=zimfile" is not a valid request.

No query provided.

)" }, - { /* url */ "/ROOT/search?content=non-existing-book&pattern=asdfqwerty", + { /* url */ "/ROOT%23%3F/search?content=non-existing-book&pattern=asdfqwerty", expected_body==R"(

Invalid request

- The requested URL "/ROOT/search?content=non-existing-book&pattern=asdfqwerty" is not a valid request. + The requested URL "/ROOT%23%3F/search?content=non-existing-book&pattern=asdfqwerty" is not a valid request.

No such book: non-existing-book

)" }, - { /* url */ "/ROOT/search?content=non-existing-book&pattern=a\"