mirror of
https://github.com/pocoproject/poco.git
synced 2025-04-25 17:28:13 +02:00
enh(Net): StreamSocket::sendFile() takes additional count parameter
This commit is contained in:
parent
3d8040bb17
commit
66c1d30bb4
Net
include/Poco/Net
src
testsuite/src
NetSSL_OpenSSL/testsuite/src
@ -287,9 +287,12 @@ public:
|
|||||||
/// The preferred way for a socket to receive urgent data
|
/// The preferred way for a socket to receive urgent data
|
||||||
/// is by enabling the SO_OOBINLINE option.
|
/// is by enabling the SO_OOBINLINE option.
|
||||||
|
|
||||||
virtual std::streamsize sendFile(Poco::FileInputStream& FileInputStream, std::streamoff offset = 0);
|
virtual std::streamsize sendFile(Poco::FileInputStream& FileInputStream, std::streamoff offset = 0, std::streamsize count = 0);
|
||||||
/// Sends the contents of a file in an optimized way, if possible.
|
/// Sends the contents of a file in an optimized way, if possible.
|
||||||
///
|
///
|
||||||
|
/// If count is != 0, sends the given number of bytes, otherwise
|
||||||
|
/// sends all bytes, starting from the given offset.
|
||||||
|
///
|
||||||
/// On POSIX systems, this means using sendfile() or sendfile64().
|
/// On POSIX systems, this means using sendfile() or sendfile64().
|
||||||
/// On Windows, this means using TransmitFile().
|
/// On Windows, this means using TransmitFile().
|
||||||
///
|
///
|
||||||
@ -544,11 +547,11 @@ protected:
|
|||||||
|
|
||||||
void checkBrokenTimeout(SelectMode mode);
|
void checkBrokenTimeout(SelectMode mode);
|
||||||
|
|
||||||
std::streamsize sendFileNative(Poco::FileInputStream& FileInputStream, std::streamoff offset);
|
std::streamsize sendFileNative(Poco::FileInputStream& FileInputStream, std::streamoff offset, std::streamsize count);
|
||||||
/// Implements sendFile() using an OS-specific API like
|
/// Implements sendFile() using an OS-specific API like
|
||||||
/// sendfile() or TransmitFile().
|
/// sendfile() or TransmitFile().
|
||||||
|
|
||||||
std::streamsize sendFileBlockwise(Poco::FileInputStream& FileInputStream, std::streamoff offset);
|
std::streamsize sendFileBlockwise(Poco::FileInputStream& FileInputStream, std::streamoff offset, std::streamsize count);
|
||||||
/// Implements sendFile() by reading the file blockwise and
|
/// Implements sendFile() by reading the file blockwise and
|
||||||
/// calling sendBytes() for each block.
|
/// calling sendBytes() for each block.
|
||||||
|
|
||||||
|
@ -268,9 +268,12 @@ public:
|
|||||||
/// The preferred way for a socket to receive urgent data
|
/// The preferred way for a socket to receive urgent data
|
||||||
/// is by enabling the SO_OOBINLINE option.
|
/// is by enabling the SO_OOBINLINE option.
|
||||||
|
|
||||||
std::streamsize sendFile(Poco::FileInputStream& FileInputStream, std::streamoff offset = 0);
|
std::streamsize sendFile(Poco::FileInputStream& FileInputStream, std::streamoff offset = 0, std::streamsize count = 0);
|
||||||
/// Sends the contents of a file in an optimized way, if possible.
|
/// Sends the contents of a file in an optimized way, if possible.
|
||||||
///
|
///
|
||||||
|
/// If count is != 0, sends the given number of bytes, otherwise
|
||||||
|
/// sends all bytes, starting from the given offset.
|
||||||
|
///
|
||||||
/// On POSIX systems, this means using sendfile() or sendfile64().
|
/// On POSIX systems, this means using sendfile() or sendfile64().
|
||||||
/// On Windows, this means using TransmitFile().
|
/// On Windows, this means using TransmitFile().
|
||||||
///
|
///
|
||||||
|
@ -698,21 +698,21 @@ void SocketImpl::sendUrgent(unsigned char data)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::streamsize SocketImpl::sendFile(FileInputStream& fileInputStream, std::streamoff offset)
|
std::streamsize SocketImpl::sendFile(FileInputStream& fileInputStream, std::streamoff offset, std::streamsize count)
|
||||||
{
|
{
|
||||||
if (!getBlocking()) throw NetException("sendFile() not supported for non-blocking sockets");
|
if (!getBlocking()) throw NetException("sendFile() not supported for non-blocking sockets");
|
||||||
|
|
||||||
#ifdef POCO_HAVE_SENDFILE
|
#ifdef POCO_HAVE_SENDFILE
|
||||||
if (secure())
|
if (secure())
|
||||||
{
|
{
|
||||||
return sendFileBlockwise(fileInputStream, offset);
|
return sendFileBlockwise(fileInputStream, offset, count);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return sendFileNative(fileInputStream, offset);
|
return sendFileNative(fileInputStream, offset, count);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
return sendFileBlockwise(fileInputStream, offset);
|
return sendFileBlockwise(fileInputStream, offset, count);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1451,11 +1451,10 @@ void SocketImpl::error(int code, const std::string& arg)
|
|||||||
#ifdef POCO_OS_FAMILY_WINDOWS
|
#ifdef POCO_OS_FAMILY_WINDOWS
|
||||||
|
|
||||||
|
|
||||||
std::streamsize SocketImpl::sendFileNative(FileInputStream& fileInputStream, std::streamoff offset)
|
std::streamsize SocketImpl::sendFileNative(FileInputStream& fileInputStream, std::streamoff offset, std::streamsize count)
|
||||||
{
|
{
|
||||||
FileIOS::NativeHandle fd = fileInputStream.nativeHandle();
|
FileIOS::NativeHandle fd = fileInputStream.nativeHandle();
|
||||||
UInt64 fileSize = fileInputStream.size();
|
if (count == 0) count = fileInputStream.size() - offset;
|
||||||
std::streamoff sentSize = fileSize - offset;
|
|
||||||
LARGE_INTEGER offsetHelper;
|
LARGE_INTEGER offsetHelper;
|
||||||
offsetHelper.QuadPart = offset;
|
offsetHelper.QuadPart = offset;
|
||||||
OVERLAPPED overlapped;
|
OVERLAPPED overlapped;
|
||||||
@ -1468,7 +1467,7 @@ std::streamsize SocketImpl::sendFileNative(FileInputStream& fileInputStream, std
|
|||||||
int err = GetLastError();
|
int err = GetLastError();
|
||||||
error(err);
|
error(err);
|
||||||
}
|
}
|
||||||
bool result = TransmitFile(_sockfd, fd, sentSize, 0, &overlapped, nullptr, 0);
|
bool result = TransmitFile(_sockfd, fd, count, 0, &overlapped, nullptr, 0);
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
int err = WSAGetLastError();
|
int err = WSAGetLastError();
|
||||||
@ -1480,7 +1479,7 @@ std::streamsize SocketImpl::sendFileNative(FileInputStream& fileInputStream, std
|
|||||||
WaitForSingleObject(overlapped.hEvent, INFINITE);
|
WaitForSingleObject(overlapped.hEvent, INFINITE);
|
||||||
}
|
}
|
||||||
CloseHandle(overlapped.hEvent);
|
CloseHandle(overlapped.hEvent);
|
||||||
return sentSize;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1489,23 +1488,33 @@ std::streamsize SocketImpl::sendFileNative(FileInputStream& fileInputStream, std
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
std::streamsize sendFilePosix(poco_socket_t sd, FileIOS::NativeHandle fd, std::streamsize offset, std::streamoff sentSize)
|
std::streamsize sendFileUnix(poco_socket_t sd, FileIOS::NativeHandle fd, std::streamsize offset, std::streamoff count)
|
||||||
{
|
{
|
||||||
Int64 sent = 0;
|
Int64 sent = 0;
|
||||||
#ifdef __USE_LARGEFILE64
|
#ifdef __USE_LARGEFILE64
|
||||||
sent = sendfile64(sd, fd, (off64_t*) &offset, sentSize);
|
sent = sendfile64(sd, fd, (off64_t*) &offset, count);
|
||||||
#else
|
#else
|
||||||
#if POCO_OS == POCO_OS_LINUX && !defined(POCO_EMSCRIPTEN)
|
#if POCO_OS == POCO_OS_LINUX && !defined(POCO_EMSCRIPTEN)
|
||||||
sent = sendfile(sd, fd, (off_t*) &offset, sentSize);
|
sent = sendfile(sd, fd, (off_t*) &offset, count);
|
||||||
#elif POCO_OS == POCO_OS_MAC_OS_X
|
#elif POCO_OS == POCO_OS_MAC_OS_X
|
||||||
int result = sendfile(fd, sd, offset, &sentSize, nullptr, 0);
|
int result = sendfile(fd, sd, offset, &count, NULL, 0);
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
{
|
{
|
||||||
sent = -1;
|
sent = -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sent = sentSize;
|
sent = count;
|
||||||
|
}
|
||||||
|
#elif POCO_OS == POCO_OS_FREE_BSD
|
||||||
|
int result = sendfile(fd, sd, offset, &count, NULL, NULL, 0);
|
||||||
|
if (result < 0)
|
||||||
|
{
|
||||||
|
sent = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sent = count;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
throw Poco::NotImplementedException("sendfile not implemented for this platform");
|
throw Poco::NotImplementedException("sendfile not implemented for this platform");
|
||||||
@ -1520,12 +1529,11 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::streamsize SocketImpl::sendFileNative(FileInputStream& fileInputStream, std::streamoff offset)
|
std::streamsize SocketImpl::sendFileNative(FileInputStream& fileInputStream, std::streamoff offset, std::streamsize count)
|
||||||
{
|
{
|
||||||
FileIOS::NativeHandle fd = fileInputStream.nativeHandle();
|
FileIOS::NativeHandle fd = fileInputStream.nativeHandle();
|
||||||
UInt64 fileSize = fileInputStream.size();
|
if (count == 0) count = fileInputStream.size() - offset;
|
||||||
std::streamoff sentSize = fileSize - offset;
|
std::streamsize sent = 0;
|
||||||
Int64 sent = 0;
|
|
||||||
struct sigaction sa, old_sa;
|
struct sigaction sa, old_sa;
|
||||||
sa.sa_handler = SIG_IGN;
|
sa.sa_handler = SIG_IGN;
|
||||||
sigemptyset(&sa.sa_mask);
|
sigemptyset(&sa.sa_mask);
|
||||||
@ -1534,7 +1542,7 @@ std::streamsize SocketImpl::sendFileNative(FileInputStream& fileInputStream, std
|
|||||||
while (sent == 0)
|
while (sent == 0)
|
||||||
{
|
{
|
||||||
errno = 0;
|
errno = 0;
|
||||||
sent = sendFilePosix(_sockfd, fd, offset, sentSize);
|
sent = sendFileUnix(_sockfd, fd, offset, count);
|
||||||
if (sent < 0)
|
if (sent < 0)
|
||||||
{
|
{
|
||||||
error(errno);
|
error(errno);
|
||||||
@ -1553,21 +1561,28 @@ std::streamsize SocketImpl::sendFileNative(FileInputStream& fileInputStream, std
|
|||||||
#endif // POCO_HAVE_SENDFILE
|
#endif // POCO_HAVE_SENDFILE
|
||||||
|
|
||||||
|
|
||||||
std::streamsize SocketImpl::sendFileBlockwise(FileInputStream& fileInputStream, std::streamoff offset)
|
std::streamsize SocketImpl::sendFileBlockwise(FileInputStream& fileInputStream, std::streamoff offset, std::streamsize count)
|
||||||
{
|
{
|
||||||
fileInputStream.seekg(offset);
|
fileInputStream.seekg(offset, std::ios_base::beg);
|
||||||
Poco::Buffer<char> buffer(8192);
|
Poco::Buffer<char> buffer(8192);
|
||||||
|
std::size_t bufferSize = buffer.size();
|
||||||
|
if (count > 0 && bufferSize > count) bufferSize = count;
|
||||||
|
|
||||||
std::streamsize len = 0;
|
std::streamsize len = 0;
|
||||||
fileInputStream.read(buffer.begin(), buffer.size());
|
fileInputStream.read(buffer.begin(), bufferSize);
|
||||||
std::streamsize n = fileInputStream.gcount();
|
std::streamsize n = fileInputStream.gcount();
|
||||||
while (n > 0)
|
while (n > 0 && (count == 0 || len < count))
|
||||||
{
|
{
|
||||||
len += n;
|
len += n;
|
||||||
sendBytes(buffer.begin(), n);
|
sendBytes(buffer.begin(), n);
|
||||||
|
if (count > 0 && len < count)
|
||||||
|
{
|
||||||
|
const std::size_t remaining = count - len;
|
||||||
|
if (bufferSize > remaining) bufferSize = remaining;
|
||||||
|
}
|
||||||
if (fileInputStream)
|
if (fileInputStream)
|
||||||
{
|
{
|
||||||
fileInputStream.read(buffer.begin(), buffer.size());
|
fileInputStream.read(buffer.begin(), bufferSize);
|
||||||
n = fileInputStream.gcount();
|
n = fileInputStream.gcount();
|
||||||
}
|
}
|
||||||
else n = 0;
|
else n = 0;
|
||||||
|
@ -214,9 +214,9 @@ void StreamSocket::sendUrgent(unsigned char data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::streamsize StreamSocket::sendFile(Poco::FileInputStream& fileInputStream, std::streamoff offset)
|
std::streamsize StreamSocket::sendFile(Poco::FileInputStream& fileInputStream, std::streamoff offset, std::streamsize count)
|
||||||
{
|
{
|
||||||
return impl()->sendFile(fileInputStream, offset);
|
return impl()->sendFile(fileInputStream, offset, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,6 +15,9 @@
|
|||||||
#include "Poco/Net/StreamSocket.h"
|
#include "Poco/Net/StreamSocket.h"
|
||||||
#include "Poco/Net/ServerSocket.h"
|
#include "Poco/Net/ServerSocket.h"
|
||||||
#include "Poco/Net/SocketAddress.h"
|
#include "Poco/Net/SocketAddress.h"
|
||||||
|
#include "Poco/Net/TCPServerConnection.h"
|
||||||
|
#include "Poco/Net/TCPServerConnectionFactory.h"
|
||||||
|
#include "Poco/Net/TCPServer.h"
|
||||||
#include "Poco/Net/NetException.h"
|
#include "Poco/Net/NetException.h"
|
||||||
#include "Poco/Timespan.h"
|
#include "Poco/Timespan.h"
|
||||||
#include "Poco/Stopwatch.h"
|
#include "Poco/Stopwatch.h"
|
||||||
@ -25,6 +28,7 @@
|
|||||||
#include "Poco/TemporaryFile.h"
|
#include "Poco/TemporaryFile.h"
|
||||||
#include "Poco/FileStream.h"
|
#include "Poco/FileStream.h"
|
||||||
#include "Poco/Path.h"
|
#include "Poco/Path.h"
|
||||||
|
#include "Poco/Thread.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
@ -33,6 +37,9 @@ using Poco::Net::StreamSocket;
|
|||||||
using Poco::Net::ServerSocket;
|
using Poco::Net::ServerSocket;
|
||||||
using Poco::Net::SocketAddress;
|
using Poco::Net::SocketAddress;
|
||||||
using Poco::Net::ConnectionRefusedException;
|
using Poco::Net::ConnectionRefusedException;
|
||||||
|
using Poco::Net::TCPServerConnection;
|
||||||
|
using Poco::Net::TCPServerConnectionFactoryImpl;
|
||||||
|
using Poco::Net::TCPServer;
|
||||||
using Poco::Timespan;
|
using Poco::Timespan;
|
||||||
using Poco::Stopwatch;
|
using Poco::Stopwatch;
|
||||||
using Poco::TimeoutException;
|
using Poco::TimeoutException;
|
||||||
@ -44,6 +51,49 @@ using Poco::File;
|
|||||||
using Poco::delegate;
|
using Poco::delegate;
|
||||||
|
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
class CopyToStringConnection: public TCPServerConnection
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CopyToStringConnection(const StreamSocket& s):
|
||||||
|
TCPServerConnection(s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void run()
|
||||||
|
{
|
||||||
|
_data.clear();
|
||||||
|
StreamSocket& ss = socket();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
char buffer[256];
|
||||||
|
int n = ss.receiveBytes(buffer, sizeof(buffer));
|
||||||
|
while (n > 0)
|
||||||
|
{
|
||||||
|
_data.append(buffer, n);
|
||||||
|
n = ss.receiveBytes(buffer, sizeof(buffer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Poco::Exception& exc)
|
||||||
|
{
|
||||||
|
std::cerr << "CopyToStringConnection: " << exc.displayText() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const std::string& data()
|
||||||
|
{
|
||||||
|
return _data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::string _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string CopyToStringConnection::_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SocketTest::SocketTest(const std::string& name): CppUnit::TestCase(name)
|
SocketTest::SocketTest(const std::string& name): CppUnit::TestCase(name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -671,9 +721,12 @@ void SocketTest::testUseFd()
|
|||||||
|
|
||||||
void SocketTest::testSendFile()
|
void SocketTest::testSendFile()
|
||||||
{
|
{
|
||||||
EchoServer echoServer;
|
ServerSocket svs(0);
|
||||||
|
TCPServer srv(new TCPServerConnectionFactoryImpl<CopyToStringConnection>(), svs);
|
||||||
|
srv.start();
|
||||||
|
|
||||||
StreamSocket ss;
|
StreamSocket ss;
|
||||||
ss.connect(SocketAddress("127.0.0.1", echoServer.port()));
|
ss.connect(SocketAddress("127.0.0.1", srv.port()));
|
||||||
|
|
||||||
std::string sentData = "Hello, world!";
|
std::string sentData = "Hello, world!";
|
||||||
|
|
||||||
@ -683,28 +736,89 @@ void SocketTest::testSendFile()
|
|||||||
ostr.close();
|
ostr.close();
|
||||||
|
|
||||||
Poco::FileInputStream istr(file.path());
|
Poco::FileInputStream istr(file.path());
|
||||||
std::streamsize sent = 0;
|
ss.sendFile(istr);
|
||||||
while (sent < file.getSize())
|
|
||||||
{
|
|
||||||
sent += ss.sendFile(istr, sent);
|
|
||||||
}
|
|
||||||
istr.close();
|
istr.close();
|
||||||
|
ss.close();
|
||||||
|
|
||||||
std::string receivedData;
|
while (srv.currentConnections() > 0)
|
||||||
char buffer[1024];
|
|
||||||
int n = ss.receiveBytes(buffer, sizeof(buffer));
|
|
||||||
while (n > 0)
|
|
||||||
{
|
{
|
||||||
receivedData.append(buffer, n);
|
Poco::Thread::sleep(100);
|
||||||
if (receivedData.size() < sentData.size())
|
|
||||||
n = ss.receiveBytes(buffer, sizeof(buffer));
|
|
||||||
else
|
|
||||||
n = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assertTrue (receivedData == sentData);
|
assertTrue (CopyToStringConnection::data() == sentData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SocketTest::testSendFileLarge()
|
||||||
|
{
|
||||||
|
ServerSocket svs(0);
|
||||||
|
TCPServer srv(new TCPServerConnectionFactoryImpl<CopyToStringConnection>(), svs);
|
||||||
|
srv.start();
|
||||||
|
|
||||||
|
StreamSocket ss;
|
||||||
|
ss.connect(SocketAddress("127.0.0.1", srv.port()));
|
||||||
|
|
||||||
|
std::string sentData;
|
||||||
|
|
||||||
|
Poco::TemporaryFile file;
|
||||||
|
Poco::FileOutputStream ostr(file.path());
|
||||||
|
std::string data("0123456789abcdef");
|
||||||
|
for (int i = 0; i < 10000; i++)
|
||||||
|
{
|
||||||
|
ostr.write(data.data(), data.size());
|
||||||
|
sentData += data;
|
||||||
|
}
|
||||||
|
ostr.close();
|
||||||
|
|
||||||
|
Poco::FileInputStream istr(file.path());
|
||||||
|
ss.sendFile(istr);
|
||||||
|
istr.close();
|
||||||
ss.close();
|
ss.close();
|
||||||
|
|
||||||
|
while (srv.currentConnections() > 0)
|
||||||
|
{
|
||||||
|
Poco::Thread::sleep(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertTrue (CopyToStringConnection::data() == sentData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SocketTest::testSendFileRange()
|
||||||
|
{
|
||||||
|
ServerSocket svs(0);
|
||||||
|
TCPServer srv(new TCPServerConnectionFactoryImpl<CopyToStringConnection>(), svs);
|
||||||
|
srv.start();
|
||||||
|
|
||||||
|
StreamSocket ss;
|
||||||
|
ss.connect(SocketAddress("127.0.0.1", srv.port()));
|
||||||
|
|
||||||
|
std::string sentData;
|
||||||
|
|
||||||
|
Poco::TemporaryFile file;
|
||||||
|
Poco::FileOutputStream ostr(file.path());
|
||||||
|
std::string data("0123456789abcdef");
|
||||||
|
for (int i = 0; i < 1024; i++)
|
||||||
|
{
|
||||||
|
ostr.write(data.data(), data.size());
|
||||||
|
sentData += data;
|
||||||
|
}
|
||||||
|
ostr.close();
|
||||||
|
|
||||||
|
const std::streamoff offset = 4000;
|
||||||
|
const std::streamsize count = 10000;
|
||||||
|
|
||||||
|
Poco::FileInputStream istr(file.path());
|
||||||
|
ss.sendFile(istr, offset, count);
|
||||||
|
istr.close();
|
||||||
|
ss.close();
|
||||||
|
|
||||||
|
while (srv.currentConnections() > 0)
|
||||||
|
{
|
||||||
|
Poco::Thread::sleep(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertTrue (CopyToStringConnection::data() == sentData.substr(offset, count));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -766,6 +880,8 @@ CppUnit::Test* SocketTest::suite()
|
|||||||
CppUnit_addTest(pSuite, SocketTest, testUnixLocalAbstract);
|
CppUnit_addTest(pSuite, SocketTest, testUnixLocalAbstract);
|
||||||
CppUnit_addTest(pSuite, SocketTest, testUseFd);
|
CppUnit_addTest(pSuite, SocketTest, testUseFd);
|
||||||
CppUnit_addTest(pSuite, SocketTest, testSendFile);
|
CppUnit_addTest(pSuite, SocketTest, testSendFile);
|
||||||
|
CppUnit_addTest(pSuite, SocketTest, testSendFileLarge);
|
||||||
|
CppUnit_addTest(pSuite, SocketTest, testSendFileRange);
|
||||||
|
|
||||||
return pSuite;
|
return pSuite;
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,8 @@ public:
|
|||||||
void testUnixLocalAbstract();
|
void testUnixLocalAbstract();
|
||||||
void testUseFd();
|
void testUseFd();
|
||||||
void testSendFile();
|
void testSendFile();
|
||||||
|
void testSendFileLarge();
|
||||||
|
void testSendFileRange();
|
||||||
|
|
||||||
void setUp() override;
|
void setUp() override;
|
||||||
void tearDown() override;
|
void tearDown() override;
|
||||||
|
@ -75,6 +75,45 @@ namespace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CopyToStringConnection: public TCPServerConnection
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CopyToStringConnection(const StreamSocket& s):
|
||||||
|
TCPServerConnection(s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void run()
|
||||||
|
{
|
||||||
|
_data.clear();
|
||||||
|
StreamSocket& ss = socket();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
char buffer[256];
|
||||||
|
int n = ss.receiveBytes(buffer, sizeof(buffer));
|
||||||
|
while (n > 0)
|
||||||
|
{
|
||||||
|
_data.append(buffer, n);
|
||||||
|
n = ss.receiveBytes(buffer, sizeof(buffer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Poco::Exception& exc)
|
||||||
|
{
|
||||||
|
std::cerr << "CopyToStringConnection: " << exc.displayText() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const std::string& data()
|
||||||
|
{
|
||||||
|
return _data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::string _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string CopyToStringConnection::_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -206,7 +245,7 @@ void SecureStreamSocketTest::testNB()
|
|||||||
void SecureStreamSocketTest::testSendFile()
|
void SecureStreamSocketTest::testSendFile()
|
||||||
{
|
{
|
||||||
SecureServerSocket svs(0);
|
SecureServerSocket svs(0);
|
||||||
TCPServer srv(new TCPServerConnectionFactoryImpl<EchoConnection>(), svs);
|
TCPServer srv(new TCPServerConnectionFactoryImpl<CopyToStringConnection>(), svs);
|
||||||
srv.start();
|
srv.start();
|
||||||
|
|
||||||
SecureStreamSocket ss;
|
SecureStreamSocket ss;
|
||||||
@ -220,28 +259,92 @@ void SecureStreamSocketTest::testSendFile()
|
|||||||
ostr.close();
|
ostr.close();
|
||||||
|
|
||||||
Poco::FileInputStream istr(file.path());
|
Poco::FileInputStream istr(file.path());
|
||||||
std::streamsize sent = 0;
|
ss.sendFile(istr);
|
||||||
while (sent < file.getSize())
|
|
||||||
{
|
|
||||||
sent += ss.sendFile(istr, sent);
|
|
||||||
}
|
|
||||||
istr.close();
|
istr.close();
|
||||||
|
ss.close();
|
||||||
|
|
||||||
std::string receivedData;
|
while (srv.currentConnections() > 0)
|
||||||
char buffer[1024];
|
|
||||||
int n = ss.receiveBytes(buffer, sizeof(buffer));
|
|
||||||
while (n > 0)
|
|
||||||
{
|
{
|
||||||
receivedData.append(buffer, n);
|
Poco::Thread::sleep(100);
|
||||||
if (receivedData.size() < sentData.size())
|
|
||||||
n = ss.receiveBytes(buffer, sizeof(buffer));
|
|
||||||
else
|
|
||||||
n = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assertTrue (receivedData == sentData);
|
assertTrue (CopyToStringConnection::data() == sentData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SecureStreamSocketTest::testSendFileLarge()
|
||||||
|
{
|
||||||
|
SecureServerSocket svs(0);
|
||||||
|
TCPServer srv(new TCPServerConnectionFactoryImpl<CopyToStringConnection>(), svs);
|
||||||
|
srv.start();
|
||||||
|
|
||||||
|
SecureStreamSocket ss;
|
||||||
|
ss.connect(SocketAddress("127.0.0.1", srv.port()));
|
||||||
|
|
||||||
|
std::string sentData;
|
||||||
|
|
||||||
|
Poco::TemporaryFile file;
|
||||||
|
Poco::FileOutputStream ostr(file.path());
|
||||||
|
std::string data("0123456789abcdef");
|
||||||
|
for (int i = 0; i < 10000; i++)
|
||||||
|
{
|
||||||
|
ostr.write(data.data(), data.size());
|
||||||
|
sentData += data;
|
||||||
|
}
|
||||||
|
ostr.close();
|
||||||
|
|
||||||
|
Poco::FileInputStream istr(file.path());
|
||||||
|
ss.sendFile(istr);
|
||||||
|
istr.close();
|
||||||
ss.close();
|
ss.close();
|
||||||
|
|
||||||
|
while (srv.currentConnections() > 0)
|
||||||
|
{
|
||||||
|
Poco::Thread::sleep(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertTrue (CopyToStringConnection::data() == sentData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SecureStreamSocketTest::testSendFileRange()
|
||||||
|
{
|
||||||
|
SecureServerSocket svs(0);
|
||||||
|
TCPServer srv(new TCPServerConnectionFactoryImpl<CopyToStringConnection>(), svs);
|
||||||
|
srv.start();
|
||||||
|
|
||||||
|
SecureStreamSocket ss;
|
||||||
|
ss.connect(SocketAddress("127.0.0.1", srv.port()));
|
||||||
|
|
||||||
|
std::string fileData;
|
||||||
|
|
||||||
|
Poco::TemporaryFile file;
|
||||||
|
Poco::FileOutputStream ostr(file.path());
|
||||||
|
std::string data("0123456789abcdef");
|
||||||
|
for (int i = 0; i < 1024; i++)
|
||||||
|
{
|
||||||
|
ostr.write(data.data(), data.size());
|
||||||
|
fileData += data;
|
||||||
|
}
|
||||||
|
ostr.close();
|
||||||
|
|
||||||
|
const std::streamoff offset = 4000;
|
||||||
|
const std::streamsize count = 10000;
|
||||||
|
|
||||||
|
Poco::FileInputStream istr(file.path());
|
||||||
|
ss.sendFile(istr, offset, count);
|
||||||
|
istr.close();
|
||||||
|
ss.close();
|
||||||
|
|
||||||
|
while (srv.currentConnections() > 0)
|
||||||
|
{
|
||||||
|
Poco::Thread::sleep(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "\n" << fileData.size() << std::endl;
|
||||||
|
std::cout << "\n" << CopyToStringConnection::data().size() << std::endl;
|
||||||
|
|
||||||
|
assertTrue (CopyToStringConnection::data() == fileData.substr(offset, count));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -263,6 +366,8 @@ CppUnit::Test* SecureStreamSocketTest::suite()
|
|||||||
CppUnit_addTest(pSuite, SecureStreamSocketTest, testPeek);
|
CppUnit_addTest(pSuite, SecureStreamSocketTest, testPeek);
|
||||||
CppUnit_addTest(pSuite, SecureStreamSocketTest, testNB);
|
CppUnit_addTest(pSuite, SecureStreamSocketTest, testNB);
|
||||||
CppUnit_addTest(pSuite, SecureStreamSocketTest, testSendFile);
|
CppUnit_addTest(pSuite, SecureStreamSocketTest, testSendFile);
|
||||||
|
CppUnit_addTest(pSuite, SecureStreamSocketTest, testSendFileLarge);
|
||||||
|
CppUnit_addTest(pSuite, SecureStreamSocketTest, testSendFileRange);
|
||||||
|
|
||||||
return pSuite;
|
return pSuite;
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,8 @@ public:
|
|||||||
void testPeek();
|
void testPeek();
|
||||||
void testNB();
|
void testNB();
|
||||||
void testSendFile();
|
void testSendFile();
|
||||||
|
void testSendFileLarge();
|
||||||
|
void testSendFileRange();
|
||||||
|
|
||||||
void setUp();
|
void setUp();
|
||||||
void tearDown();
|
void tearDown();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user