mirror of https://github.com/kiwix/libkiwix.git
ETags for ZIM content use the ZIM file UUID
This commit is contained in:
parent
a31ccb6588
commit
b249edee60
|
@ -511,8 +511,10 @@ MHD_Result InternalServer::handlerCallback(struct MHD_Connection* connection,
|
|||
}
|
||||
}
|
||||
|
||||
if (response->getReturnCode() == MHD_HTTP_OK && !etag_not_needed(request))
|
||||
response->set_server_id(m_server_id);
|
||||
if (response->getReturnCode() == MHD_HTTP_OK
|
||||
&& response->get_kind() == Response::DYNAMIC_CONTENT
|
||||
&& !etag_not_needed(request))
|
||||
response->set_etag_body(m_server_id);
|
||||
|
||||
auto ret = response->send(request, connection);
|
||||
auto end_time = std::chrono::steady_clock::now();
|
||||
|
@ -542,7 +544,7 @@ std::unique_ptr<Response> InternalServer::handle_request(const RequestContext& r
|
|||
+ urlNotFoundMsg;
|
||||
}
|
||||
|
||||
const ETag etag = get_matching_if_none_match_etag(request);
|
||||
const ETag etag = get_matching_if_none_match_etag(request, m_server_id);
|
||||
if ( etag )
|
||||
return Response::build_304(*this, etag);
|
||||
|
||||
|
@ -611,11 +613,11 @@ bool InternalServer::etag_not_needed(const RequestContext& request) const
|
|||
}
|
||||
|
||||
ETag
|
||||
InternalServer::get_matching_if_none_match_etag(const RequestContext& r) const
|
||||
InternalServer::get_matching_if_none_match_etag(const RequestContext& r, const std::string& etagBody) const
|
||||
{
|
||||
try {
|
||||
const std::string etag_list = r.get_header(MHD_HTTP_HEADER_IF_NONE_MATCH);
|
||||
return ETag::match(etag_list, m_server_id);
|
||||
return ETag::match(etag_list, etagBody);
|
||||
} catch (const std::out_of_range&) {
|
||||
return ETag();
|
||||
}
|
||||
|
@ -1049,6 +1051,11 @@ std::unique_ptr<Response> InternalServer::handle_content(const RequestContext& r
|
|||
+ suggestSearchMsg(searchURL, kiwix::urlDecode(pattern));
|
||||
}
|
||||
|
||||
const std::string archiveUuid(archive->getUuid());
|
||||
const ETag etag = get_matching_if_none_match_etag(request, archiveUuid);
|
||||
if ( etag )
|
||||
return Response::build_304(*this, etag);
|
||||
|
||||
auto urlStr = url.substr(prefixLength + bookName.size());
|
||||
if (urlStr[0] == '/') {
|
||||
urlStr = urlStr.substr(1);
|
||||
|
@ -1067,6 +1074,7 @@ std::unique_ptr<Response> InternalServer::handle_content(const RequestContext& r
|
|||
return build_redirect(bookName, getFinalItem(*archive, entry));
|
||||
}
|
||||
auto response = ItemResponse::build(*this, request, entry.getItem());
|
||||
response->set_etag_body(archiveUuid);
|
||||
|
||||
if (m_verbose.load()) {
|
||||
printf("Found %s\n", entry.getPath().c_str());
|
||||
|
@ -1120,6 +1128,11 @@ std::unique_ptr<Response> InternalServer::handle_raw(const RequestContext& reque
|
|||
+ noSuchBookErrorMsg(bookName);
|
||||
}
|
||||
|
||||
const std::string archiveUuid(archive->getUuid());
|
||||
const ETag etag = get_matching_if_none_match_etag(request, archiveUuid);
|
||||
if ( etag )
|
||||
return Response::build_304(*this, etag);
|
||||
|
||||
// Remove the beggining of the path:
|
||||
// /raw/<bookName>/<kind>/foo
|
||||
// ^^^^^ ^ ^
|
||||
|
@ -1129,13 +1142,17 @@ std::unique_ptr<Response> InternalServer::handle_raw(const RequestContext& reque
|
|||
try {
|
||||
if (kind == "meta") {
|
||||
auto item = archive->getMetadataItem(itemPath);
|
||||
return ItemResponse::build(*this, request, item);
|
||||
auto response = ItemResponse::build(*this, request, item);
|
||||
response->set_etag_body(archiveUuid);
|
||||
return response;
|
||||
} else {
|
||||
auto entry = archive->getEntryByPath(itemPath);
|
||||
if (entry.isRedirect()) {
|
||||
return build_redirect(bookName, entry.getItem(true));
|
||||
}
|
||||
return ItemResponse::build(*this, request, entry.getItem());
|
||||
auto response = ItemResponse::build(*this, request, entry.getItem());
|
||||
response->set_etag_body(archiveUuid);
|
||||
return response;
|
||||
}
|
||||
} catch (zim::EntryNotFound& e ) {
|
||||
if (m_verbose.load()) {
|
||||
|
|
|
@ -148,7 +148,7 @@ class InternalServer {
|
|||
MustacheData get_default_data() const;
|
||||
|
||||
bool etag_not_needed(const RequestContext& r) const;
|
||||
ETag get_matching_if_none_match_etag(const RequestContext& request) const;
|
||||
ETag get_matching_if_none_match_etag(const RequestContext& request, const std::string& etagBody) const;
|
||||
std::pair<std::string, Library::BookIdSet> selectBooks(const RequestContext& r) const;
|
||||
SearchInfo getSearchInfo(const RequestContext& r) const;
|
||||
|
||||
|
|
|
@ -66,7 +66,8 @@ class Response {
|
|||
|
||||
void set_code(int code) { m_returnCode = code; }
|
||||
void set_kind(Kind k);
|
||||
void set_server_id(const std::string& id) { m_etag.set_body(id); }
|
||||
Kind get_kind() const { return m_kind; }
|
||||
void set_etag_body(const std::string& id) { m_etag.set_body(id); }
|
||||
void add_header(const std::string& name, const std::string& value) { m_customHeaders[name] = value; }
|
||||
|
||||
int getReturnCode() const { return m_returnCode; }
|
||||
|
|
|
@ -1136,17 +1136,28 @@ TEST_F(ServerTest, ETagIsTheSameAcrossHeadAndGet)
|
|||
}
|
||||
}
|
||||
|
||||
TEST_F(ServerTest, DifferentServerInstancesProduceDifferentETags)
|
||||
TEST_F(ServerTest, DifferentServerInstancesProduceDifferentETagsForDynamicContent)
|
||||
{
|
||||
ZimFileServer zfs2(SERVER_PORT + 1, ZimFileServer::DEFAULT_OPTIONS, ZIMFILES);
|
||||
for ( const Resource& res : all200Resources() ) {
|
||||
if ( !res.etag_expected() ) continue;
|
||||
if ( res.kind != DYNAMIC_CONTENT ) continue;
|
||||
const auto h1 = zfs1_->HEAD(res.url);
|
||||
const auto h2 = zfs2.HEAD(res.url);
|
||||
EXPECT_NE(h1->get_header_value("ETag"), h2->get_header_value("ETag"));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ServerTest, DifferentServerInstancesProduceIdenticalETagsForZimContent)
|
||||
{
|
||||
ZimFileServer zfs2(SERVER_PORT + 1, ZimFileServer::DEFAULT_OPTIONS, ZIMFILES);
|
||||
for ( const Resource& res : all200Resources() ) {
|
||||
if ( res.kind != ZIM_CONTENT ) continue;
|
||||
const auto h1 = zfs1_->HEAD(res.url);
|
||||
const auto h2 = zfs2.HEAD(res.url);
|
||||
EXPECT_EQ(h1->get_header_value("ETag"), h2->get_header_value("ETag"));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ServerTest, CompressionInfluencesETag)
|
||||
{
|
||||
for ( const Resource& res : resources200Compressible ) {
|
||||
|
|
Loading…
Reference in New Issue