· 4 years ago · Apr 08, 2021, 05:24 PM
1#include <iostream>
2#include <sstream>
3
4#include <simdjson.h>
5
6#include <curl/curl.h>
7
8
9static size_t curl_write(void* contents, size_t size, size_t n, void* userp) {
10 (static_cast<std::string*>(userp))->append(static_cast<char*>(contents), size * n);
11 return size * n;
12}
13
14static std::string curl_escape(std::string_view str) {
15 char* escaped = curl_easy_escape(NULL, str.data(), str.length());
16 std::string escaped_str = escaped;
17 free(escaped);
18 return escaped_str;
19}
20
21class net_client {
22public:
23 using parameter_pack_t = std::vector<std::pair<std::string, std::string>>;
24
25 std::string post_request(std::string_view method, const parameter_pack_t& postfields) {
26 CURL* curl = curl_easy_init();
27
28 std::string buffer;
29 if (curl) {
30 std::string params = create_parameters(postfields);
31 curl_easy_setopt(curl, CURLOPT_POST, 1L);
32 curl_easy_setopt(curl, CURLOPT_URL, method.data());
33 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, params.c_str());
34 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write);
35 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);
36
37 CURLcode res = curl_easy_perform(curl);
38 curl_easy_cleanup(curl);
39
40 if (res != CURLE_OK) {
41 std::string errmsg = "curl error: ";
42 errmsg += curl_easy_strerror(res);
43 throw std::runtime_error(errmsg);
44 }
45 }
46 curl_global_cleanup();
47 return buffer;
48 }
49
50private:
51 std::string create_parameters(const parameter_pack_t& body) {
52 std::string result;
53 for (const auto&[key, value] : body) {
54 result += key;
55 result += '=';
56 result += curl_escape(value);
57 result += '&';
58 }
59 result.pop_back();
60 return result;
61 }
62};
63
64class solution {
65public:
66 std::string authorize() {
67 std::string auth_data =
68 client.post_request(testing_url, {{"action", "auth"}});
69 simdjson::dom::element auth = parser.parse(auth_data);
70 return auth["data"]["key"].get_c_str().take_value();
71 }
72
73 std::string get_secret(std::string_view key) {
74 std::string secret_data = client.post_request(testing_url, {
75 {"action", "getSecret"}, {"key", key.data()}
76 });
77 simdjson::dom::element secret_key_object = parser.parse(secret_data);
78 bool is_success = secret_key_object["success"].get_bool();
79
80 if (is_success) {
81 return secret_key_object["data"]["secret"].get_c_str().take_value();
82 } else {
83 std::string errmsg = secret_key_object["data"]["message"].get_c_str().take_value();
84 throw std::runtime_error("error: " + errmsg);
85 }
86 }
87
88private:
89 static inline const std::string_view testing_url = "https://testing.burosd.ru/cpp/1/?";
90 net_client client;
91 simdjson::dom::parser parser;
92};
93
94int main() {
95 solution client;
96 std::string auth_key = client.authorize();
97 std::string secret_key = client.get_secret(auth_key);
98
99 std::cout << "auth key: " << auth_key << std::endl;
100 std::cout << "secret key: " << secret_key << std::endl;
101}