From 512db59c44a70744893ddbaf9ed776e9c910d1ea Mon Sep 17 00:00:00 2001 From: Sean DuBois Date: Thu, 6 Jun 2024 14:27:06 -0400 Subject: [PATCH] obs-webrtc: Do not use curl_easy_nextheader API not available in Ubuntu 22.04 which ships 7.81 this API was first available in 7.83 --- plugins/obs-webrtc/whip-output.cpp | 46 +++++++++++++++++------------- plugins/obs-webrtc/whip-utils.h | 40 +++++++++++++------------- 2 files changed, 46 insertions(+), 40 deletions(-) diff --git a/plugins/obs-webrtc/whip-output.cpp b/plugins/obs-webrtc/whip-output.cpp index 935824ea9..8786fc169 100644 --- a/plugins/obs-webrtc/whip-output.cpp +++ b/plugins/obs-webrtc/whip-output.cpp @@ -362,7 +362,7 @@ bool WHIPOutput::Connect() } std::string read_buffer; - std::vector location_headers; + std::vector http_headers; auto offer_sdp = std::string(peer_connection->localDescription().value()); @@ -379,9 +379,8 @@ bool WHIPOutput::Connect() CURL *c = curl_easy_init(); curl_easy_setopt(c, CURLOPT_WRITEFUNCTION, curl_writefunction); curl_easy_setopt(c, CURLOPT_WRITEDATA, (void *)&read_buffer); - curl_easy_setopt(c, CURLOPT_HEADERFUNCTION, - curl_header_location_function); - curl_easy_setopt(c, CURLOPT_HEADERDATA, (void *)&location_headers); + curl_easy_setopt(c, CURLOPT_HEADERFUNCTION, curl_header_function); + curl_easy_setopt(c, CURLOPT_HEADERDATA, (void *)&http_headers); curl_easy_setopt(c, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(c, CURLOPT_URL, endpoint_url.c_str()); curl_easy_setopt(c, CURLOPT_POST, 1L); @@ -428,7 +427,18 @@ bool WHIPOutput::Connect() long redirect_count = 0; curl_easy_getinfo(c, CURLINFO_REDIRECT_COUNT, &redirect_count); - if (location_headers.size() < static_cast(redirect_count) + 1) { + std::string last_location_header; + size_t location_header_count = 0; + for (auto &http_header : http_headers) { + auto value = value_for_header("location", http_header); + if (value.empty()) + continue; + + location_header_count++; + last_location_header = value; + } + + if (location_header_count < static_cast(redirect_count) + 1) { do_log(LOG_ERROR, "WHIP server did not provide a resource URL via the Location header"); cleanup(); @@ -437,25 +447,21 @@ bool WHIPOutput::Connect() } CURLU *url_builder = curl_url(); - auto last_location_header = location_headers.back(); // Parse Link headers to extract STUN/TURN server configuration URLs - struct curl_header *prev = nullptr; - struct curl_header *h = nullptr; std::vector iceServers; - while ((h = curl_easy_nextheader(c, CURLH_HEADER, 0, prev))) { - if (astrcmpi("Link", h->name) == 0) { - auto value = std::string(h->value); - // Parse multiple links separated by ',' - for (auto end = value.find(","); - end != std::string::npos; end = value.find(",")) { - this->ParseLinkHeader(value.substr(0, end), - iceServers); - value = value.substr(end + 1); - } - this->ParseLinkHeader(value, iceServers); + for (auto &http_header : http_headers) { + auto value = value_for_header("link", http_header); + if (value.empty()) + continue; + + // Parse multiple links separated by ',' + for (auto end = value.find(","); end != std::string::npos; + end = value.find(",")) { + this->ParseLinkHeader(value.substr(0, end), iceServers); + value = value.substr(end + 1); } - prev = h; + this->ParseLinkHeader(value, iceServers); } // If Location header doesn't start with `http` it is a relative URL. diff --git a/plugins/obs-webrtc/whip-utils.h b/plugins/obs-webrtc/whip-utils.h index ed1bd0d10..64338d6ed 100644 --- a/plugins/obs-webrtc/whip-utils.h +++ b/plugins/obs-webrtc/whip-utils.h @@ -26,6 +26,22 @@ static std::string trim_string(const std::string &source) return ret; } +static std::string value_for_header(const std::string &header, + const std::string &val) +{ + if (val.size() <= header.size() || + astrcmpi_n(header.c_str(), val.c_str(), header.size()) != 0) { + return ""; + } + + auto delimiter = val.find_first_of(" "); + if (delimiter == std::string::npos) { + return ""; + } + + return val.substr(delimiter + 1); +} + static size_t curl_writefunction(char *data, size_t size, size_t nmemb, void *priv_data) { @@ -37,28 +53,12 @@ static size_t curl_writefunction(char *data, size_t size, size_t nmemb, return real_size; } -#define LOCATION_HEADER_LENGTH 10 - -static size_t curl_header_location_function(char *data, size_t size, - size_t nmemb, void *priv_data) +static size_t curl_header_function(char *data, size_t size, size_t nmemb, + void *priv_data) { auto header_buffer = static_cast *>(priv_data); - - size_t real_size = size * nmemb; - - if (real_size < LOCATION_HEADER_LENGTH) - return real_size; - - if (!astrcmpi_n(data, "location: ", LOCATION_HEADER_LENGTH)) { - char *val = data + LOCATION_HEADER_LENGTH; - auto header_temp = - std::string(val, real_size - LOCATION_HEADER_LENGTH); - - header_temp = trim_string(header_temp); - header_buffer->push_back(header_temp); - } - - return real_size; + header_buffer->push_back(trim_string(std::string(data, size * nmemb))); + return size * nmemb; } static inline std::string generate_user_agent()