diff --git a/include/dpp/httpsclient.h b/include/dpp/httpsclient.h index 09bbd8453d..c2733b0b04 100644 --- a/include/dpp/httpsclient.h +++ b/include/dpp/httpsclient.h @@ -27,9 +27,17 @@ #include #include #include +#include +#include namespace dpp { +static inline const std::string http_version = "DiscordBot (https://github.com/brainboxdotcc/DPP, " + + to_hex(DPP_VERSION_MAJOR, false) + "." + + to_hex(DPP_VERSION_MINOR, false) + "." + + to_hex(DPP_VERSION_PATCH, false) + ")"; + +static inline constexpr const char* DISCORD_HOST = "https://discord.com"; /** * @brief HTTP connection status diff --git a/src/dpp/discordvoiceclient.cpp b/src/dpp/discordvoiceclient.cpp index 833a2dc0a8..3f8dc7201c 100644 --- a/src/dpp/discordvoiceclient.cpp +++ b/src/dpp/discordvoiceclient.cpp @@ -404,11 +404,35 @@ bool discord_voice_client::is_playing() { void discord_voice_client::thread_run() { utility::set_thread_name(std::string("vc/") + std::to_string(server_id)); + + size_t times_looped = 0; + time_t last_loop_time = time(nullptr); + do { bool error = false; ssl_client::read_loop(); ssl_client::close(); + + time_t current_time = time(nullptr); + /* Here, we check if it's been longer than 3 seconds since the previous loop, + * this gives us time to see if it's an actual disconnect, or an error. + * This will prevent us from looping too much, meaning error codes do not cause an infinite loop. + */ + if(current_time - last_loop_time >= 3) + times_looped = 0; + + /* This does mean we'll always have times_looped at a minimum of 1, this is intended. */ + times_looped++; + /* If we've looped 5 or more times, abort the loop. */ + if(times_looped >= 5) { + log(dpp::ll_warning, "Reached max loops whilst attempting to read from the websocket. Aborting websocket."); + break; + } + + last_loop_time = current_time; + if (!terminating) { + log(dpp::ll_debug, "Attempting to reconnect the websocket..."); do { try { ssl_client::connect(); diff --git a/src/dpp/queues.cpp b/src/dpp/queues.cpp index 2c7fed5af2..4625020a46 100644 --- a/src/dpp/queues.cpp +++ b/src/dpp/queues.cpp @@ -29,13 +29,9 @@ #include #include #include -#include namespace dpp { -static std::string http_version = "DiscordBot (https://github.com/brainboxdotcc/DPP, " + std::to_string(DPP_VERSION_MAJOR) + "." + std::to_string(DPP_VERSION_MINOR) + "." + std::to_string(DPP_VERSION_PATCH) + ")"; -static const char* DISCORD_HOST = "https://discord.com"; - http_request::http_request(const std::string &_endpoint, const std::string &_parameters, http_completion_event completion, const std::string &_postdata, http_method _method, const std::string &audit_reason, const std::string &filename, const std::string &filecontent, const std::string &filemimetype) : complete_handler(completion), completed(false), non_discord(false), endpoint(_endpoint), parameters(_parameters), postdata(_postdata), method(_method), reason(audit_reason), mimetype("application/json"), waiting(false) { diff --git a/src/dpp/sslclient.cpp b/src/dpp/sslclient.cpp index 3bf3f948bf..a3dc1c40be 100644 --- a/src/dpp/sslclient.cpp +++ b/src/dpp/sslclient.cpp @@ -504,6 +504,27 @@ void ssl_client::read_loop() case SSL_ERROR_NONE: /* Data received, add it to the buffer */ if (r > 0) { + const std::string data(server_to_client_buffer, r); + /* Split the data into an array for every line. */ + const std::vector data_lines = utility::tokenize(data); + /* Get the first line as we always know that's the HTTP response. */ + const std::string http_reponse(data_lines[0]); + + /* Does the first line begin with a http code? */ + if(http_reponse.rfind("HTTP/1.1", 0) != std::string::npos) { + /* Now let's split the first line by every space, meaning we can check the actual HTTP code. */ + const std::vector line_split_by_space = utility::tokenize(data_lines[0], " "); + + /* We need to make sure there's at least 3 elements in line_split_by_space. */ + if(line_split_by_space.size() >= 3) { + const int http_code = std::stoi(line_split_by_space[1]); + + /* If the http_code isn't 204, 101, or 200, log it. */ + if(http_code != 204 && http_code != 101 && http_code != 200) + log(ll_warning, "Received unhandled code: " + http_reponse); + } + } + buffer.append(server_to_client_buffer, r); if (!this->handle_buffer(buffer)) { return; diff --git a/src/dpp/utility.cpp b/src/dpp/utility.cpp index 8a28201c33..04db275526 100644 --- a/src/dpp/utility.cpp +++ b/src/dpp/utility.cpp @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include diff --git a/src/dpp/wsclient.cpp b/src/dpp/wsclient.cpp index 38465cf2d1..d23f6742af 100644 --- a/src/dpp/wsclient.cpp +++ b/src/dpp/wsclient.cpp @@ -24,6 +24,7 @@ #include #include #include +#include namespace dpp { @@ -52,7 +53,7 @@ void websocket_client::connect() "GET " + this->path + " HTTP/1.1\r\n" "Host: " + this->hostname + "\r\n" "pragma: no-cache\r\n" - "User-Agent: DPP/0.1\r\n" + "User-Agent: " + http_version + "\r\n" "Upgrade: WebSocket\r\n" "Connection: Upgrade\r\n" "Sec-WebSocket-Key: " + this->key + "\r\n"