Compare commits

...

11 Commits

Author SHA1 Message Date
restitux 8570d7f356 add debugging
CodeQL / Get language matrix (push) Successful in -6s
CodeQL / Analyze (${{ matrix.name }}) (push) Failing after 1m56s
2025-06-29 20:08:11 -06:00
Cody Maness 64544e7960 fix(httpcommon): sonarqube warning cleanup (#3558)
Co-authored-by: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com>
2025-01-22 09:16:14 -05:00
LizardByte-bot 2a31ee5422 chore(l10n): update translations (#3563) 2025-01-22 02:45:44 +00:00
dependabot[bot] 8263d8976f build(deps): bump packaging/linux/flatpak/deps/shared-modules from f5d368a to 26def5f (#3568)
build(deps): bump packaging/linux/flatpak/deps/shared-modules

Bumps [packaging/linux/flatpak/deps/shared-modules](https://github.com/flathub/shared-modules) from `f5d368a` to `26def5f`.
- [Commits](https://github.com/flathub/shared-modules/compare/f5d368a31d6ef046eb2955c74ec6f54f32ed5c4e...26def5f1d263653f9b9f93399ca9c6f2118964f5)

---
updated-dependencies:
- dependency-name: packaging/linux/flatpak/deps/shared-modules
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-21 20:38:20 -05:00
ReenigneArcher eb6916ef34 fix(web-ui): fix new version notification conditions (#3577) 2025-01-22 00:46:04 +00:00
dependabot[bot] 5af21bde88 build(deps): bump third-party/tray from e80058b to d45306e (#3574)
Bumps [third-party/tray](https://github.com/LizardByte/tray) from `e80058b` to `d45306e`.
- [Commits](https://github.com/LizardByte/tray/compare/e80058b9a9f3a1574775a57b6eb9159aa3299bf5...d45306e686c90a18f5792a1541783d7bc8555bc6)

---
updated-dependencies:
- dependency-name: third-party/tray
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-21 09:15:26 -05:00
dependabot[bot] 31866fde35 build(deps): bump third-party/libdisplaydevice from 63599b0 to 1975f75 (#3576)
build(deps): bump third-party/libdisplaydevice

Bumps [third-party/libdisplaydevice](https://github.com/LizardByte/libdisplaydevice) from `63599b0` to `1975f75`.
- [Release notes](https://github.com/LizardByte/libdisplaydevice/releases)
- [Commits](https://github.com/LizardByte/libdisplaydevice/compare/63599b07659a5d1dd554a24bd0c8e96b21e21112...1975f75add5812afa1ec82b1553c9d830757687a)

---
updated-dependencies:
- dependency-name: third-party/libdisplaydevice
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-21 09:14:58 -05:00
dependabot[bot] 299b12347f build(deps): bump third-party/doxyconfig from 4c94524 to 4501c7b (#3573)
Bumps [third-party/doxyconfig](https://github.com/LizardByte/doxyconfig) from `4c94524` to `4501c7b`.
- [Commits](https://github.com/LizardByte/doxyconfig/compare/4c9452482bd01cb36764dc914d4537b278ad4218...4501c7b191170cd2adcc12336821b65449186d85)

---
updated-dependencies:
- dependency-name: third-party/doxyconfig
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-21 05:06:24 +00:00
LizardByte-bot 2ac87fdc36 chore: update global workflows (#3570) 2025-01-21 02:30:06 +00:00
dependabot[bot] a88c01f3b8 build(deps): bump third-party/tray from ebbd14f to e80058b (#3567)
Bumps [third-party/tray](https://github.com/LizardByte/tray) from `ebbd14f` to `e80058b`.
- [Commits](https://github.com/LizardByte/tray/compare/ebbd14fe6af30e61ddbb710251f612d32e371d98...e80058b9a9f3a1574775a57b6eb9159aa3299bf5)

---
updated-dependencies:
- dependency-name: third-party/tray
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-20 20:19:36 -05:00
ReenigneArcher f5b923c406 fix(flatpak): fix broken desktop file, icons, and service (#3561) 2025-01-21 00:15:23 +00:00
21 changed files with 171 additions and 132 deletions
+2 -1
View File
@@ -80,13 +80,14 @@ jobs:
month_day=$(printf "%04d" "$month_day") month_day=$(printf "%04d" "$month_day")
# create the filename # create the filename
file_name="_posts/releases/${year}-${month_day:0:2}-${month_day:2:2}-v${semver}.md" file_name="_posts/releases/${repo_lower}/${year}-${month_day:0:2}-${month_day:2:2}-v${semver}.md"
mkdir -p "$(dirname "${file_name}")" mkdir -p "$(dirname "${file_name}")"
# create jekyll blog post # create jekyll blog post
echo "---" > "${file_name}" echo "---" > "${file_name}"
echo "layout: release" >> "${file_name}" echo "layout: release" >> "${file_name}"
echo "title: ${{ github.event.repository.name }} ${tag_name} Released" >> "${file_name}" echo "title: ${{ github.event.repository.name }} ${tag_name} Released" >> "${file_name}"
echo "release-tag: ${tag_name}" >> "${file_name}"
echo "gh-repo: ${{ github.repository }}" >> "${file_name}" echo "gh-repo: ${{ github.repository }}" >> "${file_name}"
echo "gh-badge: [follow, fork, star]" >> "${file_name}" echo "gh-badge: [follow, fork, star]" >> "${file_name}"
echo "tags: [release, ${repo_lower}]" >> "${file_name}" echo "tags: [release, ${repo_lower}]" >> "${file_name}"
+8 -1
View File
@@ -81,9 +81,16 @@ jobs:
--arg description "${{ github.event.repository.description }}" \ --arg description "${{ github.event.repository.description }}" \
'{default_branch: $default_branch}') '{default_branch: $default_branch}')
# change the default branch to the latest release
curl \ curl \
-X PATCH \ -X PATCH \
-H "Authorization: Token ${RTD_TOKEN}" \ -H "Authorization: Token ${RTD_TOKEN}" \
https://readthedocs.org/api/v3/projects/${RTD_SLUG}/ \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
https://readthedocs.org/api/v3/projects/${RTD_SLUG}/ \
-d "$json_body" -d "$json_body"
# trigger a build for the latest version
curl \
-X POST \
-H "Authorization: Token ${RTD_TOKEN}" \
https://readthedocs.org/api/v3/projects/${RTD_SLUG}/versions/latest/builds/
+8
View File
@@ -198,6 +198,14 @@ if(${SUNSHINE_ENABLE_TRAY})
list(APPEND PLATFORM_TARGET_FILES "${CMAKE_SOURCE_DIR}/third-party/tray/src/tray_linux.c") list(APPEND PLATFORM_TARGET_FILES "${CMAKE_SOURCE_DIR}/third-party/tray/src/tray_linux.c")
list(APPEND SUNSHINE_EXTERNAL_LIBRARIES ${APPINDICATOR_LIBRARIES} ${LIBNOTIFY_LIBRARIES}) list(APPEND SUNSHINE_EXTERNAL_LIBRARIES ${APPINDICATOR_LIBRARIES} ${LIBNOTIFY_LIBRARIES})
endif() endif()
# flatpak icons must be prefixed with the app id or they will not be included in the flatpak
if(${SUNSHINE_BUILD_FLATPAK})
set(SUNSHINE_TRAY_PREFIX "${PROJECT_FQDN}")
else()
set(SUNSHINE_TRAY_PREFIX "sunshine")
endif()
list(APPEND SUNSHINE_DEFINITIONS SUNSHINE_TRAY_PREFIX="${SUNSHINE_TRAY_PREFIX}")
else() else()
set(SUNSHINE_TRAY 0) set(SUNSHINE_TRAY 0)
message(STATUS "Tray icon disabled") message(STATUS "Tray icon disabled")
+17 -8
View File
@@ -100,6 +100,7 @@ endif()
# tray icon # tray icon
if(${SUNSHINE_TRAY} STREQUAL 1) if(${SUNSHINE_TRAY} STREQUAL 1)
if(NOT ${SUNSHINE_BUILD_FLATPAK})
install(FILES "${CMAKE_SOURCE_DIR}/sunshine.svg" install(FILES "${CMAKE_SOURCE_DIR}/sunshine.svg"
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/status" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/status"
RENAME "sunshine-tray.svg") RENAME "sunshine-tray.svg")
@@ -109,6 +110,21 @@ if(${SUNSHINE_TRAY} STREQUAL 1)
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/status") DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/status")
install(FILES "${SUNSHINE_SOURCE_ASSETS_DIR}/common/assets/web/public/images/sunshine-locked.svg" install(FILES "${SUNSHINE_SOURCE_ASSETS_DIR}/common/assets/web/public/images/sunshine-locked.svg"
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/status") DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/status")
else()
# flatpak icons must be prefixed with the app id or they will not be included in the flatpak
install(FILES "${CMAKE_SOURCE_DIR}/sunshine.svg"
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/status"
RENAME "${PROJECT_FQDN}-tray.svg")
install(FILES "${SUNSHINE_SOURCE_ASSETS_DIR}/common/assets/web/public/images/sunshine-playing.svg"
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/status"
RENAME "${PROJECT_FQDN}-playing.svg")
install(FILES "${SUNSHINE_SOURCE_ASSETS_DIR}/common/assets/web/public/images/sunshine-pausing.svg"
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/status"
RENAME "${PROJECT_FQDN}-pausing.svg")
install(FILES "${SUNSHINE_SOURCE_ASSETS_DIR}/common/assets/web/public/images/sunshine-locked.svg"
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/status"
RENAME "${PROJECT_FQDN}-locked.svg")
endif()
set(CPACK_DEBIAN_PACKAGE_DEPENDS "\ set(CPACK_DEBIAN_PACKAGE_DEPENDS "\
${CPACK_DEBIAN_PACKAGE_DEPENDS}, \ ${CPACK_DEBIAN_PACKAGE_DEPENDS}, \
@@ -128,15 +144,8 @@ else()
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine.desktop" install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine.desktop"
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications"
RENAME "${PROJECT_FQDN}.desktop") RENAME "${PROJECT_FQDN}.desktop")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine_kms.desktop"
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications"
RENAME "${PROJECT_FQDN}_kms.desktop")
endif() endif()
if(${SUNSHINE_BUILD_FLATPAK}) if(NOT ${SUNSHINE_BUILD_APPIMAGE} AND NOT ${SUNSHINE_BUILD_FLATPAK})
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine_terminal.desktop"
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications"
RENAME "${PROJECT_FQDN}_terminal.desktop")
elseif(NOT ${SUNSHINE_BUILD_APPIMAGE})
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine_terminal.desktop" install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine_terminal.desktop"
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications") DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications")
endif() endif()
+1 -1
View File
@@ -8,7 +8,7 @@ elseif (UNIX)
endif() endif()
if(SUNSHINE_BUILD_FLATPAK) if(SUNSHINE_BUILD_FLATPAK)
set(SUNSHINE_SERVICE_START_COMMAND "ExecStart=${PROJECT_FQDN}") set(SUNSHINE_SERVICE_START_COMMAND "ExecStart=flatpak run --command=sunshine ${PROJECT_FQDN}")
set(SUNSHINE_SERVICE_STOP_COMMAND "ExecStop=flatpak kill ${PROJECT_FQDN}") set(SUNSHINE_SERVICE_STOP_COMMAND "ExecStop=flatpak kill ${PROJECT_FQDN}")
else() else()
set(SUNSHINE_SERVICE_START_COMMAND "ExecStart=${SUNSHINE_EXECUTABLE_PATH}") set(SUNSHINE_SERVICE_START_COMMAND "ExecStart=${SUNSHINE_EXECUTABLE_PATH}")
@@ -10,14 +10,12 @@ if(APPLE)
endif() endif()
elseif(UNIX) elseif(UNIX)
# configure the .desktop file # configure the .desktop file
set(SUNSHINE_DESKTOP_ICON "sunshine.svg") set(SUNSHINE_DESKTOP_ICON "sunshine")
if(${SUNSHINE_BUILD_APPIMAGE}) if(${SUNSHINE_BUILD_APPIMAGE})
configure_file(packaging/linux/AppImage/sunshine.desktop sunshine.desktop @ONLY) configure_file(packaging/linux/AppImage/sunshine.desktop sunshine.desktop @ONLY)
elseif(${SUNSHINE_BUILD_FLATPAK}) elseif(${SUNSHINE_BUILD_FLATPAK})
set(SUNSHINE_DESKTOP_ICON "${PROJECT_FQDN}.svg") set(SUNSHINE_DESKTOP_ICON "${PROJECT_FQDN}")
configure_file(packaging/linux/flatpak/sunshine.desktop sunshine.desktop @ONLY) configure_file(packaging/linux/flatpak/sunshine.desktop sunshine.desktop @ONLY)
configure_file(packaging/linux/flatpak/sunshine_kms.desktop sunshine_kms.desktop @ONLY)
configure_file(packaging/linux/sunshine_terminal.desktop sunshine_terminal.desktop @ONLY)
configure_file(packaging/linux/flatpak/${PROJECT_FQDN}.metainfo.xml configure_file(packaging/linux/flatpak/${PROJECT_FQDN}.metainfo.xml
${PROJECT_FQDN}.metainfo.xml @ONLY) ${PROJECT_FQDN}.metainfo.xml @ONLY)
else() else()
@@ -0,0 +1,11 @@
#!/bin/sh
PORT=47990
if ! curl -k https://localhost:$PORT > /dev/null 2>&1; then
(sleep 3 && xdg-open https://localhost:$PORT) &
exec sunshine "$@"
else
echo "Sunshine is already running, opening the web interface..."
xdg-open https://localhost:$PORT
fi
+5 -16
View File
@@ -1,20 +1,9 @@
[Desktop Entry] [Desktop Entry]
Type=Application Categories=AudioVideo;Network;RemoteAccess;
Name=@PROJECT_NAME@
Exec=@PROJECT_FQDN@
Version=1.0
Comment=@PROJECT_DESCRIPTION@ Comment=@PROJECT_DESCRIPTION@
Exec=sunshine.sh
Icon=@SUNSHINE_DESKTOP_ICON@ Icon=@SUNSHINE_DESKTOP_ICON@
Keywords=gamestream;stream;moonlight;remote play; Keywords=gamestream;stream;moonlight;remote play;
Categories=AudioVideo;Network;RemoteAccess; Name=@PROJECT_NAME@
Actions=RunInTerminal;KMS; Type=Application
Version=1.0
[Desktop Action RunInTerminal]
Name=Run in Terminal
Icon=application-x-executable
Exec=gio launch @CMAKE_INSTALL_FULL_DATAROOTDIR@/applications/@PROJECT_FQDN@_terminal.desktop
[Desktop Action KMS]
Name=Run in Terminal (KMS)
Icon=application-x-executable
Exec=gio launch @CMAKE_INSTALL_FULL_DATAROOTDIR@/applications/@PROJECT_FQDN@_kms.desktop
@@ -1,6 +0,0 @@
[Desktop Entry]
Name=@PROJECT_NAME@ (KMS)
Exec=sudo -i PULSE_SERVER=unix:$(pactl info | awk '/Server String/{print$3}') flatpak run @PROJECT_FQDN@
Terminal=true
Type=Application
NoDisplay=true
+13 -22
View File
@@ -54,17 +54,14 @@ namespace http {
config::nvhttp.pkey = (dir / ("pkey-"s + unique_id)).string(); config::nvhttp.pkey = (dir / ("pkey-"s + unique_id)).string();
} }
if (!fs::exists(config::nvhttp.pkey) || !fs::exists(config::nvhttp.cert)) { if ((!fs::exists(config::nvhttp.pkey) || !fs::exists(config::nvhttp.cert)) &&
if (create_creds(config::nvhttp.pkey, config::nvhttp.cert)) { create_creds(config::nvhttp.pkey, config::nvhttp.cert)) {
return -1; return -1;
} }
} if (!user_creds_exist(config::sunshine.credentials_file)) {
if (user_creds_exist(config::sunshine.credentials_file)) {
if (reload_user_creds(config::sunshine.credentials_file)) {
return -1;
}
} else {
BOOST_LOG(info) << "Open the Web UI to set your new username and password and getting started"; BOOST_LOG(info) << "Open the Web UI to set your new username and password and getting started";
} else if (reload_user_creds(config::sunshine.credentials_file)) {
return -1;
} }
return 0; return 0;
} }
@@ -179,19 +176,15 @@ namespace http {
return 0; return 0;
} }
bool download_file(const std::string &url, const std::string &file) { bool download_file(const std::string &url, const std::string &file, long ssl_version) {
CURL *curl = curl_easy_init(); // sonar complains about weak ssl and tls versions; however sonar cannot detect the fix
if (curl) { CURL *curl = curl_easy_init(); // NOSONAR
// sonar complains about weak ssl and tls versions if (!curl) {
// ideally, the setopts should go after the early returns; however sonar cannot detect the fix
curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
} else {
BOOST_LOG(error) << "Couldn't create CURL instance"; BOOST_LOG(error) << "Couldn't create CURL instance";
return false; return false;
} }
std::string file_dir = file_handler::get_parent_directory(file); if (std::string file_dir = file_handler::get_parent_directory(file); !file_handler::make_directory(file_dir)) {
if (!file_handler::make_directory(file_dir)) {
BOOST_LOG(error) << "Couldn't create directory ["sv << file_dir << ']'; BOOST_LOG(error) << "Couldn't create directory ["sv << file_dir << ']';
curl_easy_cleanup(curl); curl_easy_cleanup(curl);
return false; return false;
@@ -204,6 +197,7 @@ namespace http {
return false; return false;
} }
curl_easy_setopt(curl, CURLOPT_SSLVERSION, ssl_version); // NOSONAR
curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
@@ -219,17 +213,15 @@ namespace http {
} }
std::string url_escape(const std::string &url) { std::string url_escape(const std::string &url) {
CURL *curl = curl_easy_init(); char *string = curl_easy_escape(nullptr, url.c_str(), static_cast<int>(url.length()));
char *string = curl_easy_escape(curl, url.c_str(), url.length());
std::string result(string); std::string result(string);
curl_free(string); curl_free(string);
curl_easy_cleanup(curl);
return result; return result;
} }
std::string url_get_host(const std::string &url) { std::string url_get_host(const std::string &url) {
CURLU *curlu = curl_url(); CURLU *curlu = curl_url();
curl_url_set(curlu, CURLUPART_URL, url.c_str(), url.length()); curl_url_set(curlu, CURLUPART_URL, url.c_str(), static_cast<unsigned int>(url.length()));
char *host; char *host;
if (curl_url_get(curlu, CURLUPART_HOST, &host, 0) != CURLUE_OK) { if (curl_url_get(curlu, CURLUPART_HOST, &host, 0) != CURLUE_OK) {
curl_url_cleanup(curlu); curl_url_cleanup(curlu);
@@ -240,5 +232,4 @@ namespace http {
curl_url_cleanup(curlu); curl_url_cleanup(curlu);
return result; return result;
} }
} // namespace http } // namespace http
+4 -1
View File
@@ -4,6 +4,9 @@
*/ */
#pragma once #pragma once
// lib includes
#include <curl/curl.h>
// local includes // local includes
#include "network.h" #include "network.h"
#include "thread_safe.h" #include "thread_safe.h"
@@ -20,7 +23,7 @@ namespace http {
); );
int reload_user_creds(const std::string &file); int reload_user_creds(const std::string &file);
bool download_file(const std::string &url, const std::string &file); bool download_file(const std::string &url, const std::string &file, long ssl_version = CURL_SSLVERSION_TLSv1_3);
std::string url_escape(const std::string &url); std::string url_escape(const std::string &url);
std::string url_get_host(const std::string &url); std::string url_get_host(const std::string &url);
+23
View File
@@ -361,8 +361,19 @@ namespace nvhttp {
auto salt = util::from_hex<std::array<uint8_t, 16>>(salt_view, true); auto salt = util::from_hex<std::array<uint8_t, 16>>(salt_view, true);
auto key = crypto::gen_aes_key(salt, pin); auto key = crypto::gen_aes_key(salt, pin);
std::ostringstream cipher_key_hex;
for (auto b = key.begin(); b != key.end(); ++b) {
cipher_key_hex << std::hex // Output in hexadecimal
<< std::setw(2) // Each byte prints as two characters
<< std::setfill('0') // Fill with '0' if less than two characters
<< static_cast<unsigned int>(*b); // Cast to unsigned int for correct printing
}
BOOST_LOG(debug) << "cipher_key_hex: " << cipher_key_hex.str();
sess.cipher_key = std::make_unique<crypto::aes_t>(key); sess.cipher_key = std::make_unique<crypto::aes_t>(key);
tree.put("root.paired", 1); tree.put("root.paired", 1);
tree.put("root.plaincert", util::hex_vec(conf_intern.servercert, true)); tree.put("root.plaincert", util::hex_vec(conf_intern.servercert, true));
tree.put("root.<xmlattr>.status_code", 200); tree.put("root.<xmlattr>.status_code", 200);
@@ -471,11 +482,23 @@ namespace nvhttp {
data.insert(std::end(data), std::begin(x509_sign), std::end(x509_sign)); data.insert(std::end(data), std::begin(x509_sign), std::end(x509_sign));
data.insert(std::end(data), std::begin(secret), std::end(secret)); data.insert(std::end(data), std::begin(secret), std::end(secret));
std::ostringstream data_hex;
for (auto d = data.begin(); d != data.end(); ++d) {
data_hex << std::hex // Output in hexadecimal
<< std::setw(2) // Each byte prints as two characters
<< std::setfill('0') // Fill with '0' if less than two characters
<< static_cast<unsigned int>(*d); // Cast to unsigned int for correct printing
}
BOOST_LOG(debug) << "data_hex: " << data_hex.str();
auto hash = crypto::hash(data); auto hash = crypto::hash(data);
// if hash not correct, probably MITM // if hash not correct, probably MITM
bool same_hash = hash.size() == sess.clienthash.size() && std::equal(hash.begin(), hash.end(), sess.clienthash.begin()); bool same_hash = hash.size() == sess.clienthash.size() && std::equal(hash.begin(), hash.end(), sess.clienthash.begin());
auto verify = crypto::verify256(crypto::x509(client.cert), secret, sign); auto verify = crypto::verify256(crypto::x509(client.cert), secret, sign);
BOOST_LOG(debug) << "same_hash: " << same_hash;
BOOST_LOG(debug) << "verify: " << verify;
if (same_hash && verify) { if (same_hash && verify) {
tree.put("root.paired", 1); tree.put("root.paired", 1);
add_cert->raise(crypto::x509(client.cert)); add_cert->raise(crypto::x509(client.cert));
+4 -4
View File
@@ -14,10 +14,10 @@
#define TRAY_ICON_PAUSING WEB_DIR "images/sunshine-pausing.ico" #define TRAY_ICON_PAUSING WEB_DIR "images/sunshine-pausing.ico"
#define TRAY_ICON_LOCKED WEB_DIR "images/sunshine-locked.ico" #define TRAY_ICON_LOCKED WEB_DIR "images/sunshine-locked.ico"
#elif defined(__linux__) || defined(linux) || defined(__linux) #elif defined(__linux__) || defined(linux) || defined(__linux)
#define TRAY_ICON "sunshine-tray" #define TRAY_ICON SUNSHINE_TRAY_PREFIX "-tray"
#define TRAY_ICON_PLAYING "sunshine-playing" #define TRAY_ICON_PLAYING SUNSHINE_TRAY_PREFIX "-playing"
#define TRAY_ICON_PAUSING "sunshine-pausing" #define TRAY_ICON_PAUSING SUNSHINE_TRAY_PREFIX "-pausing"
#define TRAY_ICON_LOCKED "sunshine-locked" #define TRAY_ICON_LOCKED SUNSHINE_TRAY_PREFIX "-locked"
#elif defined(__APPLE__) || defined(__MACH__) #elif defined(__APPLE__) || defined(__MACH__)
#define TRAY_ICON WEB_DIR "images/logo-sunshine-16.png" #define TRAY_ICON WEB_DIR "images/logo-sunshine-16.png"
#define TRAY_ICON_PLAYING WEB_DIR "images/sunshine-playing-16.png" #define TRAY_ICON_PLAYING WEB_DIR "images/sunshine-playing-16.png"
@@ -10,7 +10,7 @@
"disabled_def_cbox": "기본값: 선택 안 함", "disabled_def_cbox": "기본값: 선택 안 함",
"dismiss": "해제", "dismiss": "해제",
"do_cmd": "명령 수행", "do_cmd": "명령 수행",
"elevated": "상승", "elevated": "관리자 권한으로 실행",
"enabled": "활성화됨", "enabled": "활성화됨",
"enabled_def": "활성화됨 (기본값)", "enabled_def": "활성화됨 (기본값)",
"enabled_def_cbox": "기본값: 확인됨", "enabled_def_cbox": "기본값: 확인됨",
@@ -209,7 +209,7 @@
"gamepad_ds4": "DS4 (PS4)", "gamepad_ds4": "DS4 (PS4)",
"gamepad_ds4_manual": "DS4 선택 옵션", "gamepad_ds4_manual": "DS4 선택 옵션",
"gamepad_ds5": "DS5 (PS5)", "gamepad_ds5": "DS5 (PS5)",
"gamepad_switch": "닌텐도 프로(스위치)", "gamepad_switch": "닌텐도 프로 (스위치 컨트롤러)",
"gamepad_manual": "DS4 수동 옵션", "gamepad_manual": "DS4 수동 옵션",
"gamepad_x360": "X360 (Xbox 360)", "gamepad_x360": "X360 (Xbox 360)",
"gamepad_xone": "XOne (Xbox One)", "gamepad_xone": "XOne (Xbox One)",
@@ -224,18 +224,18 @@
"high_resolution_scrolling": "고해상도 스크롤 지원", "high_resolution_scrolling": "고해상도 스크롤 지원",
"high_resolution_scrolling_desc": "이 옵션을 활성화하면 Sunshine은 Moonlight 클라이언트의 고해상도 스크롤 이벤트를 통과합니다. 고해상도 스크롤 이벤트로 너무 빠르게 스크롤하는 구형 애플리케이션의 경우 이 옵션을 비활성화하면 유용할 수 있습니다.", "high_resolution_scrolling_desc": "이 옵션을 활성화하면 Sunshine은 Moonlight 클라이언트의 고해상도 스크롤 이벤트를 통과합니다. 고해상도 스크롤 이벤트로 너무 빠르게 스크롤하는 구형 애플리케이션의 경우 이 옵션을 비활성화하면 유용할 수 있습니다.",
"install_steam_audio_drivers": "Steam 오디오 드라이버 설치", "install_steam_audio_drivers": "Steam 오디오 드라이버 설치",
"install_steam_audio_drivers_desc": "Steam이 설치되어 있으면 5.1/7.1 서라운드 사운드와 호스트 오디오 음소거를 지원하는 Steam 스트리밍 스피커 드라이버가 자동으로 설치됩니다.", "install_steam_audio_drivers_desc": "Steam이 설치되어 있으면 5.1/7.1 서라운드 사운드와 호스트 오디오 음소거를 지원하는 Steam Streaming Speakers 드라이버가 자동으로 설치됩니다.",
"key_repeat_delay": "키 반복 지연", "key_repeat_delay": "키 반복 지연",
"key_repeat_delay_desc": "키가 반복되는 속도를 제어합니다. 키가 반복되기 전 초기 지연 시간(밀리초)입니다.", "key_repeat_delay_desc": "키가 반복되는 속도를 제어합니다. 키가 반복되기 전 초기 지연 시간 (ms) 입니다.",
"key_repeat_frequency": "키 반복 빈도", "key_repeat_frequency": "키 반복 빈도",
"key_repeat_frequency_desc": "매 초마다 키가 반복되는 빈도. 이 구성 가능한 옵션은 소수를 지원합니다.", "key_repeat_frequency_desc": "매 초마다 키가 반복되는 빈도입니다. (이 옵션은 소수점 입력이 가능합니다.)",
"key_rightalt_to_key_win": "오른쪽 Alt 키를 Windows 키로 매핑", "key_rightalt_to_key_win": "오른쪽 Alt 키를 Windows 키로 매핑",
"key_rightalt_to_key_win_desc": "달빛에서 Windows 키를 직접 보낼 수 없는 경우가 있을 수 있습니다. 이러한 경우 Sunshine이 오른쪽 Alt 키를 Windows 키로 인식하도록 하는 것이 유용할 수 있습니다.", "key_rightalt_to_key_win_desc": "달빛에서 Windows 키를 직접 보낼 수 없는 경우가 있을 수 있습니다. 이러한 경우 Sunshine이 오른쪽 Alt 키를 Windows 키로 인식하도록 하는 것이 유용할 수 있습니다.",
"keyboard": "키보드 입력 활성화", "keyboard": "키보드 입력 활성화",
"keyboard_desc": "게스트가 키보드로 호스트 시스템을 제어할 수 있습니다.", "keyboard_desc": "게스트가 키보드로 호스트 시스템을 제어할 수 있습니다.",
"lan_encryption_mode": "LAN 암호화 모드", "lan_encryption_mode": "LAN 암호화 모드",
"lan_encryption_mode_1": "지원되는 클라이언트에서 사용 가능", "lan_encryption_mode_1": "지원되는 클라이언트에서 사용 가능",
"lan_encryption_mode_2": "모든 고객에게 필수", "lan_encryption_mode_2": "모든 사용자에게 필수",
"lan_encryption_mode_desc": "로컬 네트워크를 통해 스트리밍할 때 암호화를 사용할 시기를 결정합니다. 암호화는 특히 성능이 낮은 호스트와 클라이언트에서 스트리밍 성능을 저하시킬 수 있습니다.", "lan_encryption_mode_desc": "로컬 네트워크를 통해 스트리밍할 때 암호화를 사용할 시기를 결정합니다. 암호화는 특히 성능이 낮은 호스트와 클라이언트에서 스트리밍 성능을 저하시킬 수 있습니다.",
"locale": "로캘", "locale": "로캘",
"locale_desc": "Sunshine의 사용자 인터페이스에 사용되는 로캘입니다.", "locale_desc": "Sunshine의 사용자 인터페이스에 사용되는 로캘입니다.",
@@ -255,8 +255,8 @@
"min_threads": "최소 CPU 스레드 수", "min_threads": "최소 CPU 스레드 수",
"min_threads_desc": "이 값을 높이면 인코딩 효율이 약간 떨어지지만, 일반적으로 인코딩에 더 많은 CPU 코어를 사용할 수 있다는 점에서 그만한 가치가 있습니다. 이상적인 값은 하드웨어에서 원하는 스트리밍 설정으로 안정적으로 인코딩할 수 있는 가장 낮은 값입니다.", "min_threads_desc": "이 값을 높이면 인코딩 효율이 약간 떨어지지만, 일반적으로 인코딩에 더 많은 CPU 코어를 사용할 수 있다는 점에서 그만한 가치가 있습니다. 이상적인 값은 하드웨어에서 원하는 스트리밍 설정으로 안정적으로 인코딩할 수 있는 가장 낮은 값입니다.",
"misc": "기타 옵션", "misc": "기타 옵션",
"motion_as_ds4": "클라이언트 게임패드가 모션 센서가 있다고 보고하는 경우 DS4 게임패드 에뮬레이", "motion_as_ds4": "클라이언트 게임패드가 모션 기능을 보유중인 경우 DS4 게임패드 에뮬레이",
"motion_as_ds4_desc": "비활성화하면 게임패드 유형을 선택할 때 모션 센서가 고려되지 않습니다.", "motion_as_ds4_desc": "비활성화시, 게임패드 선택할 때 모션 센서 유무를 확인하지 않습니다.",
"mouse": "마우스 입력 활성화", "mouse": "마우스 입력 활성화",
"mouse_desc": "게스트가 마우스로 호스트 시스템을 제어할 수 있습니다.", "mouse_desc": "게스트가 마우스로 호스트 시스템을 제어할 수 있습니다.",
"native_pen_touch": "기본 펜/터치 지원", "native_pen_touch": "기본 펜/터치 지원",
@@ -300,10 +300,10 @@
"pkey": "개인 키", "pkey": "개인 키",
"pkey_desc": "웹 UI와 Moonlight 클라이언트 페어링에 사용되는 개인 키입니다. 최상의 호환성을 위해 RSA-2048 개인키를 사용해야 합니다.", "pkey_desc": "웹 UI와 Moonlight 클라이언트 페어링에 사용되는 개인 키입니다. 최상의 호환성을 위해 RSA-2048 개인키를 사용해야 합니다.",
"port": "포트", "port": "포트",
"port_alert_1": "선샤인은 1024 이하의 포트를 사용할 수 없습니다!", "port_alert_1": "Sunshine은 1024 이하의 포트를 사용할 수 없습니다, 다시 확인하세요.",
"port_alert_2": "65535 이상의 포트는 사용할 수 없습니다!", "port_alert_2": "65535 이상의 포트는 사용할 수 없습니다, 다시 확인하세요.",
"port_desc": "Sunshine에서 사용하는 포트 제품군 설정", "port_desc": "Sunshine에서 사용하는 포트 제품군 설정",
"port_http_port_note": "이 포트를 사용하여 문라이트에 연결하세요.", "port_http_port_note": "이 포트를 사용하여 Moonlight에 연결하세요.",
"port_note": "참고", "port_note": "참고",
"port_port": "포트", "port_port": "포트",
"port_protocol": "프로토콜", "port_protocol": "프로토콜",
@@ -316,26 +316,26 @@
"qsv_coder": "퀵싱크 코더(H264)", "qsv_coder": "퀵싱크 코더(H264)",
"qsv_preset": "퀵싱크 프리셋", "qsv_preset": "퀵싱크 프리셋",
"qsv_preset_fast": "빠름 (낮은 품질)", "qsv_preset_fast": "빠름 (낮은 품질)",
"qsv_preset_faster": "더 빠름(품질 저하)", "qsv_preset_faster": "더 빠름 (더 낮은 품질)",
"qsv_preset_medium": "중간 (기본값)", "qsv_preset_medium": "중간 (기본값)",
"qsv_preset_slow": "느림 (좋은 품질)", "qsv_preset_slow": "느림 (좋은 품질)",
"qsv_preset_slower": "느림(더 은 품질)", "qsv_preset_slower": "느림 (더 은 품질)",
"qsv_preset_slowest": "가장 느림 (최고 품질)", "qsv_preset_slowest": "가장 느림 (최고 품질)",
"qsv_preset_veryfast": "가장 빠름 (최저 품질)", "qsv_preset_veryfast": "가장 빠름 (최저 품질)",
"qsv_slow_hevc": "느린 HEVC 인코딩 허용", "qsv_slow_hevc": "느린 HEVC 인코딩 허용",
"qsv_slow_hevc_desc": "이렇게 하면 구형 인텔 GPU에서 HEVC 인코딩이 가능하지만, GPU 사용량이 증가하고 성능이 저하될 수 있습니다.", "qsv_slow_hevc_desc": "이렇게 하면 구형 인텔 GPU에서 HEVC 인코딩이 가능하지만, GPU 사용량이 증가하고 성능이 저하될 수 있습니다.",
"restart_note": "변경 사항을 적용하기 위해 Sunshine이 다시 시작됩니다.", "restart_note": "변경 사항을 적용하기 위해 Sunshine이 다시 시작됩니다.",
"sunshine_name": "선샤인 이름", "sunshine_name": "Sunshine 이름",
"sunshine_name_desc": "달빛이 표시는 이름입니다. 지정하지 않으면 PC의 호스트 이름이 사용됩니다.", "sunshine_name_desc": "Moonlight에서 표시는 이름입니다. 지정하지 않으면 PC의 이름이 사용됩니다.",
"sw_preset": "SW 프리셋", "sw_preset": "SW 프리셋",
"sw_preset_desc": "인코딩 속도(초당 인코딩 프레임 수)와 압축 효율성(비트스트림의 비트당 품질) 간의 절충점을 최적화합니다. 기본값은 초고속입니다.", "sw_preset_desc": "인코딩 속도(초당 인코딩 프레임 수)와 압축 효율성(비트스트림의 비트당 품질) 간의 절충점을 최적화합니다. 기본값은 초고속입니다.",
"sw_preset_fast": "빠", "sw_preset_fast": "빠",
"sw_preset_faster": "더 빠르게", "sw_preset_faster": "더 빠",
"sw_preset_medium": "medium", "sw_preset_medium": "중간",
"sw_preset_slow": "slow", "sw_preset_slow": "느림",
"sw_preset_slower": "느린", "sw_preset_slower": "더 느림",
"sw_preset_superfast": "초고속(기본값)", "sw_preset_superfast": "엄청 빠름 (기본값)",
"sw_preset_ultrafast": "초고속", "sw_preset_ultrafast": "엄청 빠름",
"sw_preset_veryfast": "매우 빠름", "sw_preset_veryfast": "매우 빠름",
"sw_preset_veryslow": "매우 느림", "sw_preset_veryslow": "매우 느림",
"sw_tune": "SW Tune", "sw_tune": "SW Tune",
@@ -353,8 +353,8 @@
"vaapi_strict_rc_buffer": "AMD GPU에서 H.264/HEVC에 대한 프레임 비트레이트 제한을 엄격하게 적용합니다.", "vaapi_strict_rc_buffer": "AMD GPU에서 H.264/HEVC에 대한 프레임 비트레이트 제한을 엄격하게 적용합니다.",
"vaapi_strict_rc_buffer_desc": "이 옵션을 활성화하면 장면이 변경되는 동안 네트워크를 통해 프레임이 끊기는 것을 방지할 수 있지만 움직이는 동안 동영상 품질이 저하될 수 있습니다.", "vaapi_strict_rc_buffer_desc": "이 옵션을 활성화하면 장면이 변경되는 동안 네트워크를 통해 프레임이 끊기는 것을 방지할 수 있지만 움직이는 동안 동영상 품질이 저하될 수 있습니다.",
"virtual_sink": "가상 싱크", "virtual_sink": "가상 싱크",
"virtual_sink_desc": "사용할 가상 오디오 장치를 수동으로 지정합니다. 설정하지 않으면 장치가 자동으로 선택됩니다. 자동 장치 선택을 사용하려면 이 필드를 비워 두는 것이 좋습니다!", "virtual_sink_desc": "사용할 가상 오디오 장치를 수동으로 지정합니다. 설정하지 않으면 자동으로 장치가 선택됩니다. 자동으로 장치 선택할려면 이 칸을 비우는 것을 권장드립니다.",
"virtual_sink_placeholder": "Steam 스트리밍 스피커", "virtual_sink_placeholder": "Steam Streaming Speakers",
"vt_coder": "비디오 툴박스 코더", "vt_coder": "비디오 툴박스 코더",
"vt_realtime": "비디오툴박스 실시간 인코딩", "vt_realtime": "비디오툴박스 실시간 인코딩",
"vt_software": "비디오툴박스 소프트웨어 인코딩", "vt_software": "비디오툴박스 소프트웨어 인코딩",
@@ -362,30 +362,30 @@
"vt_software_forced": "강제", "vt_software_forced": "강제",
"wan_encryption_mode": "WAN 암호화 모드", "wan_encryption_mode": "WAN 암호화 모드",
"wan_encryption_mode_1": "지원되는 클라이언트에 사용(기본값)", "wan_encryption_mode_1": "지원되는 클라이언트에 사용(기본값)",
"wan_encryption_mode_2": "모든 고객에게 필수", "wan_encryption_mode_2": "모든 사용자에게 필수",
"wan_encryption_mode_desc": "인터넷을 통해 스트리밍할 때 암호화를 사용할 시기를 결정합니다. 암호화는 특히 성능이 낮은 호스트와 클라이언트에서 스트리밍 성능을 저하시킬 수 있습니다." "wan_encryption_mode_desc": "인터넷을 통해 스트리밍할 때 암호화를 사용할 시기를 결정합니다. 암호화는 특히 성능이 낮은 호스트와 클라이언트에서 스트리밍 성능을 저하시킬 수 있습니다."
}, },
"index": { "index": {
"description": "선샤인은 문라이트의 자체 호스팅 게임 스트림 호스트입니다.", "description": "Sunshine은 Moonlight의 게임 스트리밍 프로그램 입니다.",
"download": "다운로드", "download": "다운로드",
"installed_version_not_stable": "선샤인 시험판 버전을 실행 중입니다. 버그나 기타 문제가 발생할 수 있습니다. 문제가 발생하면 신고해 주세요. Sunshine을 더 나은 소프트웨어로 만드는 데 도움을 주셔서 감사합니다!", "installed_version_not_stable": "Sunshine의 정식 출시 이전 버전을 실행 중입니다. 버그나 기타 문제가 발생할 수 있습니다. 문제가 발생하면 신고해 주세요. Sunshine을 더 나은 소프트웨어로 만드는 데 도움을 주셔서 감사합니다!",
"loading_latest": "최신 릴리스 로드 중...", "loading_latest": "새로운 업데이트를 확인하는 중...",
"new_pre_release": "새로운 사전 출시 버전이 출시되었습니다!", "new_pre_release": "새로운 사전 출시 버전이 출시되었습니다!",
"new_stable": "새로운 안정 버전이 출시되었습니다!", "new_stable": "새로운 안정 버전이 출시되었습니다!",
"startup_errors": "<b>주의!</b> 시작 중에 이러한 오류가 감지되었습니다. 스트리밍하기 전에 이 오류를 수정할 <b>것을 강력히 권장합니다</b>.", "startup_errors": "<b>주의!</b> 시작하는 중에 오류가 감지되었습니다. 스트리밍하기 전에 이 오류를 수정할 것을 <b>강력히 권장합니다.</b>",
"version_dirty": "선샤인이 더 나은 소프트웨어가 될 수 있도록 도와주셔서 감사합니다!", "version_dirty": "Sunshine이 더 나은 소프트웨어가 될 수 있도록 도와주셔서 감사합니다!",
"version_latest": "최신 버전의 Sunshine을 실행 중입니다.", "version_latest": "최신 버전의 Sunshine을 실행 중입니다.",
"welcome": "안녕하세요, 선샤인!" "welcome": "반가워요, Sunshine!"
}, },
"navbar": { "navbar": {
"applications": "애플리케이션", "applications": "애플리케이션",
"configuration": "구성", "configuration": "설정",
"home": "홈", "home": "홈",
"password": "비밀번호 변경", "password": "비밀번호 변경",
"pin": "핀", "pin": "핀",
"theme_auto": "자동", "theme_auto": "자동",
"theme_dark": "Dark", "theme_dark": "다크 테마",
"theme_light": "", "theme_light": "라이트 테마",
"toggle_theme": "테마", "toggle_theme": "테마",
"troubleshoot": "문제 해결" "troubleshoot": "문제 해결"
}, },
@@ -444,8 +444,8 @@
"confirm_password": "비밀번호 확인", "confirm_password": "비밀번호 확인",
"create_creds": "시작하기 전에 웹 UI에 액세스하기 위한 새 사용자 아이디와 비밀번호를 만들어야 합니다.", "create_creds": "시작하기 전에 웹 UI에 액세스하기 위한 새 사용자 아이디와 비밀번호를 만들어야 합니다.",
"create_creds_alert": "선샤인의 웹 UI에 액세스하려면 아래 자격 증명이 필요합니다. 다시는 볼 수 없으니 안전하게 보관하세요!", "create_creds_alert": "선샤인의 웹 UI에 액세스하려면 아래 자격 증명이 필요합니다. 다시는 볼 수 없으니 안전하게 보관하세요!",
"greeting": "선샤인에 오신 것을 환영합니다!", "greeting": "Sunshine에 오신 것을 환영합니다!",
"login": "로그인", "login": "로그인",
"welcome_success": "이 페이지다시 로드되며 브라우저에서 새 자격 증명을 입력하라는 메시지가 표시됩니다." "welcome_success": "이 페이지새로고침 될 것이며, 브라우저에서 다시 로그인을 해야 합니다."
} }
} }
@@ -172,9 +172,9 @@
"dd_mode_remapping_desc_5_sops_mixed_only": "\"优化游戏设置\"选项必须在 Moonlight 客户端启用,否则将跳过指定任何分辨率字段的条目。", "dd_mode_remapping_desc_5_sops_mixed_only": "\"优化游戏设置\"选项必须在 Moonlight 客户端启用,否则将跳过指定任何分辨率字段的条目。",
"dd_mode_remapping_desc_5_sops_resolution_only": "\"优化游戏设置\"选项必须在 Moonlight 客户端启用,否则将跳过映射。", "dd_mode_remapping_desc_5_sops_resolution_only": "\"优化游戏设置\"选项必须在 Moonlight 客户端启用,否则将跳过映射。",
"dd_mode_remapping_final_refresh_rate": "最终刷新率", "dd_mode_remapping_final_refresh_rate": "最终刷新率",
"dd_mode_remapping_final_resolution": "最后决议", "dd_mode_remapping_final_resolution": "最终分辨率",
"dd_mode_remapping_requested_fps": "请求FPS", "dd_mode_remapping_requested_fps": "请求FPS",
"dd_mode_remapping_requested_resolution": "请求的决议", "dd_mode_remapping_requested_resolution": "请求的分辨率",
"dd_options_header": "高级显示设备选项", "dd_options_header": "高级显示设备选项",
"dd_refresh_rate_option": "刷新率", "dd_refresh_rate_option": "刷新率",
"dd_refresh_rate_option_auto": "使用客户端提供的 FPS 值 (默认)", "dd_refresh_rate_option_auto": "使用客户端提供的 FPS 值 (默认)",
@@ -44,8 +44,8 @@ class SunshineVersion {
return false; return false;
} }
for (let i = 0; i < Math.min(3, this.versionParts.length, otherVersionParts.length); i++) { for (let i = 0; i < Math.min(3, this.versionParts.length, otherVersionParts.length); i++) {
if (this.versionParts[i] > otherVersionParts[i]) { if (this.versionParts[i] !== otherVersionParts[i]) {
return true; return this.versionParts[i] > otherVersionParts[i];
} }
} }
return false; return false;
+10 -5
View File
@@ -2,14 +2,19 @@
* @file tests/unit/test_httpcommon.cpp * @file tests/unit/test_httpcommon.cpp
* @brief Test src/httpcommon.*. * @brief Test src/httpcommon.*.
*/ */
// test imports
#include "../tests_common.h" #include "../tests_common.h"
// lib imports
#include <curl/curl.h>
// local imports
#include <src/httpcommon.h> #include <src/httpcommon.h>
struct UrlEscapeTest: testing::TestWithParam<std::tuple<std::string, std::string>> {}; struct UrlEscapeTest: testing::TestWithParam<std::tuple<std::string, std::string>> {};
TEST_P(UrlEscapeTest, Run) { TEST_P(UrlEscapeTest, Run) {
auto [input, expected] = GetParam(); const auto &[input, expected] = GetParam();
ASSERT_EQ(http::url_escape(input), expected); ASSERT_EQ(http::url_escape(input), expected);
} }
@@ -26,7 +31,7 @@ INSTANTIATE_TEST_SUITE_P(
struct UrlGetHostTest: testing::TestWithParam<std::tuple<std::string, std::string>> {}; struct UrlGetHostTest: testing::TestWithParam<std::tuple<std::string, std::string>> {};
TEST_P(UrlGetHostTest, Run) { TEST_P(UrlGetHostTest, Run) {
auto [input, expected] = GetParam(); const auto &[input, expected] = GetParam();
ASSERT_EQ(http::url_get_host(input), expected); ASSERT_EQ(http::url_get_host(input), expected);
} }
@@ -43,10 +48,10 @@ INSTANTIATE_TEST_SUITE_P(
struct DownloadFileTest: testing::TestWithParam<std::tuple<std::string, std::string>> {}; struct DownloadFileTest: testing::TestWithParam<std::tuple<std::string, std::string>> {};
TEST_P(DownloadFileTest, Run) { TEST_P(DownloadFileTest, Run) {
auto [url, filename] = GetParam(); const auto &[url, filename] = GetParam();
const std::string test_dir = platf::appdata().string() + "/tests/"; const std::string test_dir = platf::appdata().string() + "/tests/";
std::basic_string path = test_dir + filename; std::string path = test_dir + filename;
ASSERT_TRUE(http::download_file(url, path)); ASSERT_TRUE(http::download_file(url, path, CURL_SSLVERSION_TLSv1_0));
} }
#ifdef SUNSHINE_BUILD_FLATPAK #ifdef SUNSHINE_BUILD_FLATPAK