From 1b1c1e352eb4ec65c2736116230ab7f85f7b1c4d Mon Sep 17 00:00:00 2001
From: Veloman Yunkan
Date: Sat, 25 Jun 2022 17:54:21 +0400
Subject: [PATCH] Introduced /content endpoint
Book content is now served under /content/book/...
The old access to book content via a top-level URL /book/... is so far
preserved for backward compatibility.
Redirects were changed to use the new URL scheme. Links in the search results
still use the old scheme.
---
src/server/internalServer.cpp | 22 ++++---
test/data/customized_resources.txt | 1 +
test/server.cpp | 95 +++++++++++++++++++++++++++++-
3 files changed, 104 insertions(+), 14 deletions(-)
diff --git a/src/server/internalServer.cpp b/src/server/internalServer.cpp
index 75a0e4738..d3d5aef42 100644
--- a/src/server/internalServer.cpp
+++ b/src/server/internalServer.cpp
@@ -545,6 +545,9 @@ std::unique_ptr InternalServer::handle_request(const RequestContext& r
if (startsWith(request.get_url(), "/skin/"))
return handle_skin(request);
+ if (startsWith(request.get_url(), "/content/"))
+ return handle_content(request);
+
if (startsWith(request.get_url(), "/catalog/"))
return handle_catalog(request);
@@ -922,15 +925,6 @@ InternalServer::search_catalog(const RequestContext& request,
namespace
{
-std::string get_book_name(const RequestContext& request)
-{
- try {
- return request.get_url_part(0);
- } catch (const std::out_of_range& e) {
- return std::string();
- }
-}
-
ParameterizedMessage suggestSearchMsg(const std::string& searchURL, const std::string& pattern)
{
return ParameterizedMessage("suggest-search",
@@ -945,7 +939,8 @@ ParameterizedMessage suggestSearchMsg(const std::string& searchURL, const std::s
std::unique_ptr
InternalServer::build_redirect(const std::string& bookName, const zim::Item& item) const
{
- auto redirectUrl = m_root + "/" + bookName + "/" + kiwix::urlEncode(item.getPath());
+ const auto path = kiwix::urlEncode(item.getPath());
+ const auto redirectUrl = m_root + "/content/" + bookName + "/" + path;
return Response::build_redirect(*this, redirectUrl);
}
@@ -957,7 +952,10 @@ std::unique_ptr InternalServer::handle_content(const RequestContext& r
printf("** running handle_content\n");
}
- const std::string bookName = get_book_name(request);
+ const std::string contentPrefix = "/content/";
+ const bool isContentPrefixedUrl = startsWith(url, contentPrefix);
+ const size_t prefixLength = isContentPrefixedUrl ? contentPrefix.size() : 1;
+ const std::string bookName = request.get_url_part(isContentPrefixedUrl);
std::shared_ptr archive;
try {
@@ -973,7 +971,7 @@ std::unique_ptr InternalServer::handle_content(const RequestContext& r
+ TaskbarInfo(bookName);
}
- auto urlStr = request.get_url().substr(bookName.size()+1);
+ auto urlStr = url.substr(prefixLength + bookName.size());
if (urlStr[0] == '/') {
urlStr = urlStr.substr(1);
}
diff --git a/test/data/customized_resources.txt b/test/data/customized_resources.txt
index 5c5f2b72e..16c4b69c2 100644
--- a/test/data/customized_resources.txt
+++ b/test/data/customized_resources.txt
@@ -2,4 +2,5 @@
/ text/html ./test/welcome.html
/skin/index.css application/json ./test/helloworld.txt
/zimfile/A/Ray_Charles ray/charles ./test/welcome.html
+/content/zimfile/A/Ray_Charles charles/ray ./test/welcome.html
/search text/html ./test/helloworld.txt
diff --git a/test/server.cpp b/test/server.cpp
index 034a398cb..b50dbe396 100644
--- a/test/server.cpp
+++ b/test/server.cpp
@@ -6,6 +6,8 @@
#define SERVER_PORT 8001
#include "server_testing_tools.h"
+#include "../src/tools/stringTools.h"
+
bool is_valid_etag(const std::string& etag)
{
@@ -56,6 +58,9 @@ const ResourceCollection resources200Compressible{
{ WITH_ETAG, "/ROOT/zimfile/A/index" },
{ WITH_ETAG, "/ROOT/zimfile/A/Ray_Charles" },
+ { WITH_ETAG, "/ROOT/content/zimfile/A/index" },
+ { WITH_ETAG, "/ROOT/content/zimfile/A/Ray_Charles" },
+
{ WITH_ETAG, "/ROOT/raw/zimfile/content/A/index" },
{ WITH_ETAG, "/ROOT/raw/zimfile/content/A/Ray_Charles" },
};
@@ -75,11 +80,17 @@ const ResourceCollection resources200Uncompressible{
{ NO_ETAG, "/ROOT/catalog/v2/illustration/6f1d19d0-633f-087b-fb55-7ac324ff9baf?size=48" },
{ WITH_ETAG, "/ROOT/zimfile/I/m/Ray_Charles_classic_piano_pose.jpg" },
+ { WITH_ETAG, "/ROOT/content/zimfile/I/m/Ray_Charles_classic_piano_pose.jpg" },
{ WITH_ETAG, "/ROOT/corner_cases/A/empty.html" },
{ WITH_ETAG, "/ROOT/corner_cases/-/empty.css" },
{ WITH_ETAG, "/ROOT/corner_cases/-/empty.js" },
+ { WITH_ETAG, "/ROOT/content/corner_cases/A/empty.html" },
+ { WITH_ETAG, "/ROOT/content/corner_cases/-/empty.css" },
+ { WITH_ETAG, "/ROOT/content/corner_cases/-/empty.js" },
+
+
// The following url's responses are too small to be compressed
{ NO_ETAG, "/ROOT/catalog/root.xml" },
{ NO_ETAG, "/ROOT/catalog/searchdescription.xml" },
@@ -197,6 +208,15 @@ R"EXPECTEDRESULT(
+
+
+)EXPECTEDRESULT"
+ },
+ {
+ /* url */ "/ROOT/content/zimfile/A/index",
+R"EXPECTEDRESULT(
+
+
)EXPECTEDRESULT"
@@ -265,6 +285,7 @@ const char* urls404[] = {
"/ROOT/suggest?content=non-existent-book&term=abcd",
"/ROOT/catch/external",
"/ROOT/zimfile/A/non-existent-article",
+ "/ROOT/content/zimfile/A/non-existent-article",
"/ROOT/raw/non-existent-book/meta/Title",
"/ROOT/raw/zimfile/wrong-kind/Foo",
@@ -335,6 +356,13 @@ TEST_F(CustomizedServerTest, ContentOfAnyServableUrlCanBeOverriden)
EXPECT_EQ(r->body, "Welcome\n");
}
+ {
+ const auto r = zfs1_->GET("/ROOT/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");
EXPECT_EQ(r->status, 200);
@@ -685,6 +713,19 @@ TEST_F(ServerTest, Http404HtmlError)
)" },
+ { /* url */ "/ROOT/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.
+
+
+ Make a full text search for invalid-article
+
+)" },
+
{ /* url */ R"(/ROOT/">