Skip to content

Commit

Permalink
Add raw endpoint.
Browse files Browse the repository at this point in the history
As the name suggests it, this endpoint is not smart :
It returns the content as it is and only if it is present
(no compatibility or whatever).

The only "smart" thing is to return a redirect if the entry is a redirect.
  • Loading branch information
mgautierfr committed Dec 15, 2021
1 parent 8181d0a commit 8551b7e
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 0 deletions.
57 changes: 57 additions & 0 deletions src/server/internalServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,9 @@ std::unique_ptr<Response> InternalServer::handle_request(const RequestContext& r
if (startsWith(request.get_url(), "/catalog/"))
return handle_catalog(request);

if (startsWith(request.get_url(), "/raw/"))
return handle_raw(request);

if (request.get_url() == "/meta")
return handle_meta(request);

Expand Down Expand Up @@ -891,4 +894,58 @@ std::unique_ptr<Response> InternalServer::handle_content(const RequestContext& r
}
}


std::unique_ptr<Response> InternalServer::handle_raw(const RequestContext& request)
{
if (m_verbose.load()) {
printf("** running handle_raw\n");
}

std::string bookName;
std::string kind;
try {
bookName = request.get_url_part(1);
kind = request.get_url_part(2);
} catch (const std::out_of_range& e) {
return Response::build_404(*this, request, bookName, "", "");
}

if (kind != "meta" && kind!= "content") {
return Response::build_404(*this, request, bookName, "", "");
}

std::shared_ptr<zim::Archive> archive;
try {
const std::string bookId = mp_nameMapper->getIdForName(bookName);
archive = mp_library->getArchiveById(bookId);
} catch (const std::out_of_range& e) {}

if (archive == nullptr) {
return Response::build_404(*this, request, bookName, "", "");
}

auto itemPath = request.get_url().substr(bookName.size()+kind.size()+6);
if (itemPath[0] == '/') {
itemPath = itemPath.substr(1);
}

try {
if (kind == "meta") {
auto item = archive->getMetadataItem(itemPath);
return ItemResponse::build(*this, request, item, true);
} else {
auto entry = archive->getEntryByPath(itemPath);
if (entry.isRedirect()) {
return build_redirect(bookName, entry.getItem(true));
}
return ItemResponse::build(*this, request, entry.getItem(), true);
}
} catch (zim::EntryNotFound& e ) {
if (m_verbose.load()) {
printf("Failed to find %s\n", itemPath.c_str());
}
return Response::build_404(*this, request, bookName, getArchiveTitle(*archive), "");
}
}

}
1 change: 1 addition & 0 deletions src/server/internalServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ class InternalServer {
std::unique_ptr<Response> handle_random(const RequestContext& request);
std::unique_ptr<Response> handle_captured_external(const RequestContext& request);
std::unique_ptr<Response> handle_content(const RequestContext& request);
std::unique_ptr<Response> handle_raw(const RequestContext& request);

std::vector<std::string> search_catalog(const RequestContext& request,
kiwix::OPDSDumper& opdsDumper);
Expand Down
29 changes: 29 additions & 0 deletions test/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,9 @@ const ResourceCollection resources200Compressible{

{ WITH_ETAG, "/zimfile/A/index" },
{ WITH_ETAG, "/zimfile/A/Ray_Charles" },

{ WITH_ETAG, "/raw/zimfile/content/A/index" },
{ WITH_ETAG, "/raw/zimfile/content/A/Ray_Charles" },
};

const ResourceCollection resources200Uncompressible{
Expand All @@ -207,6 +210,10 @@ const ResourceCollection resources200Uncompressible{
{ WITH_ETAG, "/corner_cases/A/empty.html" },
{ WITH_ETAG, "/corner_cases/-/empty.css" },
{ WITH_ETAG, "/corner_cases/-/empty.js" },

// The title and creator are too small to be compressed
{ WITH_ETAG, "/raw/zimfile/meta/Creator" },
{ WITH_ETAG, "/raw/zimfile/meta/Title" },
};

ResourceCollection all200Resources()
Expand Down Expand Up @@ -310,6 +317,28 @@ TEST_F(ServerTest, BookMainPageIsRedirectedToArticleIndex)
ASSERT_EQ("/zimfile/A/index", g->get_header_value("Location"));
}


TEST_F(ServerTest, RawEntry)
{
auto p = zfs1_->GET("/raw/zimfile/meta/Title");
EXPECT_EQ(200, p->status);
EXPECT_EQ(p->body, std::string("Ray Charles"));

p = zfs1_->GET("/raw/zimfile/meta/Creator");
EXPECT_EQ(200, p->status);
EXPECT_EQ(p->body, std::string("Wikipedia"));

// The raw content of Ray_Charles doesn't contain a taskbar...
p = zfs1_->GET("/raw/zimfile/content/A/Ray_Charles");
EXPECT_EQ(200, p->status);
EXPECT_TRUE(p->body.find("taskbar") == std::string::npos);

// ... but the "normal" content does.
p = zfs1_->GET("/zimfile/A/Ray_Charles");
EXPECT_EQ(200, p->status);
EXPECT_TRUE(p->body.find("taskbar") != std::string::npos);
}

TEST_F(ServerTest, HeadMethodIsSupported)
{
for ( const Resource& res : all200Resources() )
Expand Down

0 comments on commit 8551b7e

Please sign in to comment.