Skip to content

Commit

Permalink
http proxy support
Browse files Browse the repository at this point in the history
  • Loading branch information
pablohoch committed Dec 9, 2024
1 parent e1b66c5 commit efbc8b1
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 6 deletions.
1 change: 1 addition & 0 deletions include/motis/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ struct config {
unsigned update_interval_{60};
unsigned http_timeout_{10};
unsigned cache_size_{50};
std::optional<std::string> proxy_;
};
std::optional<gbfs> gbfs_{};

Expand Down
12 changes: 12 additions & 0 deletions include/motis/http_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ struct http_client {
bool ssl_{};
};

struct proxy_settings {
operator bool() const { return !host_.empty(); }

std::string host_;
std::string port_;
bool ssl_{};
};

struct connection;
struct request;

Expand All @@ -46,8 +54,12 @@ struct http_client {
boost::asio::awaitable<http_response> get(
boost::urls::url url, std::map<std::string, std::string> headers);

void set_proxy(boost::urls::url const&);

hash_map<connection_key, std::shared_ptr<connection>> connections_;
std::chrono::seconds timeout_{std::chrono::seconds{10}};

proxy_settings proxy_{};
};

} // namespace motis
Expand Down
3 changes: 3 additions & 0 deletions src/gbfs/update.cc
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ struct gbfs_update {
gbfs_data const* prev_d)
: c_{c}, w_{w}, l_{l}, d_{d}, prev_d_{prev_d} {
client_.timeout_ = std::chrono::seconds{c.http_timeout_};
if (c.proxy_ && !c.proxy_->empty()) {
client_.set_proxy(boost::urls::url{*c.proxy_});
}
}

awaitable<void> run() {
Expand Down
24 changes: 18 additions & 6 deletions src/http_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,16 @@ struct http_client::connection
connection(Executor const& executor,
connection_key key,
std::chrono::seconds const timeout,
proxy_settings const& proxy,
std::size_t const max_in_flight = 1)
: key_{std::move(key)},
unlimited_pipelining_{max_in_flight == kUnlimitedHttpPipelining},
request_channel_{executor},
requests_in_flight_{std::make_unique<
asio::experimental::channel<void(boost::system::error_code)>>(
executor, max_in_flight)},
timeout_{timeout} {
timeout_{timeout},
proxy_{proxy} {
ssl_ctx_.set_default_verify_paths();
ssl_ctx_.set_verify_mode(ssl::verify_none);
ssl_ctx_.set_options(ssl::context::default_workarounds |
Expand Down Expand Up @@ -128,15 +130,17 @@ struct http_client::connection
auto executor = co_await asio::this_coro::executor;
auto resolver = asio::ip::tcp::resolver{executor};

auto const results =
co_await resolver.async_resolve(key_.host_, key_.port_);
auto const host = proxy_ ? proxy_.host_ : key_.host_;
auto const port = proxy_ ? proxy_.port_ : key_.port_;

auto const results = co_await resolver.async_resolve(host, port);
++n_connects_;
if (ssl()) {
ssl_stream_ =
std::make_unique<ssl::stream<beast::tcp_stream>>(executor, ssl_ctx_);

if (!SSL_set_tlsext_host_name(ssl_stream_->native_handle(),
const_cast<char*>(key_.host_.c_str()))) {
const_cast<char*>(host.c_str()))) {
throw boost::system::system_error{{static_cast<int>(::ERR_get_error()),
asio::error::get_ssl_category()}};
}
Expand Down Expand Up @@ -290,7 +294,7 @@ struct http_client::connection
} while (!pending_requests_.empty());
}

bool ssl() const { return key_.ssl_; }
bool ssl() const { return proxy_ ? proxy_.ssl_ : key_.ssl_; }

connection_key key_{};
bool unlimited_pipelining_{false};
Expand All @@ -313,6 +317,7 @@ struct http_client::connection

ssl::context ssl_ctx_{ssl::context::tlsv12_client};
std::chrono::seconds timeout_;
http_client::proxy_settings proxy_;

unsigned n_sent_{};
unsigned n_received_{};
Expand All @@ -335,7 +340,8 @@ asio::awaitable<http_response> http_client::get(

auto executor = co_await asio::this_coro::executor;
if (auto const it = connections_.find(key); it == connections_.end()) {
auto conn = std::make_shared<connection>(executor, key, timeout_, 1);
auto conn =
std::make_shared<connection>(executor, key, timeout_, proxy_, 1);
connections_[key] = conn;
asio::co_spawn(executor, conn->run(), asio::detached);
}
Expand All @@ -348,4 +354,10 @@ asio::awaitable<http_response> http_client::get(
co_return response;
}

void http_client::set_proxy(boost::urls::url const& url) {
proxy_.ssl_ = url.scheme_id() == boost::urls::scheme::https;
proxy_.host_ = url.host();
proxy_.port_ = url.has_port() ? url.port() : (proxy_.ssl_ ? "443" : "80");
}

} // namespace motis

0 comments on commit efbc8b1

Please sign in to comment.