7 #include <boost/beast/core/flat_buffer.hpp> 8 #include <boost/beast/http/buffer_body.hpp> 9 #include <boost/beast/http/message.hpp> 10 #include <boost/beast/http/parser.hpp> 11 #include <boost/beast/http/read.hpp> 12 #include <boost/beast/http/write.hpp> 14 #include "absl/strings/string_view.h" 15 #include "absl/types/variant.h" 16 #include "util/http/ssl_stream.h" 20 class FiberSyncSocket;
25 using SslContextResult = absl::variant<::boost::system::error_code, ::boost::asio::ssl::context>;
26 SslContextResult CreateClientSslContext(absl::string_view cert_string);
30 using error_code = ::boost::system::error_code;
40 HttpsClient(absl::string_view host,
IoContext* io_context, ::boost::asio::ssl::context* ssl_ctx);
44 error_code Connect(
unsigned msec);
51 template <
typename Req> error_code
Send(
const Req& req);
58 template <
typename Req,
typename Resp> error_code
Send(
const Req& req, Resp* resp);
60 error_code ReadHeader(::boost::beast::http::basic_parser<false>* parser);
61 template <
typename Parser> error_code Read(Parser* parser);
63 error_code DrainResponse(
64 ::boost::beast::http::response_parser<::boost::beast::http::buffer_body>* parser);
66 SslStream* client() {
return client_.get(); }
68 void schedule_reconnect() { reconnect_needed_ =
true; }
70 int32_t native_handle() {
return client_->next_layer().native_handle(); }
72 uint32_t retry_count()
const {
return retry_cnt_; }
77 ::boost::asio::ssl::context& ssl_context() {
return ssl_cntx_; }
79 error_code status()
const {
80 namespace err = ::boost::asio::error;
82 return reconnect_needed_ ? err::not_connected : client_->next_layer().status();
86 error_code HandleError(
const error_code& ec);
87 bool HandleWriteError(
const error_code& ec);
89 bool IsError(
const error_code& ec)
const {
90 using err = ::boost::beast::http::error;
91 return ec && ec != err::need_buffer;
94 error_code ReconnectIfNeeded() {
95 if (reconnect_needed_)
96 return InitSslClient();
100 error_code InitSslClient();
102 IoContext& io_context_;
103 ::boost::asio::ssl::context& ssl_cntx_;
105 ::boost::beast::flat_buffer tmp_buffer_;
107 std::string host_name_;
109 std::unique_ptr<FiberSyncSocket> socket_;
110 std::unique_ptr<SslStream> client_;
112 uint32_t reconnect_msec_ = 1000;
113 bool reconnect_needed_ =
true;
114 uint32_t retry_cnt_ = 1;
119 template <
typename Req,
typename Resp>
121 namespace h2 = ::boost::beast::http;
124 for (uint32_t i = 0; i < retry_cnt_; ++i) {
130 h2::read(*client_, tmp_buffer_, *resp, ec);
132 h2::read(*socket_, tmp_buffer_, *resp, ec);
139 return HandleError(ec);
144 for (uint32_t i = 0; i < retry_cnt_; ++i) {
145 ec = ReconnectIfNeeded();
149 ::boost::beast::http::write(*client_, req, ec);
151 ::boost::beast::http::write(*socket_, req, ec);
153 if (HandleWriteError(ec)) {
157 return HandleError(ec);
161 inline auto HttpsClient::ReadHeader(::boost::beast::http::basic_parser<false>* parser)
165 ::boost::beast::http::read_header(*client_, tmp_buffer_, *parser, ec);
167 ::boost::beast::http::read_header(*socket_, tmp_buffer_, *parser, ec);
168 return HandleError(ec);
171 template <
typename Parser>
auto HttpsClient::Read(Parser* parser) -> error_code {
177 ::boost::beast::http::read(*client_, tmp_buffer_, *parser, ec);
179 ::boost::beast::http::read(*socket_, tmp_buffer_, *parser, ec);
180 return HandleError(ec);
183 inline auto HttpsClient::HandleError(
const error_code& ec) -> error_code {
185 reconnect_needed_ =
true;
HttpsClient(absl::string_view host, IoContext *io_context, ::boost::asio::ssl::context *ssl_ctx)
Construct a new Https Client object.
error_code Send(const Req &req)
Sends http request but does not read response back.
void set_retry_count(uint32_t cnt)
Sets number of retries for Send(...) methods.