Implement ApiNap::ping()
This commit is contained in:
parent
99d577f43a
commit
3ff82985c9
8 changed files with 73 additions and 12 deletions
|
@ -39,18 +39,20 @@ namespace {
|
|||
|
||||
std::tuple<std::unique_ptr<char[]>, std::string_view, std::string_view> make_raw_string (
|
||||
const std::ostringstream& head,
|
||||
const std::ostringstream& body
|
||||
const std::ostringstream& body,
|
||||
std::size_t body_padding
|
||||
) {
|
||||
//TODO: use .view() with c++20
|
||||
auto head_str = head.str();
|
||||
auto body_str = body.str();
|
||||
|
||||
const std::size_t size = head_str.size() + 1 + body_str.size();
|
||||
const std::size_t size = head_str.size() + 1 + body_str.size() + body_padding;
|
||||
auto ret = std::make_unique<char[]>(size);
|
||||
|
||||
std::copy(head_str.begin(), head_str.end(), ret.get());
|
||||
ret[head_str.size()] = '\n';
|
||||
std::copy(body_str.begin(), body_str.end(), ret.get() + head_str.size() + 1);
|
||||
std::fill(ret.get() + size - body_padding, ret.get() + size, ' ');
|
||||
|
||||
const char* const buff = ret.get();
|
||||
return std::make_tuple(
|
||||
|
@ -64,7 +66,8 @@ namespace {
|
|||
HttpResponse page_fetch (
|
||||
const std::string& url,
|
||||
const std::string& user_agent,
|
||||
const PageFetchHeaders& headers
|
||||
const PageFetchHeaders& headers,
|
||||
std::size_t body_padding
|
||||
) {
|
||||
using curl::curl_pair;
|
||||
|
||||
|
@ -100,7 +103,7 @@ HttpResponse page_fetch (
|
|||
|
||||
std::string_view head;
|
||||
{
|
||||
auto [raw, head_tmp, body] = make_raw_string(header_oss, body_oss);
|
||||
auto [raw, head_tmp, body] = make_raw_string(header_oss, body_oss, body_padding);
|
||||
head = head_tmp;
|
||||
resp.raw = std::move(raw);
|
||||
resp.body = body;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <string_view>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cstddef>
|
||||
|
||||
namespace nap {
|
||||
|
||||
|
@ -29,7 +30,8 @@ typedef std::vector<std::string> PageFetchHeaders;
|
|||
HttpResponse page_fetch (
|
||||
const std::string& url,
|
||||
const std::string& user_agent,
|
||||
const PageFetchHeaders& headers
|
||||
const PageFetchHeaders& headers,
|
||||
std::size_t body_padding
|
||||
);
|
||||
|
||||
} //namespace nap
|
||||
|
|
|
@ -21,6 +21,11 @@
|
|||
|
||||
namespace nap {
|
||||
|
||||
QuickRest::QuickRest (std::size_t body_padding) :
|
||||
m_body_padding(body_padding)
|
||||
{
|
||||
}
|
||||
|
||||
void QuickRest::add_headers (std::initializer_list<HeaderPairView> headers) {
|
||||
m_header_lines.reserve(m_header_lines.size() + headers.size());
|
||||
|
||||
|
@ -39,6 +44,6 @@ void QuickRest::set_user_agent (std::string&& name) {
|
|||
}
|
||||
|
||||
HttpResponse QuickRest::fetch (std::string_view url) {
|
||||
return page_fetch(std::string(url), m_user_agent, m_header_lines);
|
||||
return page_fetch(std::string(url), m_user_agent, m_header_lines, m_body_padding);
|
||||
}
|
||||
} //namespace nap
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <initializer_list>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <cstddef>
|
||||
|
||||
namespace nap {
|
||||
|
||||
|
@ -31,7 +32,7 @@ class QuickRest {
|
|||
public:
|
||||
typedef std::pair<std::string_view, std::string_view> HeaderPairView;
|
||||
|
||||
QuickRest() = default;
|
||||
explicit QuickRest(std::size_t body_padding=0);
|
||||
|
||||
void add_headers (std::initializer_list<HeaderPairView> headers);
|
||||
void set_user_agent (std::string&& name);
|
||||
|
@ -40,6 +41,7 @@ public:
|
|||
private:
|
||||
std::string m_user_agent;
|
||||
std::vector<std::string> m_header_lines;
|
||||
std::size_t m_body_padding;
|
||||
};
|
||||
|
||||
} //namespace nap
|
||||
|
|
|
@ -17,9 +17,35 @@
|
|||
|
||||
#include "private/api_nap.hpp"
|
||||
#include "private/v1_endpoints.hpp"
|
||||
#include "private/dateconv.hpp"
|
||||
#include "duckhandy/int_conv.hpp"
|
||||
|
||||
namespace oro {
|
||||
|
||||
namespace {
|
||||
Header to_header (const nap::HttpResponse& resp) {
|
||||
using dhandy::int_conv;
|
||||
|
||||
Header ret;
|
||||
for (const auto& entry : resp.header) {
|
||||
if (entry.first == "Date")
|
||||
ret.date = from_header_timestamp(entry.second);
|
||||
else if (entry.first == "X-RateLimit-Limit")
|
||||
ret.rate_limit = int_conv<decltype(ret.rate_limit)>(entry.second);
|
||||
else if (entry.first == "X-RateLimit-Remaining")
|
||||
ret.rate_limit_remaining = int_conv<decltype(ret.rate_limit_remaining)>(entry.second);
|
||||
else if (entry.first == "X-RateLimit-Reset")
|
||||
ret.rate_limit_reset = int_conv<decltype(ret.rate_limit_reset)>(entry.second);
|
||||
else if (entry.first == "Retry-After")
|
||||
ret.retry_after = int_conv<decltype(ret.retry_after)>(entry.second);
|
||||
else if (entry.first == "Server")
|
||||
ret.server = std::string(entry.second);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} //unnamed namespace
|
||||
|
||||
ApiNap::ApiNap (
|
||||
std::string&& root_address,
|
||||
std::string&& api_key,
|
||||
|
@ -27,7 +53,7 @@ ApiNap::ApiNap (
|
|||
std::string&& client_purpose
|
||||
) :
|
||||
Api(std::move(root_address), std::move(api_key), std::move(client_name), std::move(client_purpose)),
|
||||
m_qrest()
|
||||
m_qrest(simdjson::SIMDJSON_PADDING)
|
||||
{
|
||||
m_qrest.add_headers({
|
||||
{"X-Client", m_client_name},
|
||||
|
@ -40,8 +66,22 @@ ApiNap::ApiNap (
|
|||
ApiNap::~ApiNap() noexcept = default;
|
||||
|
||||
std::pair<Header, Ping> ApiNap::ping() {
|
||||
m_qrest.fetch(m_prefix + g_endpoint_ping);
|
||||
//std::cout << nap::page_fetch(url, client_name).body << '\n';
|
||||
auto resp = m_qrest.fetch(m_prefix + g_endpoint_ping);
|
||||
|
||||
Ping dataret;
|
||||
{
|
||||
std::unique_lock lock(m_json_mutex);
|
||||
simdjson::dom::element doc = m_json.parse(
|
||||
reinterpret_cast<const uint8_t*>(resp.body.data()),
|
||||
resp.body.size()
|
||||
);
|
||||
|
||||
dataret.message = doc["message"];
|
||||
dataret.generation_timestamp = std::string(doc["generation_timestamp"]);
|
||||
dataret.version = static_cast<int>(int64_t(doc["version"]));
|
||||
}
|
||||
|
||||
return {to_header(resp), std::move(dataret)};
|
||||
}
|
||||
|
||||
std::pair<Header, WhoAmI> ApiNap::who_am_i() {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "oro/api.hpp"
|
||||
#include "nap/quick_rest.hpp"
|
||||
#include <mutex>
|
||||
|
||||
namespace oro {
|
||||
|
||||
|
@ -41,6 +42,8 @@ public:
|
|||
virtual std::pair<Header, Creators> fame_list() override;
|
||||
|
||||
private:
|
||||
std::mutex m_json_mutex;
|
||||
simdjson::dom::parser m_json;
|
||||
nap::QuickRest m_qrest;
|
||||
};
|
||||
|
||||
|
|
|
@ -32,8 +32,8 @@ namespace {
|
|||
}
|
||||
};
|
||||
|
||||
Timestamp to_timestamp (const char* fmt, const std::string& str) {
|
||||
std::istringstream iss(str);
|
||||
Timestamp to_timestamp (const char* fmt, std::string_view str) {
|
||||
std::istringstream iss{std::string(str)};
|
||||
Timestamp ts;
|
||||
date::from_stream(iss, fmt, ts.ts);
|
||||
return ts;
|
||||
|
@ -57,6 +57,10 @@ Timestamp from_json_timestamp (const std::string& str) {
|
|||
}
|
||||
|
||||
Timestamp from_header_timestamp (const std::string& str) {
|
||||
return from_header_timestamp(std::string_view(str));
|
||||
}
|
||||
|
||||
Timestamp from_header_timestamp (std::string_view str) {
|
||||
UniqueLocale loc(std::setlocale(LC_TIME, "POSIX"));
|
||||
//date has this format: Fri, 19 Jun 2020 22:33:43 GMT
|
||||
return to_timestamp("%a, %d %b %Y %T %Z", str);
|
||||
|
|
|
@ -19,9 +19,11 @@
|
|||
|
||||
#include "oro/datatypes.hpp"
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace oro {
|
||||
Timestamp from_json_timestamp (const std::string& str);
|
||||
Timestamp from_header_timestamp (std::string_view str);
|
||||
Timestamp from_header_timestamp (const std::string& str);
|
||||
Timestamp from_sqlite_timestamp (const std::string& str);
|
||||
std::string to_sqlite_string (const Timestamp& ts);
|
||||
|
|
Loading…
Reference in a new issue