fix(sharedMemory): x64 size error #2976 (#4295)

* fix(sharedMemory): x64 size error #2976

* chore: add Util dependency to Prometheus samples

* fix(HTTPClientSession): not working with UNIX_LOCAL SocketAddress #2578

* fix(WebSocketTest): supress connection reset exception assertion

* fix(PollSet): wait on premature epoll_wait return; reinforce tests for windows

* fix(build): add DataTest dependency to Makefile

* fix(Task): intermittently hanging test and some other improvements

* fix(Net): PollSet loop; suppress test WebSocket handler shutdown IOExeption
This commit is contained in:
Aleksandar Fabijanic 2023-11-26 04:57:39 +01:00 committed by GitHub
parent 70bb3a40de
commit 11de40399c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 244 additions and 104 deletions

View File

@ -76,7 +76,7 @@ private:
std::string _name; std::string _name;
HANDLE _memHandle; HANDLE _memHandle;
HANDLE _fileHandle; HANDLE _fileHandle;
DWORD _size; std::size_t _size;
DWORD _mode; DWORD _mode;
char* _address; char* _address;
}; };

View File

@ -147,7 +147,7 @@ private:
std::string _name; std::string _name;
TaskManager* _pOwner; TaskManager* _pOwner;
float _progress; std::atomic<float> _progress;
std::atomic<TaskState> _state; std::atomic<TaskState> _state;
Event _cancelEvent; Event _cancelEvent;
mutable FastMutex _mutex; mutable FastMutex _mutex;
@ -167,8 +167,6 @@ inline const std::string& Task::name() const
inline float Task::progress() const inline float Task::progress() const
{ {
FastMutex::ScopedLock lock(_mutex);
return _progress; return _progress;
} }

View File

@ -28,7 +28,7 @@ SharedMemoryImpl::SharedMemoryImpl(const std::string& name, std::size_t size, Sh
_name(name), _name(name),
_memHandle(INVALID_HANDLE_VALUE), _memHandle(INVALID_HANDLE_VALUE),
_fileHandle(INVALID_HANDLE_VALUE), _fileHandle(INVALID_HANDLE_VALUE),
_size(static_cast<DWORD>(size)), _size(size),
_mode(PAGE_READONLY), _mode(PAGE_READONLY),
_address(0) _address(0)
{ {
@ -37,22 +37,40 @@ SharedMemoryImpl::SharedMemoryImpl(const std::string& name, std::size_t size, Sh
std::wstring utf16name; std::wstring utf16name;
UnicodeConverter::toUTF16(_name, utf16name); UnicodeConverter::toUTF16(_name, utf16name);
_memHandle = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, _mode, 0, _size, utf16name.c_str()); #ifdef _WIN64
const DWORD dwMaxSizeLow = static_cast<DWORD>(_size & 0xFFFFFFFFULL);
const DWORD dwMaxSizeHigh = static_cast<DWORD>((_size & (0xFFFFFFFFULL << 32)) >> 32);
#else
if (_size > std::numeric_limits<DWORD>::max())
{
throw Poco::InvalidArgumentException(Poco::format("Requested shared memory size (%z) too large (max %lu)",
_size, std::numeric_limits<DWORD>::max()));
}
const DWORD dwMaxSizeLow = static_cast<DWORD>(_size);
const DWORD dwMaxSizeHigh = 0UL;
#endif
_memHandle = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, _mode, dwMaxSizeHigh, dwMaxSizeLow, utf16name.c_str());
if (!_memHandle) if (!_memHandle)
{ {
DWORD dwRetVal = GetLastError(); DWORD dwRetVal = GetLastError();
int retVal = static_cast<int>(dwRetVal);
#if defined (_WIN32_WCE) #if defined (_WIN32_WCE)
throw SystemException(format("Cannot create shared memory object %s [Error %d: %s]", _name, static_cast<int>(dwRetVal), Error::getMessage(dwRetVal))); throw SystemException(Poco::format("Cannot create shared memory object %s [Error %d: %s]",
_name, retVal, Error::getMessage(dwRetVal)));
#else #else
if (_mode != PAGE_READONLY || dwRetVal != 5) if (_mode != PAGE_READONLY || dwRetVal != 5)
throw SystemException(format("Cannot create shared memory object %s [Error %d: %s]", _name, static_cast<int>(dwRetVal), Error::getMessage(dwRetVal))); {
throw SystemException(Poco::format("Cannot create shared memory object %s [Error %d: %s]",
_name, retVal, Error::getMessage(dwRetVal)), retVal);
}
_memHandle = OpenFileMappingW(PAGE_READONLY, FALSE, utf16name.c_str()); _memHandle = OpenFileMappingW(PAGE_READONLY, FALSE, utf16name.c_str());
if (!_memHandle) if (!_memHandle)
{ {
dwRetVal = GetLastError(); dwRetVal = GetLastError();
throw SystemException(format("Cannot open shared memory object %s [Error %d: %s]", _name, static_cast<int>(dwRetVal), Error::getMessage(dwRetVal))); throw SystemException(Poco::format("Cannot open shared memory object %s [Error %d: %s]",
_name, retVal, Error::getMessage(dwRetVal)), retVal);
} }
#endif #endif
} }

View File

@ -71,12 +71,12 @@ void Task::run()
catch (std::exception& exc) catch (std::exception& exc)
{ {
if (pOwner) if (pOwner)
pOwner->taskFailed(this, SystemException(exc.what())); pOwner->taskFailed(this, SystemException("Task::run()", exc.what()));
} }
catch (...) catch (...)
{ {
if (pOwner) if (pOwner)
pOwner->taskFailed(this, SystemException("unknown exception")); pOwner->taskFailed(this, SystemException("Task::run(): unknown exception"));
} }
_state = TASK_FINISHED; _state = TASK_FINISHED;
if (pOwner) pOwner->taskFinished(this); if (pOwner) pOwner->taskFinished(this);
@ -98,11 +98,9 @@ bool Task::yield()
void Task::setProgress(float progress) void Task::setProgress(float progress)
{ {
FastMutex::ScopedLock lock(_mutex); if (_progress.exchange(progress) != progress)
if (_progress != progress)
{ {
_progress = progress; FastMutex::ScopedLock lock(_mutex);
if (_pOwner) if (_pOwner)
_pOwner->taskProgress(this, _progress); _pOwner->taskProgress(this, _progress);
} }
@ -112,7 +110,6 @@ void Task::setProgress(float progress)
void Task::setOwner(TaskManager* pOwner) void Task::setOwner(TaskManager* pOwner)
{ {
FastMutex::ScopedLock lock(_mutex); FastMutex::ScopedLock lock(_mutex);
_pOwner = pOwner; _pOwner = pOwner;
} }

View File

@ -72,6 +72,30 @@ Poco::Path SharedMemoryTest::findDataFile(const std::string& afile)
} }
void SharedMemoryTest::testCreateLarge()
{
#if POCO_OS == POCO_OS_WINDOWS_NT
try
{
#ifdef _WIN64
const size_t size = 0x03FFFFFFFFULL;
#else
const size_t size = 0xDFFFFFFFUL;
#endif
SharedMemory mem("hiLarge", size, SharedMemory::AM_WRITE);
assertTrue((mem.end() - mem.begin()) == size);
mem.begin()[0] = 'A';
mem.end()[-1] = 'Z';
}
catch (Poco::SystemException& ex)
{
// no memory, quite posible to happen
assertEqual(ERROR_NOT_ENOUGH_MEMORY, ex.code());
}
#endif
}
void SharedMemoryTest::setUp() void SharedMemoryTest::setUp()
{ {
} }
@ -89,6 +113,7 @@ CppUnit::Test* SharedMemoryTest::suite()
#if !defined(POCO_NO_SHAREDMEMORY) #if !defined(POCO_NO_SHAREDMEMORY)
CppUnit_addTest(pSuite, SharedMemoryTest, testCreate); CppUnit_addTest(pSuite, SharedMemoryTest, testCreate);
CppUnit_addTest(pSuite, SharedMemoryTest, testCreateFromFile); CppUnit_addTest(pSuite, SharedMemoryTest, testCreateFromFile);
CppUnit_addTest(pSuite, SharedMemoryTest, testCreateLarge);
#endif #endif
return pSuite; return pSuite;
} }

View File

@ -27,6 +27,7 @@ public:
void testCreate(); void testCreate();
void testCreateFromFile(); void testCreateFromFile();
void testCreateLarge();
void setUp(); void setUp();
void tearDown(); void tearDown();

View File

@ -38,7 +38,7 @@ namespace
try try
{ {
_event.wait(); _event.wait();
if (sleep(10)) if (sleep(100))
return; return;
setProgress(0.5); setProgress(0.5);
_event.wait(); _event.wait();
@ -131,6 +131,8 @@ void TaskTest::testCancel2()
assertTrue (pTT->state() == Task::TASK_IDLE); assertTrue (pTT->state() == Task::TASK_IDLE);
Thread thr; Thread thr;
thr.start(*pTT); thr.start(*pTT);
while (pTT->state() != Task::TASK_RUNNING)
Thread::sleep(50);
assertTrue (pTT->progress() == 0); assertTrue (pTT->progress() == 0);
pTT->cancel(); pTT->cancel();
assertTrue (pTT->state() == Task::TASK_CANCELLING); assertTrue (pTT->state() == Task::TASK_CANCELLING);

View File

@ -246,7 +246,10 @@ NetSSL_OpenSSL-clean:
Data-libexec: Foundation-libexec Data-libexec: Foundation-libexec
$(MAKE) -C $(POCO_BASE)/Data $(MAKE) -C $(POCO_BASE)/Data
Data-tests: Data-libexec cppunit DataTest-libexec: Data-libexec
$(MAKE) -C $(POCO_BASE)/Data/testsuite/DataTest
Data-tests: Data-libexec DataTest-libexec cppunit
$(MAKE) -C $(POCO_BASE)/Data/testsuite $(MAKE) -C $(POCO_BASE)/Data/testsuite
Data-samples: Data-libexec Data-libexec Data/SQLite-libexec Net-libexec Data-samples: Data-libexec Data-libexec Data/SQLite-libexec Net-libexec
@ -260,7 +263,7 @@ Data-clean:
Data/SQLite-libexec: Foundation-libexec Data-libexec Data/SQLite-libexec: Foundation-libexec Data-libexec
$(MAKE) -C $(POCO_BASE)/Data/SQLite $(MAKE) -C $(POCO_BASE)/Data/SQLite
Data/SQLite-tests: Data/SQLite-libexec cppunit Data/SQLite-tests: Data/SQLite-libexec DataTest-libexec cppunit
$(MAKE) -C $(POCO_BASE)/Data/SQLite/testsuite $(MAKE) -C $(POCO_BASE)/Data/SQLite/testsuite
Data/SQLite-clean: Data/SQLite-clean:
@ -270,7 +273,7 @@ Data/SQLite-clean:
Data/ODBC-libexec: Foundation-libexec Data-libexec Data/ODBC-libexec: Foundation-libexec Data-libexec
$(MAKE) -C $(POCO_BASE)/Data/ODBC $(MAKE) -C $(POCO_BASE)/Data/ODBC
Data/ODBC-tests: Data/ODBC-libexec cppunit Data/ODBC-tests: Data/ODBC-libexec DataTest-libexec cppunit
$(MAKE) -C $(POCO_BASE)/Data/ODBC/testsuite $(MAKE) -C $(POCO_BASE)/Data/ODBC/testsuite
Data/ODBC-clean: Data/ODBC-clean:
@ -280,7 +283,7 @@ Data/ODBC-clean:
Data/MySQL-libexec: Foundation-libexec Data-libexec Data/MySQL-libexec: Foundation-libexec Data-libexec
$(MAKE) -C $(POCO_BASE)/Data/MySQL $(MAKE) -C $(POCO_BASE)/Data/MySQL
Data/MySQL-tests: Data/MySQL-libexec cppunit Data/MySQL-tests: Data/MySQL-libexec DataTest-libexec cppunit
$(MAKE) -C $(POCO_BASE)/Data/MySQL/testsuite $(MAKE) -C $(POCO_BASE)/Data/MySQL/testsuite
Data/MySQL-clean: Data/MySQL-clean:
@ -290,7 +293,7 @@ Data/MySQL-clean:
Data/PostgreSQL-libexec: Foundation-libexec Data-libexec Data/PostgreSQL-libexec: Foundation-libexec Data-libexec
$(MAKE) -C $(POCO_BASE)/Data/PostgreSQL $(MAKE) -C $(POCO_BASE)/Data/PostgreSQL
Data/PostgreSQL-tests: Data/PostgreSQL-libexec cppunit Data/PostgreSQL-tests: Data/PostgreSQL-libexec DataTest-libexec cppunit
$(MAKE) -C $(POCO_BASE)/Data/PostgreSQL/testsuite $(MAKE) -C $(POCO_BASE)/Data/PostgreSQL/testsuite
Data/PostgreSQL-clean: Data/PostgreSQL-clean:
@ -407,7 +410,7 @@ Prometheus-libexec: Foundation-libexec Net-libexec
Prometheus-tests: Prometheus-libexec cppunit Prometheus-tests: Prometheus-libexec cppunit
$(MAKE) -C $(POCO_BASE)/Prometheus/testsuite $(MAKE) -C $(POCO_BASE)/Prometheus/testsuite
Prometheus-samples: Prometheus-libexec Prometheus-samples: Prometheus-libexec Util-libexec
$(MAKE) -C $(POCO_BASE)/Prometheus/samples $(MAKE) -C $(POCO_BASE)/Prometheus/samples
Prometheus-clean: Prometheus-clean:

View File

@ -384,7 +384,7 @@ private:
HTTPBasicCredentials _proxyBasicCreds; HTTPBasicCredentials _proxyBasicCreds;
HTTPDigestCredentials _proxyDigestCreds; HTTPDigestCredentials _proxyDigestCreds;
HTTPNTLMCredentials _proxyNTLMCreds; HTTPNTLMCredentials _proxyNTLMCreds;
bool _ntlmProxyAuthenticated; bool _ntlmProxyAuthenticated = false;
static ProxyConfig _globalProxyConfig; static ProxyConfig _globalProxyConfig;

View File

@ -208,6 +208,9 @@ public:
/// Maximum length in bytes of a socket address. /// Maximum length in bytes of a socket address.
}; };
static bool isUnixLocal(const std::string& hostAndPort);
/// Returns true iff `hostAndPort` is an absolute file path.
protected: protected:
void init(const IPAddress& hostAddress, Poco::UInt16 portNumber); void init(const IPAddress& hostAddress, Poco::UInt16 portNumber);
void init(const std::string& hostAddress, Poco::UInt16 portNumber); void init(const std::string& hostAddress, Poco::UInt16 portNumber);

View File

@ -459,7 +459,12 @@ void HTTPClientSession::reconnect()
{ {
SocketAddress addr; SocketAddress addr;
if (_proxyConfig.host.empty() || bypassProxy()) if (_proxyConfig.host.empty() || bypassProxy())
{
if (SocketAddress::isUnixLocal(_host))
addr = SocketAddress(_host);
else
addr = SocketAddress(_host, _port); addr = SocketAddress(_host, _port);
}
else else
addr = SocketAddress(_proxyConfig.host, _proxyConfig.port); addr = SocketAddress(_proxyConfig.host, _proxyConfig.port);

View File

@ -196,6 +196,7 @@ void HTTPSession::connect(const SocketAddress& address)
_socket.connect(address, _connectionTimeout); _socket.connect(address, _connectionTimeout);
_socket.setReceiveTimeout(_receiveTimeout); _socket.setReceiveTimeout(_receiveTimeout);
_socket.setSendTimeout(_sendTimeout); _socket.setSendTimeout(_sendTimeout);
if (address.family() != SocketAddress::UNIX_LOCAL)
_socket.setNoDelay(true); _socket.setNoDelay(true);
// There may be leftover data from a previous (failed) request in the buffer, // There may be leftover data from a previous (failed) request in the buffer,
// so we clear it. // so we clear it.

View File

@ -171,12 +171,16 @@ public:
Poco::Timespan remainingTime(timeout); Poco::Timespan remainingTime(timeout);
int rc; int rc;
do while (true)
{ {
Poco::Timestamp start; Poco::Timestamp start;
rc = epoll_wait(_epollfd, &_events[0], rc = epoll_wait(_epollfd, &_events[0],
static_cast<int>(_events.size()), static_cast<int>(remainingTime.totalMilliseconds())); static_cast<int>(_events.size()), static_cast<int>(remainingTime.totalMilliseconds()));
if (rc == 0) return result; if (rc == 0)
{
if (keepWaiting(start, remainingTime)) continue;
return result;
}
// if we are hitting the events limit, resize it; even without resizing, the subseqent // if we are hitting the events limit, resize it; even without resizing, the subseqent
// calls would round-robin through the remaining ready sockets, but it's better to give // calls would round-robin through the remaining ready sockets, but it's better to give
@ -187,18 +191,12 @@ public:
// if interrupted and there's still time left, keep waiting // if interrupted and there's still time left, keep waiting
if (SocketImpl::lastError() == POCO_EINTR) if (SocketImpl::lastError() == POCO_EINTR)
{ {
Poco::Timestamp end; if (keepWaiting(start, remainingTime)) continue;
Poco::Timespan waited = end - start;
if (waited < remainingTime)
{
remainingTime -= waited;
continue;
}
} }
else SocketImpl::error(); else SocketImpl::error();
} }
break;
} }
while (false);
ScopedLock lock(_mutex); ScopedLock lock(_mutex);
@ -304,6 +302,18 @@ private:
return epoll_ctl(_epollfd, op, fd, &ev); return epoll_ctl(_epollfd, op, fd, &ev);
} }
static bool keepWaiting(const Poco::Timestamp& start, Poco::Timespan& remainingTime)
{
Poco::Timestamp end;
Poco::Timespan waited = end - start;
if (waited < remainingTime)
{
remainingTime -= waited;
return true;
}
return false;
}
#ifndef WEPOLL_H_ #ifndef WEPOLL_H_
using EPollHandle = std::atomic<int>; using EPollHandle = std::atomic<int>;
#else // WEPOLL_H_ #else // WEPOLL_H_

View File

@ -362,31 +362,34 @@ void SocketAddress::init(Family fam, const std::string& address)
} }
bool SocketAddress::isUnixLocal(const std::string& hostAndPort)
{
#if defined(POCO_HAS_UNIX_SOCKET)
#if defined(POCO_OS_FAMILY_WINDOWS)
RegularExpression re(R"((?:[a-zA-Z]\:|\\\\[\w\s\.]+\\[\w\s\.$]+)\\(?:[\w\s\.]+\\)*[\w\s\.]*?$)");
if (re.match(hostAndPort)) return true;
#elif defined(POCO_OS_FAMILY_UNIX)
if (hostAndPort.size() && (hostAndPort[0] == '/')) return true;
#endif
#endif
return false;
}
void SocketAddress::init(const std::string& hostAndPort) void SocketAddress::init(const std::string& hostAndPort)
{ {
poco_assert (!hostAndPort.empty()); poco_assert (!hostAndPort.empty());
#if defined(POCO_OS_FAMILY_WINDOWS) && defined(POCO_HAS_UNIX_SOCKET) if (isUnixLocal(hostAndPort))
RegularExpression re(R"((?:[a-zA-Z]\:|\\\\[\w\s\.]+\\[\w\s\.$]+)\\(?:[\w\s\.]+\\)*[\w\s\.]*?$)");
if (re.match(hostAndPort))
{ {
newLocal(hostAndPort); newLocal(hostAndPort);
return; return;
} }
#endif
std::string host; std::string host;
std::string port; std::string port;
std::string::const_iterator it = hostAndPort.begin(); std::string::const_iterator it = hostAndPort.begin();
std::string::const_iterator end = hostAndPort.end(); std::string::const_iterator end = hostAndPort.end();
#if defined(POCO_OS_FAMILY_UNIX)
if (*it == '/')
{
newLocal(hostAndPort);
return;
}
#endif
if (*it == '[') if (*it == '[')
{ {
++it; ++it;

View File

@ -83,8 +83,10 @@ void EchoServer::run()
{ {
std::cerr << "EchoServer: " << exc.displayText() << std::endl; std::cerr << "EchoServer: " << exc.displayText() << std::endl;
} }
ss.close();
} }
} }
_socket.close();
_done = true; _done = true;
} }
@ -99,4 +101,3 @@ bool EchoServer::done()
{ {
return _done; return _done;
} }

View File

@ -15,6 +15,8 @@
#include "Poco/Net/HTTPRequest.h" #include "Poco/Net/HTTPRequest.h"
#include "Poco/Net/HTTPResponse.h" #include "Poco/Net/HTTPResponse.h"
#include "Poco/StreamCopier.h" #include "Poco/StreamCopier.h"
#include "Poco/File.h"
#include "Poco/Path.h"
#include "HTTPTestServer.h" #include "HTTPTestServer.h"
#include <istream> #include <istream>
#include <ostream> #include <ostream>
@ -26,6 +28,8 @@ using Poco::Net::HTTPRequest;
using Poco::Net::HTTPResponse; using Poco::Net::HTTPResponse;
using Poco::Net::HTTPMessage; using Poco::Net::HTTPMessage;
using Poco::StreamCopier; using Poco::StreamCopier;
using Poco::File;
using Poco::Path;
HTTPClientSessionTest::HTTPClientSessionTest(const std::string& name): CppUnit::TestCase(name) HTTPClientSessionTest::HTTPClientSessionTest(const std::string& name): CppUnit::TestCase(name)
@ -54,6 +58,32 @@ void HTTPClientSessionTest::testGetSmall()
} }
void HTTPClientSessionTest::testGetSmallUnix()
{
#if defined(POCO_HAS_UNIX_SOCKET)
#if POCO_OS == POCO_OS_ANDROID
File socketFile("/data/local/tmp/SocketTest.sock");
#elif defined(POCO_OS_FAMILY_WINDOWS)
File socketFile(Path::tempHome() + "SocketTest.sock");
#else
File socketFile("/tmp/SocketTest.sock");
#endif // POCO_OS == POCO_OS_ANDROID
if (socketFile.exists()) socketFile.remove();
HTTPTestServer srv(socketFile.path());
HTTPClientSession s(socketFile.path());
HTTPRequest request(HTTPRequest::HTTP_GET, "/small");
s.sendRequest(request);
HTTPResponse response;
std::istream& rs = s.receiveResponse(response);
assertTrue(response.getContentLength() == HTTPTestServer::SMALL_BODY.length());
assertTrue(response.getContentType() == "text/plain");
std::ostringstream ostr;
StreamCopier::copyStream(rs, ostr);
assertTrue(ostr.str() == HTTPTestServer::SMALL_BODY);
#endif // POCO_HAS_UNIX_SOCKET
}
void HTTPClientSessionTest::testGetLarge() void HTTPClientSessionTest::testGetLarge()
{ {
HTTPTestServer srv; HTTPTestServer srv;
@ -373,6 +403,7 @@ CppUnit::Test* HTTPClientSessionTest::suite()
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("HTTPClientSessionTest"); CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("HTTPClientSessionTest");
CppUnit_addTest(pSuite, HTTPClientSessionTest, testGetSmall); CppUnit_addTest(pSuite, HTTPClientSessionTest, testGetSmall);
CppUnit_addTest(pSuite, HTTPClientSessionTest, testGetSmallUnix);
CppUnit_addTest(pSuite, HTTPClientSessionTest, testGetLarge); CppUnit_addTest(pSuite, HTTPClientSessionTest, testGetLarge);
CppUnit_addTest(pSuite, HTTPClientSessionTest, testHead); CppUnit_addTest(pSuite, HTTPClientSessionTest, testHead);
CppUnit_addTest(pSuite, HTTPClientSessionTest, testPostSmallIdentity); CppUnit_addTest(pSuite, HTTPClientSessionTest, testPostSmallIdentity);

View File

@ -25,6 +25,7 @@ public:
~HTTPClientSessionTest(); ~HTTPClientSessionTest();
void testGetSmall(); void testGetSmall();
void testGetSmallUnix();
void testGetLarge(); void testGetLarge();
void testHead(); void testHead();
void testPostSmallIdentity(); void testPostSmallIdentity();

View File

@ -37,6 +37,17 @@ HTTPTestServer::HTTPTestServer():
} }
HTTPTestServer::HTTPTestServer(const std::string& addr) :
_socket(SocketAddress(addr)),
_thread("HTTPTestServer"),
_stop(false)
{
_thread.start(*this);
_ready.wait();
_lastRequest.reserve(4000);
}
HTTPTestServer::~HTTPTestServer() HTTPTestServer::~HTTPTestServer()
{ {
_stop = true; _stop = true;
@ -74,13 +85,15 @@ void HTTPTestServer::run()
{ {
_lastRequest.append(buffer, n); _lastRequest.append(buffer, n);
if (!requestComplete()) if (!requestComplete())
{
n = ss.receiveBytes(buffer, sizeof(buffer)); n = ss.receiveBytes(buffer, sizeof(buffer));
}
else else
n = 0; n = 0;
} }
std::string response = handleRequest(); std::string response = handleRequest();
ss.sendBytes(response.data(), (int) response.size()); n = ss.sendBytes(response.data(), (int) response.size());
Poco::Thread::sleep(1000); if (n) Poco::Thread::sleep(1000);
try try
{ {
ss.shutdown(); ss.shutdown();

View File

@ -27,6 +27,9 @@ public:
HTTPTestServer(); HTTPTestServer();
/// Creates the HTTPTestServer. /// Creates the HTTPTestServer.
HTTPTestServer(const std::string& addr);
/// Creates the HTTPTestServer on the specified address.
~HTTPTestServer(); ~HTTPTestServer();
/// Destroys the HTTPTestServer. /// Destroys the HTTPTestServer.

View File

@ -404,9 +404,19 @@ void PollSetTest::testPollClosedServer()
"waiting on server after %ds", secs), __LINE__); "waiting on server after %ds", secs), __LINE__);
} }
} }
char buffer[5];
int n = ss1.receiveBytes(buffer, sizeof(buffer));
assertTrue(n == 0);
auto smm = ps.poll(Timespan(1000000));
assertEqual(1, smm.size());
assertTrue(ss1 == smm.begin()->first);
ps.remove(ss1);
assertTrue(!ps.empty());
assertTrue(!ps.has(ss1));
assertTrue(ps.has(ss2));
echoServer2.stop(); echoServer2.stop();
assertTrue (len == ss2.sendBytes(str.data(), len)); assertTrue (len == ss2.sendBytes(str.data(), len));
sw.restart();
while (!echoServer2.done()) while (!echoServer2.done())
{ {
Thread::sleep(10); Thread::sleep(10);
@ -417,8 +427,11 @@ void PollSetTest::testPollClosedServer()
"waiting on server after %ds", secs), __LINE__); "waiting on server after %ds", secs), __LINE__);
} }
} }
n = ss2.receiveBytes(buffer, sizeof(buffer));
assertEqual(2, ps.poll(Timespan(1000000)).size()); assertTrue(n == 0);
smm = ps.poll(Timespan(1000000));
assertEqual(1, smm.size());
assertTrue(ss2 == smm.begin()->first);
// socket closed or error // socket closed or error
assertTrue(0 >= ss1.receiveBytes(0, 0)); assertTrue(0 >= ss1.receiveBytes(0, 0));

View File

@ -562,8 +562,10 @@ void SocketTest::testEchoUnixLocal()
if (socketFile.exists()) socketFile.remove(); if (socketFile.exists()) socketFile.remove();
echoServer.stop(); echoServer.stop();
#else // POCO_HAS_UNIX_SOCKET #else // POCO_HAS_UNIX_SOCKET
#if POCO_OS == POCO_OS_WINDOWS_NT
#pragma message("[UNIX LOCAL SOCKET DISABLED]") #pragma message("[UNIX LOCAL SOCKET DISABLED]")
std::cout << "[UNIX LOCAL SOCKET DISABLED]" << std::endl; #endif
std::cout << "[UNIX LOCAL SOCKET DISABLED]";
#endif #endif
} }
@ -588,8 +590,10 @@ void SocketTest::testUnixLocalAbstract()
ss.close(); ss.close();
echoServer.stop(); echoServer.stop();
#else // POCO_HAS_UNIX_SOCKET #else // POCO_HAS_UNIX_SOCKET
#pragma message("[ABSTRACT UNIX LOCAL SOCKET DISABLED]") #if POCO_OS == POCO_OS_WINDOWS_NT
std::cout << "[ABSTRACT UNIX LOCAL SOCKET DISABLED]" << std::endl; #pragma message("[ABSTRACT UNIX LOCAL SOCKET DISABLED]")
#endif
std::cout << "[ABSTRACT UNIX LOCAL SOCKET DISABLED]";
#endif #endif
} }

View File

@ -53,10 +53,10 @@ private:
void onReadable(bool& b); void onReadable(bool& b);
void onWritable(bool& b); void onWritable(bool& b);
int _readableToNot; int _readableToNot = 0;
int _notToReadable; int _notToReadable = 0;
int _writableToNot; int _writableToNot = 0;
int _notToWritable; int _notToWritable = 0;
}; };

View File

@ -34,6 +34,8 @@ using Poco::Net::HTTPServerResponse;
using Poco::Net::SocketStream; using Poco::Net::SocketStream;
using Poco::Net::WebSocket; using Poco::Net::WebSocket;
using Poco::Net::WebSocketException; using Poco::Net::WebSocketException;
using Poco::Net::ConnectionAbortedException;
using Poco::IOException;
namespace namespace
@ -76,6 +78,12 @@ namespace
break; break;
} }
} }
catch (ConnectionAbortedException&)
{
}
catch (IOException&)
{
}
} }
private: private: