#include "stdafx.h" #include "SiaCurl.h" #include using namespace Sia::Api; CSiaCurl::CSiaCurl() : _curlHandle(curl_easy_init()) { SetHostConfig({ L"localhost", 9980, L""}); curl_easy_setopt(_curlHandle, CURLOPT_USERAGENT, "Sia-Agent"); } CSiaCurl::~CSiaCurl() { curl_easy_cleanup(_curlHandle); } SiaCurlError CSiaCurl::CheckApiError(const json& result) { SiaCurlError ret = SiaCurlError::Success; if (result.find("message") != result.end()) { ret = SiaCurlError::UnknownFailure; const std::string msg = result["message"].get(); if ((msg.length() >= 3)) { if ((msg.substr(0, 3) == "404")) { ret = SiaCurlError::InvalidRequestPath; } } } return ret; } std::string CSiaCurl::ConstructPath(const String& relativePath) const { const std::string ret = "http://" + std::string(CW2A(GetHostConfig().HostName.c_str())) + ":" + std::to_string(GetHostConfig().HostPort) + std::string(CW2A(relativePath.c_str())); return ret; } SiaCurlError CSiaCurl::_Get(const String& path, json& response) const { std::string result; SiaCurlError ret = SiaCurlError::Success; if (API_SUCCESS(SiaCurlError, ret)) { curl_easy_setopt(_curlHandle, CURLOPT_URL, ConstructPath(path).c_str()); curl_easy_setopt(_curlHandle, CURLOPT_WRITEFUNCTION, static_cast([](char *buffer, size_t size, size_t nitems, void *outstream) -> size_t { (*reinterpret_cast(outstream)) += std::string(reinterpret_cast(buffer), size * nitems); return size * nitems; })); curl_easy_setopt(_curlHandle, CURLOPT_WRITEDATA, &result); const CURLcode res = curl_easy_perform(_curlHandle); if (res == CURLE_OK) { ret = CheckApiError((response = json::parse(result.c_str()))); } else { if ((res == CURLE_COULDNT_RESOLVE_HOST) || (res == CURLE_COULDNT_CONNECT)) { ret = SiaCurlError::NoResponse; } else { ret = SiaCurlError::UnknownFailure; } } } return ret; } bool CSiaCurl::CheckVersion(SiaCurlError& error) const { error = SiaCurlError::InvalidRequiredVersion; if (GetHostConfig().RequiredVersion.length()) { error = SiaCurlError::NoResponse; const String serverVersion = GetServerVersion(); if (serverVersion.length()) { error = (serverVersion == GetHostConfig().RequiredVersion) ? SiaCurlError::Success : SiaCurlError::ServerVersionMismatch; } } return API_SUCCESS(SiaCurlError, error); } String CSiaCurl::GetServerVersion() const { json response; if (API_SUCCESS(SiaCurlError, _Get(L"/daemon/version", response))) { return String(CA2W(response["version"].get().c_str())); } return L""; } SiaCurlError CSiaCurl::Get(const String& path, json& response) const { std::string result; SiaCurlError ret; if (CheckVersion(ret)) { ret = _Get(path, response); } return ret; }