|
@@ -22,6 +22,9 @@
|
|
|
|
|
|
using namespace std;
|
|
using namespace std;
|
|
|
|
|
|
|
|
+static auto curl_deleter = [] (CURL *curl) {curl_easy_cleanup(curl);};
|
|
|
|
+using Curl = unique_ptr<CURL, decltype(curl_deleter)>;
|
|
|
|
+
|
|
static size_t string_write(char *ptr, size_t size, size_t nmemb, string &str)
|
|
static size_t string_write(char *ptr, size_t size, size_t nmemb, string &str)
|
|
{
|
|
{
|
|
size_t total = size * nmemb;
|
|
size_t total = size * nmemb;
|
|
@@ -45,9 +48,6 @@ void RemoteTextThread::run()
|
|
contentTypeString += contentType;
|
|
contentTypeString += contentType;
|
|
}
|
|
}
|
|
|
|
|
|
- auto curl_deleter = [] (CURL *curl) {curl_easy_cleanup(curl);};
|
|
|
|
- using Curl = unique_ptr<CURL, decltype(curl_deleter)>;
|
|
|
|
-
|
|
|
|
Curl curl{curl_easy_init(), curl_deleter};
|
|
Curl curl{curl_easy_init(), curl_deleter};
|
|
if (curl) {
|
|
if (curl) {
|
|
struct curl_slist *header = nullptr;
|
|
struct curl_slist *header = nullptr;
|
|
@@ -91,3 +91,110 @@ void RemoteTextThread::run()
|
|
curl_slist_free_all(header);
|
|
curl_slist_free_all(header);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+static size_t header_write(char *ptr, size_t size, size_t nmemb,
|
|
|
|
+ vector<string> &list)
|
|
|
|
+{
|
|
|
|
+ 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;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+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)
|
|
|
|
+{
|
|
|
|
+ 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;
|
|
|
|
+
|
|
|
|
+ header = curl_slist_append(header,
|
|
|
|
+ versionString.c_str());
|
|
|
|
+
|
|
|
|
+ if (!contentTypeString.empty()) {
|
|
|
|
+ header = curl_slist_append(header,
|
|
|
|
+ contentTypeString.c_str());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (std::string &h : extraHeaders)
|
|
|
|
+ header = curl_slist_append(header, h.c_str());
|
|
|
|
+
|
|
|
|
+ curl_easy_setopt(curl.get(), CURLOPT_URL, url);
|
|
|
|
+ curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER,
|
|
|
|
+ header);
|
|
|
|
+ curl_easy_setopt(curl.get(), CURLOPT_ERRORBUFFER,
|
|
|
|
+ error_in);
|
|
|
|
+ curl_easy_setopt(curl.get(), CURLOPT_WRITEFUNCTION,
|
|
|
|
+ string_write);
|
|
|
|
+ curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA,
|
|
|
|
+ &str);
|
|
|
|
+ if (signature) {
|
|
|
|
+ curl_easy_setopt(curl.get(), CURLOPT_HEADERFUNCTION,
|
|
|
|
+ header_write);
|
|
|
|
+ curl_easy_setopt(curl.get(), CURLOPT_HEADERDATA,
|
|
|
|
+ &header_in_list);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+#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,
|
|
|
|
+ postData);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ code = curl_easy_perform(curl.get());
|
|
|
|
+ if (responseCode)
|
|
|
|
+ curl_easy_getinfo(curl.get(), CURLINFO_RESPONSE_CODE,
|
|
|
|
+ responseCode);
|
|
|
|
+
|
|
|
|
+ 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;
|
|
|
|
+}
|