diff --git a/Net/include/Poco/Net/HTTPClientSession.h b/Net/include/Poco/Net/HTTPClientSession.h index 14ae999bb9..5cad1bcb46 100644 --- a/Net/include/Poco/Net/HTTPClientSession.h +++ b/Net/include/Poco/Net/HTTPClientSession.h @@ -20,9 +20,11 @@ #include "Poco/Net/Net.h" #include "Poco/Net/HTTPSession.h" +#include "Poco/Net/HTTPSessionFactory.h" #include "Poco/Net/HTTPBasicCredentials.h" #include "Poco/Net/HTTPDigestCredentials.h" #include "Poco/Net/HTTPNTLMCredentials.h" +#include "Poco/Net/ProxyConfig.h" #include "Poco/Net/SocketAddress.h" #include "Poco/SharedPtr.h" #include @@ -32,7 +34,6 @@ namespace Poco { namespace Net { - class HTTPRequest; class HTTPResponse; @@ -65,40 +66,6 @@ class Net_API HTTPClientSession: public HTTPSession /// set up a session through a proxy. { public: - enum ProxyAuthentication - { - PROXY_AUTH_NONE, /// No proxy authentication - PROXY_AUTH_HTTP_BASIC, /// HTTP Basic proxy authentication (default, if username and password are supplied) - PROXY_AUTH_HTTP_DIGEST, /// HTTP Digest proxy authentication - PROXY_AUTH_NTLM /// NTLMv2 proxy authentication - }; - - struct ProxyConfig - /// HTTP proxy server configuration. - { - ProxyConfig(): - port(HTTP_PORT), - authMethod(PROXY_AUTH_HTTP_BASIC) - { - } - - std::string host; - /// Proxy server host name or IP address. - Poco::UInt16 port; - /// Proxy server TCP port. - std::string username; - /// Proxy server username. - std::string password; - /// Proxy server password. - std::string nonProxyHosts; - /// A regular expression defining hosts for which the proxy should be bypassed, - /// e.g. "localhost|127\.0\.0\.1|192\.168\.0\.\d+". Can also be an empty - /// string to disable proxy bypassing. - - ProxyAuthentication authMethod; - /// The authentication method to use - HTTP Basic or NTLM. - }; - HTTPClientSession(); /// Creates an unconnected HTTPClientSession. @@ -167,8 +134,8 @@ class Net_API HTTPClientSession: public HTTPSession const SocketAddress& getSourceAddress6(); /// Returns the last IPV6 source address set with setSourceAddress - void setProxy(const std::string& host, Poco::UInt16 port = HTTPSession::HTTP_PORT); - /// Sets the proxy host name and port number. + void setProxy(const std::string& host, Poco::UInt16 port = HTTPSession::HTTP_PORT, const std::string& protocol = "http", bool tunnel = true); + /// Sets the proxy host name, port number, protocol (http or https) and tunnel behaviour. void setProxyHost(const std::string& host); /// Sets the host name of the proxy server. @@ -176,12 +143,24 @@ class Net_API HTTPClientSession: public HTTPSession void setProxyPort(Poco::UInt16 port); /// Sets the port number of the proxy server. + void setProxyProtocol(const std::string& protocol); + /// Sets the proxy protocol (http or https). + + void setProxyTunnel(bool tunnel); + /// If 'true' proxy will be used as tunnel. + const std::string& getProxyHost() const; /// Returns the proxy host name. Poco::UInt16 getProxyPort() const; /// Returns the proxy port number. + const std::string& getProxyProtocol() const; + /// Returns the proxy protocol. + + bool isProxyTunnel() const; + /// Returns 'true' if proxy is configured as tunnel. + void setProxyCredentials(const std::string& username, const std::string& password); /// Sets the username and password for proxy authentication. /// Only Basic authentication is supported. @@ -363,6 +342,8 @@ class Net_API HTTPClientSession: public HTTPSession /// Calls proxyConnect() and attaches the resulting StreamSocket /// to the HTTPClientSession. + HTTPSessionFactory _proxySessionFactory; + /// Factory to create HTTPClientSession to proxy. private: using OStreamPtr = Poco::SharedPtr; using IStreamPtr = Poco::SharedPtr; @@ -422,6 +403,18 @@ inline Poco::UInt16 HTTPClientSession::getProxyPort() const } +inline const std::string& HTTPClientSession::getProxyProtocol() const +{ + return _proxyConfig.protocol; +} + + +inline bool HTTPClientSession::isProxyTunnel() const +{ + return _proxyConfig.tunnel; +} + + inline const std::string& HTTPClientSession::getProxyUsername() const { return _proxyConfig.username; @@ -434,13 +427,13 @@ inline const std::string& HTTPClientSession::getProxyPassword() const } -inline const HTTPClientSession::ProxyConfig& HTTPClientSession::getProxyConfig() const +inline const ProxyConfig& HTTPClientSession::getProxyConfig() const { return _proxyConfig; } -inline const HTTPClientSession::ProxyConfig& HTTPClientSession::getGlobalProxyConfig() +inline const ProxyConfig& HTTPClientSession::getGlobalProxyConfig() { return _globalProxyConfig; } diff --git a/Net/include/Poco/Net/HTTPSessionFactory.h b/Net/include/Poco/Net/HTTPSessionFactory.h index 58bbc7a3ff..28fc2e4828 100644 --- a/Net/include/Poco/Net/HTTPSessionFactory.h +++ b/Net/include/Poco/Net/HTTPSessionFactory.h @@ -19,7 +19,7 @@ #include "Poco/Net/Net.h" -#include "Poco/Net/HTTPClientSession.h" +#include "Poco/Net/ProxyConfig.h" #include "Poco/Mutex.h" #include "Poco/URI.h" #include "Poco/SingletonHolder.h" @@ -30,7 +30,7 @@ namespace Poco { namespace Net { - +class HTTPClientSession; class HTTPSessionInstantiator; @@ -52,7 +52,7 @@ class Net_API HTTPSessionFactory HTTPSessionFactory(const std::string& proxyHost, Poco::UInt16 proxyPort); /// Creates the HTTPSessionFactory and sets the proxy host and port. - HTTPSessionFactory(const HTTPClientSession::ProxyConfig& proxyConfig); + HTTPSessionFactory(const ProxyConfig& proxyConfig); /// Creates the HTTPSessionFactory and sets the proxy configuration. ~HTTPSessionFactory(); @@ -97,10 +97,10 @@ class Net_API HTTPSessionFactory const std::string& proxyPassword() const; /// Returns the password for proxy authorization. - void setProxyConfig(const HTTPClientSession::ProxyConfig& proxyConfig); + void setProxyConfig(const ProxyConfig& proxyConfig); /// Sets the proxy configuration. - const HTTPClientSession::ProxyConfig& getProxyConfig() const; + const ProxyConfig& getProxyConfig() const; /// Returns the proxy configuration. static HTTPSessionFactory& defaultFactory(); @@ -122,7 +122,7 @@ class Net_API HTTPSessionFactory typedef std::map Instantiators; Instantiators _instantiators; - HTTPClientSession::ProxyConfig _proxyConfig; + ProxyConfig _proxyConfig; mutable Poco::FastMutex _mutex; }; @@ -155,7 +155,7 @@ inline const std::string& HTTPSessionFactory::proxyPassword() const } -inline const HTTPClientSession::ProxyConfig& HTTPSessionFactory::getProxyConfig() const +inline const ProxyConfig& HTTPSessionFactory::getProxyConfig() const { return _proxyConfig; } diff --git a/Net/include/Poco/Net/HTTPSessionInstantiator.h b/Net/include/Poco/Net/HTTPSessionInstantiator.h index 3cfedfa91c..45b35081cd 100644 --- a/Net/include/Poco/Net/HTTPSessionInstantiator.h +++ b/Net/include/Poco/Net/HTTPSessionInstantiator.h @@ -52,14 +52,14 @@ class Net_API HTTPSessionInstantiator /// Unregisters the factory with the global HTTPSessionFactory. protected: - void setProxyConfig(const HTTPClientSession::ProxyConfig& proxyConfig); + void setProxyConfig(const ProxyConfig& proxyConfig); /// Sets the proxy configuration. - const HTTPClientSession::ProxyConfig& getProxyConfig() const; + const ProxyConfig& getProxyConfig() const; /// Returns the proxy configuration. private: - HTTPClientSession::ProxyConfig _proxyConfig; + ProxyConfig _proxyConfig; friend class HTTPSessionFactory; }; @@ -68,7 +68,7 @@ class Net_API HTTPSessionInstantiator // // inlines // -inline const HTTPClientSession::ProxyConfig& HTTPSessionInstantiator::getProxyConfig() const +inline const ProxyConfig& HTTPSessionInstantiator::getProxyConfig() const { return _proxyConfig; } diff --git a/Net/include/Poco/Net/ProxyConfig.h b/Net/include/Poco/Net/ProxyConfig.h new file mode 100644 index 0000000000..b9d5f05dac --- /dev/null +++ b/Net/include/Poco/Net/ProxyConfig.h @@ -0,0 +1,65 @@ +// +// ProxyConfig.h +// +// Library: Net +// Package: HTTP +// Module: ProxyConfig +// +// Definition of the ProxyConfig class. +// +// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + +#ifndef Net_ProxyConfig_INCLUDED +#define Net_ProxyConfig_INCLUDED + +#include "Poco/Net/Net.h" +#include "Poco/Net/HTTPSession.h" + +namespace Poco { +namespace Net { + enum ProxyAuthentication { + PROXY_AUTH_NONE, /// No proxy authentication + PROXY_AUTH_HTTP_BASIC, /// HTTP Basic proxy authentication (default, if username and password are supplied) + PROXY_AUTH_HTTP_DIGEST, /// HTTP Digest proxy authentication + PROXY_AUTH_NTLM /// NTLMv2 proxy authentication + }; + + struct ProxyConfig + /// HTTP proxy server configuration. + { + ProxyConfig() : + port(HTTPSession::HTTP_PORT), + protocol("http"), + tunnel(true), + authMethod(PROXY_AUTH_HTTP_BASIC) { + } + + std::string host; + /// Proxy server host name or IP address. + Poco::UInt16 port; + /// Proxy server TCP port. + std::string protocol; + /// Protocol to use (http or https). + bool tunnel; + /// Use proxy as tunnel (establish 2-way communication through CONNECT request). + /// If tunnel option is 'false' request will be send directly to proxy without CONNECT request. + std::string username; + /// Proxy server username. + std::string password; + /// Proxy server password. + std::string nonProxyHosts; + /// A regular expression defining hosts for which the proxy should be bypassed, + /// e.g. "localhost|127\.0\.0\.1|192\.168\.0\.\d+". Can also be an empty + /// string to disable proxy bypassing. + + ProxyAuthentication authMethod; + /// The authentication method to use - HTTP Basic or NTLM. + }; + +} } // namespace Poco::Net + +#endif // Net_ProxyConfig_INCLUDED diff --git a/Net/src/HTTPClientSession.cpp b/Net/src/HTTPClientSession.cpp index 7197e26adb..0b17a8a7e9 100644 --- a/Net/src/HTTPClientSession.cpp +++ b/Net/src/HTTPClientSession.cpp @@ -13,6 +13,8 @@ #include "Poco/Net/HTTPClientSession.h" +#include "Poco/Net/HTTPSessionFactory.h" +#include "Poco/Net/HTTPSessionInstantiator.h" #include "Poco/Net/HTTPRequest.h" #include "Poco/Net/HTTPResponse.h" #include "Poco/Net/HTTPHeaderStream.h" @@ -35,7 +37,7 @@ namespace Poco { namespace Net { -HTTPClientSession::ProxyConfig HTTPClientSession::_globalProxyConfig; +ProxyConfig HTTPClientSession::_globalProxyConfig; HTTPClientSession::HTTPClientSession(): @@ -50,6 +52,7 @@ HTTPClientSession::HTTPClientSession(): _responseReceived(false), _ntlmProxyAuthenticated(false) { + _proxySessionFactory.registerProtocol("http", new HTTPSessionInstantiator); } @@ -66,6 +69,7 @@ HTTPClientSession::HTTPClientSession(const StreamSocket& socket): _responseReceived(false), _ntlmProxyAuthenticated(false) { + _proxySessionFactory.registerProtocol("http", new HTTPSessionInstantiator); } @@ -82,6 +86,7 @@ HTTPClientSession::HTTPClientSession(const SocketAddress& address): _responseReceived(false), _ntlmProxyAuthenticated(false) { + _proxySessionFactory.registerProtocol("http", new HTTPSessionInstantiator); } @@ -98,6 +103,7 @@ HTTPClientSession::HTTPClientSession(const std::string& host, Poco::UInt16 port) _responseReceived(false), _ntlmProxyAuthenticated(false) { + _proxySessionFactory.registerProtocol("http", new HTTPSessionInstantiator); } @@ -127,11 +133,13 @@ HTTPClientSession::HTTPClientSession(const StreamSocket& socket, const ProxyConf _expectResponseBody(false), _responseReceived(false) { + _proxySessionFactory.registerProtocol("http", new HTTPSessionInstantiator); } HTTPClientSession::~HTTPClientSession() { + _proxySessionFactory.unregisterProtocol("http"); } @@ -186,14 +194,19 @@ const SocketAddress& HTTPClientSession::getSourceAddress6() } -void HTTPClientSession::setProxy(const std::string& host, Poco::UInt16 port) +void HTTPClientSession::setProxy(const std::string& host, Poco::UInt16 port, const std::string& protocol, bool tunnel) { - if (!connected()) + if (protocol != "http" && protocol != "https") + throw IllegalStateException("Protocol must be either http or https"); + + if (!connected()) { _proxyConfig.host = host; _proxyConfig.port = port; + _proxyConfig.protocol = protocol; + _proxyConfig.tunnel = tunnel; } - else throw IllegalStateException("Cannot set the proxy host and port for an already connected session"); + else throw IllegalStateException("Cannot set the proxy host, port and protocol for an already connected session"); } @@ -215,6 +228,28 @@ void HTTPClientSession::setProxyPort(Poco::UInt16 port) } +void HTTPClientSession::setProxyProtocol(const std::string& protocol) +{ + if (protocol != "http" && protocol != "https") + throw IllegalStateException("Protocol must be either http or https"); + + if (!connected()) + _proxyConfig.protocol = protocol; + else + throw IllegalStateException("Cannot set the proxy port number for an already connected session"); +} + + +void HTTPClientSession::setProxyTunnel(bool tunnel) +{ + if (!connected()) + _proxyConfig.tunnel = tunnel; + else + throw IllegalStateException("Cannot set the proxy tunnel for an already connected session"); + +} + + void HTTPClientSession::setProxyCredentials(const std::string& username, const std::string& password) { _proxyConfig.username = username; @@ -476,8 +511,13 @@ std::string HTTPClientSession::proxyRequestPrefix() const { std::string result("http://"); result.append(_host); - result.append(":"); - NumberFormatter::append(result, _port); + /// Do not append default by default, since this may break some servers. + /// One example of such server is GCS (Google Cloud Storage). + if (_port != HTTPSession::HTTP_PORT) + { + result.append(":"); + NumberFormatter::append(result, _port); + } return result; } @@ -583,25 +623,30 @@ void HTTPClientSession::sendChallengeRequest(const HTTPRequest& request, HTTPRes StreamSocket HTTPClientSession::proxyConnect() { - ProxyConfig emptyProxyConfig; - HTTPClientSession proxySession(getProxyHost(), getProxyPort(), emptyProxyConfig); - proxySession.setTimeout(getTimeout()); + URI proxyUri; + proxyUri.setScheme(getProxyProtocol()); + proxyUri.setHost(getProxyHost()); + proxyUri.setPort(getProxyPort()); + + SharedPtr proxySession (_proxySessionFactory.createClientSession(proxyUri)); + + proxySession->setTimeout(getTimeout()); std::string targetAddress(_host); targetAddress.append(":"); NumberFormatter::append(targetAddress, _port); HTTPRequest proxyRequest(HTTPRequest::HTTP_CONNECT, targetAddress, HTTPMessage::HTTP_1_1); HTTPResponse proxyResponse; proxyRequest.set(HTTPMessage::PROXY_CONNECTION, HTTPMessage::CONNECTION_KEEP_ALIVE); - proxyRequest.set(HTTPRequest::HOST, getHost()); - proxySession.proxyAuthenticateImpl(proxyRequest, _proxyConfig); - proxySession.setKeepAlive(true); - proxySession.setSourceAddress(_sourceAddress4); - proxySession.setSourceAddress(_sourceAddress6); - proxySession.sendRequest(proxyRequest); - proxySession.receiveResponse(proxyResponse); + proxyRequest.set(HTTPRequest::HOST, targetAddress); + 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) throw HTTPException("Cannot establish proxy connection", proxyResponse.getReason()); - return proxySession.detachSocket(); + return proxySession->detachSocket(); } @@ -621,5 +666,4 @@ bool HTTPClientSession::bypassProxy() const else return false; } - } } // namespace Poco::Net diff --git a/Net/src/HTTPSessionFactory.cpp b/Net/src/HTTPSessionFactory.cpp index 01b86666b2..352e34f554 100644 --- a/Net/src/HTTPSessionFactory.cpp +++ b/Net/src/HTTPSessionFactory.cpp @@ -39,7 +39,7 @@ HTTPSessionFactory::HTTPSessionFactory(const std::string& proxyHost, Poco::UInt1 } -HTTPSessionFactory::HTTPSessionFactory(const HTTPClientSession::ProxyConfig& proxyConfig): +HTTPSessionFactory::HTTPSessionFactory(const ProxyConfig& proxyConfig): _proxyConfig(proxyConfig) { } @@ -129,7 +129,7 @@ void HTTPSessionFactory::setProxyCredentials(const std::string& username, const } -void HTTPSessionFactory::setProxyConfig(const HTTPClientSession::ProxyConfig& proxyConfig) +void HTTPSessionFactory::setProxyConfig(const ProxyConfig& proxyConfig) { FastMutex::ScopedLock lock(_mutex); diff --git a/Net/src/HTTPSessionInstantiator.cpp b/Net/src/HTTPSessionInstantiator.cpp index e92d8a4de5..71a31a79d0 100644 --- a/Net/src/HTTPSessionInstantiator.cpp +++ b/Net/src/HTTPSessionInstantiator.cpp @@ -58,7 +58,7 @@ void HTTPSessionInstantiator::unregisterInstantiator() } -void HTTPSessionInstantiator::setProxyConfig(const HTTPClientSession::ProxyConfig& proxyConfig) +void HTTPSessionInstantiator::setProxyConfig(const ProxyConfig& proxyConfig) { _proxyConfig = proxyConfig; } diff --git a/Net/testsuite/src/HTTPClientSessionTest.cpp b/Net/testsuite/src/HTTPClientSessionTest.cpp index b7bf375e4d..ab5279153c 100644 --- a/Net/testsuite/src/HTTPClientSessionTest.cpp +++ b/Net/testsuite/src/HTTPClientSessionTest.cpp @@ -22,6 +22,7 @@ using Poco::Net::HTTPClientSession; +using Poco::Net::ProxyConfig; using Poco::Net::HTTPRequest; using Poco::Net::HTTPResponse; using Poco::Net::HTTPMessage; @@ -298,7 +299,7 @@ void HTTPClientSessionTest::testProxyAuth() void HTTPClientSessionTest::testBypassProxy() { - HTTPClientSession::ProxyConfig proxyConfig; + ProxyConfig proxyConfig; proxyConfig.host = "proxy.domain.com"; proxyConfig.port = 80; proxyConfig.nonProxyHosts = "localhost|127\\.0\\.0\\.1"; diff --git a/NetSSL_OpenSSL/src/HTTPSClientSession.cpp b/NetSSL_OpenSSL/src/HTTPSClientSession.cpp index 73cc3f61dd..a48b620a9e 100644 --- a/NetSSL_OpenSSL/src/HTTPSClientSession.cpp +++ b/NetSSL_OpenSSL/src/HTTPSClientSession.cpp @@ -13,6 +13,7 @@ #include "Poco/Net/HTTPSClientSession.h" +#include "Poco/Net/HTTPSSessionInstantiator.h" #include "Poco/Net/SecureStreamSocket.h" #include "Poco/Net/SecureStreamSocketImpl.h" #include "Poco/Net/SSLManager.h" @@ -36,6 +37,7 @@ HTTPSClientSession::HTTPSClientSession(): _pContext(SSLManager::instance().defaultClientContext()) { setPort(HTTPS_PORT); + _proxySessionFactory.registerProtocol("https", new HTTPSSessionInstantiator); } @@ -44,6 +46,7 @@ HTTPSClientSession::HTTPSClientSession(const SecureStreamSocket& socket): _pContext(socket.context()) { setPort(HTTPS_PORT); + _proxySessionFactory.registerProtocol("https", new HTTPSSessionInstantiator); } @@ -53,6 +56,7 @@ HTTPSClientSession::HTTPSClientSession(const SecureStreamSocket& socket, Session _pSession(pSession) { setPort(HTTPS_PORT); + _proxySessionFactory.registerProtocol("https", new HTTPSSessionInstantiator); } @@ -62,6 +66,7 @@ HTTPSClientSession::HTTPSClientSession(const std::string& host, Poco::UInt16 por { setHost(host); setPort(port); + _proxySessionFactory.registerProtocol("https", new HTTPSSessionInstantiator); } @@ -69,6 +74,7 @@ HTTPSClientSession::HTTPSClientSession(Context::Ptr pContext): HTTPClientSession(SecureStreamSocket(pContext)), _pContext(pContext) { + _proxySessionFactory.registerProtocol("https", new HTTPSSessionInstantiator(pContext)); } @@ -77,6 +83,7 @@ HTTPSClientSession::HTTPSClientSession(Context::Ptr pContext, Session::Ptr pSess _pContext(pContext), _pSession(pSession) { + _proxySessionFactory.registerProtocol("https", new HTTPSSessionInstantiator(pContext)); } @@ -86,6 +93,7 @@ HTTPSClientSession::HTTPSClientSession(const std::string& host, Poco::UInt16 por { setHost(host); setPort(port); + _proxySessionFactory.registerProtocol("https", new HTTPSSessionInstantiator(pContext)); } @@ -96,11 +104,13 @@ HTTPSClientSession::HTTPSClientSession(const std::string& host, Poco::UInt16 por { setHost(host); setPort(port); + _proxySessionFactory.registerProtocol("https", new HTTPSSessionInstantiator(pContext)); } HTTPSClientSession::~HTTPSClientSession() { + _proxySessionFactory.unregisterProtocol("https"); } @@ -126,7 +136,15 @@ X509Certificate HTTPSClientSession::serverCertificate() std::string HTTPSClientSession::proxyRequestPrefix() const { - return std::string(); + std::string result("https://"); + result.append(getHost()); + /// Do not append default by default, since this may break some servers. + /// One example of such server is GCS (Google Cloud Storage). + if (getPort() != HTTPS_PORT) { + result.append(":"); + NumberFormatter::append(result, getPort()); + } + return result; } @@ -137,33 +155,35 @@ void HTTPSClientSession::proxyAuthenticate(HTTPRequest& request) void HTTPSClientSession::connect(const SocketAddress& address) { - if (getProxyHost().empty() || bypassProxy()) - { - SecureStreamSocket sss(socket()); - if (sss.getPeerHostName().empty()) - { - sss.setPeerHostName(getHost()); - } - if (_pContext->sessionCacheEnabled()) - { - sss.useSession(_pSession); - } - HTTPSession::connect(address); - if (_pContext->sessionCacheEnabled()) - { - _pSession = sss.currentSession(); - } - } - else - { - StreamSocket proxySocket(proxyConnect()); - SecureStreamSocket secureSocket = SecureStreamSocket::attach(proxySocket, getHost(), _pContext, _pSession); - attachSocket(secureSocket); - if (_pContext->sessionCacheEnabled()) - { - _pSession = secureSocket.currentSession(); - } - } + bool useProxy = !getProxyHost().empty() && !bypassProxy(); + + if (useProxy && isProxyTunnel()) + { + StreamSocket proxySocket(proxyConnect()); + SecureStreamSocket secureSocket = SecureStreamSocket::attach(proxySocket, getHost(), _pContext, _pSession); + attachSocket(secureSocket); + if (_pContext->sessionCacheEnabled()) + { + _pSession = secureSocket.currentSession(); + } + } + else + { + SecureStreamSocket sss(socket()); + if (sss.getPeerHostName().empty()) + { + sss.setPeerHostName(useProxy ? getProxyHost() : getHost()); + } + if (_pContext->sessionCacheEnabled()) + { + sss.useSession(_pSession); + } + HTTPSession::connect(address); + if (_pContext->sessionCacheEnabled()) + { + _pSession = sss.currentSession(); + } + } }