| 218 | } |
| 219 | |
| 220 | void streamfx::updater::task(streamfx::util::threadpool::task_data_t) |
| 221 | { |
| 222 | try { |
| 223 | auto query_fn = [](std::vector<char>& buffer) { |
| 224 | static constexpr std::string_view ST_API_URL = "https://api.github.com/repos/Xaymar/obs-StreamFX/releases?per_page=25&page=1"; |
| 225 | |
| 226 | streamfx::util::curl curl; |
| 227 | size_t buffer_offset = 0; |
| 228 | |
| 229 | // Set headers (User-Agent is needed so Github can contact us!). |
| 230 | curl.set_header("User-Agent", "StreamFX Updater v" STREAMFX_VERSION_STRING); |
| 231 | curl.set_header("Accept", "application/vnd.github.v3+json"); |
| 232 | |
| 233 | // Set up request. |
| 234 | curl.set_option(CURLOPT_HTTPGET, true); // GET |
| 235 | curl.set_option(CURLOPT_POST, false); // Not POST |
| 236 | curl.set_option(CURLOPT_URL, ST_API_URL); |
| 237 | curl.set_option(CURLOPT_TIMEOUT, 30); // 10s until we fail. |
| 238 | |
| 239 | // Callbacks |
| 240 | curl.set_write_callback([&buffer, &buffer_offset](void* data, size_t s1, size_t s2) { |
| 241 | size_t size = s1 * s2; |
| 242 | if (buffer.size() < (size + buffer_offset)) |
| 243 | buffer.resize(buffer_offset + size); |
| 244 | |
| 245 | memcpy(buffer.data() + buffer_offset, data, size); |
| 246 | buffer_offset += size; |
| 247 | |
| 248 | return s1 * s2; |
| 249 | }); |
| 250 | //std::bind(&streamfx::updater::task_write_cb, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3) |
| 251 | |
| 252 | // Clear any unknown data and reserve 64KiB of memory. |
| 253 | buffer.clear(); |
| 254 | buffer.reserve(0xFFFF); |
| 255 | |
| 256 | // Finally, execute the request. |
| 257 | D_LOG_DEBUG("Querying for latest releases...", ""); |
| 258 | if (CURLcode res = curl.perform(); res != CURLE_OK) { |
| 259 | D_LOG_ERROR("Performing query failed with error: %s", curl_easy_strerror(res)); |
| 260 | throw std::runtime_error(curl_easy_strerror(res)); |
| 261 | } |
| 262 | |
| 263 | int32_t status_code = 0; |
| 264 | if (CURLcode res = curl.get_info(CURLINFO_HTTP_CODE, status_code); res != CURLE_OK) { |
| 265 | D_LOG_ERROR("Retrieving status code failed with error: %s", curl_easy_strerror(res)); |
| 266 | throw std::runtime_error(curl_easy_strerror(res)); |
| 267 | } |
| 268 | D_LOG_DEBUG("API returned status code %d.", status_code); |
| 269 | |
| 270 | if (status_code != 200) { |
| 271 | D_LOG_ERROR("API returned unexpected status code %d.", status_code); |
| 272 | throw std::runtime_error("Request failed due to one or more reasons."); |
| 273 | } |
| 274 | }; |
| 275 | auto parse_fn = [this](nlohmann::json json) { |
| 276 | // Check if it was parsed as an object. |
| 277 | if (json.type() != nlohmann::json::value_t::array) { |
nothing calls this directly
no test coverage detected