feat(HTTPClientSession): HTTPClientSession source IP address #2271

This commit is contained in:
Alex Fabijanic
2022-05-20 14:38:23 -07:00
parent cf4dc753f0
commit be7006af2f
6 changed files with 162 additions and 21 deletions

View File

@@ -40,6 +40,8 @@ HTTPClientSession::ProxyConfig HTTPClientSession::_globalProxyConfig;
HTTPClientSession::HTTPClientSession():
_port(HTTPSession::HTTP_PORT),
_sourceAddress4(IPAddress::wildcard(IPAddress::IPv4), 0),
_sourceAddress6(IPAddress::wildcard(IPAddress::IPv6), 0),
_proxyConfig(_globalProxyConfig),
_keepAliveTimeout(DEFAULT_KEEP_ALIVE_TIMEOUT, 0),
_reconnect(false),
@@ -54,6 +56,8 @@ HTTPClientSession::HTTPClientSession():
HTTPClientSession::HTTPClientSession(const StreamSocket& socket):
HTTPSession(socket),
_port(HTTPSession::HTTP_PORT),
_sourceAddress4(IPAddress::wildcard(IPAddress::IPv4), 0),
_sourceAddress6(IPAddress::wildcard(IPAddress::IPv6), 0),
_proxyConfig(_globalProxyConfig),
_keepAliveTimeout(DEFAULT_KEEP_ALIVE_TIMEOUT, 0),
_reconnect(false),
@@ -68,6 +72,8 @@ HTTPClientSession::HTTPClientSession(const StreamSocket& socket):
HTTPClientSession::HTTPClientSession(const SocketAddress& address):
_host(address.host().toString()),
_port(address.port()),
_sourceAddress4(IPAddress::wildcard(IPAddress::IPv4), 0),
_sourceAddress6(IPAddress::wildcard(IPAddress::IPv6), 0),
_proxyConfig(_globalProxyConfig),
_keepAliveTimeout(DEFAULT_KEEP_ALIVE_TIMEOUT, 0),
_reconnect(false),
@@ -82,6 +88,8 @@ HTTPClientSession::HTTPClientSession(const SocketAddress& address):
HTTPClientSession::HTTPClientSession(const std::string& host, Poco::UInt16 port):
_host(host),
_port(port),
_sourceAddress4(IPAddress::wildcard(IPAddress::IPv4), 0),
_sourceAddress6(IPAddress::wildcard(IPAddress::IPv6), 0),
_proxyConfig(_globalProxyConfig),
_keepAliveTimeout(DEFAULT_KEEP_ALIVE_TIMEOUT, 0),
_reconnect(false),
@@ -107,6 +115,21 @@ HTTPClientSession::HTTPClientSession(const std::string& host, Poco::UInt16 port,
}
HTTPClientSession::HTTPClientSession(const StreamSocket& socket, const ProxyConfig& proxyConfig):
HTTPSession(socket),
_port(HTTPSession::HTTP_PORT),
_sourceAddress4(IPAddress::wildcard(IPAddress::IPv4), 0),
_sourceAddress6(IPAddress::wildcard(IPAddress::IPv6), 0),
_proxyConfig(proxyConfig),
_keepAliveTimeout(DEFAULT_KEEP_ALIVE_TIMEOUT, 0),
_reconnect(false),
_mustReconnect(false),
_expectResponseBody(false),
_responseReceived(false)
{
}
HTTPClientSession::~HTTPClientSession()
{
}
@@ -130,6 +153,39 @@ void HTTPClientSession::setPort(Poco::UInt16 port)
}
void HTTPClientSession::setSourceAddress(const SocketAddress& address)
{
if (!connected())
{
if (address.family() == IPAddress::IPv4)
_sourceAddress4 = address;
else
_sourceAddress6 = address;
_sourceAddress = address;
}
else
throw IllegalStateException("Cannot set the source address for an already connected session");
}
const SocketAddress& HTTPClientSession::getSourceAddress()
{
return _sourceAddress;
}
const SocketAddress& HTTPClientSession::getSourceAddress4()
{
return _sourceAddress4;
}
const SocketAddress& HTTPClientSession::getSourceAddress6()
{
return _sourceAddress6;
}
void HTTPClientSession::setProxy(const std::string& host, Poco::UInt16 port)
{
if (!connected())
@@ -400,16 +456,22 @@ int HTTPClientSession::write(const char* buffer, std::streamsize length)
void HTTPClientSession::reconnect()
{
SocketAddress addr(_host, _port);
if (_proxyConfig.host.empty() || bypassProxy())
{
SocketAddress addr(_host, _port);
connect(addr);
}
addr = SocketAddress(_host, _port);
else
addr = SocketAddress(_proxyConfig.host, _proxyConfig.port);
SocketAddress sourceAddr;
if (addr.family() == IPAddress::IPv4)
sourceAddr = _sourceAddress4;
else
sourceAddr = _sourceAddress6;
if ((!sourceAddr.host().isWildcard()) || (sourceAddr.port() != 0))
connect(addr, sourceAddr);
else
{
SocketAddress addr(_proxyConfig.host, _proxyConfig.port);
connect(addr);
}
}
@@ -536,6 +598,8 @@ StreamSocket HTTPClientSession::proxyConnect()
proxyRequest.set(HTTPRequest::HOST, getHost());
proxySession.proxyAuthenticateImpl(proxyRequest, _proxyConfig);
proxySession.setKeepAlive(true);
proxySession.setSourceAddress(_sourceAddress4);
proxySession.setSourceAddress(_sourceAddress6);
proxySession.sendRequest(proxyRequest);
proxySession.receiveResponse(proxyResponse);
if (proxyResponse.getStatus() != HTTPResponse::HTTP_OK)