mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-20 05:49:04 +02:00
fix(NetSSL): Non-blocking sockets support #4773
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
|
||||
|
||||
#include "NetSSLTestSuite.h"
|
||||
|
||||
#include "SecureStreamSocketTestSuite.h"
|
||||
#include "HTTPSClientTestSuite.h"
|
||||
#include "TCPServerTestSuite.h"
|
||||
#include "HTTPSServerTestSuite.h"
|
||||
@@ -21,6 +21,7 @@ CppUnit::Test* NetSSLTestSuite::suite()
|
||||
{
|
||||
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("OpenSSLTestSuite");
|
||||
|
||||
pSuite->addTest(SecureStreamSocketTestSuite::suite());
|
||||
pSuite->addTest(HTTPSClientTestSuite::suite());
|
||||
pSuite->addTest(TCPServerTestSuite::suite());
|
||||
pSuite->addTest(HTTPSServerTestSuite::suite());
|
||||
|
222
NetSSL_OpenSSL/testsuite/src/SecureStreamSocketTest.cpp
Normal file
222
NetSSL_OpenSSL/testsuite/src/SecureStreamSocketTest.cpp
Normal file
@@ -0,0 +1,222 @@
|
||||
//
|
||||
// SecureStreamSocketTest.cpp
|
||||
//
|
||||
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "SecureStreamSocketTest.h"
|
||||
#include "CppUnit/TestCaller.h"
|
||||
#include "CppUnit/TestSuite.h"
|
||||
#include "Poco/Net/TCPServer.h"
|
||||
#include "Poco/Net/TCPServerConnection.h"
|
||||
#include "Poco/Net/TCPServerConnectionFactory.h"
|
||||
#include "Poco/Net/TCPServerParams.h"
|
||||
#include "Poco/Net/SecureStreamSocket.h"
|
||||
#include "Poco/Net/SecureServerSocket.h"
|
||||
#include "Poco/Net/Context.h"
|
||||
#include "Poco/Net/RejectCertificateHandler.h"
|
||||
#include "Poco/Net/AcceptCertificateHandler.h"
|
||||
#include "Poco/Net/Session.h"
|
||||
#include "Poco/Net/SSLManager.h"
|
||||
#include "Poco/Util/Application.h"
|
||||
#include "Poco/Util/AbstractConfiguration.h"
|
||||
#include "Poco/Thread.h"
|
||||
#include <iostream>
|
||||
|
||||
|
||||
using Poco::Net::TCPServer;
|
||||
using Poco::Net::TCPServerConnection;
|
||||
using Poco::Net::TCPServerConnectionFactory;
|
||||
using Poco::Net::TCPServerConnectionFactoryImpl;
|
||||
using Poco::Net::TCPServerParams;
|
||||
using Poco::Net::StreamSocket;
|
||||
using Poco::Net::SecureStreamSocket;
|
||||
using Poco::Net::SecureServerSocket;
|
||||
using Poco::Net::SocketAddress;
|
||||
using Poco::Net::Context;
|
||||
using Poco::Net::Session;
|
||||
using Poco::Net::SSLManager;
|
||||
using Poco::Thread;
|
||||
using Poco::Util::Application;
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
class EchoConnection: public TCPServerConnection
|
||||
{
|
||||
public:
|
||||
EchoConnection(const StreamSocket& s): TCPServerConnection(s)
|
||||
{
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
StreamSocket& ss = socket();
|
||||
try
|
||||
{
|
||||
char buffer[256];
|
||||
int n = ss.receiveBytes(buffer, sizeof(buffer));
|
||||
while (n > 0)
|
||||
{
|
||||
ss.sendBytes(buffer, n);
|
||||
n = ss.receiveBytes(buffer, sizeof(buffer));
|
||||
}
|
||||
}
|
||||
catch (Poco::Exception& exc)
|
||||
{
|
||||
std::cerr << "EchoConnection: " << exc.displayText() << std::endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
SecureStreamSocketTest::SecureStreamSocketTest(const std::string& name): CppUnit::TestCase(name)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SecureStreamSocketTest::~SecureStreamSocketTest()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void SecureStreamSocketTest::testSendReceive()
|
||||
{
|
||||
SecureServerSocket svs(0);
|
||||
TCPServer srv(new TCPServerConnectionFactoryImpl<EchoConnection>(), svs);
|
||||
srv.start();
|
||||
|
||||
SocketAddress sa("127.0.0.1", svs.address().port());
|
||||
SecureStreamSocket ss1(sa);
|
||||
std::string data("hello, world");
|
||||
ss1.sendBytes(data.data(), static_cast<int>(data.size()));
|
||||
char buffer[8192];
|
||||
int n = ss1.receiveBytes(buffer, sizeof(buffer));
|
||||
assertTrue (n > 0);
|
||||
assertTrue (std::string(buffer, n) == data);
|
||||
|
||||
const std::vector<std::size_t> sizes = {67, 467, 7883, 19937};
|
||||
for (const auto n: sizes)
|
||||
{
|
||||
data.assign(n, 'X');
|
||||
ss1.sendBytes(data.data(), static_cast<int>(data.size()));
|
||||
std::string received;
|
||||
while (received.size() < n)
|
||||
{
|
||||
int rc = ss1.receiveBytes(buffer, sizeof(buffer));
|
||||
if (rc > 0)
|
||||
{
|
||||
received.append(buffer, rc);
|
||||
}
|
||||
else if (n == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
assertTrue (received == data);
|
||||
}
|
||||
|
||||
ss1.close();
|
||||
}
|
||||
|
||||
|
||||
void SecureStreamSocketTest::testPeek()
|
||||
{
|
||||
SecureServerSocket svs(0);
|
||||
TCPServer srv(new TCPServerConnectionFactoryImpl<EchoConnection>(), svs);
|
||||
srv.start();
|
||||
|
||||
SocketAddress sa("127.0.0.1", svs.address().port());
|
||||
SecureStreamSocket ss(sa);
|
||||
|
||||
int n = ss.sendBytes("hello, world!", 13);
|
||||
assertTrue (n == 13);
|
||||
char buffer[256];
|
||||
n = ss.receiveBytes(buffer, 5, MSG_PEEK);
|
||||
assertTrue (n == 5);
|
||||
assertTrue (std::string(buffer, n) == "hello");
|
||||
n = ss.receiveBytes(buffer, sizeof(buffer), MSG_PEEK);
|
||||
assertTrue (n == 13);
|
||||
assertTrue (std::string(buffer, n) == "hello, world!");
|
||||
n = ss.receiveBytes(buffer, 7);
|
||||
assertTrue (n == 7);
|
||||
assertTrue (std::string(buffer, n) == "hello, ");
|
||||
n = ss.receiveBytes(buffer, 6);
|
||||
assertTrue (n == 6);
|
||||
assertTrue (std::string(buffer, n) == "world!");
|
||||
ss.close();
|
||||
}
|
||||
|
||||
|
||||
void SecureStreamSocketTest::testNB()
|
||||
{
|
||||
SecureServerSocket svs(0);
|
||||
TCPServer srv(new TCPServerConnectionFactoryImpl<EchoConnection>(), svs);
|
||||
srv.start();
|
||||
|
||||
SocketAddress sa("127.0.0.1", svs.address().port());
|
||||
SecureStreamSocket ss1(sa);
|
||||
ss1.setBlocking(false);
|
||||
ss1.setSendBufferSize(32000);
|
||||
|
||||
char buffer[8192];
|
||||
const std::vector<std::size_t> sizes = {67, 467, 7883, 19937};
|
||||
for (const auto n: sizes)
|
||||
{
|
||||
std::string data(n, 'X');
|
||||
int rc = ss1.sendBytes(data.data(), static_cast<int>(data.size()));
|
||||
assertTrue (rc == n);
|
||||
|
||||
rc = -1;
|
||||
while (rc < 0)
|
||||
{
|
||||
rc = ss1.receiveBytes(buffer, sizeof(buffer), MSG_PEEK);
|
||||
}
|
||||
assertTrue (rc > 0 && rc <= n);
|
||||
assertTrue (data.compare(0, rc, buffer, rc) == 0);
|
||||
|
||||
std::string received;
|
||||
while (received.size() < n)
|
||||
{
|
||||
int rc = ss1.receiveBytes(buffer, sizeof(buffer));
|
||||
if (rc > 0)
|
||||
{
|
||||
received.append(buffer, rc);
|
||||
}
|
||||
else if (n == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
assertTrue (received == data);
|
||||
}
|
||||
|
||||
ss1.close();
|
||||
}
|
||||
|
||||
|
||||
void SecureStreamSocketTest::setUp()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void SecureStreamSocketTest::tearDown()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
CppUnit::Test* SecureStreamSocketTest::suite()
|
||||
{
|
||||
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("SecureStreamSocketTest");
|
||||
|
||||
CppUnit_addTest(pSuite, SecureStreamSocketTest, testSendReceive);
|
||||
CppUnit_addTest(pSuite, SecureStreamSocketTest, testPeek);
|
||||
CppUnit_addTest(pSuite, SecureStreamSocketTest, testNB);
|
||||
|
||||
return pSuite;
|
||||
}
|
40
NetSSL_OpenSSL/testsuite/src/SecureStreamSocketTest.h
Normal file
40
NetSSL_OpenSSL/testsuite/src/SecureStreamSocketTest.h
Normal file
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// SecureStreamSocketTest.h
|
||||
//
|
||||
// Definition of the SecureStreamSocketTest class.
|
||||
//
|
||||
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#ifndef SecureStreamSocketTest_INCLUDED
|
||||
#define SecureStreamSocketTest_INCLUDED
|
||||
|
||||
|
||||
#include "Poco/Net/Net.h"
|
||||
#include "CppUnit/TestCase.h"
|
||||
|
||||
|
||||
class SecureStreamSocketTest: public CppUnit::TestCase
|
||||
{
|
||||
public:
|
||||
SecureStreamSocketTest(const std::string& name);
|
||||
~SecureStreamSocketTest();
|
||||
|
||||
void testSendReceive();
|
||||
void testPeek();
|
||||
void testNB();
|
||||
|
||||
void setUp();
|
||||
void tearDown();
|
||||
|
||||
static CppUnit::Test* suite();
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
#endif // SecureStreamSocketTest
|
22
NetSSL_OpenSSL/testsuite/src/SecureStreamSocketTestSuite.cpp
Normal file
22
NetSSL_OpenSSL/testsuite/src/SecureStreamSocketTestSuite.cpp
Normal file
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// SecureStreamSocketTestSuite.cpp
|
||||
//
|
||||
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "SecureStreamSocketTestSuite.h"
|
||||
#include "SecureStreamSocketTest.h"
|
||||
|
||||
|
||||
CppUnit::Test* SecureStreamSocketTestSuite::suite()
|
||||
{
|
||||
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("SecureStreamSocketTestSuite");
|
||||
|
||||
pSuite->addTest(SecureStreamSocketTest::suite());
|
||||
|
||||
return pSuite;
|
||||
}
|
27
NetSSL_OpenSSL/testsuite/src/SecureStreamSocketTestSuite.h
Normal file
27
NetSSL_OpenSSL/testsuite/src/SecureStreamSocketTestSuite.h
Normal file
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// SecureStreamSocketTestSuite.h
|
||||
//
|
||||
// Definition of the SecureStreamSocketTestSuite class.
|
||||
//
|
||||
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#ifndef SecureStreamSocketTestSuite_INCLUDED
|
||||
#define SecureStreamSocketTestSuite_INCLUDED
|
||||
|
||||
|
||||
#include "CppUnit/TestSuite.h"
|
||||
|
||||
|
||||
class SecureStreamSocketTestSuite
|
||||
{
|
||||
public:
|
||||
static CppUnit::Test* suite();
|
||||
};
|
||||
|
||||
|
||||
#endif // SecureStreamSocketTestSuite
|
@@ -49,16 +49,16 @@ namespace
|
||||
try
|
||||
{
|
||||
WebSocket ws(request, response);
|
||||
std::unique_ptr<char[]> pBuffer(new char[_bufSize]);
|
||||
Poco::Buffer<char> buffer(_bufSize);
|
||||
int flags;
|
||||
int n;
|
||||
do
|
||||
{
|
||||
n = ws.receiveFrame(pBuffer.get(), static_cast<int>(_bufSize), flags);
|
||||
Poco::Thread::current()->sleep(handleDelay.totalMilliseconds());
|
||||
n = ws.receiveFrame(buffer.begin(), static_cast<int>(_bufSize), flags);
|
||||
if (n == 0)
|
||||
break;
|
||||
ws.sendFrame(pBuffer.get(), n, flags);
|
||||
Poco::Thread::current()->sleep(handleDelay.totalMilliseconds());
|
||||
ws.sendFrame(buffer.begin(), n, flags);
|
||||
}
|
||||
while ((flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE);
|
||||
}
|
||||
@@ -156,6 +156,8 @@ void WebSocketTest::testWebSocketTimeout()
|
||||
ws.shutdown();
|
||||
ws.receiveFrame(buffer, sizeof(buffer), flags);
|
||||
server.stop();
|
||||
|
||||
WebSocketRequestHandler::handleDelay = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -220,7 +222,7 @@ void WebSocketTest::testWebSocket()
|
||||
assertTrue (n == 2);
|
||||
assertTrue ((flags & WebSocket::FRAME_OP_BITMASK) == WebSocket::FRAME_OP_CLOSE);
|
||||
|
||||
server.stop();
|
||||
server.stopAll(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -256,7 +258,74 @@ void WebSocketTest::testWebSocketLarge()
|
||||
assertTrue (n == payload.size());
|
||||
assertTrue (payload.compare(0, payload.size(), buffer, 0, n) == 0);
|
||||
|
||||
server.stop();
|
||||
server.stopAll(true);
|
||||
}
|
||||
|
||||
|
||||
void WebSocketTest::testWebSocketNB()
|
||||
{
|
||||
Poco::Net::SecureServerSocket ss(0);
|
||||
Poco::Net::HTTPServer server(new WebSocketRequestHandlerFactory(256*1024), ss, new Poco::Net::HTTPServerParams);
|
||||
server.start();
|
||||
|
||||
Poco::Thread::sleep(200);
|
||||
|
||||
HTTPSClientSession cs("127.0.0.1", ss.address().port());
|
||||
HTTPRequest request(HTTPRequest::HTTP_GET, "/ws", HTTPRequest::HTTP_1_1);
|
||||
HTTPResponse response;
|
||||
WebSocket ws(cs, request, response);
|
||||
ws.setBlocking(false);
|
||||
|
||||
int flags;
|
||||
char buffer[256*1024] = {};
|
||||
int n = ws.receiveFrame(buffer, sizeof(buffer), flags);
|
||||
assertTrue (n < 0);
|
||||
|
||||
std::string payload("x");
|
||||
n = ws.sendFrame(payload.data(), (int) payload.size());
|
||||
assertTrue (n > 0);
|
||||
if (ws.poll(1000000, Poco::Net::Socket::SELECT_READ))
|
||||
{
|
||||
n = ws.receiveFrame(buffer, sizeof(buffer), flags);
|
||||
while (n < 0)
|
||||
{
|
||||
n = ws.receiveFrame(buffer, sizeof(buffer), flags);
|
||||
}
|
||||
}
|
||||
assertTrue (n == payload.size());
|
||||
assertTrue (payload.compare(0, payload.size(), buffer, n) == 0);
|
||||
assertTrue (flags == WebSocket::FRAME_TEXT);
|
||||
|
||||
ws.setSendBufferSize(256*1024);
|
||||
ws.setReceiveBufferSize(256*1024);
|
||||
|
||||
payload.assign(256000, 'z');
|
||||
n = ws.sendFrame(payload.data(), (int) payload.size());
|
||||
assertTrue (n > 0);
|
||||
if (ws.poll(1000000, Poco::Net::Socket::SELECT_READ))
|
||||
{
|
||||
n = ws.receiveFrame(buffer, sizeof(buffer), flags);
|
||||
while (n < 0)
|
||||
{
|
||||
n = ws.receiveFrame(buffer, sizeof(buffer), flags);
|
||||
}
|
||||
}
|
||||
assertTrue (n == payload.size());
|
||||
assertTrue (payload.compare(0, payload.size(), buffer, n) == 0);
|
||||
assertTrue (flags == WebSocket::FRAME_TEXT);
|
||||
|
||||
n = ws.shutdown();
|
||||
assertTrue (n > 0);
|
||||
|
||||
n = ws.receiveFrame(buffer, sizeof(buffer), flags);
|
||||
while (n < 0)
|
||||
{
|
||||
n = ws.receiveFrame(buffer, sizeof(buffer), flags);
|
||||
}
|
||||
assertTrue (n == 2);
|
||||
assertTrue ((flags & WebSocket::FRAME_OP_BITMASK) == WebSocket::FRAME_OP_CLOSE);
|
||||
|
||||
server.stopAll(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -277,6 +346,7 @@ CppUnit::Test* WebSocketTest::suite()
|
||||
CppUnit_addTest(pSuite, WebSocketTest, testWebSocket);
|
||||
CppUnit_addTest(pSuite, WebSocketTest, testWebSocketTimeout);
|
||||
CppUnit_addTest(pSuite, WebSocketTest, testWebSocketLarge);
|
||||
CppUnit_addTest(pSuite, WebSocketTest, testWebSocketNB);
|
||||
|
||||
return pSuite;
|
||||
}
|
||||
|
@@ -27,6 +27,7 @@ public:
|
||||
void testWebSocketTimeout();
|
||||
void testWebSocket();
|
||||
void testWebSocketLarge();
|
||||
void testWebSocketNB();
|
||||
|
||||
void setUp() override;
|
||||
void tearDown() override;
|
||||
|
Reference in New Issue
Block a user