38#ifndef OPENVPN_HTTP_CLISET_RC
39#define OPENVPN_HTTP_CLISET_RC RC<thread_unsafe_refcount>
67 void stop(
const bool shutdown)
70 c->
http->stop(shutdown);
102 return std::unique_ptr<openvpn_io::io_context>();
111#ifdef ASIO_HAS_LOCAL_SOCKETS
116 AsioPolySock::Unix *us =
dynamic_cast<AsioPolySock::Unix *
>(
c->
http->get_socket());
119 return us->socket.native_handle();
135 c->
http->attach(parent);
138 void close(
const bool keepalive,
const bool shutdown)
142 c->
http->detach(keepalive, shutdown);
158 c->
http->start_request();
232 const size_t orig_size = co->size();
233 co = ZLib::compress_gzip(co, 0, 0, 1);
235 log_compress(
"HTTPClientSet: GZIP COMPRESS", orig_size, co->size());
334 typedef std::vector<std::unique_ptr<Transaction>>
Vector;
385 throw Exception(
"TransactionSet::first_transaction: transaction list is empty");
400 if (!t->http_status_success())
418 void dump(std::ostream &os,
const bool content_only =
false)
const
423 os << t->content_in_string();
440 template <
typename T,
typename... Args>
443 reserve(1 +
sizeof...(args));
449 std::shuffle(begin(), end(),
prng);
456 throw Exception(
"HostRetry: empty host list");
459 return (*
this)[
index++];
470 push_back(std::move(arg));
475 push_back(std::string(arg));
478 template <
typename T,
typename... Args>
497 prng = std::move(prng_arg);
511 const bool sps =
false)
513 std::unique_ptr<openvpn_io::io_context>
io_context;
544 io_context.reset(
new openvpn_io::io_context(1));
552 cs->abort(
"stop message received"); });
559 while (cs->clients.size() && !
io_context->stopped())
583 std::unique_ptr<openvpn_io::io_context>
io_context(
new openvpn_io::io_context(1));
590 cs->abort(
"stop message received"); });
592 cs->set_random(
prng);
612 c.second->stop(
false,
false);
613 c.second->reset_callbacks();
636 ts(std::move(ts_arg)),
653 if (
ts->delayed_start.defined())
665 void stop(
const bool keepalive,
const bool shutdown)
677 ts->reset_callbacks();
689 ts->hsc.close(keepalive, shutdown);
696 { parent->remove_client_id(id); });
710 void done(
const bool status,
const bool shutdown)
713 auto clean =
Cleanup([
this, shutdown]()
715 if (!
ts->preserve_http_state)
716 ts->hsc.stop(shutdown); });
717 stop(status, shutdown);
757 if (error_retry &&
ts->error_recovery)
758 ts->error_recovery->retry(*
ts, t);
761 if (
ts->debug_level >= 3)
762 OPENVPN_LOG(
"HTTPStateContainer alive=" <<
ts->alive() <<
" error_retry=" << error_retry <<
" n_clients=" <<
parent->
clients.size());
765 ts->hsc.attach(
this);
767 ts->hsc.start_request();
777 if (!error && !self->halt)
778 self->next_request(error_retry); });
806 if (
ts->debug_level >= 2)
808 std::ostringstream os;
809 os <<
"----- HEADERS RECEIVED -----\n";
810 os <<
" " <<
title() <<
'\n';
842 if (
ts->debug_level >= 2)
844 std::ostringstream os;
845 os <<
"----- HEADERS SENT -----\n";
846 os <<
" " <<
title() <<
'\n';
895 if (
ts->debug_level >= 2)
897 std::ostringstream os;
898 os <<
"----- DONE -----\n";
899 os <<
" " <<
title() <<
'\n';
913 bp = ZLib::decompress_gzip(std::move(bp), 0, 0, hd.
http_config().max_content_bytes);
916 throw Exception(
"gzip-compressed data returned from server but app not linked with zlib");
950 catch (
const std::exception &e)
953 t.
description = std::string(
"http_done: ") + e.what();
963 { self->next_request(
false); });
974 if (
ts->post_connect)
975 ts->post_connect(*
ts, sock);
980 return status >= (
ts->retry_on_http_4xx ? 400 : 500) && status < 600;
985 TransactionSet::Vector::const_iterator
ts_iter;
999 auto e =
clients.find(client_id);
std::size_t expires_after(const Time::Duration &d)
void async_wait(F &&func)
void reset() noexcept
Points this RCPtr<T> to nullptr safely.
Reference count base class for objects tracked by RCPtr. Disallows copying and assignment.
Abstract base class for random number generators.
static Ptr Create(ArgsT &&...args)
Creates a new instance of RcEnable with the given arguments.
std::string to_string() const
static Parse from_components(const bool https, const std::string &host, const std::string &port, const std::string &uri)
void remove_self_from_map()
void http_headers_sent(HTTPDelegate &hd, const Buffer &buf)
void http_mutate_resolver_results(HTTPDelegate &hd, openvpn_io::ip::tcp::resolver::results_type &results)
std::string title() const
void next_request(const bool error_retry)
void http_post_connect(HTTPDelegate &hd, AsioPolySock::Base &sock)
void http_content_in(HTTPDelegate &hd, BufferAllocated &buf)
Time::Duration retry_duration
BufferPtr http_content_out(HTTPDelegate &hd)
WS::Client::Request http_request(HTTPDelegate &hd) const
AsioTimerSafe reconnect_timer
BufferList::const_iterator out_iter
void http_content_out_needed(HTTPDelegate &hd)
void http_keepalive_close(HTTPDelegate &hd, const int status, const std::string &description)
WS::Client::Host http_host(HTTPDelegate &hd) const
Client(ClientSet *parent_arg, const TransactionSet::Ptr ts_arg, client_t client_id_arg)
void abort(const std::string &message)
WS::Client::ContentInfo http_content_info(HTTPDelegate &hd) const
void http_done(HTTPDelegate &hd, const int status, const std::string &description)
void http_headers_received(HTTPDelegate &hd)
void reconnect_schedule(const bool error_retry)
const Transaction & trans() const
bool http_status_should_retry(const int status) const
TransactionSet::Vector::const_iterator ts_iter
void done(const bool status, const bool shutdown)
void close_http(const bool keepalive, const bool shutdown)
void stop(const bool keepalive, const bool shutdown)
~HTTPStateContainerAutoStop()
HTTPStateContainerAutoStop(const bool shutdown)
std::unique_ptr< openvpn_io::io_context > acquire_io_context()
bool alive(const std::string &host) const
void stop(const bool shutdown)
void abort(const std::string &message)
void attach(Client *parent)
void construct(openvpn_io::io_context &io_context, const WS::Client::Config::Ptr config)
void close(const bool keepalive, const bool shutdown)
void persist_io_context(std::unique_ptr< openvpn_io::io_context > &&io_context)
void from_list(T first, Args... args)
void from_list(const char *arg)
void from_list(std::string arg)
HostRetry(T first, Args... args)
virtual void retry(TransactionSet &ts, Transaction &t) override
void shuffle(RandomAPI &prng)
WS::ClientSet::Transaction & first_transaction()
bool http_status_success() const
std::vector< std::unique_ptr< Transaction > > Vector
void assign_http_state(HTTPStateContainer &http_state)
void dump(std::ostream &os, const bool content_only=false) const
Function< void(TransactionSet &ts, AsioPolySock::Base &sock)> post_connect
Time::Duration delayed_start
RCPtr< TransactionSet > Ptr
WS::Client::Config::Ptr http_config
Function< void(TransactionSet &ts)> completion
void stop(const bool shutdown)
Time::Duration retry_duration
ErrorRecovery::Ptr error_recovery
static void run_synchronous(Function< void(ClientSet::Ptr)> job, Stop *stop=nullptr, RandomAPI *prng=nullptr)
WS::Client::HTTPDelegate< Client > HTTPDelegate
ClientSet(openvpn_io::io_context &io_context_arg)
std::map< client_t, Client::Ptr > clients
openvpn_io::io_context & io_context
void new_request(const TransactionSet::Ptr ts)
void set_random(RandomAPI::Ptr prng_arg)
static void new_request_synchronous(const TransactionSet::Ptr ts, Stop *stop=nullptr, RandomAPI *prng=nullptr, const bool sps=false)
void abort(const std::string &message)
void remove_client_id(const client_t client_id)
std::string remote_endpoint_str() const
const HTTP::Reply & reply() const
olong content_length() const
std::string ssl_handshake_details() const
const CONFIG & http_config() const
#define OPENVPN_HTTP_CLISET_RC
#define OPENVPN_LOG(args)
#define OPENVPN_LOG_STRING(str)
std::string headers_redact(const std::string &headers)
void randomize_results(RESULTS &results, RandomAPI &prng)
void filter_by_ip_version(RESULTS &results, const IP::Addr::Version ip_ver)
bool ends_with_newline(const STRING &str)
std::string indent(const std::string &str, const int first, const int remaining)
std::string to_string(T value)
CleanupType< F > Cleanup(F method) noexcept
void log_compress(const std::string prefix, const size_t orig_size, const size_t new_size)
RCPtr< BufferAllocatedRc > BufferPtr
std::string buf_to_string(const Buffer &buf)
Implementation of the base classes for random number generators.
BufferPtr join(const size_t headroom, const size_t tailroom, const bool size_1_optim) const
void put_consume(BufferAllocated &buf, const size_t tailroom=0)
std::string to_string() const
virtual void retry(TransactionSet &ts, Transaction &t)=0
RCPtr< ErrorRecovery > Ptr
std::unique_ptr< openvpn_io::io_context > io_context
IP::Addr::Version ip_version_preference
bool request_status_success() const
void dump(std::ostream &os, const TransactionSet &ts) const
bool http_status_success() const
std::string format_status(const TransactionSet &ts) const
std::string url(const TransactionSet &ts) const
std::string title(const TransactionSet &ts) const
std::string format_status() const
bool randomize_resolver_results
void compress_content_out(const unsigned int min_size=64, const bool verbose=false)
std::string get_redirect_location() const
WS::Client::ContentInfo ci
bool comm_status_success() const
std::string content_in_string() const
BufferPtr content_in_buffer() const
static constexpr int UNDEF
bool comm_status_timeout() const
std::vector< std::string > extra_headers
std::string content_encoding
static std::string error_str(const int status)
static const char config[]