mirror of
https://github.com/pocoproject/poco.git
synced 2025-03-03 04:38:39 +01:00
* 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:
parent
70bb3a40de
commit
11de40399c
@ -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;
|
||||||
};
|
};
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ public:
|
|||||||
|
|
||||||
void testCreate();
|
void testCreate();
|
||||||
void testCreateFromFile();
|
void testCreateFromFile();
|
||||||
|
void testCreateLarge();
|
||||||
|
|
||||||
void setUp();
|
void setUp();
|
||||||
void tearDown();
|
void tearDown();
|
||||||
|
@ -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);
|
||||||
|
15
Makefile
15
Makefile
@ -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:
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
@ -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_
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
@ -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));
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -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:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user