由于内部需要使用c++做授权认证,但是代码不能公开,因此只能进行将代码在编译二进制文件里面进行执行,而实际代码不显示。这样授权的代码就无法越过权限认证这一步了。但是如何实现呢?
其实简单的方案是,采用curl来进行,curl是支持C和C++的。但是这个库坑很深,它并不会像你预想的那样工作。经过探索,这里记录一下真正可行的http请求方案:
thor::security::CheckResult thor::security::LicenseChecker::checkLicense(string license) {
string api_url;
api_url = (_url + "?license=" + license);
CURL* _curl = curl_easy_init();
if (!_curl) {
// error to
LOG(ERROR) << "can not launch curl instance, is curl installed? or network connected?\n";
exit(1);
}
LOG(INFO) << "satellite initialized.\n";
CURLcode res;
long httpCode(0);
std::string readBuffer;
curl_easy_setopt(_curl, CURLOPT_URL, api_url.c_str());
curl_easy_setopt(_curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(_curl, CURLOPT_WRITEDATA, &readBuffer);
curl_easy_setopt(_curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
curl_easy_setopt(_curl, CURLOPT_TIMEOUT, 10);
res = curl_easy_perform(_curl);
curl_easy_getinfo(_curl, CURLINFO_RESPONSE_CODE, &httpCode);
LOG(INFO) << "checking done.";
CheckResult checkResult;
if (httpCode != CURLE_HTTP_RETURNED_ERROR) {
json j_res = json::parse(readBuffer);
if (j_res["status"] == "success") {
checkResult.ok = true;
checkResult.msg = "license ok";
} else {
checkResult.ok = false;
checkResult.msg = j_res["message"];
}
} else {
LOG(ERROR) << "connect cloud error, either offline or cloud down.";
checkResult.ok = false;
checkResult.msg = "network is not ok.";
}
curl_easy_cleanup(_curl);
return checkResult;
}
size_t thor::security::LicenseChecker::WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) {
((std::string*)userp)->append((char*)contents, size * nmemb);
return size * nmemb;
}
这里将两个核心方法剥离出来,实际使用需要住的几行代码是:
curl_easy_setopt(_curl, CURLOPT_URL, api_url.c_str());
curl_easy_setopt(_curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(_curl, CURLOPT_WRITEDATA, &readBuffer);
curl_easy_setopt(_curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
curl_easy_setopt(_curl, CURLOPT_TIMEOUT, 10);
这里你需要指定WriteCallback
以及WriteData
, 这样才能写入返回结果,否则你就会得到segmentation fault的错误。虽然能够通过编译。