Skip to content

Commit

Permalink
Make the addons server generate hashlists on upload
Browse files Browse the repository at this point in the history
  • Loading branch information
kabachuha authored and irydacea committed Oct 15, 2020
1 parent 0f3af61 commit 74fda8e
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 16 deletions.
64 changes: 64 additions & 0 deletions src/addon/validation.cpp
Expand Up @@ -16,6 +16,7 @@
#include "addon/validation.hpp"
#include "config.hpp"
#include "serialization/unicode_cast.hpp"
#include "hash.hpp"

#include <algorithm>
#include <array>
Expand Down Expand Up @@ -305,3 +306,66 @@ std::string unencode_binary(const std::string& str)
res.resize(n);
return res;
}

static const std::string file_hash_raw(const config& file)
{
return utils::md5(file["contents"].str()).base64_digest();
}

const std::string file_hash(const config& file)
{
std::string hash = file["hash"].str();
if(hash.empty()) {
hash = file_hash_raw(file);
}
return hash;
}

bool comp_file_hash(const config& file_a, const config& file_b)
{
return file_hash(file_a) == file_hash(file_b);
}

void write_hashlist(config& hashlist, const config& data)
{
hashlist["name"] = data["name"];

for(const config& f : data.child_range("file")) {
config& file = hashlist.add_child("file");
file["name"] = f["name"];
file["hash"] = file_hash_raw(f);
}

for(const config& d : data.child_range("dir")) {
config& dir = hashlist.add_child("dir");
write_hashlist(dir, d);
}
}

bool contains_hashlist(const config& from, const config& to)
{
for(const config& f : to.child_range("file")) {
bool found = false;
for(const config& d : from.child_range("file")) {
found |= comp_file_hash(f, d);
if(found)
break;
}
if(!found) {
return false;
}
}

for(const config& d : to.child_range("dir")) {
const config& origin_dir = from.find_child("dir", "name", d["name"]);
if(origin_dir) {
return contains_hashlist(origin_dir, d);
} else {
// The case of empty new subdirectories
const config dummy_dir = config("name", d["name"]);
return contains_hashlist(dummy_dir, d);
}
}

return true;
}
5 changes: 5 additions & 0 deletions src/addon/validation.hpp
Expand Up @@ -96,3 +96,8 @@ bool check_case_insensitive_duplicates(const config& dir, std::vector<std::strin
std::string encode_binary(const std::string& str);
std::string unencode_binary(const std::string& str);
bool needs_escaping(char c);

const std::string file_hash(const config& file);
bool comp_file_hash(const config& file_a, const config& file_b);
void write_hashlist(config& hashlist, const config& data);
bool contains_hashlist(const config& from, const config& to);
16 changes: 1 addition & 15 deletions src/server/campaignd/addon_utils.cpp
Expand Up @@ -20,7 +20,7 @@
#include "game_config.hpp"
#include "log.hpp"
#include "serialization/string_utils.hpp"
#include "hash.hpp"
#include "addon/validation.hpp"

#include <boost/algorithm/string.hpp>

Expand Down Expand Up @@ -153,20 +153,6 @@ void add_license(config& cfg)
copying["contents"] = contents;
}

static const std::string file_hash(const config& file)
{
std::string hash = file["hash"].str();
if(hash.empty()) {
hash = utils::md5(file["contents"].str()).base64_digest();
}
return hash;
}

static bool comp_file_hash(const config& file_a, const config& file_b)
{
return file_hash(file_a) == file_hash(file_b);
}

//! Surround with [dir][/dir]
static void write_difference(config& pack, const config& from, const config& to, bool with_content)
{
Expand Down
18 changes: 17 additions & 1 deletion src/server/campaignd/server.cpp
Expand Up @@ -275,6 +275,14 @@ void server::load_config()
writer.write(data);
campaign_file.commit();
}
{
filesystem::atomic_commit campaign_hash_file(addon_file + version_cfg["filename"].str() + ".hash");
config_writer writer(*campaign_hash_file.ostream(), true, compress_level_);
config data_hash = config("name", "");
write_hashlist(data_hash, data);
writer.write(data_hash);
campaign_hash_file.commit();
}

addons_.emplace(addon_id, campaign);
dirty_addons_.emplace(addon_id);
Expand Down Expand Up @@ -1073,7 +1081,6 @@ void server::handle_upload(const server::request& req)
add_license(data);

const std::string& new_version = (*campaign)["version"].str();
//#TODO: probably make hash from new_version + required_wesnoth_version ?
const std::string& file_hash = utils::md5(new_version).hex_digest();

//sorted version map
Expand All @@ -1099,6 +1106,15 @@ void server::handle_upload(const server::request& req)
writer.write(data);
campaign_file.commit();
}
// Let's write its hashes
{
filesystem::atomic_commit campaign_hash_file(filename + version_cfg["filename"].str() + ".hash");
config_writer writer(*campaign_hash_file.ostream(), true, compress_level_);
config data_hash = config("name", "");
write_hashlist(data_hash, data);
writer.write(data_hash);
campaign_hash_file.commit();
}

(*campaign)["size"] = filesystem::file_size(filename + version_cfg["filename"].str());

Expand Down

0 comments on commit 74fda8e

Please sign in to comment.