CCF
Loading...
Searching...
No Matches
rpc_tls_client.h
Go to the documentation of this file.
1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the Apache 2.0 License.
3#pragma once
4
5#include "ccf/http_consts.h"
6#include "http/http_builder.h"
7#include "http/http_parser.h"
8#include "tls_client.h"
9
10#define FMT_HEADER_ONLY
11#include <fmt/format.h>
12#include <nlohmann/json.hpp>
13#include <optional>
14#include <thread>
15
16namespace client
17{
19 {
20 public:
22 {
23 std::vector<uint8_t> encoded;
24 size_t id;
25 };
26
27 struct Response
28 {
29 size_t id;
32 std::vector<uint8_t> body;
33 };
34
35 protected:
37 std::optional<std::string> prefix;
39 std::string key_id = "Invalid";
40
41 size_t next_send_id = 0;
42 size_t next_recv_id = 0;
43
44 std::vector<uint8_t> gen_http_request_internal(
45 const std::string& method,
46 const std::span<const uint8_t> params,
47 const std::string& content_type,
48 llhttp_method verb,
49 const char* auth_token = nullptr)
50 {
51 auto path = method;
52 if (prefix.has_value())
53 {
54 path = fmt::format("/{}/{}", prefix.value(), path);
55 }
56
57 auto r = http::Request(path, verb);
58 r.set_body(params.data(), params.size());
59 r.set_header(ccf::http::headers::CONTENT_TYPE, content_type);
60 r.set_header("Host", host);
61 if (auth_token != nullptr)
62 {
63 r.set_header(
64 ccf::http::headers::AUTHORIZATION,
65 fmt::format("Bearer {}", auth_token));
66 }
67
68 return r.build_request();
69 }
70
71 std::vector<uint8_t> gen_request_internal(
72 const std::string& method,
73 const std::span<const uint8_t> params,
74 const std::string& content_type,
75 llhttp_method verb,
76 const char* auth_token = nullptr)
77 {
79 method, params, content_type, verb, auth_token);
80 }
81
82 Response call_raw(const std::vector<uint8_t>& raw)
83 {
84 write(raw);
85 return read_response();
86 }
87
89 {
90 return call_raw(prep.encoded);
91 }
92
93 std::optional<Response> last_response;
94
95 public:
97
99 const std::string& host,
100 const std::string& port,
101 std::shared_ptr<::tls::CA> node_ca = nullptr,
102 std::shared_ptr<::tls::Cert> cert = nullptr,
103 const std::string& key_id_ = "Invalid") :
105 parser(*this),
106 key_id(key_id_)
107 {}
108
110 TlsClient(c),
111 parser(*this),
112 key_id(c.key_id)
113 {}
114
116 {
118 }
119
121 const std::string& method,
122 const std::span<const uint8_t> params,
123 const std::string& content_type,
124 llhttp_method verb = HTTP_POST,
125 const char* auth_token = nullptr)
126 {
127 return {
128 gen_request_internal(method, params, content_type, verb, auth_token),
129 next_send_id++};
130 }
131
133 const std::string& method,
134 const nlohmann::json& params = nullptr,
135 llhttp_method verb = HTTP_POST)
136 {
137 std::vector<uint8_t> body;
138 if (!params.is_null())
139 {
140 auto body_s = params.dump();
141 body = {body_s.begin(), body_s.end()};
142 }
143
144 return call_raw(gen_request(
145 method,
146 body,
147 ccf::http::headervalues::contenttype::JSON,
148 verb,
149 nullptr));
150 }
151
153 const std::string& method,
154 const std::span<const uint8_t> params,
155 llhttp_method verb = HTTP_POST)
156 {
157 return call_raw(gen_request(
158 method, params, ccf::http::headervalues::contenttype::JSON, verb));
159 }
160
161 Response post(const std::string& method, const nlohmann::json& params)
162 {
163 return call(method, params, HTTP_POST);
164 }
165
167 const std::string& method, const nlohmann::json& params = nullptr)
168 {
169 // GET body is ignored, so params must be placed in query
170 auto full_path = method;
171 if (!params.is_null())
172 {
173 for (auto it = params.begin(); it != params.end(); ++it)
174 {
175 full_path += fmt::format(
176 "{}{}={}",
177 it == params.begin() ? "?" : "&",
178 it.key(),
179 it.value().is_string() ? it.value().get<std::string>() :
180 it.value().dump());
181 }
182 }
183 return call(full_path, nullptr, HTTP_GET);
184 }
185
186 nlohmann::json unpack_body(const Response& resp)
187 {
188 if (resp.body.empty())
189 {
190 return nullptr;
191 }
192 else if (http::status_success(resp.status))
193 {
194 const auto& content_type =
195 resp.headers.find(ccf::http::headers::CONTENT_TYPE);
196 return nlohmann::json::parse(resp.body);
197 }
198 else
199 {
200 return std::string(resp.body.begin(), resp.body.end());
201 }
202 }
203
204 std::string get_error(const Response& resp)
205 {
206 return std::string(resp.body.begin(), resp.body.end());
207 }
208
210 {
211 last_response = std::nullopt;
212
213 while (!last_response.has_value())
214 {
215 const auto next = read_all();
216 parser.execute(next.data(), next.size());
217 }
218
219 return std::move(last_response.value());
220 }
221
222 std::optional<Response> read_response_non_blocking()
223 {
224 if (bytes_available())
225 {
226 return read_response();
227 }
228
229 return std::nullopt;
230 }
231
232 virtual void handle_response(
233 ccf::http_status status,
234 ccf::http::HeaderMap&& headers,
235 std::vector<uint8_t>&& body) override
236 {
237 last_response = {
238 next_recv_id++, status, std::move(headers), std::move(body)};
239 }
240
241 void set_prefix(const std::string& prefix_)
242 {
243 prefix = prefix_;
244 }
245 };
246
248}
Definition pem.h:18
Definition rpc_tls_client.h:19
Response get(const std::string &method, const nlohmann::json &params=nullptr)
Definition rpc_tls_client.h:166
virtual void handle_response(ccf::http_status status, ccf::http::HeaderMap &&headers, std::vector< uint8_t > &&body) override
Definition rpc_tls_client.h:232
HttpRpcTlsClient(const HttpRpcTlsClient &c)
Definition rpc_tls_client.h:109
Response call_raw(const PreparedRpc &prep)
Definition rpc_tls_client.h:88
std::vector< uint8_t > gen_http_request_internal(const std::string &method, const std::span< const uint8_t > params, const std::string &content_type, llhttp_method verb, const char *auth_token=nullptr)
Definition rpc_tls_client.h:44
std::optional< Response > last_response
Definition rpc_tls_client.h:93
Response read_response()
Definition rpc_tls_client.h:209
ccf::crypto::ECKeyPairPtr key_pair
Definition rpc_tls_client.h:38
std::optional< std::string > prefix
Definition rpc_tls_client.h:37
Response call_raw(const std::vector< uint8_t > &raw)
Definition rpc_tls_client.h:82
size_t next_recv_id
Definition rpc_tls_client.h:42
Response call(const std::string &method, const std::span< const uint8_t > params, llhttp_method verb=HTTP_POST)
Definition rpc_tls_client.h:152
std::optional< Response > read_response_non_blocking()
Definition rpc_tls_client.h:222
nlohmann::json unpack_body(const Response &resp)
Definition rpc_tls_client.h:186
Response post(const std::string &method, const nlohmann::json &params)
Definition rpc_tls_client.h:161
HttpRpcTlsClient(const std::string &host, const std::string &port, std::shared_ptr<::tls::CA > node_ca=nullptr, std::shared_ptr<::tls::Cert > cert=nullptr, const std::string &key_id_="Invalid")
Definition rpc_tls_client.h:98
std::string key_id
Definition rpc_tls_client.h:39
void create_key_pair(const ccf::crypto::Pem priv_key)
Definition rpc_tls_client.h:115
PreparedRpc gen_request(const std::string &method, const std::span< const uint8_t > params, const std::string &content_type, llhttp_method verb=HTTP_POST, const char *auth_token=nullptr)
Definition rpc_tls_client.h:120
::http::ResponseParser parser
Definition rpc_tls_client.h:36
std::string get_error(const Response &resp)
Definition rpc_tls_client.h:204
Response call(const std::string &method, const nlohmann::json &params=nullptr, llhttp_method verb=HTTP_POST)
Definition rpc_tls_client.h:132
std::vector< uint8_t > gen_request_internal(const std::string &method, const std::span< const uint8_t > params, const std::string &content_type, llhttp_method verb, const char *auth_token=nullptr)
Definition rpc_tls_client.h:71
size_t next_send_id
Definition rpc_tls_client.h:41
void set_prefix(const std::string &prefix_)
Definition rpc_tls_client.h:241
Definition tls_client.h:67
std::vector< uint8_t > read_all()
Definition tls_client.h:212
std::string port
Definition tls_client.h:70
std::shared_ptr<::tls::CA > node_ca
Definition tls_client.h:71
bool bytes_available()
Definition tls_client.h:207
std::shared_ptr<::tls::Cert > cert
Definition tls_client.h:72
TlsClient(const std::string &host, const std::string &port, std::shared_ptr<::tls::CA > node_ca=nullptr, std::shared_ptr<::tls::Cert > cert=nullptr)
Definition tls_client.h:119
void write(std::span< const uint8_t > b)
Definition tls_client.h:159
void execute(const uint8_t *data, size_t size)
Definition http_parser.h:232
Definition http_builder.h:117
Definition http_parser.h:466
Definition http_proc.h:33
ECKeyPairPtr make_ec_key_pair(CurveID curve_id=service_identity_curve_choice)
Definition ec_key_pair.cpp:530
std::shared_ptr< ECKeyPair > ECKeyPairPtr
Definition ec_key_pair.h:144
std::map< std::string, std::string, std::less<> > HeaderMap
Definition http_header_map.h:10
llhttp_status http_status
Definition http_status.h:9
Definition perf_client.h:12
Definition configuration.h:14
bool status_success(ccf::http_status status)
Definition http_parser.h:73
Definition rpc_tls_client.h:22
size_t id
Definition rpc_tls_client.h:24
std::vector< uint8_t > encoded
Definition rpc_tls_client.h:23
Definition rpc_tls_client.h:28
size_t id
Definition rpc_tls_client.h:29
std::vector< uint8_t > body
Definition rpc_tls_client.h:32
ccf::http_status status
Definition rpc_tls_client.h:30
ccf::http::HeaderMap headers
Definition rpc_tls_client.h:31