Proper URI-encoding in InternalServer::build_redirect()

- Before this change `InternalServer::build_redirect()` only URI-encoded the
  article path, ignoring the book name and/or the root location components of
  the URL.

- In order to be able to test this fix, corner_cases.zim was renamed to
  contain a couple of special URL symbols in its filename. The
  `create_corner_cases_zim_file` script was updated accordingly.
This commit is contained in:
Veloman Yunkan 2023-02-08 15:31:29 +01:00
parent 2f419996ab
commit 2e9bec95b0
7 changed files with 34 additions and 18 deletions

View File

@ -1030,9 +1030,8 @@ ParameterizedMessage suggestSearchMsg(const std::string& searchURL, const std::s
std::unique_ptr<Response> std::unique_ptr<Response>
InternalServer::build_redirect(const std::string& bookName, const zim::Item& item) const InternalServer::build_redirect(const std::string& bookName, const zim::Item& item) const
{ {
const auto path = kiwix::urlEncode(item.getPath()); const auto absPath = m_root + "/content/" + bookName + "/" + item.getPath();
const auto redirectUrl = m_root + "/content/" + bookName + "/" + path; return Response::build_redirect(*this, kiwix::urlEncode(absPath));
return Response::build_redirect(*this, redirectUrl);
} }
std::unique_ptr<Response> InternalServer::handle_content(const RequestContext& request) std::unique_ptr<Response> InternalServer::handle_content(const RequestContext& request)

View File

@ -1,7 +1,24 @@
#!/usr/bin/env bash #!/usr/bin/env bash
cd "$(dirname "$0")" cd "$(dirname "$0")"
rm -f corner_cases.zim
# The following symbols (that would be nice to include in testing) are not
# allowed under NTFS and/or FAT32 filesystems, and would result in the
# impossibility to git clone (or rather checkout) the libkiwix repository under
# Windows:
#
# ?
# =
# + (that's a pity, since the + symbol in a ZIM filename is replaced with the
# text 'plus' when the ZIM file is added to kiwix-serve's library and it
# would be nice to test that functionality)
#
# Assuming that tests are NOT run under Windows, above symbols can be included
# in testing if the file is renamed while copying to the build directory (see
# test/meson.build), though that would make maintenance slightly more confusing.
zimfilename='corner_cases#&.zim'
rm -f "$zimfilename"
zimwriterfs --withoutFTIndex --dont-check-arguments \ zimwriterfs --withoutFTIndex --dont-check-arguments \
-w empty.html \ -w empty.html \
-I empty.png \ -I empty.png \
@ -11,6 +28,6 @@ zimwriterfs --withoutFTIndex --dont-check-arguments \
-c "" \ -c "" \
-p "" \ -p "" \
corner_cases \ corner_cases \
corner_cases.zim \ "$zimfilename" \
&& echo 'corner_cases.zim was successfully created' \ && echo "$zimfilename was successfully created" \
|| echo '!!! Failed to create corner_cases.zim !!!' >&2 || echo '!!! Failed to create' "$zimfilename" '!!!' >&2

View File

@ -34,7 +34,7 @@ if gtest_dep.found() and not meson.is_cross_build()
'example.zim', 'example.zim',
'zimfile.zim', 'zimfile.zim',
'zimfile&other.zim', 'zimfile&other.zim',
'corner_cases.zim', 'corner_cases#&.zim',
'poor.zim', 'poor.zim',
'library.xml', 'library.xml',
'lib_for_server_search_test.xml', 'lib_for_server_search_test.xml',

View File

@ -166,9 +166,9 @@ const ResourceCollection resources200Uncompressible{
{ ZIM_CONTENT, "/ROOT/content/zimfile/I/m/Ray_Charles_classic_piano_pose.jpg" }, { ZIM_CONTENT, "/ROOT/content/zimfile/I/m/Ray_Charles_classic_piano_pose.jpg" },
{ ZIM_CONTENT, "/ROOT/content/corner_cases/empty.html" }, { ZIM_CONTENT, "/ROOT/content/corner_cases%23%26/empty.html" },
{ ZIM_CONTENT, "/ROOT/content/corner_cases/empty.css" }, { ZIM_CONTENT, "/ROOT/content/corner_cases%23%26/empty.css" },
{ ZIM_CONTENT, "/ROOT/content/corner_cases/empty.js" }, { ZIM_CONTENT, "/ROOT/content/corner_cases%23%26/empty.js" },
// The following url's responses are too small to be compressed // The following url's responses are too small to be compressed
@ -188,7 +188,7 @@ TEST(indexTemplateStringTest, emptyIndexTemplate) {
const int PORT = 8001; const int PORT = 8001;
const ZimFileServer::FilePathCollection ZIMFILES { const ZimFileServer::FilePathCollection ZIMFILES {
"./test/zimfile.zim", "./test/zimfile.zim",
"./test/corner_cases.zim" "./test/corner_cases#&.zim"
}; };
ZimFileServer zfs(PORT, ZimFileServer::DEFAULT_OPTIONS, ZIMFILES, ""); ZimFileServer zfs(PORT, ZimFileServer::DEFAULT_OPTIONS, ZIMFILES, "");
@ -199,7 +199,7 @@ TEST(indexTemplateStringTest, indexTemplateCheck) {
const int PORT = 8001; const int PORT = 8001;
const ZimFileServer::FilePathCollection ZIMFILES { const ZimFileServer::FilePathCollection ZIMFILES {
"./test/zimfile.zim", "./test/zimfile.zim",
"./test/corner_cases.zim" "./test/corner_cases#&.zim"
}; };
ZimFileServer zfs(PORT, ZimFileServer::DEFAULT_OPTIONS, ZIMFILES, "<!DOCTYPE html><head>" ZimFileServer zfs(PORT, ZimFileServer::DEFAULT_OPTIONS, ZIMFILES, "<!DOCTYPE html><head>"
@ -1291,10 +1291,10 @@ TEST_F(ServerTest, NonEndpointUrlsAreRedirectedToContentUrls)
TEST_F(ServerTest, RedirectionsToURLsWithSpecialSymbols) TEST_F(ServerTest, RedirectionsToURLsWithSpecialSymbols)
{ {
auto g = zfs1_->GET("/ROOT/content/corner_cases/c_sharp.html"); auto g = zfs1_->GET("/ROOT/content/corner_cases%23%26/c_sharp.html");
ASSERT_EQ(302, g->status); ASSERT_EQ(302, g->status);
ASSERT_TRUE(g->has_header("Location")); ASSERT_TRUE(g->has_header("Location"));
ASSERT_EQ(g->get_header_value("Location"), "/ROOT/content/corner_cases/c%23.html"); ASSERT_EQ(g->get_header_value("Location"), "/ROOT/content/corner_cases%23%26/c%23.html");
ASSERT_EQ(getCacheControlHeader(*g), "max-age=0, must-revalidate"); ASSERT_EQ(getCacheControlHeader(*g), "max-age=0, must-revalidate");
ASSERT_FALSE(g->has_header("ETag")); ASSERT_FALSE(g->has_header("ETag"));
} }
@ -1611,7 +1611,7 @@ TEST_F(ServerTest, InvalidAndMultiRangeByteRangeRequestsResultIn416Responses)
TEST_F(ServerTest, ValidByteRangeRequestsOfZeroSizedEntriesResultIn416Responses) TEST_F(ServerTest, ValidByteRangeRequestsOfZeroSizedEntriesResultIn416Responses)
{ {
const char url[] = "/ROOT/content/corner_cases/empty.js"; const char url[] = "/ROOT/content/corner_cases%23%26/empty.js";
const char* ranges[] = { const char* ranges[] = {
"bytes=0-", "bytes=0-",

View File

@ -1517,7 +1517,7 @@ TEST(ServerSearchTest, searchInMultilanguageBookSetIsDenied)
const ZimFileServer::FilePathCollection ZIMFILES{ const ZimFileServer::FilePathCollection ZIMFILES{
"./test/zimfile.zim", // eng "./test/zimfile.zim", // eng
"./test/example.zim", // en "./test/example.zim", // en
"./test/corner_cases.zim" // =en "./test/corner_cases#&.zim" // =en
}; };
ZimFileServer zfs(SERVER_PORT, ZimFileServer::DEFAULT_OPTIONS, ZIMFILES); ZimFileServer zfs(SERVER_PORT, ZimFileServer::DEFAULT_OPTIONS, ZIMFILES);

View File

@ -163,7 +163,7 @@ protected:
"./test/zimfile.zim", "./test/zimfile.zim",
"./test/example.zim", "./test/example.zim",
"./test/poor.zim", "./test/poor.zim",
"./test/corner_cases.zim" "./test/corner_cases#&.zim"
}; };
protected: protected: