GitHub - libcpr/cpr: C++ Requests: Curl for People, a spiritual port of Python Requests.
GitHub - psf/requests: A simple, yet elegant, HTTP library.
#include "cpr/cpr.h"
#include "cpr/util.h"
#include <chrono>
using namespace cpr;
// CPR_USE_SYSTEM_CURL
class ChangeRequestMethodToPutInterceptorMulti : public InterceptorMulti {
public:
std::vector<Response> intercept(MultiPerform& multi) override {
multi.GetSessions().front().second = MultiPerform::HttpMethod::PUT_REQUEST;
multi.GetSessions().front().first->SetOption(Payload{ {"x", "5"} });
return proceed(multi);
}
};
class HiddenHelloWorldRedirectInterceptor : public Interceptor {
public:
Response intercept(Session& session) override {
// Save original url
Url old_url = session.GetFullRequestUrl();
// Rewrite the url
Url url{ "https://api.github.com/repos/whoshuu/cpr/contributors" };
session.SetUrl(url);
// Proceed the chain
Response response = proceed(session);
// Restore the url again
response.url = old_url;
return response;
}
};
// ErrorCode::OPERATION_TIMEDOUT
// ErrorCode::UNSUPPORTED_PROTOCOL
int status_callback(int& status_code, Response r) {
status_code = r.status_code;
return r.status_code;
}
bool write_data(std::string /*data*/, intptr_t /*userdata*/) {
return true;
}
void InterceptorTest() {
cpr::Url url{ "https://api.github.com/repos/whoshuu/cpr/contributors" };
std::shared_ptr<Session> session = std::make_shared<Session>();
session->SetUrl(url);
MultiPerform multi;
multi.AddSession(session);
multi.AddInterceptor(std::make_shared<ChangeRequestMethodToPutInterceptorMulti>());
std::vector<Response> response = multi.Get();
}
void test() {
// GET
Cookies cookies{
{"SID", "31d4d96e407aad42", "127.0.0.1", false, "/", true, std::chrono::system_clock::from_time_t(3905119080)},
{"lang", "en-US", "127.0.0.1", false, "/", true, std::chrono::system_clock::from_time_t(3905119080)},
};
Body body{ static_cast<std::string_view>("message=abc123") };
SslOptions sslOpts = Ssl(ssl::CaInfo{ "ca-bundle.crt" }, ssl::CertFile{ "client.crt" }, ssl::KeyFile{ "client.key" }, ssl::VerifyPeer{ true }, ssl::PinnedPublicKey{"server.pub" }, ssl::VerifyHost{ true }, ssl::VerifyStatus{ false });
//Resolve resolve{ "www.example.com", "127.0.0.1", {server->GetPort()} };
cpr::Url url{ "https://api.github.com/repos/whoshuu/cpr/contributors" };
cpr::Response r = cpr::Get(url, cookies, cpr::ConnectTimeout{ std::chrono::milliseconds{1} },
Header{ {"key", "value"}, {"hello", "world"}, {"test", "case"} },
cpr::Authentication{ "user", "pass", cpr::AuthMode::BASIC },
LimitRate(1024, 1024),
body,
sslOpts,
Verbose{},
cpr::Parameters{ {"anon", "true"}, {"key", "value"} });
r.status_code; // 200
r.header["content-type"]; // application/json; charset=utf-8
r.text; // JSON text string
auto responseProxy = cpr::Get(url, cpr::Proxies{ {"http", "http://bad_host.libcpr.org"} });
// ASYNC GET
cpr::AsyncResponse future = cpr::GetAsync(url);
auto response = future.get();
// CALLBACK
int status_code = 0;
auto callback = std::function<int(Response)>(std::bind(status_callback, std::ref(status_code), std::placeholders::_1));
//auto future = cpr::GetCallback(callback, url);
//auto future = cpr::HeadCallback(callback, url);
//auto future = cpr::PostCallback(callback, url, payload);
//auto future = cpr::PutCallback(callback, url, payload);
//auto future = cpr::OptionsCallback(callback, url);
//auto future = cpr::PatchCallback(callback, url, payload);
//auto future = cpr::DeleteCallback(callback, url);
unsigned count = 0;
//Response response = cpr::Put(url, cpr::ReadCallback{ 3, [&](char* buffer, size_t& size, intptr_t /*userdata*/) -> size_t {
// std::string data;
// ++count;
// switch (count) {
// case 1:
// data = "x=";
// break;
// case 2:
// data = "5";
// break;
// default:
// return false;
// }
// std::copy(data.begin(), data.end(), buffer);
// size = data.size();
// return true;
// } });
response = cpr::Post(url, cpr::ReadCallback{ 3, [&](char* buffer, size_t& size, intptr_t /*userdata*/) -> size_t {
std::string data;
++count;
switch (count) {
case 1:
data = "x=";
break;
case 2:
data = "5";
break;
default:
return false;
}
std::copy(data.begin(), data.end(), buffer);
size = data.size();
return true;
} });
response = Post(url, HeaderCallback{ [](std::string /*header*/, intptr_t /*userdata*/) -> bool { return false; } });
std::string response_text;
response = Post(url, Payload{ {"x", "5"} }, WriteCallback{ [&response_text](const std::string& header, intptr_t /*userdata*/) -> bool {
response_text.append(header);
return true;
} });
response = Post(url, ProgressCallback{ [](size_t /*downloadTotal*/, size_t /*downloadNow*/, size_t /*uploadTotal*/, size_t /*uploadNow*/, intptr_t /*userdata*/) -> bool { return false; } });
std::string debug_body;
response = Post(url, body, DebugCallback{ [&](DebugCallback::InfoType type, const std::string& data, intptr_t /*userdata*/) {
if (type == DebugCallback::InfoType::DATA_OUT) {
debug_body = data;
}
} });
// ASYNC DOWNLOAD
//future = cpr::DownloadAsync(fs::path{ "/tmp/aync_download" }, url, cpr::Header{ {"Accept-Encoding", "gzip"} }, cpr::WriteCallback{ write_data, 0 });
//response = future.get();
// PUT
Session session;
session.SetUrl(url);
session.SetHeader(cpr::Header{ {"Accept-Encoding", "gzip"} });
session.SetRange(cpr::Range{ std::nullopt, std::nullopt });
session.SetPayload({ {"x", "5"} });
session.SetRedirect(Redirect(false));
//session.SetMultiRange(cpr::MultiRange{ cpr::Range{std::nullopt, 3}, cpr::Range{5, 6} });
session.AddInterceptor(std::make_shared<HiddenHelloWorldRedirectInterceptor>());
response = session.Download(cpr::WriteCallback{ write_data, 0 });
auto len = session.GetDownloadFileLength();
Payload payload{ {"x", "5"} };
response = cpr::Put(url, payload);
// DELETE
response = session.Delete();
response = cpr::Delete(url, cpr::Body{ "'foo': 'bar'" }, cpr::Header{ {"Content-Type", "application/json"} });
cpr::AsyncResponse future_response = cpr::DeleteAsync(url);
//Auth
std::string user = "一二三";
std::string pass = "Hello World!";
EncodedAuthentication pa{ user, pass };
// UPLOAD
cpr::fs::path filePath = "test_file.txt";
cpr::Multipart mp{ {cpr::Part("file_name", cpr::File(filePath.string()))} };
response = cpr::Post(url, mp);
// Util
std::string input = "%E4%B8%80%E4%BA%8C%E4%B8%89";
std::string result = util::urlDecode(input);
}