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