aboutsummaryrefslogtreecommitdiff
path: root/src/client/clientmedia.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/clientmedia.cpp')
-rw-r--r--src/client/clientmedia.cpp193
1 files changed, 111 insertions, 82 deletions
diff --git a/src/client/clientmedia.cpp b/src/client/clientmedia.cpp
index 1cf18b84b..8cd3b6bcc 100644
--- a/src/client/clientmedia.cpp
+++ b/src/client/clientmedia.cpp
@@ -48,8 +48,9 @@ bool clientMediaUpdateCache(const std::string &raw_hash, const std::string &file
ClientMediaDownloader
*/
-ClientMediaDownloader::ClientMediaDownloader() :
- m_media_cache(getMediaCacheDir()), m_httpfetch_caller(HTTPFETCH_DISCARD)
+ClientMediaDownloader::ClientMediaDownloader():
+ m_media_cache(getMediaCacheDir()),
+ m_httpfetch_caller(HTTPFETCH_DISCARD)
{
}
@@ -72,21 +73,24 @@ void ClientMediaDownloader::addFile(const std::string &name, const std::string &
// if name was already announced, ignore the new announcement
if (m_files.count(name) != 0) {
errorstream << "Client: ignoring duplicate media announcement "
- << "sent by server: \"" << name << "\"" << std::endl;
+ << "sent by server: \"" << name << "\""
+ << std::endl;
return;
}
// if name is empty or contains illegal characters, ignore the file
if (name.empty() || !string_allowed(name, TEXTURENAME_ALLOWED_CHARS)) {
errorstream << "Client: ignoring illegal file name "
- << "sent by server: \"" << name << "\"" << std::endl;
+ << "sent by server: \"" << name << "\""
+ << std::endl;
return;
}
// length of sha1 must be exactly 20 (160 bits), else ignore the file
if (sha1.size() != 20) {
errorstream << "Client: ignoring illegal SHA1 sent by server: "
- << hex_encode(sha1) << " \"" << name << "\"" << std::endl;
+ << hex_encode(sha1) << " \"" << name << "\""
+ << std::endl;
return;
}
@@ -99,13 +103,13 @@ void ClientMediaDownloader::addFile(const std::string &name, const std::string &
void ClientMediaDownloader::addRemoteServer(const std::string &baseurl)
{
- assert(!m_initial_step_done); // pre-condition
+ assert(!m_initial_step_done); // pre-condition
-#ifdef USE_CURL
+ #ifdef USE_CURL
if (g_settings->getBool("enable_remote_media_server")) {
- infostream << "Client: Adding remote server \"" << baseurl
- << "\" for media download" << std::endl;
+ infostream << "Client: Adding remote server \""
+ << baseurl << "\" for media download" << std::endl;
RemoteServerStatus *remote = new RemoteServerStatus();
remote->baseurl = baseurl;
@@ -113,12 +117,13 @@ void ClientMediaDownloader::addRemoteServer(const std::string &baseurl)
m_remotes.push_back(remote);
}
-#else
+ #else
- infostream << "Client: Ignoring remote server \"" << baseurl
- << "\" because cURL support is not compiled in" << std::endl;
+ infostream << "Client: Ignoring remote server \""
+ << baseurl << "\" because cURL support is not compiled in"
+ << std::endl;
-#endif
+ #endif
}
void ClientMediaDownloader::step(Client *client)
@@ -153,10 +158,9 @@ void ClientMediaDownloader::step(Client *client)
if (m_httpfetch_active == 0) {
if (m_uncached_received_count < m_uncached_count) {
infostream << "Client: Failed to remote-fetch "
- << (m_uncached_count -
- m_uncached_received_count)
- << " files. Requesting them"
- << " the usual way." << std::endl;
+ << (m_uncached_count-m_uncached_received_count)
+ << " files. Requesting them"
+ << " the usual way." << std::endl;
}
startConventionalTransfers(client);
}
@@ -177,8 +181,8 @@ void ClientMediaDownloader::initialStep(Client *client)
// If found in cache, try to load it from there
if (found_in_cache) {
- bool success = checkAndLoad(
- name, sha1, tmp_os.str(), true, client);
+ bool success = checkAndLoad(name, sha1,
+ tmp_os.str(), true, client);
if (success) {
filestatus->received = true;
m_uncached_count--;
@@ -193,8 +197,9 @@ void ClientMediaDownloader::initialStep(Client *client)
bool did = fs::CreateAllDirs(getMediaCacheDir());
if (!did) {
errorstream << "Client: "
- << "Could not create media cache directory: "
- << getMediaCacheDir() << std::endl;
+ << "Could not create media cache directory: "
+ << getMediaCacheDir()
+ << std::endl;
}
}
@@ -205,7 +210,8 @@ void ClientMediaDownloader::initialStep(Client *client)
// reduce the size of the compiled code
if (!USE_CURL || m_uncached_count == 0 || m_remotes.empty()) {
startConventionalTransfers(client);
- } else {
+ }
+ else {
// Otherwise start off by requesting each server's sha1 set
// This is the first time we use httpfetch, so alloc a caller ID
@@ -245,26 +251,27 @@ void ClientMediaDownloader::initialStep(Client *client)
RemoteServerStatus *remote = m_remotes[i];
actionstream << "Client: Contacting remote server \""
- << remote->baseurl << "\"" << std::endl;
+ << remote->baseurl << "\"" << std::endl;
HTTPFetchRequest fetch_request;
- fetch_request.url = remote->baseurl + MTHASHSET_FILE_NAME;
+ fetch_request.url =
+ remote->baseurl + MTHASHSET_FILE_NAME;
fetch_request.caller = m_httpfetch_caller;
fetch_request.request_id = m_httpfetch_next_id; // == i
fetch_request.timeout = m_httpfetch_timeout;
fetch_request.connect_timeout = m_httpfetch_timeout;
fetch_request.post_data = required_hash_set;
fetch_request.extra_headers.emplace_back(
- "Content-Type: application/octet-stream");
+ "Content-Type: application/octet-stream");
// Encapsulate possible IPv6 plain address in []
std::string addr = client->getAddressName();
if (addr.find(':', 0) != std::string::npos)
addr = '[' + addr + ']';
fetch_request.extra_headers.emplace_back(
- std::string("Referer: minetest://") + addr + ":" +
- std::to_string(client->getServerAddress()
- .getPort()));
+ std::string("Referer: minetest://") +
+ addr + ":" +
+ std::to_string(client->getServerAddress().getPort()));
httpfetch_async(fetch_request);
@@ -275,7 +282,8 @@ void ClientMediaDownloader::initialStep(Client *client)
}
}
-void ClientMediaDownloader::remoteHashSetReceived(const HTTPFetchResult &fetch_result)
+void ClientMediaDownloader::remoteHashSetReceived(
+ const HTTPFetchResult &fetch_result)
{
u32 remote_id = fetch_result.request_id;
assert(remote_id < m_remotes.size());
@@ -295,23 +303,25 @@ void ClientMediaDownloader::remoteHashSetReceived(const HTTPFetchResult &fetch_r
// available on this server, add this server
// to the available_remotes array
- for (std::map<std::string, FileStatus *>::iterator it =
- m_files.upper_bound(m_name_bound);
+ for(std::map<std::string, FileStatus*>::iterator
+ it = m_files.upper_bound(m_name_bound);
it != m_files.end(); ++it) {
FileStatus *f = it->second;
if (!f->received && sha1_set.count(f->sha1))
f->available_remotes.push_back(remote_id);
}
- } catch (SerializationError &e) {
- infostream << "Client: Remote server \"" << remote->baseurl
- << "\" sent invalid hash set: " << e.what()
- << std::endl;
+ }
+ catch (SerializationError &e) {
+ infostream << "Client: Remote server \""
+ << remote->baseurl << "\" sent invalid hash set: "
+ << e.what() << std::endl;
}
}
}
void ClientMediaDownloader::remoteMediaReceived(
- const HTTPFetchResult &fetch_result, Client *client)
+ const HTTPFetchResult &fetch_result,
+ Client *client)
{
// Some remote server sent us a file.
// -> decrement number of active fetches
@@ -321,7 +331,7 @@ void ClientMediaDownloader::remoteMediaReceived(
std::string name;
{
std::unordered_map<unsigned long, std::string>::iterator it =
- m_remote_file_transfers.find(fetch_result.request_id);
+ m_remote_file_transfers.find(fetch_result.request_id);
assert(it != m_remote_file_transfers.end());
name = it->second;
m_remote_file_transfers.erase(it);
@@ -341,8 +351,8 @@ void ClientMediaDownloader::remoteMediaReceived(
// If fetch succeeded, try to load media file
if (fetch_result.succeeded) {
- bool success = checkAndLoad(
- name, filestatus->sha1, fetch_result.data, false, client);
+ bool success = checkAndLoad(name, filestatus->sha1,
+ fetch_result.data, false, client);
if (success) {
filestatus->received = true;
assert(m_uncached_received_count < m_uncached_count);
@@ -379,17 +389,19 @@ s32 ClientMediaDownloader::selectRemoteServer(FileStatus *filestatus)
}
}
- filestatus->available_remotes.erase(filestatus->available_remotes.begin() + best);
+ filestatus->available_remotes.erase(
+ filestatus->available_remotes.begin() + best);
return best_remote_id;
+
}
void ClientMediaDownloader::startRemoteMediaTransfers()
{
bool changing_name_bound = true;
- for (std::map<std::string, FileStatus *>::iterator files_iter =
- m_files.upper_bound(m_name_bound);
+ for (std::map<std::string, FileStatus*>::iterator
+ files_iter = m_files.upper_bound(m_name_bound);
files_iter != m_files.end(); ++files_iter) {
// Abort if active fetch limit is exceeded
@@ -405,25 +417,28 @@ void ClientMediaDownloader::startRemoteMediaTransfers()
s32 remote_id = selectRemoteServer(filestatus);
if (remote_id >= 0) {
// Found a server, so start fetching
- RemoteServerStatus *remote = m_remotes[remote_id];
+ RemoteServerStatus *remote =
+ m_remotes[remote_id];
std::string url = remote->baseurl +
- hex_encode(filestatus->sha1);
+ hex_encode(filestatus->sha1);
verbosestream << "Client: "
- << "Requesting remote media file "
- << "\"" << name << "\" "
- << "\"" << url << "\"" << std::endl;
+ << "Requesting remote media file "
+ << "\"" << name << "\" "
+ << "\"" << url << "\"" << std::endl;
HTTPFetchRequest fetch_request;
fetch_request.url = url;
fetch_request.caller = m_httpfetch_caller;
fetch_request.request_id = m_httpfetch_next_id;
fetch_request.timeout = 0; // no data timeout!
- fetch_request.connect_timeout = m_httpfetch_timeout;
+ fetch_request.connect_timeout =
+ m_httpfetch_timeout;
httpfetch_async(fetch_request);
m_remote_file_transfers.insert(std::make_pair(
- m_httpfetch_next_id, name));
+ m_httpfetch_next_id,
+ name));
filestatus->current_remote = remote_id;
remote->active_count++;
@@ -432,21 +447,24 @@ void ClientMediaDownloader::startRemoteMediaTransfers()
}
}
- if (filestatus->received || (filestatus->current_remote < 0 &&
- !m_outstanding_hash_sets)) {
+ if (filestatus->received ||
+ (filestatus->current_remote < 0 &&
+ !m_outstanding_hash_sets)) {
// If we arrive here, we conclusively know that we
// won't fetch this file from a remote server in the
// future. So update the name bound if possible.
if (changing_name_bound)
m_name_bound = name;
- } else
+ }
+ else
changing_name_bound = false;
}
+
}
void ClientMediaDownloader::startConventionalTransfers(Client *client)
{
- assert(m_httpfetch_active == 0); // pre-condition
+ assert(m_httpfetch_active == 0); // pre-condition
if (m_uncached_received_count != m_uncached_count) {
// Some media files have not been received yet, use the
@@ -456,21 +474,24 @@ void ClientMediaDownloader::startConventionalTransfers(Client *client)
if (!file.second->received)
file_requests.push_back(file.first);
}
- assert((s32)file_requests.size() ==
+ assert((s32) file_requests.size() ==
m_uncached_count - m_uncached_received_count);
client->request_media(file_requests);
}
}
void ClientMediaDownloader::conventionalTransferDone(
- const std::string &name, const std::string &data, Client *client)
+ const std::string &name,
+ const std::string &data,
+ Client *client)
{
// Check that file was announced
- std::map<std::string, FileStatus *>::iterator file_iter = m_files.find(name);
+ std::map<std::string, FileStatus*>::iterator
+ file_iter = m_files.find(name);
if (file_iter == m_files.end()) {
errorstream << "Client: server sent media file that was"
- << "not announced, ignoring it: \"" << name << "\""
- << std::endl;
+ << "not announced, ignoring it: \"" << name << "\""
+ << std::endl;
return;
}
FileStatus *filestatus = file_iter->second;
@@ -479,7 +500,8 @@ void ClientMediaDownloader::conventionalTransferDone(
// Check that file hasn't already been received
if (filestatus->received) {
errorstream << "Client: server sent media file that we already"
- << "received, ignoring it: \"" << name << "\"" << std::endl;
+ << "received, ignoring it: \"" << name << "\""
+ << std::endl;
return;
}
@@ -495,7 +517,8 @@ void ClientMediaDownloader::conventionalTransferDone(
checkAndLoad(name, filestatus->sha1, data, false, client);
}
-bool ClientMediaDownloader::checkAndLoad(const std::string &name, const std::string &sha1,
+bool ClientMediaDownloader::checkAndLoad(
+ const std::string &name, const std::string &sha1,
const std::string &data, bool is_from_cache, Client *client)
{
const char *cached_or_received = is_from_cache ? "cached" : "received";
@@ -508,16 +531,18 @@ bool ClientMediaDownloader::checkAndLoad(const std::string &name, const std::str
SHA1 data_sha1_calculator;
data_sha1_calculator.addBytes(data.c_str(), data.size());
unsigned char *data_tmpdigest = data_sha1_calculator.getDigest();
- data_sha1.assign((char *)data_tmpdigest, 20);
+ data_sha1.assign((char*) data_tmpdigest, 20);
free(data_tmpdigest);
}
// Check that received file matches announced checksum
if (data_sha1 != sha1) {
std::string data_sha1_hex = hex_encode(data_sha1);
- infostream << "Client: " << cached_or_received_uc << " media file "
- << sha1_hex << " \"" << name << "\" "
- << "mismatches actual checksum " << data_sha1_hex << std::endl;
+ infostream << "Client: "
+ << cached_or_received_uc << " media file "
+ << sha1_hex << " \"" << name << "\" "
+ << "mismatches actual checksum " << data_sha1_hex
+ << std::endl;
return false;
}
@@ -525,15 +550,16 @@ bool ClientMediaDownloader::checkAndLoad(const std::string &name, const std::str
bool success = client->loadMedia(data, name);
if (!success) {
infostream << "Client: "
- << "Failed to load " << cached_or_received
- << " media: " << sha1_hex << " \"" << name << "\""
- << std::endl;
+ << "Failed to load " << cached_or_received << " media: "
+ << sha1_hex << " \"" << name << "\""
+ << std::endl;
return false;
}
verbosestream << "Client: "
- << "Loaded " << cached_or_received << " media: " << sha1_hex
- << " \"" << name << "\"" << std::endl;
+ << "Loaded " << cached_or_received << " media: "
+ << sha1_hex << " \"" << name << "\""
+ << std::endl;
// Update cache (unless we just loaded the file from the cache)
if (!is_from_cache)
@@ -560,15 +586,15 @@ std::string ClientMediaDownloader::serializeRequiredHashSet()
std::ostringstream os(std::ios::binary);
writeU32(os, MTHASHSET_FILE_SIGNATURE); // signature
- writeU16(os, 1); // version
+ writeU16(os, 1); // version
// Write list of hashes of files that have not been
// received (found in cache) yet
- for (std::map<std::string, FileStatus *>::iterator it = m_files.begin();
+ for (std::map<std::string, FileStatus*>::iterator
+ it = m_files.begin();
it != m_files.end(); ++it) {
if (!it->second->received) {
- FATAL_ERROR_IF(it->second->sha1.size() != 20,
- "Invalid SHA1 size");
+ FATAL_ERROR_IF(it->second->sha1.size() != 20, "Invalid SHA1 size");
os << it->second->sha1;
}
}
@@ -576,26 +602,29 @@ std::string ClientMediaDownloader::serializeRequiredHashSet()
return os.str();
}
-void ClientMediaDownloader::deSerializeHashSet(
- const std::string &data, std::set<std::string> &result)
+void ClientMediaDownloader::deSerializeHashSet(const std::string &data,
+ std::set<std::string> &result)
{
if (data.size() < 6 || data.size() % 20 != 6) {
- throw SerializationError("ClientMediaDownloader::deSerializeHashSet: "
- "invalid hash set file size");
+ throw SerializationError(
+ "ClientMediaDownloader::deSerializeHashSet: "
+ "invalid hash set file size");
}
- const u8 *data_cstr = (const u8 *)data.c_str();
+ const u8 *data_cstr = (const u8*) data.c_str();
u32 signature = readU32(&data_cstr[0]);
if (signature != MTHASHSET_FILE_SIGNATURE) {
- throw SerializationError("ClientMediaDownloader::deSerializeHashSet: "
- "invalid hash set file signature");
+ throw SerializationError(
+ "ClientMediaDownloader::deSerializeHashSet: "
+ "invalid hash set file signature");
}
u16 version = readU16(&data_cstr[4]);
if (version != 1) {
- throw SerializationError("ClientMediaDownloader::deSerializeHashSet: "
- "unsupported hash set file version");
+ throw SerializationError(
+ "ClientMediaDownloader::deSerializeHashSet: "
+ "unsupported hash set file version");
}
for (u32 pos = 6; pos < data.size(); pos += 20) {