fix(HTTPSClientSession): There is no way to resolve host in advance and connect to HTTPS server with SNI. #4395 (#4751)

This commit is contained in:
Aleksandar Fabijanic
2024-11-05 13:46:42 -06:00
committed by GitHub
parent ca63bf0db9
commit c156f0b357
6 changed files with 53 additions and 4 deletions

View File

@@ -78,10 +78,12 @@ public:
HTTPSClientSession(); HTTPSClientSession();
/// Creates an unconnected HTTPSClientSession. /// Creates an unconnected HTTPSClientSession.
explicit HTTPSClientSession(const SecureStreamSocket& socket); explicit HTTPSClientSession(const SecureStreamSocket& socket, const std::string& host, Poco::UInt16 port = HTTPS_PORT);
/// Creates a HTTPSClientSession using the given socket. /// Creates a HTTPSClientSession using the given socket.
/// The socket must not be connected. The session /// The socket must not be connected. The session
/// takes ownership of the socket. /// takes ownership of the socket.
///
/// The given host name is used for certificate verification.
HTTPSClientSession(const SecureStreamSocket& socket, Session::Ptr pSession); HTTPSClientSession(const SecureStreamSocket& socket, Session::Ptr pSession);
/// Creates a HTTPSClientSession using the given socket. /// Creates a HTTPSClientSession using the given socket.

View File

@@ -108,6 +108,12 @@ public:
/// ///
/// The given host name is used for certificate verification. /// The given host name is used for certificate verification.
SecureStreamSocket(const std::string& hostName);
/// Creates a secure stream socket using the default
/// client SSL context. The created socket is not connected.
///
/// The given host name is used for certificate verification.
SecureStreamSocket(const SocketAddress& address, const std::string& hostName, Context::Ptr pContext); SecureStreamSocket(const SocketAddress& address, const std::string& hostName, Context::Ptr pContext);
/// Creates a secure stream socket using the given /// Creates a secure stream socket using the given
/// client SSL context and connects it to /// client SSL context and connects it to
@@ -115,6 +121,12 @@ public:
/// ///
/// The given host name is used for certificate verification. /// The given host name is used for certificate verification.
SecureStreamSocket(const std::string& hostName, Context::Ptr pContext);
/// Creates a secure stream socket using the given
/// client SSL context. The created socket is not connected.
///
/// The given host name is used for certificate verification.
SecureStreamSocket(const SocketAddress& address, const std::string& hostName, Context::Ptr pContext, Session::Ptr pSession); SecureStreamSocket(const SocketAddress& address, const std::string& hostName, Context::Ptr pContext, Session::Ptr pSession);
/// Creates a secure stream socket using the given /// Creates a secure stream socket using the given
/// client SSL context and connects it to /// client SSL context and connects it to

View File

@@ -39,11 +39,12 @@ HTTPSClientSession::HTTPSClientSession():
} }
HTTPSClientSession::HTTPSClientSession(const SecureStreamSocket& socket): HTTPSClientSession::HTTPSClientSession(const SecureStreamSocket& socket, const std::string& host, Poco::UInt16 port):
HTTPClientSession(socket), HTTPClientSession(socket),
_pContext(socket.context()) _pContext(socket.context())
{ {
setPort(HTTPS_PORT); setHost(host);
setPort(port);
} }

View File

@@ -60,6 +60,13 @@ SecureStreamSocket::SecureStreamSocket(const SocketAddress& address, const std::
} }
SecureStreamSocket::SecureStreamSocket(const std::string& hostName):
StreamSocket(new SecureStreamSocketImpl(SSLManager::instance().defaultClientContext()))
{
static_cast<SecureStreamSocketImpl*>(impl())->setPeerHostName(hostName);
}
SecureStreamSocket::SecureStreamSocket(const SocketAddress& address, Context::Ptr pContext): SecureStreamSocket::SecureStreamSocket(const SocketAddress& address, Context::Ptr pContext):
StreamSocket(new SecureStreamSocketImpl(pContext)) StreamSocket(new SecureStreamSocketImpl(pContext))
{ {
@@ -83,6 +90,13 @@ SecureStreamSocket::SecureStreamSocket(const SocketAddress& address, const std::
} }
SecureStreamSocket::SecureStreamSocket(const std::string& hostName, Context::Ptr pContext):
StreamSocket(new SecureStreamSocketImpl(pContext))
{
static_cast<SecureStreamSocketImpl*>(impl())->setPeerHostName(hostName);
}
SecureStreamSocket::SecureStreamSocket(const SocketAddress& address, const std::string& hostName, Context::Ptr pContext, Session::Ptr pSession): SecureStreamSocket::SecureStreamSocket(const SocketAddress& address, const std::string& hostName, Context::Ptr pContext, Session::Ptr pSession):
StreamSocket(new SecureStreamSocketImpl(pContext)) StreamSocket(new SecureStreamSocketImpl(pContext))
{ {

View File

@@ -88,6 +88,23 @@ HTTPSClientSessionTest::~HTTPSClientSessionTest()
} }
void HTTPSClientSessionTest::testFromSocket()
{
HTTPSTestServer srv;
SecureStreamSocket sss("localhost");
HTTPSClientSession s(sss, "127.0.0.1", srv.port());
HTTPRequest request(HTTPRequest::HTTP_GET, "/small");
s.sendRequest(request);
HTTPResponse response;
std::istream& rs = s.receiveResponse(response);
assertTrue (response.getContentLength() == HTTPSTestServer::SMALL_BODY.length());
assertTrue (response.getContentType() == "text/plain");
std::ostringstream ostr;
StreamCopier::copyStream(rs, ostr);
assertTrue (ostr.str() == HTTPSTestServer::SMALL_BODY);
}
void HTTPSClientSessionTest::testGetSmall() void HTTPSClientSessionTest::testGetSmall()
{ {
HTTPSTestServer srv; HTTPSTestServer srv;
@@ -458,6 +475,7 @@ void HTTPSClientSessionTest::testUnknownContentLength()
assertTrue (ostr.str() == HTTPSTestServer::SMALL_BODY); assertTrue (ostr.str() == HTTPSTestServer::SMALL_BODY);
} }
void HTTPSClientSessionTest::testServerAbort() void HTTPSClientSessionTest::testServerAbort()
{ {
HTTPSTestServer srv; HTTPSTestServer srv;
@@ -471,7 +489,7 @@ void HTTPSClientSessionTest::testServerAbort()
std::ostringstream ostr; std::ostringstream ostr;
StreamCopier::copyStream(rs, ostr); StreamCopier::copyStream(rs, ostr);
assertTrue (ostr.str() == HTTPSTestServer::SMALL_BODY); assertTrue (ostr.str() == HTTPSTestServer::SMALL_BODY);
assertTrue ( dynamic_cast<const Poco::Net::SSLConnectionUnexpectedlyClosedException*>( assertTrue (dynamic_cast<const Poco::Net::SSLConnectionUnexpectedlyClosedException*>(
s.networkException()) != NULL ); s.networkException()) != NULL );
} }
@@ -490,6 +508,7 @@ CppUnit::Test* HTTPSClientSessionTest::suite()
{ {
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("HTTPSClientSessionTest"); CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("HTTPSClientSessionTest");
CppUnit_addTest(pSuite, HTTPSClientSessionTest, testFromSocket);
CppUnit_addTest(pSuite, HTTPSClientSessionTest, testGetSmall); CppUnit_addTest(pSuite, HTTPSClientSessionTest, testGetSmall);
CppUnit_addTest(pSuite, HTTPSClientSessionTest, testGetLarge); CppUnit_addTest(pSuite, HTTPSClientSessionTest, testGetLarge);
CppUnit_addTest(pSuite, HTTPSClientSessionTest, testHead); CppUnit_addTest(pSuite, HTTPSClientSessionTest, testHead);

View File

@@ -24,6 +24,7 @@ public:
HTTPSClientSessionTest(const std::string& name); HTTPSClientSessionTest(const std::string& name);
~HTTPSClientSessionTest(); ~HTTPSClientSessionTest();
void testFromSocket();
void testGetSmall(); void testGetSmall();
void testGetLarge(); void testGetLarge();
void testHead(); void testHead();