Skip to content

Commit

Permalink
support json index
Browse files Browse the repository at this point in the history
  • Loading branch information
john30 committed Oct 13, 2023
1 parent 730d92d commit dc78076
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 8 deletions.
5 changes: 3 additions & 2 deletions src/ebusd/scan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,9 @@ result_t ScanHelper::collectConfigFiles(const string& relPath, const string& pre
+ "t=" + extension.substr(1) + query;
string names;
bool repeat = false;
if (!m_configHttpClient->get(uri, "", &names, &repeat)) {
if (!names.empty()) {
bool json = true;
if (!m_configHttpClient->get(uri, "", &names, &repeat, nullptr, &json)) {
if (!names.empty() || json) {
logError(lf_main, "HTTP failure%s: %s", repeat ? ", repeating" : "", names.c_str());
names = "";
}
Expand Down
48 changes: 44 additions & 4 deletions src/lib/utils/httpclient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -431,8 +431,8 @@ void HttpClient::disconnect() {
}
}

bool HttpClient::get(const string& uri, const string& body, string* response, bool* repeatable, time_t* time) {
return request("GET", uri, body, response, repeatable, time);
bool HttpClient::get(const string& uri, const string& body, string* response, bool* repeatable, time_t* time, bool* jsonString) {
return request("GET", uri, body, response, repeatable, time, jsonString);
}

bool HttpClient::post(const string& uri, const string& body, string* response, bool* repeatable) {
Expand All @@ -447,7 +447,7 @@ const int indexToMonth[] = {
};

bool HttpClient::request(const string& method, const string& uri, const string& body, string* response,
bool* repeatable, time_t* time) {
bool* repeatable, time_t* time, bool* jsonString) {
if (!ensureConnected()) {
*response = "not connected";
if (repeatable) {
Expand Down Expand Up @@ -559,9 +559,49 @@ bool* repeatable, time_t* time) {
*response = "invalid content length ";
return false;
}
bool isJson = headers.find("\r\nContent-Type: application/json") != string::npos;
if (pos == string::npos) {
disconnect();
return true;
}
pos = readUntil("", length, response);
disconnect();
return pos == length;
if (pos != length) {
return false;
}
if (jsonString && isJson && *jsonString && length >= 2 && response->at(0) == '"') {
// check for inline conversion of JSON to string expecting a single string to de-escape
pos = length;
while (pos > 1 && (response->at(pos-1) == '\r' || response->at(pos-1) == '\n')) {
pos--;
}
if (pos > 2 && response->at(pos-1) == '"') {
response->erase(pos-1);
response->erase(0, 1);
size_t from = 0;
while ((pos = response->find_first_of("\\", from)) != string::npos) {
response->erase(pos, 1); // pos is now pointing at the char behind the backslash
switch (response->at(pos)) {
case 'r':
response->erase(pos, 1); // removed
from = pos;
continue;
case 'n':
(*response)[pos] = '\n'; // replaced
from = pos+1;
break;
default:
from = pos+1;
break; // kept
}
}
isJson = false;
}
}
if (jsonString) {
*jsonString = isJson;
}
return true;
}

size_t HttpClient::readUntil(const string& delim, size_t length, string* result) {
Expand Down
10 changes: 8 additions & 2 deletions src/lib/utils/httpclient.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,10 +191,13 @@ class HttpClient {
* @param repeatable optional pointer to a bool in which to store whether the request should be repeated later on
* (e.g. due to temporary connectivity issues).
* @param time optional pointer to a @a time_t value for storing the modification time of the file, or nullptr.
* @param jsonString optional pointer to a bool value. When returning, it is set to whether the retrieved
* content-type indicates JSON. When true upon entry, content is JSON, and response is a single JSON string, it
* will be de-escaped to a pure string and the value set to false.
* @return true on success, false on error.
*/
bool get(const string& uri, const string& body, string* response, bool* repeatable = nullptr,
time_t* time = nullptr);
time_t* time = nullptr, bool* jsonString = nullptr);

/**
* Execute a POST request.
Expand All @@ -216,10 +219,13 @@ class HttpClient {
* @param repeatable optional pointer to a bool in which to store whether the request should be repeated later on
* (e.g. due to temporary connectivity issues).
* @param time optional pointer to a @a time_t value for storing the modification time of the file, or nullptr.
* @param jsonString optional pointer to a bool value. When returning, it is set to whether the retrieved
* content-type indicates JSON. When true upon entry, content is JSON, and response is a single JSON string, it
* will be de-escaped to a pure string and the value set to false.
* @return true on success, false on error.
*/
bool request(const string& method, const string& uri, const string& body, string* response,
bool* repeatable = nullptr, time_t* time = nullptr);
bool* repeatable = nullptr, time_t* time = nullptr, bool* jsonString = nullptr);

private:
/**
Expand Down

0 comments on commit dc78076

Please sign in to comment.