so the result buffer/string wasn't being parsed by the json class because even using the "proper" ways of comparing the char * to "application/json" weren't working...ugh

This commit is contained in:
DarthArgus
2016-08-20 13:44:33 +00:00
parent 5f0e741a72
commit f7d5eeb160
4 changed files with 79 additions and 70 deletions
@@ -2863,7 +2863,7 @@ void CentralServer::sendPopulationUpdateToLoginServer()
void CentralServer::sendMetricsToWebAPI()
{
// create the object
webAPI api = webAPI::webAPI(std::string(ConfigCentralServer::getMetricsDataURL()));
webAPI api(std::string(ConfigCentralServer::getMetricsDataURL()));
// add our data
api.addJsonData<int>("totalPlayerCount", m_totalPlayerCount);
@@ -183,7 +183,7 @@ void ClientConnection::validateClient(const std::string & id, const std::string
if (!authURL.empty())
{
// create the object
webAPI api = webAPI::webAPI(authURL);
webAPI api(authURL);
// add our data
api.addJsonData<std::string>("user_name", id);
+70 -61
View File
@@ -1,19 +1,19 @@
/*
Version: 1.3
This code is just a simple wrapper around nlohmann's wonderful json lib
(https://github.com/nlohmann/json) and libcurl. While originally included directly,
we have come to realize that we may require web API functionality elsewhere in the future.
As such, and in an effort to keep the code clean, we've broken it out into this simple little
namespace/lib that is easy to include. Just make sure to link against curl when including, and
make all the cmake modifications required to properly use it.
(c) stellabellum/swgilluminati (combined crews), written by DA with help from DC
based on the original prototype by parz1val
License: what's a license? we're a bunch of dirty pirates!
*/
* Version: 1.3
*
* This code is just a simple wrapper around nlohmann's wonderful json lib
* (https://github.com/nlohmann/json) and libcurl. While originally included directly,
* we have come to realize that we may require web API functionality elsewhere in the future.
*
* As such, and in an effort to keep the code clean, we've broken it out into this simple little
* namespace/lib that is easy to include. Just make sure to link against curl when including, and
* make all the cmake modifications required to properly use it.
*
* (c) stellabellum/swgilluminati (combined crews), written by DA with help from DC
* based on the original prototype by parz1val
*
* License: what's a license? we're a bunch of dirty pirates!
*/
#include "webAPI.h"
@@ -22,27 +22,27 @@ using namespace StellaBellum;
webAPI::webAPI(std::string endpoint, std::string userAgent) : uri(endpoint), userAgent(userAgent) {}
webAPI::~webAPI()
{
requestData.clear();
responseData.clear();
this->requestData.clear();
this->responseData.clear();
}
bool webAPI::setEndpoint(std::string endpoint)
{
uri = endpoint;
this->uri = endpoint;
return true;
}
std::string webAPI::getRaw()
{
return sResponse;
return this->sResponse;
}
bool webAPI::setData(std::string &data)
{
if (!data.empty())
{
sRequest = data;
this->sRequest = data;
return true;
}
@@ -55,13 +55,13 @@ bool webAPI::submit(const int &reqType, const int &getPost, const int &respType)
if (reqType == 0) // json request
{
if (!requestData.is_null())
if (!this->requestData.is_null())
{
// serialize our data into sRequest
sRequest = requestData.dump();
this->sRequest = this->requestData.dump();
// clear our the object for next time
requestData.clear();
this->requestData.clear();
}
else
{
@@ -69,22 +69,24 @@ bool webAPI::submit(const int &reqType, const int &getPost, const int &respType)
}
}
if (fetch(getPost, respType) && !(sResponse.empty()))
if (fetch(getPost, respType) && !(this->sResponse.empty()))
{
return true;
}
sResponse.clear();
this->sResponse.clear();
return false;
}
bool webAPI::fetch(const int &getPost, const int &mimeType) // 0 for json 1 for string
{
bool fetchStatus = false;
if (!uri.empty()) //data is allowed to be an empty string if we're doing a normal GET
{
CURL *curl = curl_easy_init(); // start up curl
if (curl)
{
std::string readBuffer; // container for the remote response
@@ -93,13 +95,16 @@ bool webAPI::fetch(const int &getPost, const int &mimeType) // 0 for json 1 for
// set the content type
if (mimeType == 0)
{
slist = curl_slist_append(slist, "Content-Type: application/json");
slist = curl_slist_append(slist, "Accept: application/json");
slist = curl_slist_append(slist, "Content-Type: application/json");
}
else
{
slist = curl_slist_append(slist, "Content-Type: application/x-www-form-urlencoded");
}
slist = curl_slist_append(slist, "charsets: utf-8");
curl_easy_setopt(curl, CURLOPT_USERAGENT, userAgent.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback); // place the data into readBuffer using writeCallback
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); // specify readBuffer as the container for data
@@ -107,47 +112,51 @@ bool webAPI::fetch(const int &getPost, const int &mimeType) // 0 for json 1 for
switch (getPost)
{
case 0:
curl_easy_setopt(curl, CURLOPT_URL, std::string(uri + "?" + sRequest).c_str());
break;
case 1:
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, sRequest.c_str());
curl_easy_setopt(curl, CURLOPT_URL, uri.c_str());
break;
// want to do a put, or whatever other type? feel free to add here
case 0:
curl_easy_setopt(curl, CURLOPT_URL, std::string(this->uri + "?" + sRequest).c_str());
break;
case 1:
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, this->sRequest.c_str());
curl_easy_setopt(curl, CURLOPT_URL, this->uri.c_str());
break;
// want to do a put, or whatever other type? feel free to add here
}
CURLcode res = curl_easy_perform(curl); // make the request!
char *contentType;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &statusCode); //get status code
CURLcode res = curl_easy_perform(curl); // make the request!
char * contentType;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &this->statusCode); //get status code
curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &contentType); // get response mime type
curl_slist_free_all(slist);
curl_easy_cleanup(curl); // always wipe our butt
std::string conType(contentType);
if (res == CURLE_OK && statusCode == 200 && !(readBuffer.empty())) // check it all out and parse
if (res == CURLE_OK && this->statusCode == 200 && !(readBuffer.empty())) // check it all out and parse
{
sResponse = readBuffer;
if (std::string(contentType) == "application/json")
this->sResponse = readBuffer;
if (conType == "application/json")
{
processJSON();
fetchStatus = this->processJSON();
}
else
{
responseData.clear();
this->responseData.clear();
fetchStatus = true;
}
return true;
}
curl_slist_free_all(slist);
curl_easy_cleanup(curl); // always wipe our butt
}
}
sResponse.clear();
responseData.clear();
if (!fetchStatus)
{
this->sResponse.clear();
this->responseData.clear();
}
return false;
return fetchStatus;
}
// This is used by curl to grab the response and put it into a var
@@ -159,28 +168,28 @@ size_t webAPI::writeCallback(void *contents, size_t size, size_t nmemb, void *us
bool webAPI::processJSON()
{
if (!(sResponse.empty())) // check it all out and parse
if (!(this->sResponse.empty())) // check it all out and parse
{
try
{
responseData = nlohmann::json::parse(sResponse);
this->responseData = nlohmann::json::parse(this->sResponse);
return true;
}
catch (std::string &e)
{
responseData["message"] = e;
responseData["status"] = "failure";
this->responseData["message"] = e;
this->responseData["status"] = "failure";
}
catch (...)
{
responseData["message"] = "JSON parse error for endpoint.";
responseData["status"] = "failure";
this->responseData["message"] = "JSON parse error for endpoint.";
this->responseData["status"] = "failure";
}
}
else
{
responseData["message"] = "Error fetching data from remote.";
responseData["status"] = "failure";
this->responseData["message"] = "Error fetching data from remote.";
this->responseData["status"] = "failure";
}
return false;
+7 -7
View File
@@ -30,7 +30,7 @@ namespace StellaBellum
{
class webAPI
{
public:
public:
// useragent
std::string userAgent;
@@ -55,7 +55,7 @@ namespace StellaBellum
{
if (!key.empty())
{
requestData[key] = value;
this->requestData[key] = value;
return true;
}
@@ -65,15 +65,15 @@ namespace StellaBellum
// get json response slot
template<typename T> T getRespValue(std::string slot)
{
if (!responseData.is_null() && !slot.empty() && responseData.count(slot))
if (!this->responseData.is_null() && !slot.empty() && this->responseData.count(slot))
{
return responseData[slot].get<T>();
return this->responseData[slot].get<T>();
}
return nullptr;
return T(); // empty value of T
}
private:
private:
// json request data - object is serialized before sending, used with above setter template
nlohmann::json requestData;
@@ -98,7 +98,7 @@ namespace StellaBellum
// json processor - string to json
bool processJSON();
protected:
protected:
// http response code (200, 404, etc)
long statusCode;
};