From 7698567fc9b9d0b009264d5d8ab5babc3ea197d8 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 26 Aug 2017 19:02:03 -0400 Subject: web_backend: Fix CPR bug where Winsock is not properly initializing. --- src/web_service/web_backend.cpp | 42 ++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) (limited to 'src/web_service') diff --git a/src/web_service/web_backend.cpp b/src/web_service/web_backend.cpp index a6070fc0f..d28a3f757 100644 --- a/src/web_service/web_backend.cpp +++ b/src/web_service/web_backend.cpp @@ -2,6 +2,10 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#ifdef _WIN32 +#include +#endif + #include #include #include @@ -12,18 +16,7 @@ namespace WebService { static constexpr char API_VERSION[]{"1"}; -static void PostJsonAuthenticated(const std::string& url, const std::string& data, - const std::string& username, const std::string& token) { - cpr::Post(cpr::Url{url}, cpr::Body{data}, cpr::Header{{"Content-Type", "application/json"}, - {"x-username", username}, - {"x-token", token}, - {"api-version", API_VERSION}}); -} - -static void PostJsonAnonymous(const std::string& url, const std::string& data) { - cpr::Post(cpr::Url{url}, cpr::Body{data}, - cpr::Header{{"Content-Type", "application/json"}, {"api-version", API_VERSION}}); -} +static std::unique_ptr g_session; void PostJson(const std::string& url, const std::string& data, bool allow_anonymous, const std::string& username, const std::string& token) { @@ -38,14 +31,33 @@ void PostJson(const std::string& url, const std::string& data, bool allow_anonym return; } - // Post JSON asynchronously by spawning a new thread +#ifdef _WIN32 + // On Windows, CPR/libcurl does not properly initialize Winsock. The below code is used to + // initialize Winsock globally, which fixes this problem. Without this, only the first CPR + // session will properly be created, and subsequent ones will fail. + WSADATA wsa_data; + const int wsa_result{WSAStartup(MAKEWORD(2, 2), &wsa_data)}; + if (wsa_result) { + LOG_CRITICAL(WebService, "WSAStartup failed: %d", wsa_result); + } +#endif + + // Built request header + cpr::Header header; if (are_credentials_provided) { // Authenticated request if credentials are provided - std::thread{PostJsonAuthenticated, url, data, username, token}.detach(); + header = {{"Content-Type", "application/json"}, + {"x-username", username.c_str()}, + {"x-token", token.c_str()}, + {"api-version", API_VERSION}}; } else { // Otherwise, anonymous request - std::thread{PostJsonAnonymous, url, data}.detach(); + header = cpr::Header{{"Content-Type", "application/json"}, {"api-version", API_VERSION}}; } + + // Post JSON asynchronously + static cpr::AsyncResponse future; + future = cpr::PostAsync(cpr::Url{url.c_str()}, cpr::Body{data.c_str()}, header); } } // namespace WebService -- cgit v1.2.3