yolobs-studio/UI/remote-text.cpp

201 lines
5.4 KiB
C++
Raw Normal View History

2016-02-23 23:16:51 +00:00
/******************************************************************************
Copyright (C) 2015 by Hugh Bailey <obs.jim@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
#include <curl/curl.h>
#include "obs-app.hpp"
#include "qt-wrappers.hpp"
#include "remote-text.hpp"
using namespace std;
2019-09-22 21:19:10 +00:00
static auto curl_deleter = [](CURL *curl) { curl_easy_cleanup(curl); };
2017-04-19 19:54:15 +00:00
using Curl = unique_ptr<CURL, decltype(curl_deleter)>;
2016-02-23 23:16:51 +00:00
static size_t string_write(char *ptr, size_t size, size_t nmemb, string &str)
{
size_t total = size * nmemb;
if (total)
str.append(ptr, total);
return total;
}
void RemoteTextThread::run()
{
char error[CURL_ERROR_SIZE];
CURLcode code;
string versionString("User-Agent: obs-basic ");
versionString += App()->GetVersionString();
string contentTypeString;
if (!contentType.empty()) {
contentTypeString += "Content-Type: ";
contentTypeString += contentType;
}
Curl curl{curl_easy_init(), curl_deleter};
if (curl) {
struct curl_slist *header = nullptr;
string str;
2019-09-22 21:19:10 +00:00
header = curl_slist_append(header, versionString.c_str());
2016-02-23 23:16:51 +00:00
if (!contentTypeString.empty()) {
header = curl_slist_append(header,
2019-09-22 21:19:10 +00:00
contentTypeString.c_str());
2016-02-23 23:16:51 +00:00
}
2019-07-27 12:47:10 +00:00
for (std::string &h : extraHeaders)
header = curl_slist_append(header, h.c_str());
2016-02-23 23:16:51 +00:00
curl_easy_setopt(curl.get(), CURLOPT_URL, url.c_str());
2019-07-27 12:47:10 +00:00
curl_easy_setopt(curl.get(), CURLOPT_ACCEPT_ENCODING, "");
2019-09-22 21:19:10 +00:00
curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER, header);
curl_easy_setopt(curl.get(), CURLOPT_ERRORBUFFER, error);
2016-02-23 23:16:51 +00:00
curl_easy_setopt(curl.get(), CURLOPT_WRITEFUNCTION,
2019-09-22 21:19:10 +00:00
string_write);
curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA, &str);
2016-02-23 23:16:51 +00:00
2019-07-27 12:47:10 +00:00
if (timeoutSec)
curl_easy_setopt(curl.get(), CURLOPT_TIMEOUT,
2019-09-22 21:19:10 +00:00
timeoutSec);
2019-07-27 12:47:10 +00:00
2016-05-24 19:53:01 +00:00
#if LIBCURL_VERSION_NUM >= 0x072400
// A lot of servers don't yet support ALPN
curl_easy_setopt(curl.get(), CURLOPT_SSL_ENABLE_ALPN, 0);
#endif
2016-02-23 23:16:51 +00:00
if (!postData.empty()) {
curl_easy_setopt(curl.get(), CURLOPT_POSTFIELDS,
2019-09-22 21:19:10 +00:00
postData.c_str());
2016-02-23 23:16:51 +00:00
}
code = curl_easy_perform(curl.get());
if (code != CURLE_OK) {
emit Result(QString(), QT_UTF8(error));
} else {
emit Result(QT_UTF8(str.c_str()), QString());
}
curl_slist_free_all(header);
}
}
2017-04-19 19:54:15 +00:00
static size_t header_write(char *ptr, size_t size, size_t nmemb,
2019-09-22 21:19:10 +00:00
vector<string> &list)
2017-04-19 19:54:15 +00:00
{
string str;
size_t total = size * nmemb;
if (total)
str.append(ptr, total);
if (str.back() == '\n')
str.resize(str.size() - 1);
if (str.back() == '\r')
str.resize(str.size() - 1);
list.push_back(std::move(str));
return total;
}
2019-09-22 21:19:10 +00:00
bool GetRemoteFile(const char *url, std::string &str, std::string &error,
long *responseCode, const char *contentType,
const char *postData, std::vector<std::string> extraHeaders,
std::string *signature, int timeoutSec)
2017-04-19 19:54:15 +00:00
{
vector<string> header_in_list;
char error_in[CURL_ERROR_SIZE];
CURLcode code = CURLE_FAILED_INIT;
error_in[0] = 0;
string versionString("User-Agent: obs-basic ");
versionString += App()->GetVersionString();
string contentTypeString;
if (contentType) {
contentTypeString += "Content-Type: ";
contentTypeString += contentType;
}
Curl curl{curl_easy_init(), curl_deleter};
if (curl) {
struct curl_slist *header = nullptr;
2019-09-22 21:19:10 +00:00
header = curl_slist_append(header, versionString.c_str());
2017-04-19 19:54:15 +00:00
if (!contentTypeString.empty()) {
header = curl_slist_append(header,
2019-09-22 21:19:10 +00:00
contentTypeString.c_str());
2017-04-19 19:54:15 +00:00
}
for (std::string &h : extraHeaders)
header = curl_slist_append(header, h.c_str());
curl_easy_setopt(curl.get(), CURLOPT_URL, url);
2019-07-27 12:47:10 +00:00
curl_easy_setopt(curl.get(), CURLOPT_ACCEPT_ENCODING, "");
2019-09-22 21:19:10 +00:00
curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER, header);
curl_easy_setopt(curl.get(), CURLOPT_ERRORBUFFER, error_in);
2017-04-19 19:54:15 +00:00
curl_easy_setopt(curl.get(), CURLOPT_WRITEFUNCTION,
2019-09-22 21:19:10 +00:00
string_write);
curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA, &str);
2017-04-19 19:54:15 +00:00
if (signature) {
curl_easy_setopt(curl.get(), CURLOPT_HEADERFUNCTION,
2019-09-22 21:19:10 +00:00
header_write);
2017-04-19 19:54:15 +00:00
curl_easy_setopt(curl.get(), CURLOPT_HEADERDATA,
2019-09-22 21:19:10 +00:00
&header_in_list);
2017-04-19 19:54:15 +00:00
}
2019-07-27 12:47:10 +00:00
if (timeoutSec)
curl_easy_setopt(curl.get(), CURLOPT_TIMEOUT,
2019-09-22 21:19:10 +00:00
timeoutSec);
2019-07-27 12:47:10 +00:00
2017-04-19 19:54:15 +00:00
#if LIBCURL_VERSION_NUM >= 0x072400
// A lot of servers don't yet support ALPN
curl_easy_setopt(curl.get(), CURLOPT_SSL_ENABLE_ALPN, 0);
#endif
if (postData) {
curl_easy_setopt(curl.get(), CURLOPT_POSTFIELDS,
2019-09-22 21:19:10 +00:00
postData);
2017-04-19 19:54:15 +00:00
}
code = curl_easy_perform(curl.get());
if (responseCode)
curl_easy_getinfo(curl.get(), CURLINFO_RESPONSE_CODE,
2019-09-22 21:19:10 +00:00
responseCode);
2017-04-19 19:54:15 +00:00
if (code != CURLE_OK) {
error = error_in;
} else if (signature) {
for (string &h : header_in_list) {
string name = h.substr(0, 13);
if (name == "X-Signature: ") {
*signature = h.substr(13);
break;
}
}
}
curl_slist_free_all(header);
}
return code == CURLE_OK;
}