HTTP proxy: avoid connecting to itself (#1978)

This commit is contained in:
Jan Berkel 2017-05-08 17:04:17 +02:00 committed by Arvid Norberg
parent 14dbd1c92d
commit b3815c5533
5 changed files with 56 additions and 16 deletions

View File

@ -1,3 +1,4 @@
* fix proxying of https connections
* fix race condition in disk I/O storage class
* fix http connection timeout on multi-homed hosts
* removed depdendency on boost::uintptr_t for better compatibility

View File

@ -252,8 +252,8 @@ protected:
bool handle_error(error_code const& e, boost::shared_ptr<handler_type> const& h);
tcp::socket m_sock;
std::string m_hostname;
int m_port;
std::string m_hostname; // proxy host
int m_port; // proxy port
endpoint_type m_remote_endpoint;

@ -1 +1 @@
Subproject commit 0e8d74baf1f6d9db19857eaa87734faecd530f94
Subproject commit 70feadef80dc76ae6d5e7c2f92334377d698dd7d

View File

@ -489,8 +489,8 @@ TORRENT_TEST(http_connection_timeout_server_stalls)
error_code e;
sim.run(e);
TEST_CHECK(!e);
TEST_EQUAL(2, connect_counter); // both endpoints are connected to
TEST_EQUAL(1, handler_counter); // the handler only gets called once with error_code == timed_out
TEST_EQUAL(connect_counter, 2); // both endpoints are connected to
TEST_EQUAL(handler_counter, 1); // the handler only gets called once with error_code == timed_out
}
// tests the error scenario of a http server listening on two sockets (ipv4/ipv6) neither of which
@ -541,8 +541,8 @@ TORRENT_TEST(http_connection_timeout_server_does_not_accept)
error_code e;
sim.run(e);
TEST_CHECK(!e);
TEST_EQUAL(0, connect_counter); // no connection takes place
TEST_EQUAL(1, handler_counter); // the handler only gets called once with error_code == timed_out
TEST_EQUAL(connect_counter, 0); // no connection takes place
TEST_EQUAL(handler_counter, 1); // the handler only gets called once with error_code == timed_out
}
void test_proxy_failure(lt::settings_pack::proxy_type_t proxy_type)
@ -598,6 +598,53 @@ TORRENT_TEST(http_connection_http_error)
test_proxy_failure(settings_pack::http);
}
// Requests a proxied SSL connection. This test just ensures that the correct CONNECT request
// is sent to the proxy server.
TORRENT_TEST(http_connection_ssl_proxy)
{
using sim::asio::ip::address_v4;
sim_config network_cfg;
sim::simulation sim{network_cfg};
sim::asio::io_service client_ios(sim, address_v4::from_string("10.0.0.1"));
sim::asio::io_service proxy_ios(sim, address_v4::from_string("50.50.50.50"));
lt::resolver res(client_ios);
sim::http_server http_proxy(proxy_ios, 4445);
lt::aux::proxy_settings ps = make_proxy_settings(settings_pack::http);
int client_counter = 0;
int proxy_counter = 0;
http_proxy.register_handler("10.0.0.2:8080"
, [&proxy_counter](std::string method, std::string req, std::map<std::string, std::string>& headers)
{
proxy_counter++;
TEST_EQUAL(method, "CONNECT");
return sim::send_response(403, "Not supported", 1337);
});
auto h = boost::make_shared<http_connection>(client_ios
, res
, [&client_counter](error_code const& ec, http_parser const& parser
, char const* data, const int size, http_connection& c)
{
client_counter++;
TEST_EQUAL(ec, boost::asio::error::operation_not_supported);
});
h->start("10.0.0.2", 8080, seconds(1), 0, &ps, true /*ssl*/);
error_code e;
sim.run(e);
TEST_EQUAL(client_counter, 1);
TEST_EQUAL(proxy_counter, 1);
if (e) std::cerr << " run failed: " << e.message() << std::endl;
TEST_EQUAL(e, error_code());
}
// TODO: test http proxy with password
// TODO: test socks5 with password
// TODO: test SSL

View File

@ -61,15 +61,7 @@ namespace libtorrent
// send CONNECT
std::back_insert_iterator<std::vector<char> > p(m_buffer);
std::string endpoint;
if (!m_hostname.empty())
{
endpoint = m_hostname + ':' + to_string(m_remote_endpoint.port()).elems;
}
else
{
endpoint = print_endpoint(m_remote_endpoint);
}
std::string endpoint = print_endpoint(m_remote_endpoint);
write_string("CONNECT " + endpoint + " HTTP/1.0\r\n", p);
if (!m_user.empty())
{