From c7b0c66ab960959b5ba68c1b49848f63a906877f Mon Sep 17 00:00:00 2001 From: Pavel Kovalenko Date: Fri, 19 Jun 2020 14:21:50 +0300 Subject: [PATCH 1/3] HTTPS proxy support --- Net/include/Poco/Net/HTTPClientSession.h | 38 +++++++++++- Net/src/HTTPClientSession.cpp | 60 +++++++++++++++---- NetSSL_OpenSSL/src/HTTPSClientSession.cpp | 72 ++++++++++++++--------- 3 files changed, 128 insertions(+), 42 deletions(-) diff --git a/Net/include/Poco/Net/HTTPClientSession.h b/Net/include/Poco/Net/HTTPClientSession.h index 2f2e21c599..618ea30264 100644 --- a/Net/include/Poco/Net/HTTPClientSession.h +++ b/Net/include/Poco/Net/HTTPClientSession.h @@ -20,6 +20,7 @@ #include "Poco/Net/Net.h" #include "Poco/Net/HTTPSession.h" +#include "Poco/Net/HTTPSessionFactory.h" #include "Poco/Net/SocketAddress.h" #include "Poco/SharedPtr.h" #include @@ -66,7 +67,7 @@ class Net_API HTTPClientSession: public HTTPSession /// HTTP proxy server configuration. { ProxyConfig(): - port(HTTP_PORT) + port(HTTP_PORT), protocol("http"), tunnel(true) { } @@ -74,6 +75,11 @@ class Net_API HTTPClientSession: public HTTPSession /// 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; @@ -123,8 +129,8 @@ class Net_API HTTPClientSession: public HTTPSession Poco::UInt16 getPort() const; /// Returns the port number of the target HTTP server. - 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. @@ -132,12 +138,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. @@ -306,6 +324,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: std::string _host; Poco::UInt16 _port; @@ -355,6 +375,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; diff --git a/Net/src/HTTPClientSession.cpp b/Net/src/HTTPClientSession.cpp index 6918417a0e..16e3a8b0a7 100644 --- a/Net/src/HTTPClientSession.cpp +++ b/Net/src/HTTPClientSession.cpp @@ -13,6 +13,7 @@ #include "Poco/Net/HTTPClientSession.h" +#include "Poco/Net/HTTPSessionInstantiator.h" #include "Poco/Net/HTTPRequest.h" #include "Poco/Net/HTTPResponse.h" #include "Poco/Net/HTTPHeaderStream.h" @@ -47,6 +48,7 @@ HTTPClientSession::HTTPClientSession(): _expectResponseBody(false), _responseReceived(false) { + _proxySessionFactory.registerProtocol("http", new HTTPSessionInstantiator); } @@ -60,6 +62,7 @@ HTTPClientSession::HTTPClientSession(const StreamSocket& socket): _expectResponseBody(false), _responseReceived(false) { + _proxySessionFactory.registerProtocol("http", new HTTPSessionInstantiator); } @@ -73,6 +76,7 @@ HTTPClientSession::HTTPClientSession(const SocketAddress& address): _expectResponseBody(false), _responseReceived(false) { + _proxySessionFactory.registerProtocol("http", new HTTPSessionInstantiator); } @@ -86,6 +90,7 @@ HTTPClientSession::HTTPClientSession(const std::string& host, Poco::UInt16 port) _expectResponseBody(false), _responseReceived(false) { + _proxySessionFactory.registerProtocol("http", new HTTPSessionInstantiator); } @@ -99,11 +104,13 @@ HTTPClientSession::HTTPClientSession(const std::string& host, Poco::UInt16 port, _expectResponseBody(false), _responseReceived(false) { + _proxySessionFactory.registerProtocol("http", new HTTPSessionInstantiator); } HTTPClientSession::~HTTPClientSession() { + _proxySessionFactory.unregisterProtocol("http"); } @@ -125,14 +132,19 @@ void HTTPClientSession::setPort(Poco::UInt16 port) } -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 (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"); } @@ -154,6 +166,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; @@ -430,23 +464,28 @@ void HTTPClientSession::proxyAuthenticateImpl(HTTPRequest& request) 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 (HTTPSessionFactory::defaultFactory().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("Proxy-Connection", "keep-alive"); - proxyRequest.set("Host", getHost()); + proxyRequest.set("Host", targetAddress); proxyAuthenticateImpl(proxyRequest); - proxySession.setKeepAlive(true); - proxySession.sendRequest(proxyRequest); - proxySession.receiveResponse(proxyResponse); + proxySession->setKeepAlive(true); + 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(); } @@ -466,5 +505,4 @@ bool HTTPClientSession::bypassProxy() const else return false; } - } } // namespace Poco::Net diff --git a/NetSSL_OpenSSL/src/HTTPSClientSession.cpp b/NetSSL_OpenSSL/src/HTTPSClientSession.cpp index 325f36a60a..8a2cff2160 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,11 @@ X509Certificate HTTPSClientSession::serverCertificate() std::string HTTPSClientSession::proxyRequestPrefix() const { - return std::string(); + std::string result("https://"); + result.append(getHost()); + result.append(":"); + NumberFormatter::append(result, getPort()); + return result; } @@ -137,33 +151,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(); + } + } } From 6008337c5de549521f11d5e778ba27d472515676 Mon Sep 17 00:00:00 2001 From: Pavel Kovalenko Date: Fri, 19 Jun 2020 14:41:48 +0300 Subject: [PATCH 2/3] HTTPS Proxy better formatting --- Net/include/Poco/Net/HTTPClientSession.h | 18 ++--- Net/src/HTTPClientSession.cpp | 46 ++++++------- NetSSL_OpenSSL/src/HTTPSClientSession.cpp | 84 +++++++++++------------ 3 files changed, 74 insertions(+), 74 deletions(-) diff --git a/Net/include/Poco/Net/HTTPClientSession.h b/Net/include/Poco/Net/HTTPClientSession.h index 618ea30264..dc3272ed17 100644 --- a/Net/include/Poco/Net/HTTPClientSession.h +++ b/Net/include/Poco/Net/HTTPClientSession.h @@ -76,10 +76,10 @@ class Net_API HTTPClientSession: public HTTPSession 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. + /// 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; @@ -139,7 +139,7 @@ class Net_API HTTPClientSession: public HTTPSession /// Sets the port number of the proxy server. void setProxyProtocol(const std::string& protocol); - /// Sets the proxy protocol (http or https). + /// Sets the proxy protocol (http or https). void setProxyTunnel(bool tunnel); /// If 'true' proxy will be used as tunnel. @@ -151,7 +151,7 @@ class Net_API HTTPClientSession: public HTTPSession /// Returns the proxy port number. const std::string& getProxyProtocol() const; - /// Returns the proxy protocol. + /// Returns the proxy protocol. bool isProxyTunnel() const; /// Returns 'true' if proxy is configured as tunnel. @@ -324,8 +324,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. + HTTPSessionFactory _proxySessionFactory; + /// Factory to create HTTPClientSession to proxy. private: std::string _host; Poco::UInt16 _port; @@ -377,7 +377,7 @@ inline Poco::UInt16 HTTPClientSession::getProxyPort() const inline const std::string& HTTPClientSession::getProxyProtocol() const { - return _proxyConfig.protocol; + return _proxyConfig.protocol; } diff --git a/Net/src/HTTPClientSession.cpp b/Net/src/HTTPClientSession.cpp index 16e3a8b0a7..f4b2cfe6db 100644 --- a/Net/src/HTTPClientSession.cpp +++ b/Net/src/HTTPClientSession.cpp @@ -48,7 +48,7 @@ HTTPClientSession::HTTPClientSession(): _expectResponseBody(false), _responseReceived(false) { - _proxySessionFactory.registerProtocol("http", new HTTPSessionInstantiator); + _proxySessionFactory.registerProtocol("http", new HTTPSessionInstantiator); } @@ -62,7 +62,7 @@ HTTPClientSession::HTTPClientSession(const StreamSocket& socket): _expectResponseBody(false), _responseReceived(false) { - _proxySessionFactory.registerProtocol("http", new HTTPSessionInstantiator); + _proxySessionFactory.registerProtocol("http", new HTTPSessionInstantiator); } @@ -76,7 +76,7 @@ HTTPClientSession::HTTPClientSession(const SocketAddress& address): _expectResponseBody(false), _responseReceived(false) { - _proxySessionFactory.registerProtocol("http", new HTTPSessionInstantiator); + _proxySessionFactory.registerProtocol("http", new HTTPSessionInstantiator); } @@ -90,7 +90,7 @@ HTTPClientSession::HTTPClientSession(const std::string& host, Poco::UInt16 port) _expectResponseBody(false), _responseReceived(false) { - _proxySessionFactory.registerProtocol("http", new HTTPSessionInstantiator); + _proxySessionFactory.registerProtocol("http", new HTTPSessionInstantiator); } @@ -104,13 +104,13 @@ HTTPClientSession::HTTPClientSession(const std::string& host, Poco::UInt16 port, _expectResponseBody(false), _responseReceived(false) { - _proxySessionFactory.registerProtocol("http", new HTTPSessionInstantiator); + _proxySessionFactory.registerProtocol("http", new HTTPSessionInstantiator); } HTTPClientSession::~HTTPClientSession() { - _proxySessionFactory.unregisterProtocol("http"); + _proxySessionFactory.unregisterProtocol("http"); } @@ -134,8 +134,8 @@ void HTTPClientSession::setPort(Poco::UInt16 port) void HTTPClientSession::setProxy(const std::string& host, Poco::UInt16 port, const std::string& protocol, bool tunnel) { - if (protocol != "http" && protocol != "https") - throw IllegalStateException("Protocol must be either http or https"); + if (protocol != "http" && protocol != "https") + throw IllegalStateException("Protocol must be either http or https"); if (!connected()) { @@ -168,23 +168,22 @@ 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"); + 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"); - + if (!connected()) + _proxyConfig.tunnel = tunnel; + else + throw IllegalStateException("Cannot set the proxy tunnel for an already connected session"); } @@ -465,9 +464,9 @@ void HTTPClientSession::proxyAuthenticateImpl(HTTPRequest& request) StreamSocket HTTPClientSession::proxyConnect() { URI proxyUri; - proxyUri.setScheme(getProxyProtocol()); - proxyUri.setHost(getProxyHost()); - proxyUri.setPort(getProxyPort()); + proxyUri.setScheme(getProxyProtocol()); + proxyUri.setHost(getProxyHost()); + proxyUri.setPort(getProxyPort()); SharedPtr proxySession (HTTPSessionFactory::defaultFactory().createClientSession(proxyUri)); @@ -505,4 +504,5 @@ bool HTTPClientSession::bypassProxy() const else return false; } + } } // namespace Poco::Net diff --git a/NetSSL_OpenSSL/src/HTTPSClientSession.cpp b/NetSSL_OpenSSL/src/HTTPSClientSession.cpp index 8a2cff2160..62b6f6e3ed 100644 --- a/NetSSL_OpenSSL/src/HTTPSClientSession.cpp +++ b/NetSSL_OpenSSL/src/HTTPSClientSession.cpp @@ -46,7 +46,7 @@ HTTPSClientSession::HTTPSClientSession(const SecureStreamSocket& socket): _pContext(socket.context()) { setPort(HTTPS_PORT); - _proxySessionFactory.registerProtocol("https", new HTTPSSessionInstantiator); + _proxySessionFactory.registerProtocol("https", new HTTPSSessionInstantiator); } @@ -56,7 +56,7 @@ HTTPSClientSession::HTTPSClientSession(const SecureStreamSocket& socket, Session _pSession(pSession) { setPort(HTTPS_PORT); - _proxySessionFactory.registerProtocol("https", new HTTPSSessionInstantiator); + _proxySessionFactory.registerProtocol("https", new HTTPSSessionInstantiator); } @@ -66,7 +66,7 @@ HTTPSClientSession::HTTPSClientSession(const std::string& host, Poco::UInt16 por { setHost(host); setPort(port); - _proxySessionFactory.registerProtocol("https", new HTTPSSessionInstantiator); + _proxySessionFactory.registerProtocol("https", new HTTPSSessionInstantiator); } @@ -74,7 +74,7 @@ HTTPSClientSession::HTTPSClientSession(Context::Ptr pContext): HTTPClientSession(SecureStreamSocket(pContext)), _pContext(pContext) { - _proxySessionFactory.registerProtocol("https", new HTTPSSessionInstantiator(pContext)); + _proxySessionFactory.registerProtocol("https", new HTTPSSessionInstantiator(pContext)); } @@ -83,7 +83,7 @@ HTTPSClientSession::HTTPSClientSession(Context::Ptr pContext, Session::Ptr pSess _pContext(pContext), _pSession(pSession) { - _proxySessionFactory.registerProtocol("https", new HTTPSSessionInstantiator(pContext)); + _proxySessionFactory.registerProtocol("https", new HTTPSSessionInstantiator(pContext)); } @@ -93,7 +93,7 @@ HTTPSClientSession::HTTPSClientSession(const std::string& host, Poco::UInt16 por { setHost(host); setPort(port); - _proxySessionFactory.registerProtocol("https", new HTTPSSessionInstantiator(pContext)); + _proxySessionFactory.registerProtocol("https", new HTTPSSessionInstantiator(pContext)); } @@ -104,13 +104,13 @@ HTTPSClientSession::HTTPSClientSession(const std::string& host, Poco::UInt16 por { setHost(host); setPort(port); - _proxySessionFactory.registerProtocol("https", new HTTPSSessionInstantiator(pContext)); + _proxySessionFactory.registerProtocol("https", new HTTPSSessionInstantiator(pContext)); } HTTPSClientSession::~HTTPSClientSession() { - _proxySessionFactory.unregisterProtocol("https"); + _proxySessionFactory.unregisterProtocol("https"); } @@ -136,11 +136,11 @@ X509Certificate HTTPSClientSession::serverCertificate() std::string HTTPSClientSession::proxyRequestPrefix() const { - std::string result("https://"); - result.append(getHost()); - result.append(":"); - NumberFormatter::append(result, getPort()); - return result; + std::string result("https://"); + result.append(getHost()); + result.append(":"); + NumberFormatter::append(result, getPort()); + return result; } @@ -151,35 +151,35 @@ void HTTPSClientSession::proxyAuthenticate(HTTPRequest& request) void HTTPSClientSession::connect(const SocketAddress& address) { - bool useProxy = !getProxyHost().empty() && !bypassProxy(); - + 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(); - } - } + { + 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(); + } + } } @@ -188,7 +188,7 @@ int HTTPSClientSession::read(char* buffer, std::streamsize length) try { return HTTPSession::read(buffer, length); - } + } catch(SSLConnectionUnexpectedlyClosedException&) { return 0; From 3fcdd14aa658dd077ca2133a6a103deff2aa226c Mon Sep 17 00:00:00 2001 From: Pavel Kovalenko Date: Tue, 23 Jun 2020 14:53:07 +0300 Subject: [PATCH 3/3] Use proxySessionFactory instead of default to create proxy connections. --- Net/src/HTTPClientSession.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Net/src/HTTPClientSession.cpp b/Net/src/HTTPClientSession.cpp index f4b2cfe6db..93b0eeccf7 100644 --- a/Net/src/HTTPClientSession.cpp +++ b/Net/src/HTTPClientSession.cpp @@ -468,7 +468,7 @@ StreamSocket HTTPClientSession::proxyConnect() proxyUri.setHost(getProxyHost()); proxyUri.setPort(getProxyPort()); - SharedPtr proxySession (HTTPSessionFactory::defaultFactory().createClientSession(proxyUri)); + SharedPtr proxySession (_proxySessionFactory.createClientSession(proxyUri)); proxySession->setTimeout(getTimeout()); std::string targetAddress(_host);