diff --git a/Foundation/include/Poco/SharedMemory_WIN32.h b/Foundation/include/Poco/SharedMemory_WIN32.h index c891305491..b39bd39ab0 100644 --- a/Foundation/include/Poco/SharedMemory_WIN32.h +++ b/Foundation/include/Poco/SharedMemory_WIN32.h @@ -74,11 +74,11 @@ class Foundation_API SharedMemoryImpl: public RefCountedObject SharedMemoryImpl& operator = (const SharedMemoryImpl&); std::string _name; - HANDLE _memHandle; - HANDLE _fileHandle; - DWORD _size; - DWORD _mode; - char* _address; + HANDLE _memHandle; + HANDLE _fileHandle; + std::size_t _size; + DWORD _mode; + char* _address; }; diff --git a/Foundation/include/Poco/Task.h b/Foundation/include/Poco/Task.h index 123c74ab35..904dc97ef6 100644 --- a/Foundation/include/Poco/Task.h +++ b/Foundation/include/Poco/Task.h @@ -107,7 +107,7 @@ class Foundation_API Task: public Runnable, public RefCountedObject /// A Task should use this method in favor of Thread::sleep(). bool yield(); - /// Yields cpu to other threads + /// Yields cpu to other threads /// /// If the task is cancelled while it is suspended, /// yield() will return true. If the tasks resumes @@ -145,12 +145,12 @@ class Foundation_API Task: public Runnable, public RefCountedObject Task(const Task&); Task& operator = (const Task&); - std::string _name; - TaskManager* _pOwner; - float _progress; + std::string _name; + TaskManager* _pOwner; + std::atomic _progress; std::atomic _state; - Event _cancelEvent; - mutable FastMutex _mutex; + Event _cancelEvent; + mutable FastMutex _mutex; friend class TaskManager; }; @@ -167,8 +167,6 @@ inline const std::string& Task::name() const inline float Task::progress() const { - FastMutex::ScopedLock lock(_mutex); - return _progress; } diff --git a/Foundation/include/Poco/TaskManager.h b/Foundation/include/Poco/TaskManager.h index de3984ca18..e8f2836f20 100644 --- a/Foundation/include/Poco/TaskManager.h +++ b/Foundation/include/Poco/TaskManager.h @@ -122,7 +122,7 @@ class Foundation_API TaskManager TaskList _taskList; Timestamp _lastProgressNotification; NotificationCenter _nc; - mutable MutexT _mutex; + mutable MutexT _mutex; friend class Task; }; diff --git a/Foundation/src/SharedMemory_WIN32.cpp b/Foundation/src/SharedMemory_WIN32.cpp index 45beaa840d..6d35611cd2 100644 --- a/Foundation/src/SharedMemory_WIN32.cpp +++ b/Foundation/src/SharedMemory_WIN32.cpp @@ -28,7 +28,7 @@ SharedMemoryImpl::SharedMemoryImpl(const std::string& name, std::size_t size, Sh _name(name), _memHandle(INVALID_HANDLE_VALUE), _fileHandle(INVALID_HANDLE_VALUE), - _size(static_cast(size)), + _size(size), _mode(PAGE_READONLY), _address(0) { @@ -37,22 +37,40 @@ SharedMemoryImpl::SharedMemoryImpl(const std::string& name, std::size_t size, Sh std::wstring utf16name; UnicodeConverter::toUTF16(_name, utf16name); - _memHandle = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, _mode, 0, _size, utf16name.c_str()); +#ifdef _WIN64 + const DWORD dwMaxSizeLow = static_cast(_size & 0xFFFFFFFFULL); + const DWORD dwMaxSizeHigh = static_cast((_size & (0xFFFFFFFFULL << 32)) >> 32); +#else + if (_size > std::numeric_limits::max()) + { + throw Poco::InvalidArgumentException(Poco::format("Requested shared memory size (%z) too large (max %lu)", + _size, std::numeric_limits::max())); + } + const DWORD dwMaxSizeLow = static_cast(_size); + const DWORD dwMaxSizeHigh = 0UL; +#endif + _memHandle = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, _mode, dwMaxSizeHigh, dwMaxSizeLow, utf16name.c_str()); if (!_memHandle) { DWORD dwRetVal = GetLastError(); + int retVal = static_cast(dwRetVal); #if defined (_WIN32_WCE) - throw SystemException(format("Cannot create shared memory object %s [Error %d: %s]", _name, static_cast(dwRetVal), Error::getMessage(dwRetVal))); + throw SystemException(Poco::format("Cannot create shared memory object %s [Error %d: %s]", + _name, retVal, Error::getMessage(dwRetVal))); #else if (_mode != PAGE_READONLY || dwRetVal != 5) - throw SystemException(format("Cannot create shared memory object %s [Error %d: %s]", _name, static_cast(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()); if (!_memHandle) { dwRetVal = GetLastError(); - throw SystemException(format("Cannot open shared memory object %s [Error %d: %s]", _name, static_cast(dwRetVal), Error::getMessage(dwRetVal))); + throw SystemException(Poco::format("Cannot open shared memory object %s [Error %d: %s]", + _name, retVal, Error::getMessage(dwRetVal)), retVal); } #endif } diff --git a/Foundation/src/Task.cpp b/Foundation/src/Task.cpp index 4b1e1fa1b3..a84c0c2732 100644 --- a/Foundation/src/Task.cpp +++ b/Foundation/src/Task.cpp @@ -71,12 +71,12 @@ void Task::run() catch (std::exception& exc) { if (pOwner) - pOwner->taskFailed(this, SystemException(exc.what())); + pOwner->taskFailed(this, SystemException("Task::run()", exc.what())); } catch (...) { if (pOwner) - pOwner->taskFailed(this, SystemException("unknown exception")); + pOwner->taskFailed(this, SystemException("Task::run(): unknown exception")); } _state = TASK_FINISHED; if (pOwner) pOwner->taskFinished(this); @@ -98,11 +98,9 @@ bool Task::yield() void Task::setProgress(float progress) { - FastMutex::ScopedLock lock(_mutex); - - if (_progress != progress) + if (_progress.exchange(progress) != progress) { - _progress = progress; + FastMutex::ScopedLock lock(_mutex); if (_pOwner) _pOwner->taskProgress(this, _progress); } @@ -112,7 +110,6 @@ void Task::setProgress(float progress) void Task::setOwner(TaskManager* pOwner) { FastMutex::ScopedLock lock(_mutex); - _pOwner = pOwner; } diff --git a/Foundation/testsuite/src/SharedMemoryTest.cpp b/Foundation/testsuite/src/SharedMemoryTest.cpp index bc077b7f8c..31cf0a93df 100644 --- a/Foundation/testsuite/src/SharedMemoryTest.cpp +++ b/Foundation/testsuite/src/SharedMemoryTest.cpp @@ -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() { } @@ -89,6 +113,7 @@ CppUnit::Test* SharedMemoryTest::suite() #if !defined(POCO_NO_SHAREDMEMORY) CppUnit_addTest(pSuite, SharedMemoryTest, testCreate); CppUnit_addTest(pSuite, SharedMemoryTest, testCreateFromFile); + CppUnit_addTest(pSuite, SharedMemoryTest, testCreateLarge); #endif return pSuite; } diff --git a/Foundation/testsuite/src/SharedMemoryTest.h b/Foundation/testsuite/src/SharedMemoryTest.h index b54541b240..492ffbc6d1 100644 --- a/Foundation/testsuite/src/SharedMemoryTest.h +++ b/Foundation/testsuite/src/SharedMemoryTest.h @@ -27,6 +27,7 @@ class SharedMemoryTest: public CppUnit::TestCase void testCreate(); void testCreateFromFile(); + void testCreateLarge(); void setUp(); void tearDown(); diff --git a/Foundation/testsuite/src/TaskTest.cpp b/Foundation/testsuite/src/TaskTest.cpp index 551f0bb122..9e6b67d587 100644 --- a/Foundation/testsuite/src/TaskTest.cpp +++ b/Foundation/testsuite/src/TaskTest.cpp @@ -35,42 +35,42 @@ namespace void runTask() { - try - { - _event.wait(); - if (sleep(10)) - return; - setProgress(0.5); - _event.wait(); - if (isCancelled()) - return; - setProgress(1.0); - _event.wait(); - } - catch(const Poco::Exception& e) - { - std::cerr << "TestTask::run(): " << e.displayText() << '\n'; - } - catch(const std::exception& e) - { - std::cerr << "TestTask::run(): " << e.what() << '\n'; - } - catch(...) - { - std::cerr << "TestTask::run(): unknown exception." << '\n'; - } + try + { + _event.wait(); + if (sleep(100)) + return; + setProgress(0.5); + _event.wait(); + if (isCancelled()) + return; + setProgress(1.0); + _event.wait(); + } + catch(const Poco::Exception& e) + { + std::cerr << "TestTask::run(): " << e.displayText() << '\n'; + } + catch(const std::exception& e) + { + std::cerr << "TestTask::run(): " << e.what() << '\n'; + } + catch(...) + { + std::cerr << "TestTask::run(): unknown exception." << '\n'; + } } void cont() { - try - { - _event.set(); - } - catch(const Poco::SystemException& e) - { - std::cerr << "TestTask::cont(): " << e.displayText() << '\n'; - } + try + { + _event.set(); + } + catch(const Poco::SystemException& e) + { + std::cerr << "TestTask::cont(): " << e.displayText() << '\n'; + } } private: @@ -131,6 +131,8 @@ void TaskTest::testCancel2() assertTrue (pTT->state() == Task::TASK_IDLE); Thread thr; thr.start(*pTT); + while (pTT->state() != Task::TASK_RUNNING) + Thread::sleep(50); assertTrue (pTT->progress() == 0); pTT->cancel(); assertTrue (pTT->state() == Task::TASK_CANCELLING); diff --git a/Makefile b/Makefile index a90deb5237..35e4cb3570 100644 --- a/Makefile +++ b/Makefile @@ -246,7 +246,10 @@ NetSSL_OpenSSL-clean: Data-libexec: Foundation-libexec $(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 Data-samples: Data-libexec Data-libexec Data/SQLite-libexec Net-libexec @@ -260,7 +263,7 @@ Data-clean: Data/SQLite-libexec: Foundation-libexec Data-libexec $(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 Data/SQLite-clean: @@ -270,7 +273,7 @@ Data/SQLite-clean: Data/ODBC-libexec: Foundation-libexec Data-libexec $(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 Data/ODBC-clean: @@ -280,7 +283,7 @@ Data/ODBC-clean: Data/MySQL-libexec: Foundation-libexec Data-libexec $(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 Data/MySQL-clean: @@ -290,7 +293,7 @@ Data/MySQL-clean: Data/PostgreSQL-libexec: Foundation-libexec Data-libexec $(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 Data/PostgreSQL-clean: @@ -407,7 +410,7 @@ Prometheus-libexec: Foundation-libexec Net-libexec Prometheus-tests: Prometheus-libexec cppunit $(MAKE) -C $(POCO_BASE)/Prometheus/testsuite -Prometheus-samples: Prometheus-libexec +Prometheus-samples: Prometheus-libexec Util-libexec $(MAKE) -C $(POCO_BASE)/Prometheus/samples Prometheus-clean: diff --git a/Net/include/Poco/Net/HTTPClientSession.h b/Net/include/Poco/Net/HTTPClientSession.h index 14ae999bb9..d7eabb298a 100644 --- a/Net/include/Poco/Net/HTTPClientSession.h +++ b/Net/include/Poco/Net/HTTPClientSession.h @@ -384,7 +384,7 @@ class Net_API HTTPClientSession: public HTTPSession HTTPBasicCredentials _proxyBasicCreds; HTTPDigestCredentials _proxyDigestCreds; HTTPNTLMCredentials _proxyNTLMCreds; - bool _ntlmProxyAuthenticated; + bool _ntlmProxyAuthenticated = false; static ProxyConfig _globalProxyConfig; diff --git a/Net/include/Poco/Net/SocketAddress.h b/Net/include/Poco/Net/SocketAddress.h index d0ed93c139..622ed06bfd 100644 --- a/Net/include/Poco/Net/SocketAddress.h +++ b/Net/include/Poco/Net/SocketAddress.h @@ -208,6 +208,9 @@ class Net_API SocketAddress /// 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: void init(const IPAddress& hostAddress, Poco::UInt16 portNumber); void init(const std::string& hostAddress, Poco::UInt16 portNumber); diff --git a/Net/src/HTTPClientSession.cpp b/Net/src/HTTPClientSession.cpp index 7197e26adb..7214b58fe1 100644 --- a/Net/src/HTTPClientSession.cpp +++ b/Net/src/HTTPClientSession.cpp @@ -459,7 +459,12 @@ void HTTPClientSession::reconnect() { SocketAddress addr; if (_proxyConfig.host.empty() || bypassProxy()) - addr = SocketAddress(_host, _port); + { + if (SocketAddress::isUnixLocal(_host)) + addr = SocketAddress(_host); + else + addr = SocketAddress(_host, _port); + } else addr = SocketAddress(_proxyConfig.host, _proxyConfig.port); diff --git a/Net/src/HTTPSession.cpp b/Net/src/HTTPSession.cpp index 478a0ad78b..84e436f6d0 100644 --- a/Net/src/HTTPSession.cpp +++ b/Net/src/HTTPSession.cpp @@ -196,7 +196,8 @@ void HTTPSession::connect(const SocketAddress& address) _socket.connect(address, _connectionTimeout); _socket.setReceiveTimeout(_receiveTimeout); _socket.setSendTimeout(_sendTimeout); - _socket.setNoDelay(true); + if (address.family() != SocketAddress::UNIX_LOCAL) + _socket.setNoDelay(true); // There may be leftover data from a previous (failed) request in the buffer, // so we clear it. _pCurrent = _pEnd = _pBuffer; diff --git a/Net/src/PollSet.cpp b/Net/src/PollSet.cpp index 11bfa487e9..620d85cc30 100644 --- a/Net/src/PollSet.cpp +++ b/Net/src/PollSet.cpp @@ -171,12 +171,16 @@ class PollSetImpl Poco::Timespan remainingTime(timeout); int rc; - do + while (true) { Poco::Timestamp start; rc = epoll_wait(_epollfd, &_events[0], static_cast(_events.size()), static_cast(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 // calls would round-robin through the remaining ready sockets, but it's better to give @@ -187,18 +191,12 @@ class PollSetImpl // if interrupted and there's still time left, keep waiting if (SocketImpl::lastError() == POCO_EINTR) { - Poco::Timestamp end; - Poco::Timespan waited = end - start; - if (waited < remainingTime) - { - remainingTime -= waited; - continue; - } + if (keepWaiting(start, remainingTime)) continue; } else SocketImpl::error(); } + break; } - while (false); ScopedLock lock(_mutex); @@ -304,6 +302,18 @@ class PollSetImpl 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_ using EPollHandle = std::atomic; #else // WEPOLL_H_ diff --git a/Net/src/SocketAddress.cpp b/Net/src/SocketAddress.cpp index d9a7ce6542..3c9955b061 100644 --- a/Net/src/SocketAddress.cpp +++ b/Net/src/SocketAddress.cpp @@ -79,7 +79,7 @@ SocketAddress::SocketAddress() SocketAddress::SocketAddress(Family fam) { - init(IPAddress(fam), 0); + init(IPAddress(fam), 0); } @@ -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) { poco_assert (!hostAndPort.empty()); -#if defined(POCO_OS_FAMILY_WINDOWS) && defined(POCO_HAS_UNIX_SOCKET) - RegularExpression re(R"((?:[a-zA-Z]\:|\\\\[\w\s\.]+\\[\w\s\.$]+)\\(?:[\w\s\.]+\\)*[\w\s\.]*?$)"); - if (re.match(hostAndPort)) + if (isUnixLocal(hostAndPort)) { newLocal(hostAndPort); return; } -#endif std::string host; std::string port; std::string::const_iterator it = hostAndPort.begin(); std::string::const_iterator end = hostAndPort.end(); - -#if defined(POCO_OS_FAMILY_UNIX) - if (*it == '/') - { - newLocal(hostAndPort); - return; - } -#endif if (*it == '[') { ++it; diff --git a/Net/testsuite/src/EchoServer.cpp b/Net/testsuite/src/EchoServer.cpp index 67f3529c69..48817683f5 100644 --- a/Net/testsuite/src/EchoServer.cpp +++ b/Net/testsuite/src/EchoServer.cpp @@ -83,8 +83,10 @@ void EchoServer::run() { std::cerr << "EchoServer: " << exc.displayText() << std::endl; } + ss.close(); } } + _socket.close(); _done = true; } @@ -99,4 +101,3 @@ bool EchoServer::done() { return _done; } - diff --git a/Net/testsuite/src/HTTPClientSessionTest.cpp b/Net/testsuite/src/HTTPClientSessionTest.cpp index b7bf375e4d..31de150531 100644 --- a/Net/testsuite/src/HTTPClientSessionTest.cpp +++ b/Net/testsuite/src/HTTPClientSessionTest.cpp @@ -15,6 +15,8 @@ #include "Poco/Net/HTTPRequest.h" #include "Poco/Net/HTTPResponse.h" #include "Poco/StreamCopier.h" +#include "Poco/File.h" +#include "Poco/Path.h" #include "HTTPTestServer.h" #include #include @@ -26,6 +28,8 @@ using Poco::Net::HTTPRequest; using Poco::Net::HTTPResponse; using Poco::Net::HTTPMessage; using Poco::StreamCopier; +using Poco::File; +using Poco::Path; 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() { HTTPTestServer srv; @@ -373,6 +403,7 @@ CppUnit::Test* HTTPClientSessionTest::suite() CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("HTTPClientSessionTest"); CppUnit_addTest(pSuite, HTTPClientSessionTest, testGetSmall); + CppUnit_addTest(pSuite, HTTPClientSessionTest, testGetSmallUnix); CppUnit_addTest(pSuite, HTTPClientSessionTest, testGetLarge); CppUnit_addTest(pSuite, HTTPClientSessionTest, testHead); CppUnit_addTest(pSuite, HTTPClientSessionTest, testPostSmallIdentity); diff --git a/Net/testsuite/src/HTTPClientSessionTest.h b/Net/testsuite/src/HTTPClientSessionTest.h index ecc7b50e4a..fc0a004f91 100644 --- a/Net/testsuite/src/HTTPClientSessionTest.h +++ b/Net/testsuite/src/HTTPClientSessionTest.h @@ -25,6 +25,7 @@ class HTTPClientSessionTest: public CppUnit::TestCase ~HTTPClientSessionTest(); void testGetSmall(); + void testGetSmallUnix(); void testGetLarge(); void testHead(); void testPostSmallIdentity(); diff --git a/Net/testsuite/src/HTTPTestServer.cpp b/Net/testsuite/src/HTTPTestServer.cpp index 78e3e0a7e1..02f01a0960 100644 --- a/Net/testsuite/src/HTTPTestServer.cpp +++ b/Net/testsuite/src/HTTPTestServer.cpp @@ -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() { _stop = true; @@ -74,13 +85,15 @@ void HTTPTestServer::run() { _lastRequest.append(buffer, n); if (!requestComplete()) + { n = ss.receiveBytes(buffer, sizeof(buffer)); + } else n = 0; } std::string response = handleRequest(); - ss.sendBytes(response.data(), (int) response.size()); - Poco::Thread::sleep(1000); + n = ss.sendBytes(response.data(), (int) response.size()); + if (n) Poco::Thread::sleep(1000); try { ss.shutdown(); diff --git a/Net/testsuite/src/HTTPTestServer.h b/Net/testsuite/src/HTTPTestServer.h index 4bb6478872..02ca9e0d40 100644 --- a/Net/testsuite/src/HTTPTestServer.h +++ b/Net/testsuite/src/HTTPTestServer.h @@ -27,6 +27,9 @@ class HTTPTestServer: public Poco::Runnable HTTPTestServer(); /// Creates the HTTPTestServer. + HTTPTestServer(const std::string& addr); + /// Creates the HTTPTestServer on the specified address. + ~HTTPTestServer(); /// Destroys the HTTPTestServer. diff --git a/Net/testsuite/src/PollSetTest.cpp b/Net/testsuite/src/PollSetTest.cpp index 05a3291f48..dd8e0b2517 100644 --- a/Net/testsuite/src/PollSetTest.cpp +++ b/Net/testsuite/src/PollSetTest.cpp @@ -404,9 +404,19 @@ void PollSetTest::testPollClosedServer() "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(); assertTrue (len == ss2.sendBytes(str.data(), len)); + sw.restart(); while (!echoServer2.done()) { Thread::sleep(10); @@ -417,8 +427,11 @@ void PollSetTest::testPollClosedServer() "waiting on server after %ds", secs), __LINE__); } } - - assertEqual(2, ps.poll(Timespan(1000000)).size()); + n = ss2.receiveBytes(buffer, sizeof(buffer)); + assertTrue(n == 0); + smm = ps.poll(Timespan(1000000)); + assertEqual(1, smm.size()); + assertTrue(ss2 == smm.begin()->first); // socket closed or error assertTrue(0 >= ss1.receiveBytes(0, 0)); diff --git a/Net/testsuite/src/SocketTest.cpp b/Net/testsuite/src/SocketTest.cpp index e4df0208b3..c8976a1fb3 100644 --- a/Net/testsuite/src/SocketTest.cpp +++ b/Net/testsuite/src/SocketTest.cpp @@ -562,8 +562,10 @@ void SocketTest::testEchoUnixLocal() if (socketFile.exists()) socketFile.remove(); echoServer.stop(); #else // POCO_HAS_UNIX_SOCKET - #pragma message("[UNIX LOCAL SOCKET DISABLED]") - std::cout << "[UNIX LOCAL SOCKET DISABLED]" << std::endl; + #if POCO_OS == POCO_OS_WINDOWS_NT + #pragma message("[UNIX LOCAL SOCKET DISABLED]") + #endif + std::cout << "[UNIX LOCAL SOCKET DISABLED]"; #endif } @@ -588,8 +590,10 @@ void SocketTest::testUnixLocalAbstract() ss.close(); echoServer.stop(); #else // POCO_HAS_UNIX_SOCKET -#pragma message("[ABSTRACT UNIX LOCAL SOCKET DISABLED]") - std::cout << "[ABSTRACT UNIX LOCAL SOCKET DISABLED]" << std::endl; + #if POCO_OS == POCO_OS_WINDOWS_NT + #pragma message("[ABSTRACT UNIX LOCAL SOCKET DISABLED]") + #endif + std::cout << "[ABSTRACT UNIX LOCAL SOCKET DISABLED]"; #endif } diff --git a/Net/testsuite/src/SocketTest.h b/Net/testsuite/src/SocketTest.h index 7575d7f9df..e3b69e0f69 100644 --- a/Net/testsuite/src/SocketTest.h +++ b/Net/testsuite/src/SocketTest.h @@ -53,10 +53,10 @@ class SocketTest: public CppUnit::TestCase void onReadable(bool& b); void onWritable(bool& b); - int _readableToNot; - int _notToReadable; - int _writableToNot; - int _notToWritable; + int _readableToNot = 0; + int _notToReadable = 0; + int _writableToNot = 0; + int _notToWritable = 0; }; diff --git a/Net/testsuite/src/WebSocketTest.cpp b/Net/testsuite/src/WebSocketTest.cpp index 664bc4ff02..3cd312ed1f 100644 --- a/Net/testsuite/src/WebSocketTest.cpp +++ b/Net/testsuite/src/WebSocketTest.cpp @@ -34,6 +34,8 @@ using Poco::Net::HTTPServerResponse; using Poco::Net::SocketStream; using Poco::Net::WebSocket; using Poco::Net::WebSocketException; +using Poco::Net::ConnectionAbortedException; +using Poco::IOException; namespace @@ -76,6 +78,12 @@ namespace break; } } + catch (ConnectionAbortedException&) + { + } + catch (IOException&) + { + } } private: