607 lines
22 KiB
C++
607 lines
22 KiB
C++
#include "http_client.h"
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <sstream>
|
|
|
|
#ifdef WINDOWS
|
|
#include <windows.h>
|
|
#include <winhttp.h>
|
|
#pragma comment(lib, "winhttp.lib")
|
|
static std::string last_winhttp_error(const char* where) {
|
|
DWORD err = GetLastError();
|
|
LPVOID lpMsgBuf = nullptr;
|
|
FormatMessageA(
|
|
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
NULL,
|
|
err,
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
(LPSTR)&lpMsgBuf,
|
|
0, NULL);
|
|
std::ostringstream os;
|
|
os << "[WinHTTP] " << where << " failed, error=" << err;
|
|
if (lpMsgBuf) {
|
|
os << ": " << (char*)lpMsgBuf;
|
|
LocalFree(lpMsgBuf);
|
|
}
|
|
return os.str();
|
|
}
|
|
|
|
static std::wstring utf8_to_wide(const std::string& s) {
|
|
if (s.empty()) return std::wstring();
|
|
int needed = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), (int)s.size(), nullptr, 0);
|
|
std::wstring ws(needed, L'\0');
|
|
MultiByteToWideChar(CP_UTF8, 0, s.c_str(), (int)s.size(), &ws[0], needed);
|
|
return ws;
|
|
}
|
|
#elif LINUX
|
|
#include <curl/curl.h>
|
|
#endif
|
|
|
|
#ifdef WINDOWS
|
|
|
|
struct WinHttpData {
|
|
std::string data;
|
|
size_t size;
|
|
};
|
|
|
|
static size_t WinHttpWriteCallback(void* contents, size_t size, size_t nmemb, WinHttpData* data) {
|
|
size_t realsize = size * nmemb;
|
|
data->data.append((char*)contents, realsize);
|
|
data->size += realsize;
|
|
return realsize;
|
|
}
|
|
|
|
bool HttpClient::get(const std::string& url, std::string& response) {
|
|
// Parse URL
|
|
URL_COMPONENTS urlComp;
|
|
ZeroMemory(&urlComp, sizeof(urlComp));
|
|
urlComp.dwStructSize = sizeof(urlComp);
|
|
|
|
// Set required component lengths to non-zero to indicate they exist
|
|
urlComp.dwHostNameLength = (DWORD)-1;
|
|
urlComp.dwUrlPathLength = (DWORD)-1;
|
|
urlComp.dwExtraInfoLength = (DWORD)-1;
|
|
|
|
// Parse the URL
|
|
std::wstring wurl = utf8_to_wide(url);
|
|
if (!WinHttpCrackUrl(wurl.c_str(), 0, 0, &urlComp)) {
|
|
return false;
|
|
}
|
|
|
|
// Use WinHttpOpen to obtain a session handle
|
|
HINTERNET hSession = WinHttpOpen(L"PrivateBin API Client/1.0",
|
|
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
|
|
WINHTTP_NO_PROXY_NAME,
|
|
WINHTTP_NO_PROXY_BYPASS, 0);
|
|
|
|
if (!hSession) {
|
|
std::cerr << last_winhttp_error("WinHttpOpen(GET)") << std::endl;
|
|
return false;
|
|
}
|
|
// Force modern TLS versions to avoid handshake failures on some hosts
|
|
DWORD protocols = WINHTTP_FLAG_SECURE_PROTOCOL_TLS1 | WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1 |
|
|
WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2 | 0x00002000 /* TLS1_3 if available */;
|
|
WinHttpSetOption(hSession, WINHTTP_OPTION_SECURE_PROTOCOLS, &protocols, sizeof(protocols));
|
|
// Disable HTTP/2 if it causes issues
|
|
#ifdef WINHTTP_DISABLE_FEATURE_HTTP2
|
|
DWORD features = WINHTTP_DISABLE_FEATURE_HTTP2;
|
|
WinHttpSetOption(hSession, WINHTTP_OPTION_DISABLE_FEATURE, &features, sizeof(features));
|
|
#endif
|
|
|
|
// Specify an HTTP server (host must be null-terminated; urlComp provides length)
|
|
std::wstring host = (urlComp.lpszHostName && urlComp.dwHostNameLength > 0)
|
|
? std::wstring(urlComp.lpszHostName, urlComp.dwHostNameLength)
|
|
: std::wstring();
|
|
INTERNET_PORT port = urlComp.nPort ? urlComp.nPort : ((urlComp.nScheme == INTERNET_SCHEME_HTTPS) ? INTERNET_DEFAULT_HTTPS_PORT : INTERNET_DEFAULT_HTTP_PORT);
|
|
HINTERNET hConnect = WinHttpConnect(hSession, host.c_str(), port, 0);
|
|
|
|
if (!hConnect) {
|
|
std::cerr << last_winhttp_error("WinHttpConnect(GET)") << std::endl;
|
|
WinHttpCloseHandle(hSession);
|
|
return false;
|
|
}
|
|
|
|
// Build object name = path + extra info (query)
|
|
std::wstring pathPart = (urlComp.lpszUrlPath && urlComp.dwUrlPathLength > 0)
|
|
? std::wstring(urlComp.lpszUrlPath, urlComp.dwUrlPathLength)
|
|
: std::wstring(L"/");
|
|
std::wstring extraPart = (urlComp.lpszExtraInfo && urlComp.dwExtraInfoLength > 0)
|
|
? std::wstring(urlComp.lpszExtraInfo, urlComp.dwExtraInfoLength)
|
|
: std::wstring();
|
|
std::wstring objectName = pathPart + extraPart;
|
|
|
|
// Create an HTTP request handle
|
|
HINTERNET hRequest = WinHttpOpenRequest(hConnect, L"GET",
|
|
objectName.c_str(),
|
|
NULL, WINHTTP_NO_REFERER,
|
|
WINHTTP_DEFAULT_ACCEPT_TYPES,
|
|
(urlComp.nScheme == INTERNET_SCHEME_HTTPS) ?
|
|
WINHTTP_FLAG_SECURE : 0);
|
|
// Set headers per API requirement
|
|
LPCWSTR headers = L"X-Requested-With: JSONHttpRequest\r\nAccept: application/json";
|
|
if (!WinHttpAddRequestHeaders(hRequest, headers, -1L, WINHTTP_ADDREQ_FLAG_ADD)) {
|
|
std::cerr << last_winhttp_error("WinHttpAddRequestHeaders(GET)") << std::endl;
|
|
}
|
|
|
|
if (!hRequest) {
|
|
WinHttpCloseHandle(hConnect);
|
|
WinHttpCloseHandle(hSession);
|
|
return false;
|
|
}
|
|
|
|
// Send a request
|
|
if (!WinHttpSendRequest(hRequest,
|
|
WINHTTP_NO_ADDITIONAL_HEADERS, 0,
|
|
WINHTTP_NO_REQUEST_DATA, 0,
|
|
0, 0)) {
|
|
std::cerr << last_winhttp_error("WinHttpSendRequest(GET)") << std::endl;
|
|
WinHttpCloseHandle(hRequest);
|
|
WinHttpCloseHandle(hConnect);
|
|
WinHttpCloseHandle(hSession);
|
|
return false;
|
|
}
|
|
|
|
// End the request
|
|
if (!WinHttpReceiveResponse(hRequest, NULL)) {
|
|
std::cerr << last_winhttp_error("WinHttpReceiveResponse(GET)") << std::endl;
|
|
WinHttpCloseHandle(hRequest);
|
|
WinHttpCloseHandle(hConnect);
|
|
WinHttpCloseHandle(hSession);
|
|
return false;
|
|
}
|
|
|
|
// Keep checking for data until there is nothing left
|
|
DWORD dwSize = 0;
|
|
DWORD dwDownloaded = 0;
|
|
std::string result;
|
|
|
|
do {
|
|
// Check for available data
|
|
dwSize = 0;
|
|
if (!WinHttpQueryDataAvailable(hRequest, &dwSize)) {
|
|
std::cerr << last_winhttp_error("WinHttpQueryDataAvailable(GET)") << std::endl;
|
|
WinHttpCloseHandle(hRequest);
|
|
WinHttpCloseHandle(hConnect);
|
|
WinHttpCloseHandle(hSession);
|
|
return false;
|
|
}
|
|
|
|
// Allocate space for the buffer
|
|
char* pszOutBuffer = new char[dwSize + 1];
|
|
if (!pszOutBuffer) {
|
|
WinHttpCloseHandle(hRequest);
|
|
WinHttpCloseHandle(hConnect);
|
|
WinHttpCloseHandle(hSession);
|
|
return false;
|
|
}
|
|
|
|
// Read the data
|
|
ZeroMemory(pszOutBuffer, dwSize + 1);
|
|
if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded)) {
|
|
std::cerr << last_winhttp_error("WinHttpReadData(GET)") << std::endl;
|
|
delete[] pszOutBuffer;
|
|
WinHttpCloseHandle(hRequest);
|
|
WinHttpCloseHandle(hConnect);
|
|
WinHttpCloseHandle(hSession);
|
|
return false;
|
|
}
|
|
else {
|
|
result.append(pszOutBuffer);
|
|
}
|
|
|
|
// Free the memory
|
|
delete[] pszOutBuffer;
|
|
|
|
} while (dwSize > 0);
|
|
|
|
response = result;
|
|
|
|
// Close any open handles
|
|
WinHttpCloseHandle(hRequest);
|
|
WinHttpCloseHandle(hConnect);
|
|
WinHttpCloseHandle(hSession);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool HttpClient::post(const std::string& url, const std::string& data, std::string& response) {
|
|
// Parse URL
|
|
URL_COMPONENTS urlComp;
|
|
ZeroMemory(&urlComp, sizeof(urlComp));
|
|
urlComp.dwStructSize = sizeof(urlComp);
|
|
|
|
// Set required component lengths to non-zero to indicate they exist
|
|
urlComp.dwHostNameLength = (DWORD)-1;
|
|
urlComp.dwUrlPathLength = (DWORD)-1;
|
|
urlComp.dwExtraInfoLength = (DWORD)-1;
|
|
|
|
// Parse the URL
|
|
std::wstring wurl = utf8_to_wide(url);
|
|
if (!WinHttpCrackUrl(wurl.c_str(), 0, 0, &urlComp)) {
|
|
return false;
|
|
}
|
|
|
|
// Use WinHttpOpen to obtain a session handle
|
|
HINTERNET hSession = WinHttpOpen(L"PrivateBin API Client/1.0",
|
|
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
|
|
WINHTTP_NO_PROXY_NAME,
|
|
WINHTTP_NO_PROXY_BYPASS, 0);
|
|
|
|
if (!hSession) {
|
|
std::cerr << last_winhttp_error("WinHttpOpen(POST)") << std::endl;
|
|
return false;
|
|
}
|
|
DWORD protocols2 = WINHTTP_FLAG_SECURE_PROTOCOL_TLS1 | WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1 |
|
|
WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2 | 0x00002000;
|
|
WinHttpSetOption(hSession, WINHTTP_OPTION_SECURE_PROTOCOLS, &protocols2, sizeof(protocols2));
|
|
#ifdef WINHTTP_DISABLE_FEATURE_HTTP2
|
|
DWORD features2 = WINHTTP_DISABLE_FEATURE_HTTP2;
|
|
WinHttpSetOption(hSession, WINHTTP_OPTION_DISABLE_FEATURE, &features2, sizeof(features2));
|
|
#endif
|
|
|
|
// Specify an HTTP server (ensure host is null-terminated)
|
|
std::wstring host2 = (urlComp.lpszHostName && urlComp.dwHostNameLength > 0)
|
|
? std::wstring(urlComp.lpszHostName, urlComp.dwHostNameLength)
|
|
: std::wstring();
|
|
INTERNET_PORT port2 = urlComp.nPort ? urlComp.nPort : ((urlComp.nScheme == INTERNET_SCHEME_HTTPS) ? INTERNET_DEFAULT_HTTPS_PORT : INTERNET_DEFAULT_HTTP_PORT);
|
|
HINTERNET hConnect = WinHttpConnect(hSession, host2.c_str(), port2, 0);
|
|
|
|
if (!hConnect) {
|
|
std::cerr << last_winhttp_error("WinHttpConnect(POST)") << std::endl;
|
|
WinHttpCloseHandle(hSession);
|
|
return false;
|
|
}
|
|
|
|
// Create an HTTP request handle (POST per API 1.3)
|
|
LPCWSTR postPath = (urlComp.lpszUrlPath && urlComp.dwUrlPathLength > 0) ? urlComp.lpszUrlPath : L"/";
|
|
HINTERNET hRequest = WinHttpOpenRequest(hConnect, L"POST",
|
|
postPath,
|
|
NULL, WINHTTP_NO_REFERER,
|
|
WINHTTP_DEFAULT_ACCEPT_TYPES,
|
|
(urlComp.nScheme == INTERNET_SCHEME_HTTPS) ?
|
|
WINHTTP_FLAG_SECURE : 0);
|
|
|
|
if (!hRequest) {
|
|
std::cerr << "[WinHTTP] WinHttpOpenRequest(POST) failed" << std::endl;
|
|
WinHttpCloseHandle(hConnect);
|
|
WinHttpCloseHandle(hSession);
|
|
return false;
|
|
}
|
|
|
|
// Set headers
|
|
LPCWSTR headers = L"Content-Type: application/json\r\nX-Requested-With: JSONHttpRequest";
|
|
BOOL bResults = WinHttpAddRequestHeaders(hRequest,
|
|
headers,
|
|
-1L,
|
|
WINHTTP_ADDREQ_FLAG_ADD);
|
|
|
|
if (!bResults) {
|
|
std::cerr << last_winhttp_error("WinHttpAddRequestHeaders(POST)") << std::endl;
|
|
WinHttpCloseHandle(hRequest);
|
|
WinHttpCloseHandle(hConnect);
|
|
WinHttpCloseHandle(hSession);
|
|
return false;
|
|
}
|
|
|
|
// Send a request
|
|
// Send UTF-8 bytes as body (raw)
|
|
if (!WinHttpSendRequest(hRequest,
|
|
WINHTTP_NO_ADDITIONAL_HEADERS, 0,
|
|
(LPVOID)data.c_str(), (DWORD)data.length(),
|
|
(DWORD)data.length(), 0)) {
|
|
std::cerr << last_winhttp_error("WinHttpSendRequest(POST)") << std::endl;
|
|
WinHttpCloseHandle(hRequest);
|
|
WinHttpCloseHandle(hConnect);
|
|
WinHttpCloseHandle(hSession);
|
|
return false;
|
|
}
|
|
|
|
// End the request
|
|
if (!WinHttpReceiveResponse(hRequest, NULL)) {
|
|
std::cerr << last_winhttp_error("WinHttpReceiveResponse(POST)") << std::endl;
|
|
WinHttpCloseHandle(hRequest);
|
|
WinHttpCloseHandle(hConnect);
|
|
WinHttpCloseHandle(hSession);
|
|
return false;
|
|
}
|
|
|
|
// Keep checking for data until there is nothing left
|
|
DWORD dwSize = 0;
|
|
DWORD dwDownloaded = 0;
|
|
std::string result;
|
|
|
|
do {
|
|
// Check for available data
|
|
dwSize = 0;
|
|
if (!WinHttpQueryDataAvailable(hRequest, &dwSize)) {
|
|
std::cerr << last_winhttp_error("WinHttpQueryDataAvailable(POST)") << std::endl;
|
|
WinHttpCloseHandle(hRequest);
|
|
WinHttpCloseHandle(hConnect);
|
|
WinHttpCloseHandle(hSession);
|
|
return false;
|
|
}
|
|
|
|
// Allocate space for the buffer
|
|
char* pszOutBuffer = new char[dwSize + 1];
|
|
if (!pszOutBuffer) {
|
|
WinHttpCloseHandle(hRequest);
|
|
WinHttpCloseHandle(hConnect);
|
|
WinHttpCloseHandle(hSession);
|
|
return false;
|
|
}
|
|
|
|
// Read the data
|
|
ZeroMemory(pszOutBuffer, dwSize + 1);
|
|
if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded)) {
|
|
std::cerr << last_winhttp_error("WinHttpReadData(POST)") << std::endl;
|
|
delete[] pszOutBuffer;
|
|
WinHttpCloseHandle(hRequest);
|
|
WinHttpCloseHandle(hConnect);
|
|
WinHttpCloseHandle(hSession);
|
|
return false;
|
|
}
|
|
else {
|
|
result.append(pszOutBuffer);
|
|
}
|
|
|
|
// Free the memory
|
|
delete[] pszOutBuffer;
|
|
|
|
} while (dwSize > 0);
|
|
|
|
response = result;
|
|
|
|
// Close any open handles
|
|
WinHttpCloseHandle(hRequest);
|
|
WinHttpCloseHandle(hConnect);
|
|
WinHttpCloseHandle(hSession);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool HttpClient::delete_req(const std::string& url, const std::string& data, std::string& response) {
|
|
// Parse URL
|
|
URL_COMPONENTS urlComp;
|
|
ZeroMemory(&urlComp, sizeof(urlComp));
|
|
urlComp.dwStructSize = sizeof(urlComp);
|
|
|
|
// Set required component lengths to non-zero to indicate they exist
|
|
urlComp.dwHostNameLength = (DWORD)-1;
|
|
urlComp.dwUrlPathLength = (DWORD)-1;
|
|
urlComp.dwExtraInfoLength = (DWORD)-1;
|
|
|
|
// Parse the URL
|
|
std::wstring wurlDel = utf8_to_wide(url);
|
|
if (!WinHttpCrackUrl(wurlDel.c_str(), 0, 0, &urlComp)) {
|
|
return false;
|
|
}
|
|
|
|
// Use WinHttpOpen to obtain a session handle
|
|
HINTERNET hSession = WinHttpOpen(L"PrivateBin API Client/1.0",
|
|
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
|
|
WINHTTP_NO_PROXY_NAME,
|
|
WINHTTP_NO_PROXY_BYPASS, 0);
|
|
|
|
if (!hSession) {
|
|
std::cerr << last_winhttp_error("WinHttpOpen(DEL)") << std::endl;
|
|
return false;
|
|
}
|
|
DWORD protocols3 = WINHTTP_FLAG_SECURE_PROTOCOL_TLS1 | WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1 |
|
|
WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2 | 0x00002000;
|
|
WinHttpSetOption(hSession, WINHTTP_OPTION_SECURE_PROTOCOLS, &protocols3, sizeof(protocols3));
|
|
#ifdef WINHTTP_DISABLE_FEATURE_HTTP2
|
|
DWORD features3 = WINHTTP_DISABLE_FEATURE_HTTP2;
|
|
WinHttpSetOption(hSession, WINHTTP_OPTION_DISABLE_FEATURE, &features3, sizeof(features3));
|
|
#endif
|
|
|
|
// Specify an HTTP server (ensure host is null-terminated)
|
|
std::wstring host3 = (urlComp.lpszHostName && urlComp.dwHostNameLength > 0)
|
|
? std::wstring(urlComp.lpszHostName, urlComp.dwHostNameLength)
|
|
: std::wstring();
|
|
INTERNET_PORT port3 = urlComp.nPort ? urlComp.nPort : ((urlComp.nScheme == INTERNET_SCHEME_HTTPS) ? INTERNET_DEFAULT_HTTPS_PORT : INTERNET_DEFAULT_HTTP_PORT);
|
|
HINTERNET hConnect = WinHttpConnect(hSession, host3.c_str(), port3, 0);
|
|
|
|
if (!hConnect) {
|
|
std::cerr << last_winhttp_error("WinHttpConnect(DEL)") << std::endl;
|
|
WinHttpCloseHandle(hSession);
|
|
return false;
|
|
}
|
|
|
|
// Create an HTTP request handle
|
|
LPCWSTR delPath = (urlComp.lpszUrlPath && urlComp.dwUrlPathLength > 0) ? urlComp.lpszUrlPath : L"/";
|
|
HINTERNET hRequest = WinHttpOpenRequest(hConnect, L"POST",
|
|
delPath,
|
|
NULL, WINHTTP_NO_REFERER,
|
|
WINHTTP_DEFAULT_ACCEPT_TYPES,
|
|
(urlComp.nScheme == INTERNET_SCHEME_HTTPS) ?
|
|
WINHTTP_FLAG_SECURE : 0);
|
|
|
|
if (!hRequest) {
|
|
std::cerr << "[WinHTTP] WinHttpOpenRequest(DEL) failed" << std::endl;
|
|
WinHttpCloseHandle(hConnect);
|
|
WinHttpCloseHandle(hSession);
|
|
return false;
|
|
}
|
|
|
|
// Set headers
|
|
LPCWSTR headers = L"Content-Type: application/json\r\nX-Requested-With: JSONHttpRequest";
|
|
BOOL bResults = WinHttpAddRequestHeaders(hRequest,
|
|
headers,
|
|
-1L,
|
|
WINHTTP_ADDREQ_FLAG_ADD);
|
|
|
|
if (!bResults) {
|
|
std::cerr << last_winhttp_error("WinHttpAddRequestHeaders(DEL)") << std::endl;
|
|
WinHttpCloseHandle(hRequest);
|
|
WinHttpCloseHandle(hConnect);
|
|
WinHttpCloseHandle(hSession);
|
|
return false;
|
|
}
|
|
|
|
// Send a request body with DELETE method
|
|
if (!WinHttpSendRequest(hRequest,
|
|
WINHTTP_NO_ADDITIONAL_HEADERS, 0,
|
|
(LPVOID)data.c_str(), (DWORD)data.length(),
|
|
(DWORD)data.length(), 0)) {
|
|
std::cerr << last_winhttp_error("WinHttpSendRequest(DEL)") << std::endl;
|
|
WinHttpCloseHandle(hRequest);
|
|
WinHttpCloseHandle(hConnect);
|
|
WinHttpCloseHandle(hSession);
|
|
return false;
|
|
}
|
|
|
|
// End the request
|
|
if (!WinHttpReceiveResponse(hRequest, NULL)) {
|
|
std::cerr << last_winhttp_error("WinHttpReceiveResponse(DEL)") << std::endl;
|
|
WinHttpCloseHandle(hRequest);
|
|
WinHttpCloseHandle(hConnect);
|
|
WinHttpCloseHandle(hSession);
|
|
return false;
|
|
}
|
|
|
|
// Keep checking for data until there is nothing left
|
|
DWORD dwSize = 0;
|
|
DWORD dwDownloaded = 0;
|
|
std::string result;
|
|
|
|
do {
|
|
// Check for available data
|
|
dwSize = 0;
|
|
if (!WinHttpQueryDataAvailable(hRequest, &dwSize)) {
|
|
std::cerr << last_winhttp_error("WinHttpQueryDataAvailable(DEL)") << std::endl;
|
|
WinHttpCloseHandle(hRequest);
|
|
WinHttpCloseHandle(hConnect);
|
|
WinHttpCloseHandle(hSession);
|
|
return false;
|
|
}
|
|
|
|
// Allocate space for the buffer
|
|
char* pszOutBuffer = new char[dwSize + 1];
|
|
if (!pszOutBuffer) {
|
|
WinHttpCloseHandle(hRequest);
|
|
WinHttpCloseHandle(hConnect);
|
|
WinHttpCloseHandle(hSession);
|
|
return false;
|
|
}
|
|
|
|
// Read the data
|
|
ZeroMemory(pszOutBuffer, dwSize + 1);
|
|
if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded)) {
|
|
std::cerr << last_winhttp_error("WinHttpReadData(DEL)") << std::endl;
|
|
delete[] pszOutBuffer;
|
|
WinHttpCloseHandle(hRequest);
|
|
WinHttpCloseHandle(hConnect);
|
|
WinHttpCloseHandle(hSession);
|
|
return false;
|
|
}
|
|
else {
|
|
result.append(pszOutBuffer);
|
|
}
|
|
|
|
// Free the memory
|
|
delete[] pszOutBuffer;
|
|
|
|
} while (dwSize > 0);
|
|
|
|
response = result;
|
|
|
|
// Close any open handles
|
|
WinHttpCloseHandle(hRequest);
|
|
WinHttpCloseHandle(hConnect);
|
|
WinHttpCloseHandle(hSession);
|
|
|
|
return true;
|
|
}
|
|
|
|
#elif LINUX
|
|
|
|
static size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* userp) {
|
|
size_t realsize = size * nmemb;
|
|
userp->append((char*)contents, realsize);
|
|
return realsize;
|
|
}
|
|
|
|
bool HttpClient::get(const std::string& url, std::string& response) {
|
|
CURL* curl;
|
|
CURLcode res;
|
|
|
|
curl = curl_easy_init();
|
|
if (!curl) {
|
|
return false;
|
|
}
|
|
|
|
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
|
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
|
|
curl_easy_setopt(curl, CURLOPT_USERAGENT, "PrivateBin API Client/1.0");
|
|
|
|
struct curl_slist* headers = NULL;
|
|
headers = curl_slist_append(headers, "X-Requested-With: JSONHttpRequest");
|
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
|
|
|
res = curl_easy_perform(curl);
|
|
|
|
curl_slist_free_all(headers);
|
|
curl_easy_cleanup(curl);
|
|
|
|
return (res == CURLE_OK);
|
|
}
|
|
|
|
bool HttpClient::post(const std::string& url, const std::string& data, std::string& response) {
|
|
CURL* curl;
|
|
CURLcode res;
|
|
|
|
curl = curl_easy_init();
|
|
if (!curl) {
|
|
return false;
|
|
}
|
|
|
|
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
|
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str());
|
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
|
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
|
|
curl_easy_setopt(curl, CURLOPT_USERAGENT, "PrivateBin API Client/1.0");
|
|
|
|
struct curl_slist* headers = NULL;
|
|
headers = curl_slist_append(headers, "Content-Type: application/json");
|
|
headers = curl_slist_append(headers, "X-Requested-With: JSONHttpRequest");
|
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
|
|
|
res = curl_easy_perform(curl);
|
|
|
|
curl_slist_free_all(headers);
|
|
curl_easy_cleanup(curl);
|
|
|
|
return (res == CURLE_OK);
|
|
}
|
|
|
|
bool HttpClient::delete_req(const std::string& url, const std::string& data, std::string& response) {
|
|
CURL* curl;
|
|
CURLcode res;
|
|
|
|
curl = curl_easy_init();
|
|
if (!curl) {
|
|
return false;
|
|
}
|
|
|
|
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
|
// PrivateBin API erwartet POST für delete
|
|
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str());
|
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
|
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
|
|
curl_easy_setopt(curl, CURLOPT_USERAGENT, "PrivateBin API Client/1.0");
|
|
|
|
struct curl_slist* headers = NULL;
|
|
headers = curl_slist_append(headers, "Content-Type: application/json");
|
|
headers = curl_slist_append(headers, "X-Requested-With: JSONHttpRequest");
|
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
|
|
|
res = curl_easy_perform(curl);
|
|
|
|
curl_slist_free_all(headers);
|
|
curl_easy_cleanup(curl);
|
|
|
|
return (res == CURLE_OK);
|
|
}
|
|
|
|
#endif |