mirror of
https://github.com/pocoproject/poco.git
synced 2024-12-12 10:13:51 +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
@ -74,11 +74,11 @@ private:
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -107,7 +107,7 @@ protected:
|
||||
/// 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 @@ private:
|
||||
Task(const Task&);
|
||||
Task& operator = (const Task&);
|
||||
|
||||
std::string _name;
|
||||
TaskManager* _pOwner;
|
||||
float _progress;
|
||||
std::string _name;
|
||||
TaskManager* _pOwner;
|
||||
std::atomic<float> _progress;
|
||||
std::atomic<TaskState> _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;
|
||||
}
|
||||
|
||||
|
@ -122,7 +122,7 @@ private:
|
||||
TaskList _taskList;
|
||||
Timestamp _lastProgressNotification;
|
||||
NotificationCenter _nc;
|
||||
mutable MutexT _mutex;
|
||||
mutable MutexT _mutex;
|
||||
|
||||
friend class Task;
|
||||
};
|
||||
|
@ -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<DWORD>(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<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)
|
||||
{
|
||||
DWORD dwRetVal = GetLastError();
|
||||
int retVal = static_cast<int>(dwRetVal);
|
||||
#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
|
||||
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());
|
||||
if (!_memHandle)
|
||||
{
|
||||
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
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ public:
|
||||
|
||||
void testCreate();
|
||||
void testCreateFromFile();
|
||||
void testCreateLarge();
|
||||
|
||||
void setUp();
|
||||
void tearDown();
|
||||
|
@ -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);
|
||||
|
15
Makefile
15
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:
|
||||
|
@ -384,7 +384,7 @@ private:
|
||||
HTTPBasicCredentials _proxyBasicCreds;
|
||||
HTTPDigestCredentials _proxyDigestCreds;
|
||||
HTTPNTLMCredentials _proxyNTLMCreds;
|
||||
bool _ntlmProxyAuthenticated;
|
||||
bool _ntlmProxyAuthenticated = false;
|
||||
|
||||
static ProxyConfig _globalProxyConfig;
|
||||
|
||||
|
@ -208,6 +208,9 @@ public:
|
||||
/// 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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -171,12 +171,16 @@ public:
|
||||
Poco::Timespan remainingTime(timeout);
|
||||
int rc;
|
||||
|
||||
do
|
||||
while (true)
|
||||
{
|
||||
Poco::Timestamp start;
|
||||
rc = epoll_wait(_epollfd, &_events[0],
|
||||
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
|
||||
// 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 (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 @@ private:
|
||||
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<int>;
|
||||
#else // WEPOLL_H_
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 <istream>
|
||||
#include <ostream>
|
||||
@ -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);
|
||||
|
@ -25,6 +25,7 @@ public:
|
||||
~HTTPClientSessionTest();
|
||||
|
||||
void testGetSmall();
|
||||
void testGetSmallUnix();
|
||||
void testGetLarge();
|
||||
void testHead();
|
||||
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()
|
||||
{
|
||||
_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();
|
||||
|
@ -27,6 +27,9 @@ public:
|
||||
HTTPTestServer();
|
||||
/// Creates the HTTPTestServer.
|
||||
|
||||
HTTPTestServer(const std::string& addr);
|
||||
/// Creates the HTTPTestServer on the specified address.
|
||||
|
||||
~HTTPTestServer();
|
||||
/// Destroys the HTTPTestServer.
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -53,10 +53,10 @@ private:
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user