diff --git a/airdcpp-core/airdcpp/HttpConnection.cpp b/airdcpp-core/airdcpp/HttpConnection.cpp index 11c44cff..cbc69f92 100644 --- a/airdcpp-core/airdcpp/HttpConnection.cpp +++ b/airdcpp-core/airdcpp/HttpConnection.cpp @@ -29,6 +29,8 @@ #include #include +#include + namespace dcpp { HttpConnection::HttpConnection(bool aIsUnique, const HttpOptions& aOptions) : @@ -246,15 +248,28 @@ void HttpConnection::on(BufferedSocketListener::Line, const string& aLine) noexc if(size != -1) { socket->setDataMode(size); } else connState = CONN_CHUNKED; - } else if(Util::findSubString(aLine, "Content-Length") != string::npos) { - size = Util::toInt(aLine.substr(16, aLine.length() - 17)); - } else if(mimeType.empty()) { - if(Util::findSubString(aLine, "Content-Encoding") != string::npos) { - if(aLine.substr(18, aLine.length() - 19) == "x-bzip2") - mimeType = "application/x-bzip2"; - } else if(Util::findSubString(aLine, "Content-Type") != string::npos) { - mimeType = aLine.substr(14, aLine.length() - 15); + } else if (aLine.length() > 2) { + // Header + auto separator = aLine.find_first_of(':'); + if (separator <= 1) { + return; + } + + auto name = boost::algorithm::trim_copy(aLine.substr(0, separator)); + auto value = boost::algorithm::trim_copy(aLine.substr(separator + 1)); + + if (name == "Content-Length") { + size = Util::toInt(value); + } else if (mimeType.empty()) { + if (name == "Content-Encoding") { + if (value == "x-bzip2") + mimeType = "application/x-bzip2"; + } else if (name == "Content-Type") { + mimeType = value; + } } + + headers.try_emplace(name, value); } } diff --git a/airdcpp-core/airdcpp/HttpConnection.h b/airdcpp-core/airdcpp/HttpConnection.h index ee33b931..ac364d35 100644 --- a/airdcpp-core/airdcpp/HttpConnection.h +++ b/airdcpp-core/airdcpp/HttpConnection.h @@ -53,6 +53,7 @@ class HttpConnection : private BufferedSocketListener, public SpeakergetHeaders(); f(); } diff --git a/airdcpp-core/airdcpp/HttpDownload.h b/airdcpp-core/airdcpp/HttpDownload.h index 099bf37c..7c978a4d 100644 --- a/airdcpp-core/airdcpp/HttpDownload.h +++ b/airdcpp-core/airdcpp/HttpDownload.h @@ -30,6 +30,7 @@ struct HttpDownload : private HttpConnectionListener, private boost::noncopyable HttpConnection* c; string buf; string status; + StringMap headers; using CompletionF = std::function; CompletionF f; diff --git a/airdcpp-core/airdcpp/UpdateManager.cpp b/airdcpp-core/airdcpp/UpdateManager.cpp index af2e3549..531ce840 100644 --- a/airdcpp-core/airdcpp/UpdateManager.cpp +++ b/airdcpp-core/airdcpp/UpdateManager.cpp @@ -53,7 +53,7 @@ UpdateManager::UpdateManager() : lastIPUpdate(GET_TICK()) { links.geoip = "http://geoip.airdcpp.net"; links.ipcheck4 = "http://checkip.dyndns.org/"; links.ipcheck6 = "http://checkip.dyndns.org/"; - links.language = "http://languages.airdcpp.net/tx/checkLangVersion.php?lc=%[locale]"; + links.language = "https://languages.airdcpp.net/tx/checkLangVersion.php?lc=%[locale]"; SettingsManager::getInstance()->registerChangeHandler({ SettingsManager::GET_USER_COUNTRY, @@ -340,10 +340,14 @@ void UpdateManager::completeLanguageCheck() { if(!conn->buf.empty()) { if (Util::toDouble(conn->buf) > Localization::getCurLanguageVersion()) { fire(UpdateManagerListener::LanguageDownloading()); - conns[CONN_LANGUAGE_FILE] = make_unique( - links.language + PathUtil::getFileName(Localization::getCurLanguageFilePath()), - [this] { completeLanguageDownload(); } - ); + + auto url = conn->headers.find("X-File-Location"); + if (url != conn->headers.end()) { + conns[CONN_LANGUAGE_FILE] = make_unique( + url->second, + [this] { completeLanguageDownload(); } + ); + } } else { fire(UpdateManagerListener::LanguageFinished()); } diff --git a/airdcpp-core/scripts/generate_stringdefs.py b/airdcpp-core/scripts/generate_stringdefs.py index a8d73b0d..0189d4c9 100644 --- a/airdcpp-core/scripts/generate_stringdefs.py +++ b/airdcpp-core/scripts/generate_stringdefs.py @@ -79,6 +79,7 @@ def write_text(strings, name): (r'\n', '\n'), (r'\\', '\\'), (r'\"', '\"'), + (r'\'', '\''), ] # Convert StringDefs to Android resource XML file that is supported by Transifex diff --git a/airdcpp-core/scripts/server/checkLangVersion.php b/airdcpp-core/scripts/server/checkLangVersion.php index 78fb9f82..b6137d35 100644 --- a/airdcpp-core/scripts/server/checkLangVersion.php +++ b/airdcpp-core/scripts/server/checkLangVersion.php @@ -1,10 +1,32 @@ )/'; - if (preg_match($pattern, $fileContent, $matches)) { - echo $matches[0]; - } else { - echo '0'; - } + function removeFilename($url) { + $file_info = pathinfo($url); + return isset($file_info['extension']) + ? str_replace($file_info['filename'] . "." . $file_info['extension'], "", $url) + : $url; + } + + if (!isset($_GET["lc"])) { + $fileContent = 'Locale missing'; + http_response_code(400); + return; + } + + header('X-File-Location: https://' . $_SERVER['HTTP_HOST'] . removeFilename($_SERVER['REQUEST_URI']) . $_GET["lc"] . ".xml"); + + $filePath = getcwd() . '/' . $_GET["lc"] . ".xml"; + if (!file_exists($filePath)) { + $fileContent = 'Invalid locale'; + http_response_code(404); + return; + } + + $fileContent = @file_get_contents($filePath); + $pattern = '/(?<=\sRevision=")\d{1,9}(?=">)/'; + if (preg_match($pattern, $fileContent, $matches)) { + echo $matches[0]; + } else { + echo '0'; + } ?> diff --git a/airdcpp-core/scripts/update_languages.py b/airdcpp-core/scripts/update_languages.py index 3c41a535..842ffc50 100644 --- a/airdcpp-core/scripts/update_languages.py +++ b/airdcpp-core/scripts/update_languages.py @@ -4,6 +4,7 @@ import argparse import xml.etree.ElementTree as ET +from pathlib import Path import glob, os import shutil @@ -32,6 +33,7 @@ def get_new_version(file_path): (r'\n', '\n'), (r'\\', '\\'), (r'\"', '\"'), + (r'\'', '\''), ] @@ -47,6 +49,7 @@ def convert_file(input_file, output_file): for child in source_root: string = ET.SubElement(output_strings, 'String', Name=child.attrib['name']) + text = child.text for str, replacement in replace_map: text = text.replace(str, replacement) @@ -74,6 +77,9 @@ def has_changed(source_file_path, temp_file_path): def update_translation_files(source_directory, target_directory, force = False): temp_directory = os.path.join(source_directory, 'previous') + Path(temp_directory).mkdir(parents=True, exist_ok=True) + Path(target_directory).mkdir(parents=True, exist_ok=True) + converted = 0 unchanged = 0 failed = 0