From e48b83cd41f7b66ed383dd2f36a46cd638fb882b Mon Sep 17 00:00:00 2001 From: Kaito Udagawa Date: Mon, 14 Aug 2023 13:46:34 +0900 Subject: [PATCH] Remove libcurl from Mac and Windows (#420) * Add * Lint * Update github-utils.cpp * Update buildspec.json * Update build-project.yaml * Update WinRTHttpClient.cpp * Update CMakeLists.txt * Update FetchOpenCV.cmake * Update FetchOpenCV.cmake * Remove curl * Delete .gitmodules --- .gitmodules | 3 - CMakeLists.txt | 20 ++--- buildspec.json | 2 +- src/plugin-main.c | 12 +-- src/update-checker/Client.hpp | 5 ++ src/update-checker/CurlClient/CMakeLists.txt | 7 ++ src/update-checker/CurlClient/CurlClient.cpp | 43 +++++++++ .../URLSessionClient/CMakeLists.txt | 3 + .../URLSessionClient/URLSessionClient.mm | 49 ++++++++++ .../WinRTHttpClient/CMakeLists.txt | 10 +++ .../WinRTHttpClient/WinRTHttpClient.cpp | 40 +++++++++ src/update-checker/github-utils.cpp | 90 +++++++------------ src/update-checker/github-utils.h | 12 +-- src/update-checker/update-checker.cpp | 57 +++++++----- src/update-checker/update-checker.h | 4 +- vendor/curl | 1 - 16 files changed, 242 insertions(+), 116 deletions(-) delete mode 100644 .gitmodules create mode 100644 src/update-checker/Client.hpp create mode 100644 src/update-checker/CurlClient/CMakeLists.txt create mode 100644 src/update-checker/CurlClient/CurlClient.cpp create mode 100644 src/update-checker/URLSessionClient/CMakeLists.txt create mode 100644 src/update-checker/URLSessionClient/URLSessionClient.mm create mode 100644 src/update-checker/WinRTHttpClient/CMakeLists.txt create mode 100644 src/update-checker/WinRTHttpClient/WinRTHttpClient.cpp delete mode 160000 vendor/curl diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 3c6156a0..00000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "vendor/curl"] - path = vendor/curl - url = https://github.com/curl/curl.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 8f68daa5..9af53c49 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,17 +68,15 @@ else() target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE OpenCV) endif() -set(USE_SYSTEM_CURL - OFF - CACHE STRING "Use system cURL") - -if(USE_SYSTEM_CURL) - find_package(CURL REQUIRED) - target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE "${CURL_LIBRARIES}") - target_include_directories(${CMAKE_PROJECT_NAME} SYSTEM PUBLIC "${CURL_INCLUDE_DIRS}") -else() - include(cmake/BuildMyCurl.cmake) - target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE libcurl) +if(APPLE) + add_subdirectory(src/update-checker/URLSessionClient) + target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE URLSessionClient) +elseif(MSVC) + add_subdirectory(src/update-checker/WinRTHttpClient) + target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE WinRTHttpClient) +elseif(UNIX) + add_subdirectory(src/update-checker/CurlClient) + target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE CurlClient) endif() target_sources( diff --git a/buildspec.json b/buildspec.json index 87f1b93b..b81b926b 100644 --- a/buildspec.json +++ b/buildspec.json @@ -45,7 +45,7 @@ } }, "name": "obs-backgroundremoval", - "version": "1.1.3", + "version": "1.1.4", "author": "Roy Shilkrot", "website": "https://github.com/royshil/obs-backgroundremoval", "email": "roy.shil@gmail.com", diff --git a/src/plugin-main.c b/src/plugin-main.c index cbb6686e..8bc2a610 100644 --- a/src/plugin-main.c +++ b/src/plugin-main.c @@ -20,7 +20,6 @@ with this program. If not, see #include "plugin-support.h" -#include "update-checker/github-utils.h" #include "update-checker/update-checker.h" OBS_DECLARE_MODULE() @@ -41,16 +40,7 @@ bool obs_module_load(void) obs_log(LOG_INFO, "Plugin loaded successfully (version %s)", PLUGIN_VERSION); - const struct github_utils_release_information latestRelease = - github_utils_get_release_information(); - if (latestRelease.responseCode == OBS_BGREMOVAL_GITHUB_UTILS_SUCCESS) { - obs_log(LOG_INFO, "Latest release is %s", - latestRelease.version); - check_update(latestRelease); - } else { - obs_log(LOG_INFO, "failed to get latest release information"); - } - github_utils_release_information_free(latestRelease); + check_update(); return true; } diff --git a/src/update-checker/Client.hpp b/src/update-checker/Client.hpp new file mode 100644 index 00000000..f5c1229b --- /dev/null +++ b/src/update-checker/Client.hpp @@ -0,0 +1,5 @@ +#include +#include + +void fetchStringFromUrl(const char *urlString, + std::function callback); diff --git a/src/update-checker/CurlClient/CMakeLists.txt b/src/update-checker/CurlClient/CMakeLists.txt new file mode 100644 index 00000000..601af8f9 --- /dev/null +++ b/src/update-checker/CurlClient/CMakeLists.txt @@ -0,0 +1,7 @@ +add_library(CurlClient CurlClient.cpp) +target_link_libraries(CurlClient PRIVATE OBS::libobs plugin-support) +target_include_directories(CurlClient PRIVATE "${CMAKE_SOURCE_DIR}/src") + +find_package(CURL REQUIRED) +target_link_libraries(CurlClient PRIVATE "${CURL_LIBRARIES}") +target_include_directories(CurlClient SYSTEM PRIVATE "${CURL_INCLUDE_DIRS}") diff --git a/src/update-checker/CurlClient/CurlClient.cpp b/src/update-checker/CurlClient/CurlClient.cpp new file mode 100644 index 00000000..a301cd13 --- /dev/null +++ b/src/update-checker/CurlClient/CurlClient.cpp @@ -0,0 +1,43 @@ +#include +#include + +#include + +#include +#include + +const std::string userAgent = std::string(PLUGIN_NAME) + "/" + PLUGIN_VERSION; + +static std::size_t writeFunc(void *ptr, std::size_t size, size_t nmemb, + std::string *data) +{ + data->append(static_cast(ptr), size * nmemb); + return size * nmemb; +} + +void fetchStringFromUrl(const char *urlString, + std::function callback) +{ + CURL *curl = curl_easy_init(); + if (!curl) { + obs_log(LOG_INFO, "Failed to initialize curl"); + callback("", CURL_LAST); + return; + } + + std::string responseBody; + curl_easy_setopt(curl, CURLOPT_URL, urlString); + curl_easy_setopt(curl, CURLOPT_USERAGENT, userAgent.c_str()); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeFunc); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseBody); + + CURLcode code = curl_easy_perform(curl); + curl_easy_cleanup(curl); + + if (code == CURLE_OK) { + callback(responseBody, 0); + } else { + obs_log(LOG_INFO, "Failed to get latest release info"); + callback("", code); + } +} diff --git a/src/update-checker/URLSessionClient/CMakeLists.txt b/src/update-checker/URLSessionClient/CMakeLists.txt new file mode 100644 index 00000000..cc911cbc --- /dev/null +++ b/src/update-checker/URLSessionClient/CMakeLists.txt @@ -0,0 +1,3 @@ +add_library(URLSessionClient URLSessionClient.mm) +target_link_libraries(URLSessionClient PRIVATE OBS::libobs plugin-support) +target_include_directories(URLSessionClient PRIVATE "${CMAKE_SOURCE_DIR}/src") diff --git a/src/update-checker/URLSessionClient/URLSessionClient.mm b/src/update-checker/URLSessionClient/URLSessionClient.mm new file mode 100644 index 00000000..8a539e1a --- /dev/null +++ b/src/update-checker/URLSessionClient/URLSessionClient.mm @@ -0,0 +1,49 @@ +#include +#include + +#include + +#include +#include + +void dispatch(const std::function &callback, + std::string responseBody, int errorCode) +{ + dispatch_async(dispatch_get_main_queue(), ^{ + callback(responseBody, errorCode); + }); +} + +void fetchStringFromUrl(const char *urlString, + std::function callback) +{ + NSString *urlNsString = [[NSString alloc] initWithUTF8String:urlString]; + NSURLSession *session = [NSURLSession sharedSession]; + NSURL *url = [NSURL URLWithString:urlNsString]; + NSURLSessionDataTask *task = [session + dataTaskWithURL:url + completionHandler:^(NSData *_Nullable data, + NSURLResponse *_Nullable response, + NSError *_Nullable error) { + if (error != NULL) { + obs_log(LOG_INFO, "error"); + dispatch(callback, "", 1); + } else if (response == NULL) { + dispatch(callback, "", 2); + } else if (data == NULL || data.length == 0) { + dispatch(callback, "", 3); + } else if (![response isKindOfClass:NSHTTPURLResponse + .class]) { + dispatch(callback, "", 4); + } else { + std::string responseBody( + (const char *)data.bytes, data.length); + NSHTTPURLResponse *httpResponse = + (NSHTTPURLResponse *)response; + NSInteger code = httpResponse.statusCode; + dispatch(callback, responseBody, + code < 200 || code > 299 ? 5 : 0); + } + }]; + [task resume]; +} diff --git a/src/update-checker/WinRTHttpClient/CMakeLists.txt b/src/update-checker/WinRTHttpClient/CMakeLists.txt new file mode 100644 index 00000000..7652824f --- /dev/null +++ b/src/update-checker/WinRTHttpClient/CMakeLists.txt @@ -0,0 +1,10 @@ +add_library(WinRTHttpClient WinRTHttpClient.cpp) +set_target_properties( + WinRTHttpClient + PROPERTIES CXX_STANDARD 17 + CXX_STANDARD_REQUIRED ON + CXX_EXTENSIONS OFF + VS_GLOBAL_CppWinRTOptimized true + VS_GLOBAL_CppWinRTRootNamespaceAutoMerge true) +target_link_libraries(WinRTHttpClient PRIVATE OBS::libobs plugin-support) +target_include_directories(WinRTHttpClient PRIVATE "${CMAKE_SOURCE_DIR}/src") diff --git a/src/update-checker/WinRTHttpClient/WinRTHttpClient.cpp b/src/update-checker/WinRTHttpClient/WinRTHttpClient.cpp new file mode 100644 index 00000000..eac9b9b2 --- /dev/null +++ b/src/update-checker/WinRTHttpClient/WinRTHttpClient.cpp @@ -0,0 +1,40 @@ +#include + +#include +#include +#include +#include + +using winrt::Windows::Foundation::Uri; +using winrt::Windows::Storage::Streams::IBuffer; +using winrt::Windows::Web::Http::HttpClient; +using winrt::Windows::Web::Http::HttpResponseMessage; +using winrt::Windows::Web::Http::IHttpContent; + +winrt::hstring userAgent = winrt::to_hstring(PLUGIN_NAME) + L"/" + + winrt::to_hstring(PLUGIN_VERSION); + +void fetchStringFromUrl(const char *urlString, + std::function callback) +{ + HttpClient httpClient; + auto headers(httpClient.DefaultRequestHeaders()); + headers.UserAgent().TryParseAdd(userAgent); + Uri requestUri(winrt::to_hstring(urlString)); + HttpResponseMessage httpResponseMessage; + IBuffer httpResponseBuffer; + try { + httpResponseMessage = httpClient.GetAsync(requestUri).get(); + httpResponseMessage.EnsureSuccessStatusCode(); + IHttpContent httpContent = httpResponseMessage.Content(); + httpResponseBuffer = httpContent.ReadAsBufferAsync().get(); + + uint8_t *data = httpResponseBuffer.data(); + std::string str((const char *)data, + httpResponseBuffer.Length()); + callback(str, 0); + } catch (winrt::hresult_error const &ex) { + std::string str(winrt::to_string(ex.message())); + callback(str, 1); + } +} diff --git a/src/update-checker/github-utils.cpp b/src/update-checker/github-utils.cpp index d42a43e0..896a7938 100644 --- a/src/update-checker/github-utils.cpp +++ b/src/update-checker/github-utils.cpp @@ -1,70 +1,48 @@ -#include - #include #include #include +#include "Client.hpp" #include "github-utils.h" static const std::string GITHUB_LATEST_RELEASE_URL = "https://api.github.com/repos/royshil/obs-backgroundremoval/releases/latest"; -extern "C" const char *PLUGIN_NAME; -extern "C" const char *PLUGIN_VERSION; - -static const std::string USER_AGENT = - std::string(PLUGIN_NAME) + "/" + std::string(PLUGIN_VERSION); - -std::size_t writeFunctionStdString(void *ptr, std::size_t size, size_t nmemb, - std::string *data) -{ - data->append(static_cast(ptr), size * nmemb); - return size * nmemb; -} - -struct github_utils_release_information -github_utils_get_release_information(void) +void github_utils_get_release_information( + std::function callback) { - CURL *curl = curl_easy_init(); - if (!curl) { - blog(LOG_INFO, "Failed to initialize curl"); - return {OBS_BGREMOVAL_GITHUB_UTILS_ERROR, NULL, NULL}; - } - CURLcode code; - curl_easy_setopt(curl, CURLOPT_URL, GITHUB_LATEST_RELEASE_URL.c_str()); - curl_easy_setopt(curl, CURLOPT_USERAGENT, USER_AGENT.c_str()); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeFunctionStdString); - std::string responseBody; - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseBody); - code = curl_easy_perform(curl); - curl_easy_cleanup(curl); - if (code != CURLE_OK) { - blog(LOG_INFO, "Failed to get latest release info"); - return {OBS_BGREMOVAL_GITHUB_UTILS_ERROR, NULL, NULL}; - } - - // Parse the JSON response - obs_data_t *data = obs_data_create_from_json(responseBody.c_str()); - if (!data) { - blog(LOG_INFO, "Failed to parse latest release info"); - return {OBS_BGREMOVAL_GITHUB_UTILS_ERROR, NULL, NULL}; - } - - // The version is in the "tag_name" property - char *version = strdup(obs_data_get_string(data, "tag_name")); - char *body = strdup(obs_data_get_string(data, "body")); - obs_data_release(data); - - // remove the "v" prefix in version, if it exists - if (version[0] == 'v') { - char *newVersion = (char *)malloc(strlen(version) - 1); - strcpy(newVersion, version + 1); - free(version); - version = newVersion; - } - - return {OBS_BGREMOVAL_GITHUB_UTILS_SUCCESS, body, version}; + fetchStringFromUrl(GITHUB_LATEST_RELEASE_URL.c_str(), [callback]( + std::string + responseBody, + int code) { + if (code != 0) + return; + // Parse the JSON response + obs_data_t *data = + obs_data_create_from_json(responseBody.c_str()); + if (!data) { + blog(LOG_INFO, "Failed to parse latest release info"); + callback( + {OBS_BGREMOVAL_GITHUB_UTILS_ERROR, NULL, NULL}); + return; + } + + // The version is in the "tag_name" property + char *version = strdup(obs_data_get_string(data, "tag_name")); + char *body = strdup(obs_data_get_string(data, "body")); + obs_data_release(data); + + // remove the "v" prefix in version, if it exists + if (version[0] == 'v') { + char *newVersion = (char *)malloc(strlen(version) - 1); + strcpy(newVersion, version + 1); + free(version); + version = newVersion; + } + + callback({OBS_BGREMOVAL_GITHUB_UTILS_SUCCESS, body, version}); + }); } void github_utils_release_information_free( diff --git a/src/update-checker/github-utils.h b/src/update-checker/github-utils.h index 80f4875b..804db4bd 100644 --- a/src/update-checker/github-utils.h +++ b/src/update-checker/github-utils.h @@ -1,8 +1,6 @@ #pragma once -#ifdef __cplusplus -extern "C" { -#endif +#include enum { OBS_BGREMOVAL_GITHUB_UTILS_SUCCESS = 0, @@ -15,12 +13,8 @@ struct github_utils_release_information { char *version; }; -struct github_utils_release_information -github_utils_get_release_information(void); +void github_utils_get_release_information( + std::function callback); void github_utils_release_information_free( struct github_utils_release_information info); - -#ifdef __cplusplus -} -#endif diff --git a/src/update-checker/update-checker.cpp b/src/update-checker/update-checker.cpp index b1d25ac7..e3e5d024 100644 --- a/src/update-checker/update-checker.cpp +++ b/src/update-checker/update-checker.cpp @@ -6,32 +6,47 @@ #include #include +#include + #include UpdateDialog *update_dialog; extern "C" const char *PLUGIN_VERSION; -void check_update(struct github_utils_release_information latestRelease) +void check_update(void) { - bool shouldCheckForUpdates = false; - if (getFlagFromConfig("check_for_updates", &shouldCheckForUpdates) != - OBS_BGREMOVAL_CONFIG_SUCCESS) { - // Failed to get the config value, assume it's enabled - shouldCheckForUpdates = true; - } - - if (!shouldCheckForUpdates) { - // Update checks are disabled - return; - } - - if (strcmp(latestRelease.version, PLUGIN_VERSION) == 0) { - // No update available, latest version is the same as the current version - return; - } - - update_dialog = new UpdateDialog( - latestRelease, (QWidget *)obs_frontend_get_main_window()); - QTimer::singleShot(2000, update_dialog, &UpdateDialog::exec); + github_utils_get_release_information([](github_utils_release_information + info) { + if (info.responseCode == OBS_BGREMOVAL_GITHUB_UTILS_SUCCESS) { + obs_log(LOG_INFO, "Latest release is %s", info.version); + bool shouldCheckForUpdates = false; + if (getFlagFromConfig("check_for_updates", + &shouldCheckForUpdates) != + OBS_BGREMOVAL_CONFIG_SUCCESS) { + // Failed to get the config value, assume it's enabled + shouldCheckForUpdates = true; + } + + if (!shouldCheckForUpdates) { + // Update checks are disabled + return; + } + + if (strcmp(info.version, PLUGIN_VERSION) == 0) { + // No update available, latest version is the same as the current version + return; + } + + update_dialog = new UpdateDialog( + info, + (QWidget *)obs_frontend_get_main_window()); + QTimer::singleShot(2000, update_dialog, + &UpdateDialog::exec); + } else { + obs_log(LOG_INFO, + "failed to get latest release information"); + } + github_utils_release_information_free(info); + }); } diff --git a/src/update-checker/update-checker.h b/src/update-checker/update-checker.h index 18360c62..c42ff6dd 100644 --- a/src/update-checker/update-checker.h +++ b/src/update-checker/update-checker.h @@ -1,12 +1,10 @@ #pragma once -#include "github-utils.h" - #ifdef __cplusplus extern "C" { #endif -void check_update(struct github_utils_release_information latestRelease); +void check_update(void); #ifdef __cplusplus } diff --git a/vendor/curl b/vendor/curl deleted file mode 160000 index 7ab9d437..00000000 --- a/vendor/curl +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 7ab9d43720bc34d9aa351c7ca683c1668ebf8335