1
0
mirror of https://github.com/odrling/Aegisub synced 2025-04-11 22:56:02 +02:00

Make update checker use libcurl and https

The horrible hack with the curl_meson subproject is needed since the
libcurl dependency generated by libcurl's cmake build system (via
meson's cmake module) includes its internal files its
include_directories, which shadows certain other includes. So instead
we manually replace the include_directories with the correct ones, taken
from a separate meson subproject. This needs an additional wrap file,
but it points to the same subproject directory in order to prevent there
being multiple downloads of the same libcurl source that could go out of
sync at some point.

Co-authored-by: sepro <4618135+seproDev@users.noreply.github.com>
This commit is contained in:
arch1t3cht 2023-06-27 04:04:50 +02:00 committed by Ryan Lucia
parent 0e2a14cef5
commit c88f918be0
7 changed files with 95 additions and 38 deletions

1
.gitignore vendored
View File

@ -20,6 +20,7 @@ tools/repack-thes-dict.dSYM
build*/
subprojects/boost*/
subprojects/cairo*
subprojects/curl-*
subprojects/ffmpeg
subprojects/ffms2*
subprojects/fontconfig*

View File

@ -69,6 +69,10 @@ if get_option('official_release')
conf.set('AEGI_OFFICIAL_RELEASE', 1)
endif
conf.set('WITH_UPDATE_CHECKER', get_option('enable_update_checker'))
if get_option('enable_update_checker')
conf.set_quoted('UPDATE_CHECKER_SERVER', get_option('update_server'))
conf.set_quoted('UPDATE_CHECKER_BASE_URL', get_option('update_url'))
endif
deps = []
deps_inc = []
@ -277,6 +281,41 @@ endif
conf_platform = configuration_data()
conf_platform.set('DEFAULT_PLAYER_AUDIO', def_audio)
if get_option('enable_update_checker')
libcurl_dep = dependency('libcurl', required: false)
if (not libcurl_dep.found())
libcurl_opt = cmake.subproject_options()
options_dict = {
'HTTP_ONLY': true,
'BUILD_CURL_EXE': false,
'CMAKE_BUILD_TYPE': get_option('buildtype') == 'release' ? 'Release' : 'Debug',
}
if host_machine.system() == 'windows'
options_dict += {'CURL_USE_SCHANNEL': true}
deps += cc.find_library('crypt32')
elif host_machine.system() == 'darwin'
options_dict += {'CURL_USE_SECTRANSP': true}
else
options_dict += {'CURL_USE_OPENSSL': true}
endif
if get_option('default_library') == 'static' and (host_machine.system() == 'windows' or host_machine.system() == 'darwin')
options_dict += {'BUILD_SHARED_LIBS': false}
add_project_arguments('-DCURL_STATICLIB', language: ['cpp'])
endif
libcurl_opt.add_cmake_defines(options_dict)
libcurl = cmake.subproject('curl', options: libcurl_opt)
libcurl_dep = libcurl.dependency('libcurl')
# Horrible meson hack to work around the cmake subproject creating broken include directories
libcurl_dep = libcurl_dep.partial_dependency(compile_args: true, link_args: true, links: true, sources: true)
libcurl_fixed_inc = declare_dependency(include_directories: subproject('curl_meson').get_variable('libcurl_fixed_inc'))
deps += [libcurl_fixed_inc]
endif
deps += [libcurl_dep]
endif
luajit = dependency('luajit', version: '>=2.0.0', required: get_option('system_luajit'))
if luajit.found() and luajit.type_name() != 'internal'
luajit_test = cc.run('''#include <lauxlib.h>

View File

@ -21,8 +21,8 @@ option('wx_version', type: 'string', value: '3.0.0', description: 'The minimum w
option('credit', type: 'string', value: '', description: 'Build credit shown in program title')
option('official_release', type: 'boolean', value: false, description: 'Set on official builds')
option('enable_update_checker', type: 'boolean', value: false, description: 'Enable the update checker')
option('update_server', type: 'string', value: 'updates.aegisub.org', description: 'Server to use for the update checker')
option('enable_update_checker', type: 'boolean', value: true, description: 'Enable the update checker')
option('update_server', type: 'string', value: 'https://updates.aegisub.org', description: 'Server to use for the update checker')
option('update_url', type: 'string', value: '/trunk', description: 'Base path to use for the update checker')
option('build_osx_bundle', type: 'boolean', value: 'false', description: 'Package Aegisub.app on OSX')

View File

@ -29,10 +29,6 @@
#ifdef WITH_UPDATE_CHECKER
#ifdef _MSC_VER
#pragma warning(disable : 4250) // 'boost::asio::basic_socket_iostream<Protocol>' : inherits 'std::basic_ostream<_Elem,_Traits>::std::basic_ostream<_Elem,_Traits>::_Add_vtordisp2' via dominance
#endif
#include "compat.h"
#include "format.h"
#include "options.h"
@ -46,9 +42,10 @@
#include <libaegisub/split.h>
#include <ctime>
#include <boost/asio/ip/tcp.hpp>
#include <curl/curl.h>
#include <functional>
#include <mutex>
#include <sstream>
#include <vector>
#include <wx/button.h>
#include <wx/checkbox.h>
@ -280,44 +277,46 @@ static wxString GetAegisubLanguage() {
return to_wx(OPT_GET("App/Language")->GetString());
}
size_t writeToStringCb(char *contents, size_t size, size_t nmemb, std::string *s) {
s->append(contents, size * nmemb);
return size * nmemb;
}
void DoCheck(bool interactive) {
boost::asio::ip::tcp::iostream stream;
stream.connect(UPDATE_CHECKER_SERVER, "http");
if (!stream)
throw VersionCheckError(from_wx(_("Could not connect to updates server.")));
CURL *curl;
CURLcode res_code;
agi::format(stream,
"GET %s?rev=%d&rel=%d&os=%s&lang=%s&aegilang=%s HTTP/1.0\r\n"
"User-Agent: Aegisub %s\r\n"
"Host: %s\r\n"
"Accept: */*\r\n"
"Connection: close\r\n\r\n"
, UPDATE_CHECKER_BASE_URL
, GetSVNRevision()
, (GetIsOfficialRelease() ? 1 : 0)
, GetOSShortName()
, GetSystemLanguage()
, GetAegisubLanguage()
, GetAegisubLongVersionString()
, UPDATE_CHECKER_SERVER);
curl = curl_easy_init();
if (!curl)
throw VersionCheckError(from_wx(_("Curl could not be initialized.")));
std::string http_version;
stream >> http_version;
int status_code;
stream >> status_code;
if (!stream || http_version.substr(0, 5) != "HTTP/")
throw VersionCheckError(from_wx(_("Could not download from updates server.")));
if (status_code != 200)
throw VersionCheckError(agi::format(_("HTTP request failed, got HTTP response %d."), status_code));
curl_easy_setopt(curl, CURLOPT_URL,
agi::format("%s%s?rev=%d&rel=%d&os=%s&lang=%s&aegilang=%s"
, UPDATE_CHECKER_SERVER
, UPDATE_CHECKER_BASE_URL
, GetSVNRevision()
, (GetIsOfficialRelease() ? 1 : 0)
, GetOSShortName()
, GetSystemLanguage()
, GetAegisubLanguage()
).c_str());
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_USERAGENT, agi::format("Aegisub %s", GetAegisubLongVersionString()).c_str());
stream.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::string result;
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeToStringCb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &result);
// Skip the headers since we don't care about them
for (auto const& header : agi::line_iterator<std::string>(stream))
if (header.empty()) break;
res_code = curl_easy_perform(curl);
curl_easy_cleanup(curl);
if (res_code != CURLE_OK) {
std::string err_msg = agi::format(_("Checking for updates failed: %s."), curl_easy_strerror(res_code));
throw VersionCheckError(err_msg);
}
std::stringstream ss(result);
std::vector<AegisubUpdateDescription> results;
for (auto const& line : agi::line_iterator<std::string>(stream)) {
for (auto const& line : agi::line_iterator<std::string>(ss)) {
if (line.empty()) continue;
std::vector<std::string> parsed;

9
subprojects/curl.wrap Normal file
View File

@ -0,0 +1,9 @@
[wrap-file]
directory = curl-7.82.0
source_url = https://github.com/curl/curl/releases/download/curl-7_82_0/curl-7.82.0.tar.gz
source_filename = curl-7.82.0.tar.xz
source_hash = 910cc5fe279dc36e2cca534172c94364cf3fcf7d6494ba56e6c61a390881ddce
patch_directory = curl
[provide]
dependency_names = libcurl

View File

@ -0,0 +1,6 @@
[wrap-file]
directory = curl-7.82.0
source_url = https://github.com/curl/curl/releases/download/curl-7_82_0/curl-7.82.0.tar.gz
source_filename = curl-7.82.0.tar.xz
source_hash = 910cc5fe279dc36e2cca534172c94364cf3fcf7d6494ba56e6c61a390881ddce
patch_directory = curl

View File

@ -0,0 +1,3 @@
project('curl_meson', 'cpp')
libcurl_fixed_inc = include_directories('include/')