Skip to content

Commit d35405a

Browse files
committed
Added missing files from previous commit to repo
1 parent 261d639 commit d35405a

2 files changed

Lines changed: 127 additions & 0 deletions

File tree

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#pragma once
2+
#include <chimbuko_config.h>
3+
#include <curl/curl.h>
4+
#include <nlohmann/json.hpp>
5+
6+
namespace chimbuko{
7+
8+
class curlJsonSender{
9+
CURL* curl;
10+
curl_slist * headers;
11+
public:
12+
13+
/**
14+
* @brief Constructor
15+
* @param url The url of the destination
16+
*/
17+
curlJsonSender(const std::string &url);
18+
19+
/**
20+
* @brief Send a JSON-formatted string to the destination
21+
* @param json_str JSON-formatted string to send
22+
* @param response If non-null, the response message will be output at the provided location
23+
*/
24+
void send(const std::string &json_str, std::string *response = nullptr) const;
25+
26+
/**
27+
* @brief Send a JSON object to the destination
28+
* @param json JSON object to send
29+
* @param response If non-null, the response message will be output at the provided location
30+
*/
31+
inline void send(const nlohmann::json &json, std::string *response = nullptr) const{ send(json.dump(4),response); }
32+
33+
~curlJsonSender();
34+
};
35+
36+
}

src/util/curlJsonSender.cpp

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#include <chimbuko/util/curlJsonSender.hpp>
2+
#include <chimbuko/util/error.hpp>
3+
#include <chimbuko/util/string.hpp>
4+
5+
namespace chimbuko{
6+
7+
struct curlGlobal{
8+
curlGlobal(){ curl_global_init(CURL_GLOBAL_ALL); }
9+
~curlGlobal(){ curl_global_cleanup(); }
10+
};
11+
12+
//Initialize the curl global setup and ensure it is cleaned up at application end
13+
//Subsequent calls do nothing
14+
//Not thread safe
15+
static void curlGlobalInit(){
16+
static curlGlobal c;
17+
}
18+
19+
20+
curlJsonSender::curlJsonSender(const std::string &url): curl(nullptr), headers(nullptr){
21+
curlGlobalInit();
22+
23+
curl = curl_easy_init();
24+
if (curl == nullptr) fatal_error("Failed to initialize curl easy handler");
25+
26+
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
27+
// Dont bother trying IPv6, which would increase DNS resolution time
28+
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
29+
// Don't wait forever, time out after 10 seconds
30+
//curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
31+
// Follow HTTP redirects if necessary
32+
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
33+
// header
34+
headers = curl_slist_append(headers, "Content-Type: application/json");
35+
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
36+
}
37+
38+
39+
struct curl_fetch_str {
40+
std::string m_payload;
41+
bool m_do_fetch;
42+
curl_fetch_str(bool do_fetch) : m_do_fetch(do_fetch)
43+
{
44+
45+
}
46+
};
47+
48+
static size_t _curl_writefunc(char *ptr, size_t size, size_t nmemb, void* userp)
49+
{
50+
// std::cout << "curl_writefunc: " << std::string(ptr) << std::endl;
51+
struct curl_fetch_str *p = (struct curl_fetch_str *) userp;
52+
53+
if (ptr && p->m_do_fetch) {
54+
p->m_payload = std::string(ptr);
55+
}
56+
57+
return size * nmemb;
58+
}
59+
60+
61+
void curlJsonSender::send(const std::string &json_str, std::string *response) const{
62+
bool do_fetch = response != nullptr;
63+
64+
curl_fetch_str fetch(do_fetch); //request callback if
65+
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_str.c_str());
66+
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, json_str.size());
67+
curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
68+
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &_curl_writefunc);
69+
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&fetch);
70+
71+
CURLcode res = curl_easy_perform(curl);
72+
if (res != CURLE_OK) fatal_error(stringize("curl_easy_perform() failed: %s", curl_easy_strerror(res)));
73+
74+
long httpCode(0);
75+
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
76+
77+
if(do_fetch) *response = std::move(fetch.m_payload);
78+
}
79+
80+
curlJsonSender::~curlJsonSender(){
81+
if (headers) curl_slist_free_all(headers);
82+
curl_easy_cleanup(curl);
83+
}
84+
85+
86+
87+
88+
89+
90+
91+
}

0 commit comments

Comments
 (0)