mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-24 00:49:46 +02:00
initial import
This commit is contained in:
226
Net/src/DNS.cpp
Normal file
226
Net/src/DNS.cpp
Normal file
@@ -0,0 +1,226 @@
|
||||
//
|
||||
// DNS.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/DNS.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: NetCore
|
||||
// Module: DNS
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/DNS.h"
|
||||
#include "Net/NetException.h"
|
||||
#include "Net/SocketAddress.h"
|
||||
#include "Foundation/Environment.h"
|
||||
#include "Foundation/NumberFormatter.h"
|
||||
|
||||
|
||||
using Foundation::FastMutex;
|
||||
using Foundation::Environment;
|
||||
using Foundation::NumberFormatter;
|
||||
using Foundation::IOException;
|
||||
|
||||
|
||||
//
|
||||
// Automatic initialization of Windows networking
|
||||
//
|
||||
#if defined(_WIN32)
|
||||
namespace
|
||||
{
|
||||
class NetworkInitializer
|
||||
{
|
||||
public:
|
||||
NetworkInitializer()
|
||||
{
|
||||
WORD version = MAKEWORD(2, 2);
|
||||
WSADATA data;
|
||||
WSAStartup(version, &data);
|
||||
}
|
||||
|
||||
~NetworkInitializer()
|
||||
{
|
||||
WSACleanup();
|
||||
}
|
||||
};
|
||||
|
||||
static NetworkInitializer networkInitializer;
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
DNS::DNSCache DNS::_cache;
|
||||
Foundation::FastMutex DNS::_mutex;
|
||||
|
||||
|
||||
const HostEntry& DNS::hostByName(const std::string& hostname)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
DNSCache::const_iterator it = _cache.find(hostname);
|
||||
if (it != _cache.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(_WIN32) && defined(POCO_HAVE_IPv6)
|
||||
struct addrinfo* pAI;
|
||||
struct addrinfo hints;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
if (getaddrinfo(hostname.c_str(), NULL, &hints, &pAI) == 0)
|
||||
{
|
||||
std::pair<DNSCache::iterator, bool> res = _cache.insert(std::pair<std::string, HostEntry>(hostname, HostEntry(pAI)));
|
||||
freeaddrinfo(pAI);
|
||||
return res.first->second;
|
||||
}
|
||||
#else
|
||||
struct hostent* he = gethostbyname(hostname.c_str());
|
||||
if (he)
|
||||
{
|
||||
std::pair<DNSCache::iterator, bool> res = _cache.insert(std::pair<std::string, HostEntry>(hostname, HostEntry(he)));
|
||||
return res.first->second;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
error(lastError(), hostname); // will throw an appropriate exception
|
||||
throw NetException(); // to silence compiler
|
||||
}
|
||||
|
||||
|
||||
const HostEntry& DNS::hostByAddress(const IPAddress& address)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
#if defined(_WIN32) && defined(POCO_HAVE_IPv6)
|
||||
SocketAddress sa(address, 0);
|
||||
static char fqname[1024];
|
||||
if (getnameinfo(sa.addr(), sa.length(), fqname, sizeof(fqname), NULL, 0, 0) == 0)
|
||||
{
|
||||
DNSCache::const_iterator it = _cache.find(std::string(fqname));
|
||||
if (it != _cache.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct addrinfo* pAI;
|
||||
struct addrinfo hints;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
if (getaddrinfo(fqname, NULL, &hints, &pAI) == 0)
|
||||
{
|
||||
std::pair<DNSCache::iterator, bool> res = _cache.insert(std::pair<std::string, HostEntry>(std::string(fqname), HostEntry(pAI)));
|
||||
freeaddrinfo(pAI);
|
||||
return res.first->second;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
struct hostent* he = gethostbyaddr(reinterpret_cast<const char*>(address.addr()), address.length(), address.af());
|
||||
if (he)
|
||||
{
|
||||
std::pair<DNSCache::iterator, bool> res = _cache.insert(std::pair<std::string, HostEntry>(std::string(he->h_name), HostEntry(he)));
|
||||
return res.first->second;
|
||||
}
|
||||
#endif
|
||||
error(lastError(), address.toString()); // will throw an appropriate exception
|
||||
throw NetException(); // to silence compiler
|
||||
}
|
||||
|
||||
|
||||
const HostEntry& DNS::resolve(const std::string& address)
|
||||
{
|
||||
IPAddress ip;
|
||||
if (IPAddress::tryParse(address, ip))
|
||||
return hostByAddress(ip);
|
||||
else
|
||||
return hostByName(address);
|
||||
}
|
||||
|
||||
|
||||
IPAddress DNS::resolveOne(const std::string& address)
|
||||
{
|
||||
const HostEntry& entry = resolve(address);
|
||||
if (!entry.addresses().empty())
|
||||
return entry.addresses()[0];
|
||||
else
|
||||
throw NoAddressFoundException(address);
|
||||
}
|
||||
|
||||
|
||||
const HostEntry& DNS::thisHost()
|
||||
{
|
||||
return hostByName(Environment::nodeName());
|
||||
}
|
||||
|
||||
|
||||
void DNS::flushCache()
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
_cache.clear();
|
||||
}
|
||||
|
||||
|
||||
int DNS::lastError()
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return GetLastError();
|
||||
#else
|
||||
return h_errno;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void DNS::error(int code, const std::string& arg)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case POCO_ESYSNOTREADY:
|
||||
throw NetException("Net subsystem not ready");
|
||||
case POCO_ENOTINIT:
|
||||
throw NetException("Net subsystem not initialized");
|
||||
case POCO_HOST_NOT_FOUND:
|
||||
throw HostNotFoundException(arg);
|
||||
case POCO_TRY_AGAIN:
|
||||
throw DNSException("Temporary DNS error while resolving", arg);
|
||||
case POCO_NO_RECOVERY:
|
||||
throw DNSException("Non recoverable DNS error while resolving", arg);
|
||||
case POCO_NO_DATA:
|
||||
throw NoAddressFoundException(arg);
|
||||
default:
|
||||
throw IOException(NumberFormatter::format(code));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
129
Net/src/DatagramSocket.cpp
Normal file
129
Net/src/DatagramSocket.cpp
Normal file
@@ -0,0 +1,129 @@
|
||||
//
|
||||
// DatagramSocket.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/DatagramSocket.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Sockets
|
||||
// Module: DatagramSocket
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/DatagramSocket.h"
|
||||
#include "Net/DatagramSocketImpl.h"
|
||||
#include "Foundation/Exception.h"
|
||||
|
||||
|
||||
using Foundation::InvalidArgumentException;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
DatagramSocket::DatagramSocket(): Socket(new DatagramSocketImpl)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DatagramSocket::DatagramSocket(IPAddress::Family family): Socket(new DatagramSocketImpl(family))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DatagramSocket::DatagramSocket(const SocketAddress& address, bool reuseAddress): Socket(new DatagramSocketImpl)
|
||||
{
|
||||
bind(address, reuseAddress);
|
||||
}
|
||||
|
||||
|
||||
DatagramSocket::DatagramSocket(const Socket& socket): Socket(socket)
|
||||
{
|
||||
if (!dynamic_cast<DatagramSocketImpl*>(impl()))
|
||||
throw InvalidArgumentException("Cannot assign incompatible socket");
|
||||
}
|
||||
|
||||
|
||||
DatagramSocket::DatagramSocket(SocketImpl* pImpl): Socket(pImpl)
|
||||
{
|
||||
if (!dynamic_cast<DatagramSocketImpl*>(impl()))
|
||||
throw InvalidArgumentException("Cannot assign incompatible socket");
|
||||
}
|
||||
|
||||
|
||||
DatagramSocket::~DatagramSocket()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DatagramSocket& DatagramSocket::operator = (const Socket& socket)
|
||||
{
|
||||
if (dynamic_cast<DatagramSocketImpl*>(socket.impl()))
|
||||
Socket::operator = (socket);
|
||||
else
|
||||
throw InvalidArgumentException("Cannot assign incompatible socket");
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void DatagramSocket::connect(const SocketAddress& address)
|
||||
{
|
||||
impl()->connect(address);
|
||||
}
|
||||
|
||||
|
||||
void DatagramSocket::bind(const SocketAddress& address, bool reuseAddress)
|
||||
{
|
||||
impl()->bind(address, reuseAddress);
|
||||
}
|
||||
|
||||
|
||||
int DatagramSocket::sendBytes(const void* buffer, int length, int flags)
|
||||
{
|
||||
return impl()->sendBytes(buffer, length, flags);
|
||||
}
|
||||
|
||||
|
||||
int DatagramSocket::receiveBytes(void* buffer, int length, int flags)
|
||||
{
|
||||
return impl()->receiveBytes(buffer, length, flags);
|
||||
}
|
||||
|
||||
|
||||
int DatagramSocket::sendTo(const void* buffer, int length, const SocketAddress& address, int flags)
|
||||
{
|
||||
return impl()->sendTo(buffer, length, address, flags);
|
||||
}
|
||||
|
||||
|
||||
int DatagramSocket::receiveFrom(void* buffer, int length, SocketAddress& address, int flags)
|
||||
{
|
||||
return impl()->receiveFrom(buffer, length, address, flags);
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
82
Net/src/DatagramSocketImpl.cpp
Normal file
82
Net/src/DatagramSocketImpl.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
//
|
||||
// DatagramSocketImpl.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/DatagramSocketImpl.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Sockets
|
||||
// Module: DatagramSocketImpl
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/DatagramSocketImpl.h"
|
||||
#include "Net/NetException.h"
|
||||
|
||||
|
||||
using Foundation::InvalidArgumentException;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
DatagramSocketImpl::DatagramSocketImpl()
|
||||
{
|
||||
init(AF_INET);
|
||||
}
|
||||
|
||||
|
||||
DatagramSocketImpl::DatagramSocketImpl(IPAddress::Family family)
|
||||
{
|
||||
if (family == IPAddress::IPv4)
|
||||
init(AF_INET);
|
||||
#if POCO_HAVE_IPv6
|
||||
else if (family == IPAddress::IPv6)
|
||||
init(AF_INET6);
|
||||
#endif
|
||||
else throw InvalidArgumentException("Invalid or unsupported address family passed to DatagramSocketImpl");
|
||||
|
||||
}
|
||||
|
||||
|
||||
DatagramSocketImpl::DatagramSocketImpl(poco_socket_t sockfd): SocketImpl(sockfd)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DatagramSocketImpl::~DatagramSocketImpl()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void DatagramSocketImpl::init(int af)
|
||||
{
|
||||
initSocket(af, SOCK_DGRAM);
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
277
Net/src/DialogSocket.cpp
Normal file
277
Net/src/DialogSocket.cpp
Normal file
@@ -0,0 +1,277 @@
|
||||
//
|
||||
// DialogSocket.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/DialogSocket.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Sockets
|
||||
// Module: DialogSocket
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/DialogSocket.h"
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
DialogSocket::DialogSocket():
|
||||
_pBuffer(0),
|
||||
_pNext(0),
|
||||
_pEnd(0)
|
||||
{
|
||||
allocBuffer();
|
||||
}
|
||||
|
||||
|
||||
DialogSocket::DialogSocket(const SocketAddress& address):
|
||||
StreamSocket(address),
|
||||
_pBuffer(0),
|
||||
_pNext(0),
|
||||
_pEnd(0)
|
||||
{
|
||||
allocBuffer();
|
||||
}
|
||||
|
||||
|
||||
DialogSocket::DialogSocket(const Socket& socket):
|
||||
StreamSocket(socket),
|
||||
_pBuffer(0),
|
||||
_pNext(0),
|
||||
_pEnd(0)
|
||||
{
|
||||
allocBuffer();
|
||||
}
|
||||
|
||||
|
||||
DialogSocket::~DialogSocket()
|
||||
{
|
||||
delete [] _pBuffer;
|
||||
}
|
||||
|
||||
|
||||
DialogSocket& DialogSocket::operator = (const Socket& socket)
|
||||
{
|
||||
StreamSocket::operator = (socket);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void DialogSocket::sendByte(unsigned char ch)
|
||||
{
|
||||
sendBytes(&ch, 1);
|
||||
}
|
||||
|
||||
|
||||
void DialogSocket::sendString(const char* str)
|
||||
{
|
||||
sendBytes(str, (int) strlen(str));
|
||||
}
|
||||
|
||||
|
||||
void DialogSocket::sendString(const std::string& str)
|
||||
{
|
||||
sendBytes(str.data(), (int) str.length());
|
||||
}
|
||||
|
||||
|
||||
void DialogSocket::sendMessage(const std::string& message)
|
||||
{
|
||||
std::string line;
|
||||
line.reserve(message.length() + 2);
|
||||
line.append(message);
|
||||
line.append("\r\n");
|
||||
sendString(line);
|
||||
}
|
||||
|
||||
|
||||
void DialogSocket::sendMessage(const std::string& message, const std::string& arg)
|
||||
{
|
||||
std::string line;
|
||||
line.reserve(message.length() + arg.length() + 3);
|
||||
line.append(message);
|
||||
if (!arg.empty())
|
||||
{
|
||||
line.append(" ");
|
||||
line.append(arg);
|
||||
}
|
||||
line.append("\r\n");
|
||||
sendString(line);
|
||||
}
|
||||
|
||||
|
||||
void DialogSocket::sendMessage(const std::string& message, const std::string& arg1, const std::string& arg2)
|
||||
{
|
||||
std::string line;
|
||||
line.reserve(message.length() + arg1.length() +arg2.length() + 4);
|
||||
line.append(message);
|
||||
line.append(" ");
|
||||
line.append(arg1);
|
||||
if (!arg2.empty())
|
||||
{
|
||||
line.append(" ");
|
||||
line.append(arg2);
|
||||
}
|
||||
line.append("\r\n");
|
||||
sendString(line);
|
||||
}
|
||||
|
||||
|
||||
bool DialogSocket::receiveMessage(std::string& message)
|
||||
{
|
||||
message.clear();
|
||||
return receiveLine(message);
|
||||
}
|
||||
|
||||
|
||||
int DialogSocket::receiveStatusMessage(std::string& message)
|
||||
{
|
||||
message.clear();
|
||||
int status = receiveStatusLine(message);
|
||||
if (status < 0)
|
||||
{
|
||||
while (status <= 0)
|
||||
{
|
||||
message += '\n';
|
||||
status = receiveStatusLine(message);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
int DialogSocket::get()
|
||||
{
|
||||
refill();
|
||||
if (_pNext != _pEnd)
|
||||
return *_pNext++;
|
||||
else
|
||||
return EOF_CHAR;
|
||||
}
|
||||
|
||||
|
||||
int DialogSocket::peek()
|
||||
{
|
||||
refill();
|
||||
if (_pNext != _pEnd)
|
||||
return *_pNext;
|
||||
else
|
||||
return EOF_CHAR;
|
||||
}
|
||||
|
||||
|
||||
void DialogSocket::synch()
|
||||
{
|
||||
sendUrgent(TELNET_DM);
|
||||
}
|
||||
|
||||
|
||||
void DialogSocket::sendTelnetCommand(unsigned char command)
|
||||
{
|
||||
unsigned char buffer[2];
|
||||
buffer[0] = TELNET_IAC;
|
||||
buffer[1] = command;
|
||||
sendBytes(buffer, 2);
|
||||
}
|
||||
|
||||
|
||||
void DialogSocket::sendTelnetCommand(unsigned char command, unsigned char arg)
|
||||
{
|
||||
unsigned char buffer[3];
|
||||
buffer[0] = TELNET_IAC;
|
||||
buffer[1] = command;
|
||||
buffer[2] = arg;
|
||||
sendBytes(buffer, 3);
|
||||
}
|
||||
|
||||
|
||||
void DialogSocket::refill()
|
||||
{
|
||||
if (_pNext == _pEnd)
|
||||
{
|
||||
int n = receiveBytes(_pBuffer, RECEIVE_BUFFER_SIZE);
|
||||
_pNext = _pBuffer;
|
||||
_pEnd = _pBuffer + n;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DialogSocket::allocBuffer()
|
||||
{
|
||||
_pBuffer = new char [RECEIVE_BUFFER_SIZE];
|
||||
_pNext = _pBuffer;
|
||||
_pEnd = _pBuffer;
|
||||
}
|
||||
|
||||
|
||||
bool DialogSocket::receiveLine(std::string& line)
|
||||
{
|
||||
// An old wisdom goes: be strict in what you emit
|
||||
// and generous in what you accept.
|
||||
int ch = get();
|
||||
while (ch != EOF_CHAR && ch != '\r' && ch != '\n')
|
||||
{
|
||||
line += (char) ch;
|
||||
ch = get();
|
||||
}
|
||||
if (ch == '\r' && peek() == '\n')
|
||||
get();
|
||||
else if (ch == EOF_CHAR)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int DialogSocket::receiveStatusLine(std::string& line)
|
||||
{
|
||||
int status = 0;
|
||||
int ch = get();
|
||||
if (ch != EOF_CHAR) line += (char) ch;
|
||||
int n = 0;
|
||||
while (isdigit(ch) && n < 3)
|
||||
{
|
||||
status *= 10;
|
||||
status += ch - '0';
|
||||
++n;
|
||||
ch = get();
|
||||
if (ch != EOF_CHAR) line += (char) ch;
|
||||
}
|
||||
if (n == 3)
|
||||
{
|
||||
if (ch == '-')
|
||||
status = -status;
|
||||
}
|
||||
else status = 0;
|
||||
if (ch != EOF_CHAR) receiveLine(line);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
507
Net/src/FTPClientSession.cpp
Normal file
507
Net/src/FTPClientSession.cpp
Normal file
@@ -0,0 +1,507 @@
|
||||
//
|
||||
// FTPClientSession.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/FTPClientSession.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: FTP
|
||||
// Module: FTPClientSession
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/FTPClientSession.h"
|
||||
#include "Net/SocketAddress.h"
|
||||
#include "Net/SocketStream.h"
|
||||
#include "Net/ServerSocket.h"
|
||||
#include "Net/NetException.h"
|
||||
#include "Foundation/NumberFormatter.h"
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
using Foundation::NumberFormatter;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
FTPClientSession::FTPClientSession(const StreamSocket& socket):
|
||||
_controlSocket(socket),
|
||||
_pDataStream(0),
|
||||
_passiveMode(true),
|
||||
_fileType(TYPE_BINARY),
|
||||
_supports1738(true),
|
||||
_isOpen(true),
|
||||
_timeout(DEFAULT_TIMEOUT)
|
||||
{
|
||||
_controlSocket.setReceiveTimeout(_timeout);
|
||||
}
|
||||
|
||||
|
||||
FTPClientSession::FTPClientSession(const std::string& host, Foundation::UInt16 port):
|
||||
_controlSocket(SocketAddress(host, port)),
|
||||
_pDataStream(0),
|
||||
_passiveMode(true),
|
||||
_fileType(TYPE_BINARY),
|
||||
_supports1738(true),
|
||||
_isOpen(true),
|
||||
_timeout(DEFAULT_TIMEOUT)
|
||||
{
|
||||
_controlSocket.setReceiveTimeout(_timeout);
|
||||
}
|
||||
|
||||
|
||||
FTPClientSession::~FTPClientSession()
|
||||
{
|
||||
try
|
||||
{
|
||||
close();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::setTimeout(const Foundation::Timespan& timeout)
|
||||
{
|
||||
_timeout = timeout;
|
||||
_controlSocket.setReceiveTimeout(timeout);
|
||||
}
|
||||
|
||||
|
||||
Foundation::Timespan FTPClientSession::getTimeout() const
|
||||
{
|
||||
return _timeout;
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::setPassive(bool flag)
|
||||
{
|
||||
_passiveMode = flag;
|
||||
}
|
||||
|
||||
|
||||
bool FTPClientSession::getPassive() const
|
||||
{
|
||||
return _passiveMode;
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::login(const std::string& username, const std::string& password)
|
||||
{
|
||||
std::string response;
|
||||
int status = _controlSocket.receiveStatusMessage(response);
|
||||
if (!isPositiveCompletion(status)) throw FTPException("Cannot login to server", response);
|
||||
status = sendCommand("USER", username, response);
|
||||
if (isPositiveIntermediate(status))
|
||||
status = sendCommand("PASS", password, response);
|
||||
if (!isPositiveCompletion(status)) throw FTPException("Login denied", response);
|
||||
setFileType(_fileType);
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::close()
|
||||
{
|
||||
if (_isOpen)
|
||||
{
|
||||
try
|
||||
{
|
||||
endTransfer();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
std::string response;
|
||||
sendCommand("QUIT", response);
|
||||
_controlSocket.close();
|
||||
_isOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::setFileType(FTPClientSession::FileType type)
|
||||
{
|
||||
std::string response;
|
||||
int status = sendCommand("TYPE", (type == TYPE_TEXT ? "A" : "I"), response);
|
||||
if (!isPositiveCompletion(status)) throw FTPException("Cannot set file type", response);
|
||||
_fileType = type;
|
||||
}
|
||||
|
||||
|
||||
FTPClientSession::FileType FTPClientSession::getFileType() const
|
||||
{
|
||||
return _fileType;
|
||||
}
|
||||
|
||||
|
||||
std::string FTPClientSession::systemType()
|
||||
{
|
||||
std::string response;
|
||||
int status = sendCommand("SYST", response);
|
||||
if (isPositiveCompletion(status))
|
||||
return response.substr(4);
|
||||
else
|
||||
throw FTPException("Cannot get remote system type", response);
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::setWorkingDirectory(const std::string& path)
|
||||
{
|
||||
std::string response;
|
||||
int status = sendCommand("CWD", path, response);
|
||||
if (!isPositiveCompletion(status)) throw FTPException("Cannot change directory", response);
|
||||
}
|
||||
|
||||
|
||||
std::string FTPClientSession::getWorkingDirectory()
|
||||
{
|
||||
std::string response;
|
||||
int status = sendCommand("PWD", response);
|
||||
if (isPositiveCompletion(status))
|
||||
return extractPath(response);
|
||||
else
|
||||
throw FTPException("Cannot get current working directory", response);
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::cdup()
|
||||
{
|
||||
std::string response;
|
||||
int status = sendCommand("CDUP", response);
|
||||
if (!isPositiveCompletion(status)) throw FTPException("Cannot change directory", response);
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::rename(const std::string& oldName, const std::string& newName)
|
||||
{
|
||||
std::string response;
|
||||
int status = sendCommand("RNFR", oldName, response);
|
||||
if (!isPositiveIntermediate(status)) throw FTPException(std::string("Cannot rename ") + oldName, response);
|
||||
status = sendCommand("RNTO", newName, response);
|
||||
if (!isPositiveCompletion(status)) throw FTPException(std::string("Cannot rename to ") + newName, response);
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::remove(const std::string& path)
|
||||
{
|
||||
std::string response;
|
||||
int status = sendCommand("DELE", path, response);
|
||||
if (!isPositiveCompletion(status)) throw FTPException(std::string("Cannot remove " + path), response);
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::createDirectory(const std::string& path)
|
||||
{
|
||||
std::string response;
|
||||
int status = sendCommand("MKD", path, response);
|
||||
if (!isPositiveCompletion(status)) throw FTPException(std::string("Cannot create directory ") + path, response);
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::removeDirectory(const std::string& path)
|
||||
{
|
||||
std::string response;
|
||||
int status = sendCommand("RMD", path, response);
|
||||
if (!isPositiveCompletion(status)) throw FTPException(std::string("Cannot remove directory ") + path, response);
|
||||
}
|
||||
|
||||
|
||||
std::istream& FTPClientSession::beginDownload(const std::string& path)
|
||||
{
|
||||
delete _pDataStream;
|
||||
_pDataStream = 0;
|
||||
_pDataStream = new SocketStream(establishDataConnection("RETR", path));
|
||||
return *_pDataStream;
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::endDownload()
|
||||
{
|
||||
endTransfer();
|
||||
}
|
||||
|
||||
|
||||
std::ostream& FTPClientSession::beginUpload(const std::string& path)
|
||||
{
|
||||
delete _pDataStream;
|
||||
_pDataStream = 0;
|
||||
_pDataStream = new SocketStream(establishDataConnection("STOR", path));
|
||||
return *_pDataStream;
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::endUpload()
|
||||
{
|
||||
endTransfer();
|
||||
}
|
||||
|
||||
|
||||
std::istream& FTPClientSession::beginList(const std::string& path, bool extended)
|
||||
{
|
||||
delete _pDataStream;
|
||||
_pDataStream = 0;
|
||||
_pDataStream = new SocketStream(establishDataConnection(extended ? "LIST" : "NLST", path));
|
||||
return *_pDataStream;
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::endList()
|
||||
{
|
||||
endTransfer();
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::abort()
|
||||
{
|
||||
_controlSocket.sendByte(DialogSocket::TELNET_IP);
|
||||
_controlSocket.synch();
|
||||
std::string response;
|
||||
int status = sendCommand("ABOR", response);
|
||||
if (status == 426)
|
||||
status = _controlSocket.receiveStatusMessage(response);
|
||||
if (status != 226) throw FTPException("Cannot abort transfer", response);
|
||||
}
|
||||
|
||||
|
||||
int FTPClientSession::sendCommand(const std::string& command, std::string& response)
|
||||
{
|
||||
_controlSocket.sendMessage(command);
|
||||
return _controlSocket.receiveStatusMessage(response);
|
||||
}
|
||||
|
||||
|
||||
int FTPClientSession::sendCommand(const std::string& command, const std::string& arg, std::string& response)
|
||||
{
|
||||
_controlSocket.sendMessage(command, arg);
|
||||
return _controlSocket.receiveStatusMessage(response);
|
||||
}
|
||||
|
||||
|
||||
std::string FTPClientSession::extractPath(const std::string& response)
|
||||
{
|
||||
std::string path;
|
||||
std::string::const_iterator it = response.begin();
|
||||
std::string::const_iterator end = response.end();
|
||||
while (it != end && *it != '"') ++it;
|
||||
if (it != end)
|
||||
{
|
||||
++it;
|
||||
while (it != end)
|
||||
{
|
||||
if (*it == '"')
|
||||
{
|
||||
++it;
|
||||
if (it != end && *it != '"') break;
|
||||
}
|
||||
path += *it++;
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
StreamSocket FTPClientSession::establishDataConnection(const std::string& command, const std::string& arg)
|
||||
{
|
||||
if (_passiveMode)
|
||||
return passiveDataConnection(command, arg);
|
||||
else
|
||||
return activeDataConnection(command, arg);
|
||||
}
|
||||
|
||||
|
||||
StreamSocket FTPClientSession::activeDataConnection(const std::string& command, const std::string& arg)
|
||||
{
|
||||
ServerSocket server(SocketAddress(_controlSocket.address().host(), 0));
|
||||
sendPortCommand(server.address());
|
||||
std::string response;
|
||||
int status = sendCommand(command, arg, response);
|
||||
if (!isPositivePreliminary(status)) throw FTPException(command + " command failed", response);
|
||||
if (server.poll(_timeout, Socket::SELECT_READ))
|
||||
return server.acceptConnection();
|
||||
else
|
||||
throw FTPException("The server has not initiated a data connection");
|
||||
}
|
||||
|
||||
|
||||
StreamSocket FTPClientSession::passiveDataConnection(const std::string& command, const std::string& arg)
|
||||
{
|
||||
SocketAddress sa(sendPassiveCommand());
|
||||
StreamSocket sock(sa);
|
||||
std::string response;
|
||||
int status = sendCommand(command, arg, response);
|
||||
if (!isPositivePreliminary(status)) throw FTPException(command + " command failed", response);
|
||||
return sock;
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::sendPortCommand(const SocketAddress& addr)
|
||||
{
|
||||
if (_supports1738)
|
||||
{
|
||||
if (sendEPRT(addr))
|
||||
return;
|
||||
else
|
||||
_supports1738 = false;
|
||||
}
|
||||
sendPORT(addr);
|
||||
}
|
||||
|
||||
|
||||
SocketAddress FTPClientSession::sendPassiveCommand()
|
||||
{
|
||||
SocketAddress addr;
|
||||
if (_supports1738)
|
||||
{
|
||||
if (sendEPSV(addr))
|
||||
return addr;
|
||||
else
|
||||
_supports1738 = false;
|
||||
}
|
||||
sendPASV(addr);
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
||||
bool FTPClientSession::sendEPRT(const SocketAddress& addr)
|
||||
{
|
||||
std::string arg("|");
|
||||
arg += addr.af() == AF_INET ? '1' : '2';
|
||||
arg += '|';
|
||||
arg += addr.host().toString();
|
||||
arg += '|';
|
||||
arg += NumberFormatter::format(addr.port());
|
||||
arg += '|';
|
||||
std::string response;
|
||||
int status = sendCommand("EPRT", arg, response);
|
||||
if (isPositiveCompletion(status))
|
||||
return true;
|
||||
else if (isPermanentNegative(status))
|
||||
return false;
|
||||
else
|
||||
throw FTPException("EPRT command failed", response);
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::sendPORT(const SocketAddress& addr)
|
||||
{
|
||||
std::string arg(addr.host().toString());
|
||||
for (std::string::iterator it = arg.begin(); it != arg.end(); ++it)
|
||||
{
|
||||
if (*it == '.') *it = ',';
|
||||
}
|
||||
arg += ',';
|
||||
Foundation::UInt16 port = addr.port();
|
||||
arg += NumberFormatter::format(port/256);
|
||||
arg += ',';
|
||||
arg += NumberFormatter::format(port % 256);
|
||||
std::string response;
|
||||
int status = sendCommand("PORT", arg, response);
|
||||
if (!isPositiveCompletion(status)) throw FTPException("PORT command failed", response);
|
||||
}
|
||||
|
||||
|
||||
bool FTPClientSession::sendEPSV(SocketAddress& addr)
|
||||
{
|
||||
std::string response;
|
||||
int status = sendCommand("EPSV", response);
|
||||
if (isPositiveCompletion(status))
|
||||
{
|
||||
parseExtAddress(response, addr);
|
||||
return true;
|
||||
}
|
||||
else if (isPermanentNegative(status))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else throw FTPException("EPSV command failed", response);
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::sendPASV(SocketAddress& addr)
|
||||
{
|
||||
std::string response;
|
||||
int status = sendCommand("PASV", response);
|
||||
if (!isPositiveCompletion(status)) throw FTPException("PASV command failed", response);
|
||||
parseAddress(response, addr);
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::parseAddress(const std::string& str, SocketAddress& addr)
|
||||
{
|
||||
std::string::const_iterator it = str.begin();
|
||||
std::string::const_iterator end = str.end();
|
||||
while (it != end && *it != '(') ++it;
|
||||
if (it != end) ++it;
|
||||
std::string host;
|
||||
while (it != end && isdigit(*it)) host += *it++;
|
||||
if (it != end && *it == ',') { host += '.'; ++it; }
|
||||
while (it != end && isdigit(*it)) host += *it++;
|
||||
if (it != end && *it == ',') { host += '.'; ++it; }
|
||||
while (it != end && isdigit(*it)) host += *it++;
|
||||
if (it != end && *it == ',') { host += '.'; ++it; }
|
||||
while (it != end && isdigit(*it)) host += *it++;
|
||||
if (it != end && *it == ',') ++it;
|
||||
Foundation::UInt16 portHi = 0;
|
||||
while (it != end && isdigit(*it)) { portHi *= 10; portHi += *it++ - '0'; }
|
||||
if (it != end && *it == ',') ++it;
|
||||
Foundation::UInt16 portLo = 0;
|
||||
while (it != end && isdigit(*it)) { portLo *= 10; portLo += *it++ - '0'; }
|
||||
addr = SocketAddress(host, portHi*256 + portLo);
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::parseExtAddress(const std::string& str, SocketAddress& addr)
|
||||
{
|
||||
std::string::const_iterator it = str.begin();
|
||||
std::string::const_iterator end = str.end();
|
||||
while (it != end && *it != '(') ++it;
|
||||
if (it != end) ++it;
|
||||
char delim = '|';
|
||||
if (it != end) delim = *it++;
|
||||
if (it != end && *it == delim) ++it;
|
||||
if (it != end && *it == delim) ++it;
|
||||
Foundation::UInt16 port = 0;
|
||||
while (it != end && isdigit(*it)) { port *= 10; port += *it++ - '0'; }
|
||||
addr = SocketAddress(_controlSocket.peerAddress().host(), port);
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::endTransfer()
|
||||
{
|
||||
if (_pDataStream)
|
||||
{
|
||||
delete _pDataStream;
|
||||
_pDataStream = 0;
|
||||
std::string response;
|
||||
int status = _controlSocket.receiveStatusMessage(response);
|
||||
if (!isPositiveCompletion(status)) throw FTPException("Data transfer failed", response);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
256
Net/src/FTPStreamFactory.cpp
Normal file
256
Net/src/FTPStreamFactory.cpp
Normal file
@@ -0,0 +1,256 @@
|
||||
//
|
||||
// FTPStreamFactory.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/FTPStreamFactory.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: FTP
|
||||
// Module: FTPStreamFactory
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/FTPStreamFactory.h"
|
||||
#include "Net/FTPClientSession.h"
|
||||
#include "Net/NetException.h"
|
||||
#include "Foundation/URI.h"
|
||||
#include "Foundation/URIStreamOpener.h"
|
||||
#include "Foundation/UnbufferedStreamBuf.h"
|
||||
#include "Foundation/Path.h"
|
||||
|
||||
|
||||
using Foundation::URIStreamFactory;
|
||||
using Foundation::URI;
|
||||
using Foundation::URIStreamOpener;
|
||||
using Foundation::UnbufferedStreamBuf;
|
||||
using Foundation::Path;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
class FTPStreamBuf: public UnbufferedStreamBuf
|
||||
{
|
||||
public:
|
||||
FTPStreamBuf(std::istream& istr):
|
||||
_istr(istr)
|
||||
{
|
||||
}
|
||||
|
||||
~FTPStreamBuf()
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
int readFromDevice()
|
||||
{
|
||||
return _istr.get();
|
||||
}
|
||||
|
||||
std::istream& _istr;
|
||||
};
|
||||
|
||||
|
||||
class FTPIOS: public virtual std::ios
|
||||
{
|
||||
public:
|
||||
FTPIOS(std::istream& istr):
|
||||
_buf(istr)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
~FTPIOS()
|
||||
{
|
||||
}
|
||||
|
||||
FTPStreamBuf* rdbuf()
|
||||
{
|
||||
return &_buf;
|
||||
}
|
||||
|
||||
protected:
|
||||
FTPStreamBuf _buf;
|
||||
};
|
||||
|
||||
|
||||
class FTPStream: public FTPIOS, public std::istream
|
||||
{
|
||||
public:
|
||||
FTPStream(std::istream& istr, FTPClientSession* pSession):
|
||||
FTPIOS(istr),
|
||||
std::istream(&_buf),
|
||||
_pSession(pSession)
|
||||
{
|
||||
}
|
||||
|
||||
~FTPStream()
|
||||
{
|
||||
delete _pSession;
|
||||
}
|
||||
|
||||
private:
|
||||
FTPClientSession* _pSession;
|
||||
};
|
||||
|
||||
|
||||
FTPPasswordProvider::FTPPasswordProvider()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FTPPasswordProvider::~FTPPasswordProvider()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
std::string FTPStreamFactory::_anonymousPassword("poco@localhost");
|
||||
FTPPasswordProvider* FTPStreamFactory::_pPasswordProvider(0);
|
||||
|
||||
|
||||
FTPStreamFactory::FTPStreamFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FTPStreamFactory::~FTPStreamFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
std::istream* FTPStreamFactory::open(const URI& uri)
|
||||
{
|
||||
poco_assert (uri.getScheme() == "ftp");
|
||||
|
||||
FTPClientSession* pSession = new FTPClientSession(uri.getHost(), uri.getPort());
|
||||
try
|
||||
{
|
||||
std::string username;
|
||||
std::string password;
|
||||
getUserInfo(uri, username, password);
|
||||
|
||||
std::string path;
|
||||
char type;
|
||||
getPathAndType(uri, path, type);
|
||||
|
||||
pSession->login(username, password);
|
||||
if (type == 'a')
|
||||
pSession->setFileType(FTPClientSession::TYPE_TEXT);
|
||||
|
||||
Path p(path, Path::PATH_UNIX);
|
||||
p.makeFile();
|
||||
for (int i = 0; i < p.depth(); ++i)
|
||||
pSession->setWorkingDirectory(p[i]);
|
||||
std::string file(p.getFileName());
|
||||
std::istream& istr = (type == 'd' ? pSession->beginList(file) : pSession->beginDownload(file));
|
||||
return new FTPStream(istr, pSession);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
delete pSession;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FTPStreamFactory::setAnonymousPassword(const std::string& password)
|
||||
{
|
||||
_anonymousPassword = password;
|
||||
}
|
||||
|
||||
|
||||
const std::string& FTPStreamFactory::getAnonymousPassword()
|
||||
{
|
||||
return _anonymousPassword;
|
||||
}
|
||||
|
||||
|
||||
void FTPStreamFactory::setPasswordProvider(FTPPasswordProvider* pProvider)
|
||||
{
|
||||
_pPasswordProvider = pProvider;
|
||||
}
|
||||
|
||||
|
||||
FTPPasswordProvider* FTPStreamFactory::getPasswordProvider()
|
||||
{
|
||||
return _pPasswordProvider;
|
||||
}
|
||||
|
||||
|
||||
void FTPStreamFactory::splitUserInfo(const std::string& userInfo, std::string& username, std::string& password)
|
||||
{
|
||||
std::string::size_type pos = userInfo.find(':');
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
username.assign(userInfo, 0, pos++);
|
||||
password.assign(userInfo, pos, userInfo.size() - pos);
|
||||
}
|
||||
else username = userInfo;
|
||||
}
|
||||
|
||||
|
||||
void FTPStreamFactory::getUserInfo(const URI& uri, std::string& username, std::string& password)
|
||||
{
|
||||
splitUserInfo(uri.getUserInfo(), username, password);
|
||||
if (username.empty())
|
||||
{
|
||||
username = "anonymous";
|
||||
password = _anonymousPassword;
|
||||
}
|
||||
else if (password.empty())
|
||||
{
|
||||
if (_pPasswordProvider)
|
||||
password = _pPasswordProvider->password(username, uri.getHost());
|
||||
else
|
||||
throw FTPException(std::string("Password required for ") + username + "@" + uri.getHost());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FTPStreamFactory::getPathAndType(const Foundation::URI& uri, std::string& path, char& type)
|
||||
{
|
||||
path = uri.getPath();
|
||||
type = 'i';
|
||||
std::string::size_type pos = path.rfind(';');
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
if (path.length() == pos + 7 && path.compare(pos + 1, 5, "type=") == 0)
|
||||
{
|
||||
type = path[pos + 6];
|
||||
path.resize(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FTPStreamFactory::registerFactory()
|
||||
{
|
||||
URIStreamOpener::defaultOpener().registerStreamFactory("ftp", new FTPStreamFactory);
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
87
Net/src/FilePartSource.cpp
Normal file
87
Net/src/FilePartSource.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
//
|
||||
// FilePartSource.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/FilePartSource.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Messages
|
||||
// Module: FilePartSource
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/FilePartSource.h"
|
||||
#include "Foundation/Path.h"
|
||||
#include "Foundation/Exception.h"
|
||||
|
||||
|
||||
using Foundation::Path;
|
||||
using Foundation::OpenFileException;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
FilePartSource::FilePartSource(const std::string& path):
|
||||
_istr(path.c_str(), std::ios::in | std::ios::binary)
|
||||
{
|
||||
Path p(path);
|
||||
_filename = p.getFileName();
|
||||
if (!_istr.good())
|
||||
throw OpenFileException(path);
|
||||
}
|
||||
|
||||
|
||||
FilePartSource::FilePartSource(const std::string& path, const std::string& mediaType):
|
||||
PartSource(mediaType),
|
||||
_istr(path.c_str(), std::ios::in | std::ios::binary)
|
||||
{
|
||||
Path p(path);
|
||||
_filename = p.getFileName();
|
||||
if (!_istr.good())
|
||||
throw OpenFileException(path);
|
||||
}
|
||||
|
||||
|
||||
FilePartSource::~FilePartSource()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
std::istream& FilePartSource::stream()
|
||||
{
|
||||
return _istr;
|
||||
}
|
||||
|
||||
|
||||
const std::string& FilePartSource::filename()
|
||||
{
|
||||
return _filename;
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
358
Net/src/HTMLForm.cpp
Normal file
358
Net/src/HTMLForm.cpp
Normal file
@@ -0,0 +1,358 @@
|
||||
//
|
||||
// HTMLForm.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/HTMLForm.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: HTML
|
||||
// Module: HTMLForm
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/HTMLForm.h"
|
||||
#include "Net/HTTPRequest.h"
|
||||
#include "Net/PartSource.h"
|
||||
#include "Net/PartHandler.h"
|
||||
#include "Net/MultipartWriter.h"
|
||||
#include "Net/MultipartReader.h"
|
||||
#include "Net/NullPartHandler.h"
|
||||
#include "Foundation/NullStream.h"
|
||||
#include "Foundation/StreamCopier.h"
|
||||
#include "Foundation/Exception.h"
|
||||
#include "Foundation/URI.h"
|
||||
#include "Foundation/String.h"
|
||||
#include <sstream>
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
using Foundation::NullInputStream;
|
||||
using Foundation::StreamCopier;
|
||||
using Foundation::SyntaxException;
|
||||
using Foundation::URI;
|
||||
using Foundation::icompare;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
const std::string HTMLForm::ENCODING_URL = "application/x-www-form-urlencoded";
|
||||
const std::string HTMLForm::ENCODING_MULTIPART = "multipart/form-data";
|
||||
|
||||
|
||||
HTMLForm::HTMLForm():
|
||||
_encoding(ENCODING_URL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTMLForm::HTMLForm(const std::string& encoding):
|
||||
_encoding(encoding)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTMLForm::HTMLForm(const HTTPRequest& request, std::istream& istr, PartHandler& handler)
|
||||
{
|
||||
load(request, istr, handler);
|
||||
}
|
||||
|
||||
|
||||
HTMLForm::HTMLForm(const HTTPRequest& request, std::istream& istr)
|
||||
{
|
||||
load(request, istr);
|
||||
}
|
||||
|
||||
|
||||
HTMLForm::HTMLForm(const HTTPRequest& request)
|
||||
{
|
||||
load(request);
|
||||
}
|
||||
|
||||
|
||||
HTMLForm::~HTMLForm()
|
||||
{
|
||||
for (PartVec::iterator it = _parts.begin(); it != _parts.end(); ++it)
|
||||
{
|
||||
delete it->pSource;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HTMLForm::setEncoding(const std::string& encoding)
|
||||
{
|
||||
_encoding = encoding;
|
||||
}
|
||||
|
||||
|
||||
void HTMLForm::addPart(const std::string& name, PartSource* pSource)
|
||||
{
|
||||
poco_check_ptr (pSource);
|
||||
|
||||
Part part;
|
||||
part.name = name;
|
||||
part.pSource = pSource;
|
||||
_parts.push_back(part);
|
||||
}
|
||||
|
||||
|
||||
void HTMLForm::load(const HTTPRequest& request, std::istream& requestBody, PartHandler& handler)
|
||||
{
|
||||
if (request.getMethod() == HTTPRequest::HTTP_GET)
|
||||
{
|
||||
URI uri(request.getURI());
|
||||
std::istringstream istr(uri.getRawQuery());
|
||||
readUrl(istr);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string mediaType;
|
||||
NameValueCollection params;
|
||||
MessageHeader::splitParameters(request.getContentType(), mediaType, params);
|
||||
_encoding = mediaType;
|
||||
if (_encoding == ENCODING_MULTIPART)
|
||||
{
|
||||
_boundary = params["boundary"];
|
||||
readMultipart(requestBody, handler);
|
||||
}
|
||||
else
|
||||
{
|
||||
readUrl(requestBody);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HTMLForm::load(const HTTPRequest& request, std::istream& requestBody)
|
||||
{
|
||||
NullPartHandler nah;
|
||||
load(request, requestBody, nah);
|
||||
}
|
||||
|
||||
|
||||
void HTMLForm::load(const HTTPRequest& request)
|
||||
{
|
||||
NullPartHandler nah;
|
||||
NullInputStream nis;
|
||||
load(request, nis, nah);
|
||||
}
|
||||
|
||||
|
||||
void HTMLForm::read(std::istream& istr, PartHandler& handler)
|
||||
{
|
||||
if (_encoding == ENCODING_URL)
|
||||
readUrl(istr);
|
||||
else
|
||||
readMultipart(istr, handler);
|
||||
}
|
||||
|
||||
|
||||
void HTMLForm::prepareSubmit(HTTPRequest& request)
|
||||
{
|
||||
if (request.getMethod() == HTTPRequest::HTTP_GET)
|
||||
{
|
||||
std::string uri = request.getURI();
|
||||
std::ostringstream ostr;
|
||||
write(ostr);
|
||||
uri.append("?");
|
||||
uri.append(ostr.str());
|
||||
request.setURI(uri);
|
||||
}
|
||||
else if (request.getMethod() == HTTPRequest::HTTP_POST)
|
||||
{
|
||||
if (_encoding == ENCODING_URL)
|
||||
{
|
||||
request.setContentType(_encoding);
|
||||
}
|
||||
else
|
||||
{
|
||||
_boundary = MultipartWriter::createBoundary();
|
||||
std::string ct(_encoding);
|
||||
ct.append("; boundary=\"");
|
||||
ct.append(_boundary);
|
||||
ct.append("\"");
|
||||
request.setContentType(ct);
|
||||
}
|
||||
if (request.getVersion() == HTTPMessage::HTTP_1_0)
|
||||
{
|
||||
request.setKeepAlive(false);
|
||||
request.setChunkedTransferEncoding(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
request.setChunkedTransferEncoding(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HTMLForm::write(std::ostream& ostr, const std::string& boundary)
|
||||
{
|
||||
if (_encoding == ENCODING_URL)
|
||||
{
|
||||
writeUrl(ostr);
|
||||
}
|
||||
else
|
||||
{
|
||||
_boundary = boundary;
|
||||
writeMultipart(ostr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HTMLForm::write(std::ostream& ostr)
|
||||
{
|
||||
if (_encoding == ENCODING_URL)
|
||||
writeUrl(ostr);
|
||||
else
|
||||
writeMultipart(ostr);
|
||||
}
|
||||
|
||||
|
||||
void HTMLForm::readUrl(std::istream& istr)
|
||||
{
|
||||
static const int eof = std::char_traits<char>::eof();
|
||||
|
||||
int ch = istr.get();
|
||||
while (ch != eof)
|
||||
{
|
||||
std::string name;
|
||||
std::string value;
|
||||
while (ch != eof && ch != '=' && ch != '&')
|
||||
{
|
||||
if (ch == '+') ch = ' ';
|
||||
name += (char) ch;
|
||||
ch = istr.get();
|
||||
}
|
||||
if (ch == '=')
|
||||
{
|
||||
ch = istr.get();
|
||||
while (ch != eof && ch != '&')
|
||||
{
|
||||
if (ch == '+') ch = ' ';
|
||||
value += (char) ch;
|
||||
ch = istr.get();
|
||||
}
|
||||
}
|
||||
std::string decodedName;
|
||||
std::string decodedValue;
|
||||
URI::decode(name, decodedName);
|
||||
URI::decode(value, decodedValue);
|
||||
set(decodedName, decodedValue);
|
||||
if (ch == '&') ch = istr.get();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HTMLForm::readMultipart(std::istream& istr, PartHandler& handler)
|
||||
{
|
||||
static const int eof = std::char_traits<char>::eof();
|
||||
|
||||
MultipartReader reader(istr, _boundary);
|
||||
while (reader.hasNextPart())
|
||||
{
|
||||
MessageHeader header;
|
||||
reader.nextPart(header);
|
||||
std::string disp;
|
||||
NameValueCollection params;
|
||||
if (header.has("Content-Disposition"))
|
||||
{
|
||||
std::string cd = header.get("Content-Disposition");
|
||||
MessageHeader::splitParameters(cd, disp, params);
|
||||
}
|
||||
if (icompare(disp, "file") == 0)
|
||||
{
|
||||
handler.handlePart(header, reader.stream());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string name = params["name"];
|
||||
std::string value;
|
||||
std::istream& istr = reader.stream();
|
||||
int ch = istr.get();
|
||||
while (ch != eof)
|
||||
{
|
||||
value += (char) ch;
|
||||
ch = istr.get();
|
||||
}
|
||||
set(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HTMLForm::writeUrl(std::ostream& ostr)
|
||||
{
|
||||
for (NameValueCollection::ConstIterator it = begin(); it != end(); ++it)
|
||||
{
|
||||
if (it != begin()) ostr << "&";
|
||||
std::string name;
|
||||
URI::encode(it->first, "=&", name);
|
||||
std::string value;
|
||||
URI::encode(it->second, "=&", value);
|
||||
ostr << name << "=" << value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HTMLForm::writeMultipart(std::ostream& ostr)
|
||||
{
|
||||
MultipartWriter writer(ostr, _boundary);
|
||||
for (NameValueCollection::ConstIterator it = begin(); it != end(); ++it)
|
||||
{
|
||||
MessageHeader header;
|
||||
std::string disp("form-data; name=\"");
|
||||
disp.append(it->first);
|
||||
disp.append("\"");
|
||||
header.set("Content-Disposition", disp);
|
||||
writer.nextPart(header);
|
||||
ostr << it->second;
|
||||
}
|
||||
for (PartVec::iterator ita = _parts.begin(); ita != _parts.end(); ++ita)
|
||||
{
|
||||
MessageHeader header;
|
||||
std::string disp("file; name=\"");
|
||||
disp.append(ita->name);
|
||||
disp.append("\"");
|
||||
std::string filename = ita->pSource->filename();
|
||||
if (!filename.empty())
|
||||
{
|
||||
disp.append("; filename=\"");
|
||||
disp.append(filename);
|
||||
disp.append("\"");
|
||||
}
|
||||
header.set("Content-Disposition", disp);
|
||||
header.set("Content-Type", ita->pSource->mediaType());
|
||||
writer.nextPart(header);
|
||||
StreamCopier::copyStream(ita->pSource->stream(), ostr);
|
||||
}
|
||||
writer.close();
|
||||
_boundary = writer.boundary();
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
124
Net/src/HTTPBasicCredentials.cpp
Normal file
124
Net/src/HTTPBasicCredentials.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
//
|
||||
// HTTPBasicCredentials.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/HTTPBasicCredentials.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: HTTP
|
||||
// Module: HTTPBasicCredentials
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/HTTPBasicCredentials.h"
|
||||
#include "Net/HTTPRequest.h"
|
||||
#include "Net/NetException.h"
|
||||
#include "Foundation/Base64Encoder.h"
|
||||
#include "Foundation/Base64Decoder.h"
|
||||
#include "Foundation/String.h"
|
||||
#include <sstream>
|
||||
|
||||
|
||||
using Foundation::Base64Decoder;
|
||||
using Foundation::Base64Encoder;
|
||||
using Foundation::icompare;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
const std::string HTTPBasicCredentials::SCHEME = "Basic";
|
||||
|
||||
|
||||
HTTPBasicCredentials::HTTPBasicCredentials()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPBasicCredentials::HTTPBasicCredentials(const std::string& username, const std::string& password):
|
||||
_username(username),
|
||||
_password(password)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPBasicCredentials::HTTPBasicCredentials(const HTTPRequest& request)
|
||||
{
|
||||
static const int eof = std::char_traits<char>::eof();
|
||||
|
||||
std::string scheme;
|
||||
std::string info;
|
||||
request.getCredentials(scheme, info);
|
||||
if (icompare(scheme, SCHEME) == 0)
|
||||
{
|
||||
std::istringstream istr(info);
|
||||
Base64Decoder decoder(istr);
|
||||
int ch = decoder.get();
|
||||
while (ch != eof && ch != ':')
|
||||
{
|
||||
_username += (char) ch;
|
||||
ch = decoder.get();
|
||||
}
|
||||
if (ch == ':') ch = decoder.get();
|
||||
while (ch != eof)
|
||||
{
|
||||
_password += (char) ch;
|
||||
ch = decoder.get();
|
||||
}
|
||||
}
|
||||
else throw NotAuthenticatedException("Basic authentication expected");
|
||||
}
|
||||
|
||||
|
||||
HTTPBasicCredentials::~HTTPBasicCredentials()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void HTTPBasicCredentials::setUsername(const std::string& username)
|
||||
{
|
||||
_username = username;
|
||||
}
|
||||
|
||||
|
||||
void HTTPBasicCredentials::setPassword(const std::string& password)
|
||||
{
|
||||
_password = password;
|
||||
}
|
||||
|
||||
|
||||
void HTTPBasicCredentials::authenticate(HTTPRequest& request)
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
Base64Encoder encoder(ostr);
|
||||
encoder << _username << ":" << _password;
|
||||
encoder.close();
|
||||
request.setCredentials(SCHEME, ostr.str());
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
65
Net/src/HTTPBufferAllocator.cpp
Normal file
65
Net/src/HTTPBufferAllocator.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
//
|
||||
// HTTPBufferAllocator.cpp
|
||||
//
|
||||
// $Id: //poco/Main/template/class.cpp#4 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: HTTP
|
||||
// Module: HTTPBufferAllocator
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/HTTPBufferAllocator.h"
|
||||
|
||||
|
||||
using Foundation::MemoryPool;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
MemoryPool HTTPBufferAllocator::_pool(HTTPBufferAllocator::BUFFER_SIZE, 16);
|
||||
|
||||
|
||||
char* HTTPBufferAllocator::allocate(std::streamsize size)
|
||||
{
|
||||
poco_assert_dbg (size == BUFFER_SIZE);
|
||||
|
||||
return reinterpret_cast<char*>(_pool.get());
|
||||
}
|
||||
|
||||
|
||||
void HTTPBufferAllocator::deallocate(char* ptr, std::streamsize size)
|
||||
{
|
||||
poco_assert_dbg (size == BUFFER_SIZE);
|
||||
|
||||
_pool.release(ptr);
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
213
Net/src/HTTPChunkedStream.cpp
Normal file
213
Net/src/HTTPChunkedStream.cpp
Normal file
@@ -0,0 +1,213 @@
|
||||
//
|
||||
// HTTPChunkedStream.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/HTTPChunkedStream.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: HTTP
|
||||
// Module: HTTPChunkedStream
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/HTTPChunkedStream.h"
|
||||
#include "Net/HTTPSession.h"
|
||||
#include "Foundation/NumberFormatter.h"
|
||||
#include "Foundation/NumberParser.h"
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
using Foundation::NumberFormatter;
|
||||
using Foundation::NumberParser;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
//
|
||||
// HTTPChunkedStreamBuf
|
||||
//
|
||||
|
||||
|
||||
HTTPChunkedStreamBuf::HTTPChunkedStreamBuf(HTTPSession& session, openmode mode):
|
||||
HTTPBasicStreamBuf(HTTPBufferAllocator::BUFFER_SIZE, mode),
|
||||
_session(session),
|
||||
_mode(mode),
|
||||
_chunk(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPChunkedStreamBuf::~HTTPChunkedStreamBuf()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void HTTPChunkedStreamBuf::close()
|
||||
{
|
||||
if (_mode & std::ios::out)
|
||||
{
|
||||
sync();
|
||||
_session.write("0\r\n", 3);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int HTTPChunkedStreamBuf::readFromDevice(char* buffer, std::streamsize length)
|
||||
{
|
||||
static const int eof = std::char_traits<char>::eof();
|
||||
|
||||
if (_chunk == 0)
|
||||
{
|
||||
int ch = _session.get();
|
||||
while (isspace(ch)) ch = _session.get();
|
||||
std::string chunkLen;
|
||||
while (isxdigit(ch)) { chunkLen += (char) ch; ch = _session.get(); }
|
||||
while (ch != eof && ch != '\n') ch = _session.get();
|
||||
unsigned chunk;
|
||||
if (NumberParser::tryParseHex(chunkLen, chunk))
|
||||
_chunk = (std::streamsize) chunk;
|
||||
else
|
||||
return eof;
|
||||
}
|
||||
if (_chunk > 0)
|
||||
{
|
||||
if (length > _chunk) length = _chunk;
|
||||
int n = _session.read(buffer, length);
|
||||
if (n > 0) _chunk -= n;
|
||||
return n;
|
||||
}
|
||||
else return 0;
|
||||
}
|
||||
|
||||
|
||||
int HTTPChunkedStreamBuf::writeToDevice(const char* buffer, std::streamsize length)
|
||||
{
|
||||
std::string chunkSize(NumberFormatter::formatHex(length));
|
||||
chunkSize.append("\r\n");
|
||||
_session.write(chunkSize.data(), (std::streamsize) chunkSize.length());
|
||||
_session.write(buffer, length);
|
||||
_session.write("\r\n", 2);
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// HTTPChunkedIOS
|
||||
//
|
||||
|
||||
|
||||
HTTPChunkedIOS::HTTPChunkedIOS(HTTPSession& session, HTTPChunkedStreamBuf::openmode mode):
|
||||
_buf(session, mode)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
HTTPChunkedIOS::~HTTPChunkedIOS()
|
||||
{
|
||||
try
|
||||
{
|
||||
_buf.close();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
HTTPChunkedStreamBuf* HTTPChunkedIOS::rdbuf()
|
||||
{
|
||||
return &_buf;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// HTTPChunkedInputStream
|
||||
//
|
||||
|
||||
|
||||
Foundation::MemoryPool HTTPChunkedInputStream::_pool(sizeof(HTTPChunkedInputStream));
|
||||
|
||||
|
||||
HTTPChunkedInputStream::HTTPChunkedInputStream(HTTPSession& session):
|
||||
HTTPChunkedIOS(session, std::ios::in),
|
||||
std::istream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPChunkedInputStream::~HTTPChunkedInputStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void* HTTPChunkedInputStream::operator new(size_t size)
|
||||
{
|
||||
return _pool.get();
|
||||
}
|
||||
|
||||
|
||||
void HTTPChunkedInputStream::operator delete(void* ptr)
|
||||
{
|
||||
_pool.release(ptr);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// HTTPChunkedOutputStream
|
||||
//
|
||||
|
||||
|
||||
Foundation::MemoryPool HTTPChunkedOutputStream::_pool(sizeof(HTTPChunkedOutputStream));
|
||||
|
||||
|
||||
HTTPChunkedOutputStream::HTTPChunkedOutputStream(HTTPSession& session):
|
||||
HTTPChunkedIOS(session, std::ios::out),
|
||||
std::ostream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPChunkedOutputStream::~HTTPChunkedOutputStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void* HTTPChunkedOutputStream::operator new(size_t size)
|
||||
{
|
||||
return _pool.get();
|
||||
}
|
||||
|
||||
|
||||
void HTTPChunkedOutputStream::operator delete(void* ptr)
|
||||
{
|
||||
_pool.release(ptr);
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
269
Net/src/HTTPClientSession.cpp
Normal file
269
Net/src/HTTPClientSession.cpp
Normal file
@@ -0,0 +1,269 @@
|
||||
//
|
||||
// HTTPClientSession.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/HTTPClientSession.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: HTTPClient
|
||||
// Module: HTTPClientSession
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/HTTPClientSession.h"
|
||||
#include "Net/HTTPRequest.h"
|
||||
#include "Net/HTTPResponse.h"
|
||||
#include "Net/HTTPHeaderStream.h"
|
||||
#include "Net/HTTPStream.h"
|
||||
#include "Net/HTTPFixedLengthStream.h"
|
||||
#include "Net/HTTPChunkedStream.h"
|
||||
#include "Net/NetException.h"
|
||||
#include "Foundation/NumberFormatter.h"
|
||||
|
||||
|
||||
using Foundation::NumberFormatter;
|
||||
using Foundation::IllegalStateException;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
HTTPClientSession::HTTPClientSession():
|
||||
_port(HTTPSession::HTTP_PORT),
|
||||
_proxyPort(HTTPSession::HTTP_PORT),
|
||||
_reconnect(false),
|
||||
_expectResponseBody(false),
|
||||
_pRequestStream(0),
|
||||
_pResponseStream(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPClientSession::HTTPClientSession(const StreamSocket& socket):
|
||||
HTTPSession(socket),
|
||||
_port(HTTPSession::HTTP_PORT),
|
||||
_proxyPort(HTTPSession::HTTP_PORT),
|
||||
_reconnect(false),
|
||||
_expectResponseBody(false),
|
||||
_pRequestStream(0),
|
||||
_pResponseStream(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPClientSession::HTTPClientSession(const std::string& host, Foundation::UInt16 port):
|
||||
_host(host),
|
||||
_port(port),
|
||||
_proxyPort(HTTPSession::HTTP_PORT),
|
||||
_reconnect(false),
|
||||
_expectResponseBody(false),
|
||||
_pRequestStream(0),
|
||||
_pResponseStream(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPClientSession::~HTTPClientSession()
|
||||
{
|
||||
delete _pRequestStream;
|
||||
delete _pResponseStream;
|
||||
}
|
||||
|
||||
|
||||
void HTTPClientSession::setHost(const std::string& host)
|
||||
{
|
||||
if (!connected())
|
||||
_host = host;
|
||||
else
|
||||
throw IllegalStateException("Cannot set the host for an already connected session");
|
||||
}
|
||||
|
||||
|
||||
void HTTPClientSession::setPort(Foundation::UInt16 port)
|
||||
{
|
||||
if (!connected())
|
||||
_port = port;
|
||||
else
|
||||
throw IllegalStateException("Cannot set the port number for an already connected session");
|
||||
}
|
||||
|
||||
|
||||
void HTTPClientSession::setProxy(const std::string& host, Foundation::UInt16 port)
|
||||
{
|
||||
if (!connected())
|
||||
{
|
||||
_proxyHost = host;
|
||||
_proxyPort = port;
|
||||
}
|
||||
else throw IllegalStateException("Cannot set the proxy host and port for an already connected session");
|
||||
}
|
||||
|
||||
|
||||
void HTTPClientSession::setProxyHost(const std::string& host)
|
||||
{
|
||||
if (!connected())
|
||||
_proxyHost = host;
|
||||
else
|
||||
throw IllegalStateException("Cannot set the proxy host for an already connected session");
|
||||
}
|
||||
|
||||
|
||||
void HTTPClientSession::setProxyPort(Foundation::UInt16 port)
|
||||
{
|
||||
if (!connected())
|
||||
_proxyPort = port;
|
||||
else
|
||||
throw IllegalStateException("Cannot set the proxy port number for an already connected session");
|
||||
}
|
||||
|
||||
|
||||
std::ostream& HTTPClientSession::sendRequest(HTTPRequest& request)
|
||||
{
|
||||
delete _pResponseStream;
|
||||
_pResponseStream = 0;
|
||||
|
||||
bool keepAlive = getKeepAlive();
|
||||
if (connected() && !keepAlive)
|
||||
close();
|
||||
if (!connected())
|
||||
reconnect();
|
||||
request.setKeepAlive(keepAlive);
|
||||
request.setHost(_host, _port);
|
||||
if (!_proxyHost.empty())
|
||||
request.setURI(getHostInfo() + request.getURI());
|
||||
HTTPHeaderOutputStream hos(*this);
|
||||
_reconnect = keepAlive;
|
||||
request.write(hos);
|
||||
_reconnect = false;
|
||||
_expectResponseBody = request.getMethod() != HTTPRequest::HTTP_HEAD;
|
||||
if (request.getChunkedTransferEncoding())
|
||||
_pRequestStream = new HTTPChunkedOutputStream(*this);
|
||||
else if (request.getContentLength() != HTTPMessage::UNKNOWN_CONTENT_LENGTH)
|
||||
_pRequestStream = new HTTPFixedLengthOutputStream(*this, request.getContentLength());
|
||||
else if (request.getMethod() == HTTPRequest::HTTP_GET || request.getMethod() == HTTPRequest::HTTP_HEAD)
|
||||
_pRequestStream = new HTTPFixedLengthOutputStream(*this, 0);
|
||||
else
|
||||
_pRequestStream = new HTTPOutputStream(*this);
|
||||
|
||||
return *_pRequestStream;
|
||||
}
|
||||
|
||||
|
||||
std::istream& HTTPClientSession::receiveResponse(HTTPResponse& response)
|
||||
{
|
||||
delete _pRequestStream;
|
||||
_pRequestStream = 0;
|
||||
|
||||
response.clear();
|
||||
HTTPHeaderInputStream his(*this);
|
||||
response.read(his);
|
||||
if (!_expectResponseBody)
|
||||
_pResponseStream = new HTTPFixedLengthInputStream(*this, 0);
|
||||
else if (response.getChunkedTransferEncoding())
|
||||
_pResponseStream = new HTTPChunkedInputStream(*this);
|
||||
else if (response.getContentLength() != HTTPMessage::UNKNOWN_CONTENT_LENGTH)
|
||||
_pResponseStream = new HTTPFixedLengthInputStream(*this, response.getContentLength());
|
||||
else
|
||||
_pResponseStream = new HTTPInputStream(*this);
|
||||
|
||||
return *_pResponseStream;
|
||||
}
|
||||
|
||||
|
||||
int HTTPClientSession::write(const char* buffer, std::streamsize length)
|
||||
{
|
||||
try
|
||||
{
|
||||
return HTTPSession::write(buffer, length);
|
||||
}
|
||||
catch (NetException&)
|
||||
{
|
||||
if (_reconnect)
|
||||
{
|
||||
close();
|
||||
reconnect();
|
||||
return HTTPSession::write(buffer, length);
|
||||
}
|
||||
else throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HTTPClientSession::reconnect()
|
||||
{
|
||||
if (_proxyHost.empty())
|
||||
{
|
||||
SocketAddress addr(_host, _port);
|
||||
connect(addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
SocketAddress addr(_proxyHost, _proxyPort);
|
||||
connect(addr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string HTTPClientSession::getHostInfo() const
|
||||
{
|
||||
std::string result("http://");
|
||||
result.append(_host);
|
||||
result.append(":");
|
||||
result.append(NumberFormatter::format(_port));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void HTTPClientSession::deleteResponseStream()
|
||||
{
|
||||
delete _pResponseStream;
|
||||
_pResponseStream = 0;
|
||||
}
|
||||
|
||||
|
||||
void HTTPClientSession::deleteRequestStream()
|
||||
{
|
||||
delete _pRequestStream;
|
||||
_pRequestStream = 0;
|
||||
}
|
||||
|
||||
|
||||
void HTTPClientSession::setResponseStream(std::istream* pRespStream)
|
||||
{
|
||||
poco_assert( !_pResponseStream);
|
||||
_pResponseStream = pRespStream;
|
||||
}
|
||||
|
||||
|
||||
void HTTPClientSession::setRequestStream(std::ostream* pRequestStream)
|
||||
{
|
||||
poco_assert (!_pRequestStream);
|
||||
_pRequestStream = pRequestStream;
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
291
Net/src/HTTPCookie.cpp
Normal file
291
Net/src/HTTPCookie.cpp
Normal file
@@ -0,0 +1,291 @@
|
||||
//
|
||||
// HTTPCookie.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/HTTPCookie.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: HTTP
|
||||
// Module: HTTPCookie
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/HTTPCookie.h"
|
||||
#include "Net/NameValueCollection.h"
|
||||
#include "Foundation/Timestamp.h"
|
||||
#include "Foundation/DateTime.h"
|
||||
#include "Foundation/DateTimeFormatter.h"
|
||||
#include "Foundation/DateTimeFormat.h"
|
||||
#include "Foundation/DateTimeParser.h"
|
||||
#include "Foundation/NumberFormatter.h"
|
||||
#include "Foundation/NumberParser.h"
|
||||
#include "Foundation/String.h"
|
||||
|
||||
|
||||
using Foundation::Timestamp;
|
||||
using Foundation::DateTime;
|
||||
using Foundation::DateTimeFormatter;
|
||||
using Foundation::DateTimeFormat;
|
||||
using Foundation::DateTimeParser;
|
||||
using Foundation::NumberFormatter;
|
||||
using Foundation::NumberParser;
|
||||
using Foundation::icompare;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
HTTPCookie::HTTPCookie():
|
||||
_version(0),
|
||||
_secure(false),
|
||||
_maxAge(-1)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPCookie::HTTPCookie(const std::string& name):
|
||||
_version(0),
|
||||
_name(name),
|
||||
_secure(false),
|
||||
_maxAge(-1)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPCookie::HTTPCookie(const NameValueCollection& nvc):
|
||||
_version(0),
|
||||
_secure(false),
|
||||
_maxAge(-1)
|
||||
{
|
||||
for (NameValueCollection::ConstIterator it = nvc.begin(); it != nvc.end(); ++it)
|
||||
{
|
||||
const std::string& name = it->first;
|
||||
const std::string& value = it->second;
|
||||
if (icompare(name, "comment") == 0)
|
||||
{
|
||||
setComment(value);
|
||||
}
|
||||
else if (icompare(name, "domain") == 0)
|
||||
{
|
||||
setDomain(value);
|
||||
}
|
||||
else if (icompare(name, "path") == 0)
|
||||
{
|
||||
setPath(value);
|
||||
}
|
||||
else if (icompare(name, "max-age") == 0)
|
||||
{
|
||||
setMaxAge(NumberParser::parse(value));
|
||||
}
|
||||
else if (icompare(name, "secure") == 0)
|
||||
{
|
||||
setSecure(true);
|
||||
}
|
||||
else if (icompare(name, "expires") == 0)
|
||||
{
|
||||
int tzd;
|
||||
DateTime exp = DateTimeParser::parse(value, tzd);
|
||||
Timestamp now;
|
||||
setMaxAge((int) ((exp.timestamp() - now)/1000000));
|
||||
}
|
||||
else if (icompare(name, "version") == 0)
|
||||
{
|
||||
setVersion(NumberParser::parse(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
setName(name);
|
||||
setValue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
HTTPCookie::HTTPCookie(const std::string& name, const std::string& value):
|
||||
_version(0),
|
||||
_name(name),
|
||||
_value(value),
|
||||
_secure(false),
|
||||
_maxAge(-1)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPCookie::HTTPCookie(const HTTPCookie& cookie):
|
||||
_version(cookie._version),
|
||||
_name(cookie._name),
|
||||
_value(cookie._value),
|
||||
_comment(cookie._comment),
|
||||
_domain(cookie._domain),
|
||||
_path(cookie._path),
|
||||
_secure(cookie._secure),
|
||||
_maxAge(cookie._maxAge)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPCookie::~HTTPCookie()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPCookie& HTTPCookie::operator = (const HTTPCookie& cookie)
|
||||
{
|
||||
if (&cookie != this)
|
||||
{
|
||||
_version = cookie._version;
|
||||
_name = cookie._name;
|
||||
_value = cookie._value;
|
||||
_comment = cookie._comment;
|
||||
_domain = cookie._domain;
|
||||
_path = cookie._path;
|
||||
_secure = cookie._secure;
|
||||
_maxAge = cookie._maxAge;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void HTTPCookie::setVersion(int version)
|
||||
{
|
||||
_version = version;
|
||||
}
|
||||
|
||||
|
||||
void HTTPCookie::setName(const std::string& name)
|
||||
{
|
||||
_name = name;
|
||||
}
|
||||
|
||||
|
||||
void HTTPCookie::setValue(const std::string& value)
|
||||
{
|
||||
_value = value;
|
||||
}
|
||||
|
||||
|
||||
void HTTPCookie::setComment(const std::string& comment)
|
||||
{
|
||||
_comment = comment;
|
||||
}
|
||||
|
||||
|
||||
void HTTPCookie::setDomain(const std::string& domain)
|
||||
{
|
||||
_domain = domain;
|
||||
}
|
||||
|
||||
|
||||
void HTTPCookie::setPath(const std::string& path)
|
||||
{
|
||||
_path = path;
|
||||
}
|
||||
|
||||
|
||||
void HTTPCookie::setSecure(bool secure)
|
||||
{
|
||||
_secure = secure;
|
||||
}
|
||||
|
||||
|
||||
void HTTPCookie::setMaxAge(int maxAge)
|
||||
{
|
||||
_maxAge = maxAge;
|
||||
}
|
||||
|
||||
|
||||
std::string HTTPCookie::toString() const
|
||||
{
|
||||
std::string result(_name);
|
||||
result.append("=");
|
||||
if (_version == 0)
|
||||
{
|
||||
// Netscape cookie
|
||||
result.append(_value);
|
||||
if (!_domain.empty())
|
||||
{
|
||||
result.append("; domain=");
|
||||
result.append(_domain);
|
||||
}
|
||||
if (!_path.empty())
|
||||
{
|
||||
result.append("; path=");
|
||||
result.append(_path);
|
||||
}
|
||||
if (_maxAge >= 0)
|
||||
{
|
||||
Timestamp ts;
|
||||
ts += _maxAge*1000000;
|
||||
result.append("; expires=");
|
||||
result.append(DateTimeFormatter::format(ts, DateTimeFormat::RFC850_FORMAT));
|
||||
}
|
||||
if (_secure)
|
||||
{
|
||||
result.append("; secure");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// RFC 2109 cookie
|
||||
result.append("\"");
|
||||
result.append(_value);
|
||||
result.append("\"");
|
||||
if (!_comment.empty())
|
||||
{
|
||||
result.append("; Comment=\"");
|
||||
result.append(_comment);
|
||||
result.append("\"");
|
||||
}
|
||||
if (!_domain.empty())
|
||||
{
|
||||
result.append("; Domain=\"");
|
||||
result.append(_domain);
|
||||
result.append("\"");
|
||||
}
|
||||
if (!_path.empty())
|
||||
{
|
||||
result.append("; Path=\"");
|
||||
result.append(_path);
|
||||
result.append("\"");
|
||||
}
|
||||
if (_maxAge >= 0)
|
||||
{
|
||||
result.append("; Max-Age=\"");
|
||||
result.append(NumberFormatter::format(_maxAge));
|
||||
result.append("\"");
|
||||
}
|
||||
if (_secure)
|
||||
{
|
||||
result.append("; secure");
|
||||
}
|
||||
result.append("; Version=\"1\"");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
188
Net/src/HTTPFixedLengthStream.cpp
Normal file
188
Net/src/HTTPFixedLengthStream.cpp
Normal file
@@ -0,0 +1,188 @@
|
||||
//
|
||||
// HTTPFixedLengthStream.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/HTTPFixedLengthStream.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: HTTP
|
||||
// Module: HTTPFixedLengthStream
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/HTTPFixedLengthStream.h"
|
||||
#include "Net/HTTPSession.h"
|
||||
|
||||
|
||||
using Foundation::BufferedStreamBuf;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
//
|
||||
// HTTPFixedLengthStreamBuf
|
||||
//
|
||||
|
||||
|
||||
HTTPFixedLengthStreamBuf::HTTPFixedLengthStreamBuf(HTTPSession& session, std::streamsize length, openmode mode):
|
||||
HTTPBasicStreamBuf(HTTPBufferAllocator::BUFFER_SIZE, mode),
|
||||
_session(session),
|
||||
_length(length),
|
||||
_count(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPFixedLengthStreamBuf::~HTTPFixedLengthStreamBuf()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int HTTPFixedLengthStreamBuf::readFromDevice(char* buffer, std::streamsize length)
|
||||
{
|
||||
int n = 0;
|
||||
if (_count < _length)
|
||||
{
|
||||
if (_count + length > _length)
|
||||
length = _length - _count;
|
||||
n = _session.read(buffer, length);
|
||||
if (n > 0) _count += n;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
int HTTPFixedLengthStreamBuf::writeToDevice(const char* buffer, std::streamsize length)
|
||||
{
|
||||
int n = 0;
|
||||
if (_count < _length)
|
||||
{
|
||||
if (_count + length > _length)
|
||||
length = _length - _count;
|
||||
n = _session.write(buffer, length);
|
||||
if (n > 0) _count += n;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// HTTPFixedLengthIOS
|
||||
//
|
||||
|
||||
|
||||
HTTPFixedLengthIOS::HTTPFixedLengthIOS(HTTPSession& session, std::streamsize length, HTTPFixedLengthStreamBuf::openmode mode):
|
||||
_buf(session, length, mode)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
HTTPFixedLengthIOS::~HTTPFixedLengthIOS()
|
||||
{
|
||||
try
|
||||
{
|
||||
_buf.sync();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
HTTPFixedLengthStreamBuf* HTTPFixedLengthIOS::rdbuf()
|
||||
{
|
||||
return &_buf;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// HTTPFixedLengthInputStream
|
||||
//
|
||||
|
||||
|
||||
Foundation::MemoryPool HTTPFixedLengthInputStream::_pool(sizeof(HTTPFixedLengthInputStream));
|
||||
|
||||
|
||||
HTTPFixedLengthInputStream::HTTPFixedLengthInputStream(HTTPSession& session, std::streamsize length):
|
||||
HTTPFixedLengthIOS(session, length, std::ios::in),
|
||||
std::istream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPFixedLengthInputStream::~HTTPFixedLengthInputStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void* HTTPFixedLengthInputStream::operator new(size_t size)
|
||||
{
|
||||
return _pool.get();
|
||||
}
|
||||
|
||||
|
||||
void HTTPFixedLengthInputStream::operator delete(void* ptr)
|
||||
{
|
||||
_pool.release(ptr);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// HTTPFixedLengthOutputStream
|
||||
//
|
||||
|
||||
|
||||
Foundation::MemoryPool HTTPFixedLengthOutputStream::_pool(sizeof(HTTPFixedLengthOutputStream));
|
||||
|
||||
|
||||
HTTPFixedLengthOutputStream::HTTPFixedLengthOutputStream(HTTPSession& session, std::streamsize length):
|
||||
HTTPFixedLengthIOS(session, length, std::ios::out),
|
||||
std::ostream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPFixedLengthOutputStream::~HTTPFixedLengthOutputStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void* HTTPFixedLengthOutputStream::operator new(size_t size)
|
||||
{
|
||||
return _pool.get();
|
||||
}
|
||||
|
||||
|
||||
void HTTPFixedLengthOutputStream::operator delete(void* ptr)
|
||||
{
|
||||
_pool.release(ptr);
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
185
Net/src/HTTPHeaderStream.cpp
Normal file
185
Net/src/HTTPHeaderStream.cpp
Normal file
@@ -0,0 +1,185 @@
|
||||
//
|
||||
// HTTPHeaderStream.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/HTTPHeaderStream.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: HTTP
|
||||
// Module: HTTPHeaderStream
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/HTTPHeaderStream.h"
|
||||
#include "Net/HTTPSession.h"
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
//
|
||||
// HTTPHeaderStreamBuf
|
||||
//
|
||||
|
||||
|
||||
HTTPHeaderStreamBuf::HTTPHeaderStreamBuf(HTTPSession& session, openmode mode):
|
||||
HTTPBasicStreamBuf(HTTPBufferAllocator::BUFFER_SIZE, mode),
|
||||
_session(session),
|
||||
_end(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPHeaderStreamBuf::~HTTPHeaderStreamBuf()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int HTTPHeaderStreamBuf::readFromDevice(char* buffer, std::streamsize length)
|
||||
{
|
||||
// read line-by-line; an empty line denotes the end of the headers.
|
||||
static const int eof = std::char_traits<char>::eof();
|
||||
|
||||
if (_end) return 0;
|
||||
|
||||
int n = 0;
|
||||
int ch = _session.get();
|
||||
while (ch != eof && ch != '\n' && n < length - 1)
|
||||
{
|
||||
*buffer++ = (char) ch; ++n;
|
||||
ch = _session.get();
|
||||
}
|
||||
if (ch != eof)
|
||||
{
|
||||
*buffer++ = (char) ch; ++n;
|
||||
if (n == 2) _end = true;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
int HTTPHeaderStreamBuf::writeToDevice(const char* buffer, std::streamsize length)
|
||||
{
|
||||
return _session.write(buffer, length);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// HTTPHeaderIOS
|
||||
//
|
||||
|
||||
|
||||
HTTPHeaderIOS::HTTPHeaderIOS(HTTPSession& session, HTTPHeaderStreamBuf::openmode mode):
|
||||
_buf(session, mode)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
HTTPHeaderIOS::~HTTPHeaderIOS()
|
||||
{
|
||||
try
|
||||
{
|
||||
_buf.sync();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
HTTPHeaderStreamBuf* HTTPHeaderIOS::rdbuf()
|
||||
{
|
||||
return &_buf;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// HTTPHeaderInputStream
|
||||
//
|
||||
|
||||
|
||||
Foundation::MemoryPool HTTPHeaderInputStream::_pool(sizeof(HTTPHeaderInputStream));
|
||||
|
||||
|
||||
HTTPHeaderInputStream::HTTPHeaderInputStream(HTTPSession& session):
|
||||
HTTPHeaderIOS(session, std::ios::in),
|
||||
std::istream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPHeaderInputStream::~HTTPHeaderInputStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void* HTTPHeaderInputStream::operator new(size_t size)
|
||||
{
|
||||
return _pool.get();
|
||||
}
|
||||
|
||||
|
||||
void HTTPHeaderInputStream::operator delete(void* ptr)
|
||||
{
|
||||
_pool.release(ptr);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// HTTPHeaderOutputStream
|
||||
//
|
||||
|
||||
|
||||
Foundation::MemoryPool HTTPHeaderOutputStream::_pool(sizeof(HTTPHeaderOutputStream));
|
||||
|
||||
|
||||
HTTPHeaderOutputStream::HTTPHeaderOutputStream(HTTPSession& session):
|
||||
HTTPHeaderIOS(session, std::ios::out),
|
||||
std::ostream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPHeaderOutputStream::~HTTPHeaderOutputStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void* HTTPHeaderOutputStream::operator new(size_t size)
|
||||
{
|
||||
return _pool.get();
|
||||
}
|
||||
|
||||
|
||||
void HTTPHeaderOutputStream::operator delete(void* ptr)
|
||||
{
|
||||
_pool.release(ptr);
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
84
Net/src/HTTPIOStream.cpp
Normal file
84
Net/src/HTTPIOStream.cpp
Normal file
@@ -0,0 +1,84 @@
|
||||
//
|
||||
// HTTPIOStream.cpp
|
||||
//
|
||||
// $Id: //poco/Main/template/class.cpp#5 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: HTTP
|
||||
// Module: HTTPIOStream
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/HTTPIOStream.h"
|
||||
#include "Net/HTTPClientSession.h"
|
||||
|
||||
|
||||
using Foundation::UnbufferedStreamBuf;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
HTTPResponseStreamBuf::HTTPResponseStreamBuf(std::istream& istr):
|
||||
_istr(istr)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPResponseStreamBuf::~HTTPResponseStreamBuf()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPResponseIOS::HTTPResponseIOS(std::istream& istr):
|
||||
_buf(istr)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
HTTPResponseIOS::~HTTPResponseIOS()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPResponseStream::HTTPResponseStream(std::istream& istr, HTTPClientSession* pSession):
|
||||
HTTPResponseIOS(istr),
|
||||
std::istream(&_buf),
|
||||
_pSession(pSession)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPResponseStream::~HTTPResponseStream()
|
||||
{
|
||||
delete _pSession;
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
182
Net/src/HTTPMessage.cpp
Normal file
182
Net/src/HTTPMessage.cpp
Normal file
@@ -0,0 +1,182 @@
|
||||
//
|
||||
// HTTPMessage.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/HTTPMessage.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: HTTP
|
||||
// Module: HTTPMessage
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/HTTPMessage.h"
|
||||
#include "Net/MediaType.h"
|
||||
#include "Foundation/NumberFormatter.h"
|
||||
#include "Foundation/NumberParser.h"
|
||||
#include "Foundation/String.h"
|
||||
|
||||
|
||||
using Foundation::NumberFormatter;
|
||||
using Foundation::NumberParser;
|
||||
using Foundation::icompare;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
const std::string HTTPMessage::HTTP_1_0 = "HTTP/1.0";
|
||||
const std::string HTTPMessage::HTTP_1_1 = "HTTP/1.1";
|
||||
const std::string HTTPMessage::IDENTITY_TRANSFER_ENCODING = "identity";
|
||||
const std::string HTTPMessage::CHUNKED_TRANSFER_ENCODING = "chunked";
|
||||
const int HTTPMessage::UNKNOWN_CONTENT_LENGTH = -1;
|
||||
const std::string HTTPMessage::UNKNOWN_CONTENT_TYPE;
|
||||
const std::string HTTPMessage::CONTENT_LENGTH = "Content-Length";
|
||||
const std::string HTTPMessage::CONTENT_TYPE = "Content-Type";
|
||||
const std::string HTTPMessage::TRANSFER_ENCODING = "Transfer-Encoding";
|
||||
const std::string HTTPMessage::CONNECTION = "Connection";
|
||||
const std::string HTTPMessage::CONNECTION_KEEP_ALIVE = "Keep-Alive";
|
||||
const std::string HTTPMessage::CONNECTION_CLOSE = "Close";
|
||||
|
||||
|
||||
HTTPMessage::HTTPMessage():
|
||||
_version(HTTP_1_0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPMessage::HTTPMessage(const std::string& version):
|
||||
_version(version)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPMessage::~HTTPMessage()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void HTTPMessage::setVersion(const std::string& version)
|
||||
{
|
||||
_version = version;
|
||||
}
|
||||
|
||||
|
||||
void HTTPMessage::setContentLength(int length)
|
||||
{
|
||||
if (length != UNKNOWN_CONTENT_LENGTH)
|
||||
set(CONTENT_LENGTH, NumberFormatter::format(length));
|
||||
else
|
||||
erase(CONTENT_LENGTH);
|
||||
}
|
||||
|
||||
|
||||
int HTTPMessage::getContentLength() const
|
||||
{
|
||||
if (has(CONTENT_LENGTH))
|
||||
return NumberParser::parse(get(CONTENT_LENGTH));
|
||||
else
|
||||
return UNKNOWN_CONTENT_LENGTH;
|
||||
}
|
||||
|
||||
|
||||
void HTTPMessage::setTransferEncoding(const std::string& transferEncoding)
|
||||
{
|
||||
if (icompare(transferEncoding, IDENTITY_TRANSFER_ENCODING) == 0)
|
||||
erase(TRANSFER_ENCODING);
|
||||
else
|
||||
set(TRANSFER_ENCODING, transferEncoding);
|
||||
}
|
||||
|
||||
|
||||
const std::string& HTTPMessage::getTransferEncoding() const
|
||||
{
|
||||
if (has(TRANSFER_ENCODING))
|
||||
return get(TRANSFER_ENCODING);
|
||||
else
|
||||
return IDENTITY_TRANSFER_ENCODING;
|
||||
}
|
||||
|
||||
|
||||
void HTTPMessage::setChunkedTransferEncoding(bool flag)
|
||||
{
|
||||
if (flag)
|
||||
setTransferEncoding(CHUNKED_TRANSFER_ENCODING);
|
||||
else
|
||||
setTransferEncoding(IDENTITY_TRANSFER_ENCODING);
|
||||
}
|
||||
|
||||
|
||||
bool HTTPMessage::getChunkedTransferEncoding() const
|
||||
{
|
||||
return icompare(getTransferEncoding(), CHUNKED_TRANSFER_ENCODING) == 0;
|
||||
}
|
||||
|
||||
|
||||
void HTTPMessage::setContentType(const std::string& mediaType)
|
||||
{
|
||||
if (mediaType.empty())
|
||||
erase(CONTENT_TYPE);
|
||||
else
|
||||
set(CONTENT_TYPE, mediaType);
|
||||
}
|
||||
|
||||
|
||||
void HTTPMessage::setContentType(const MediaType& mediaType)
|
||||
{
|
||||
setContentType(mediaType.toString());
|
||||
}
|
||||
|
||||
|
||||
const std::string& HTTPMessage::getContentType() const
|
||||
{
|
||||
if (has(CONTENT_TYPE))
|
||||
return get(CONTENT_TYPE);
|
||||
else
|
||||
return UNKNOWN_CONTENT_TYPE;
|
||||
}
|
||||
|
||||
|
||||
void HTTPMessage::setKeepAlive(bool keepAlive)
|
||||
{
|
||||
if (keepAlive)
|
||||
set(CONNECTION, CONNECTION_KEEP_ALIVE);
|
||||
else
|
||||
set(CONNECTION, CONNECTION_CLOSE);
|
||||
}
|
||||
|
||||
|
||||
bool HTTPMessage::getKeepAlive() const
|
||||
{
|
||||
if (has(CONNECTION))
|
||||
return icompare(get(CONNECTION), CONNECTION_KEEP_ALIVE) == 0;
|
||||
else
|
||||
return getVersion() == HTTP_1_1;
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
229
Net/src/HTTPRequest.cpp
Normal file
229
Net/src/HTTPRequest.cpp
Normal file
@@ -0,0 +1,229 @@
|
||||
//
|
||||
// HTTPRequest.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/HTTPRequest.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: HTTP
|
||||
// Module: HTTPRequest
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/HTTPRequest.h"
|
||||
#include "Net/HTTPSession.h"
|
||||
#include "Net/NetException.h"
|
||||
#include "Net/NameValueCollection.h"
|
||||
#include "Foundation/NumberFormatter.h"
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
using Foundation::NumberFormatter;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
const std::string HTTPRequest::HTTP_GET = "GET";
|
||||
const std::string HTTPRequest::HTTP_HEAD = "HEAD";
|
||||
const std::string HTTPRequest::HTTP_PUT = "PUT";
|
||||
const std::string HTTPRequest::HTTP_POST = "POST";
|
||||
const std::string HTTPRequest::HTTP_OPTIONS = "OPTIONS";
|
||||
const std::string HTTPRequest::HTTP_DELETE = "DELETE";
|
||||
const std::string HTTPRequest::HTTP_TRACE = "TRACE";
|
||||
const std::string HTTPRequest::HTTP_CONNECT = "CONNECT";
|
||||
const std::string HTTPRequest::HOST = "Host";
|
||||
const std::string HTTPRequest::COOKIE = "Cookie";
|
||||
const std::string HTTPRequest::AUTHORIZATION = "Authorization";
|
||||
|
||||
|
||||
HTTPRequest::HTTPRequest():
|
||||
_method(HTTP_GET),
|
||||
_uri("/")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPRequest::HTTPRequest(const std::string& version):
|
||||
HTTPMessage(version),
|
||||
_method(HTTP_GET),
|
||||
_uri("/")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPRequest::HTTPRequest(const std::string& method, const std::string& uri):
|
||||
_method(method),
|
||||
_uri(uri)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPRequest::HTTPRequest(const std::string& method, const std::string& uri, const std::string& version):
|
||||
HTTPMessage(version),
|
||||
_method(method),
|
||||
_uri(uri)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPRequest::~HTTPRequest()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void HTTPRequest::setMethod(const std::string& method)
|
||||
{
|
||||
_method = method;
|
||||
}
|
||||
|
||||
|
||||
void HTTPRequest::setURI(const std::string& uri)
|
||||
{
|
||||
_uri = uri;
|
||||
}
|
||||
|
||||
|
||||
void HTTPRequest::setHost(const std::string& host)
|
||||
{
|
||||
set(HOST, host);
|
||||
}
|
||||
|
||||
|
||||
void HTTPRequest::setHost(const std::string& host, Foundation::UInt16 port)
|
||||
{
|
||||
std::string value(host);
|
||||
if (port != HTTPSession::HTTP_PORT)
|
||||
{
|
||||
value.append(":");
|
||||
value.append(NumberFormatter::format(port));
|
||||
}
|
||||
setHost(value);
|
||||
}
|
||||
|
||||
|
||||
const std::string& HTTPRequest::getHost() const
|
||||
{
|
||||
return get(HOST);
|
||||
}
|
||||
|
||||
|
||||
void HTTPRequest::setCookies(const NameValueCollection& cookies)
|
||||
{
|
||||
std::string cookie;
|
||||
for (NameValueCollection::ConstIterator it = cookies.begin(); it != cookies.end(); ++it)
|
||||
{
|
||||
if (it != cookies.begin())
|
||||
cookie.append("; ");
|
||||
cookie.append(it->first);
|
||||
cookie.append("=");
|
||||
cookie.append(it->second);
|
||||
}
|
||||
add(COOKIE, cookie);
|
||||
}
|
||||
|
||||
|
||||
void HTTPRequest::getCookies(NameValueCollection& cookies) const
|
||||
{
|
||||
NameValueCollection::ConstIterator it = find(COOKIE);
|
||||
while (it != end() && it->first == COOKIE)
|
||||
{
|
||||
splitParameters(it->second.begin(), it->second.end(), cookies);
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool HTTPRequest::hasCredentials() const
|
||||
{
|
||||
return has(AUTHORIZATION);
|
||||
}
|
||||
|
||||
|
||||
void HTTPRequest::getCredentials(std::string& scheme, std::string& authInfo) const
|
||||
{
|
||||
scheme.clear();
|
||||
authInfo.clear();
|
||||
if (has(AUTHORIZATION))
|
||||
{
|
||||
const std::string& auth = get(AUTHORIZATION);
|
||||
std::string::const_iterator it = auth.begin();
|
||||
std::string::const_iterator end = auth.end();
|
||||
while (it != end && isspace(*it)) ++it;
|
||||
while (it != end && !isspace(*it)) scheme += *it++;
|
||||
while (it != end && isspace(*it)) ++it;
|
||||
while (it != end) authInfo += *it++;
|
||||
}
|
||||
else throw NotAuthenticatedException();
|
||||
}
|
||||
|
||||
|
||||
void HTTPRequest::setCredentials(const std::string& scheme, const std::string& authInfo)
|
||||
{
|
||||
std::string auth(scheme);
|
||||
auth.append(" ");
|
||||
auth.append(authInfo);
|
||||
set(AUTHORIZATION, auth);
|
||||
}
|
||||
|
||||
|
||||
void HTTPRequest::write(std::ostream& ostr) const
|
||||
{
|
||||
ostr << _method << " " << _uri << " " << getVersion() << "\r\n";
|
||||
HTTPMessage::write(ostr);
|
||||
ostr << "\r\n";
|
||||
}
|
||||
|
||||
|
||||
void HTTPRequest::read(std::istream& istr)
|
||||
{
|
||||
static const int eof = std::char_traits<char>::eof();
|
||||
|
||||
std::string method;
|
||||
std::string uri;
|
||||
std::string version;
|
||||
int ch = istr.get();
|
||||
while (isspace(ch)) ch = istr.get();
|
||||
while (!isspace(ch) && ch != eof && method.length() < MAX_METHOD_LENGTH) { method += (char) ch; ch = istr.get(); }
|
||||
if (!isspace(ch)) throw MessageException("HTTP request method too long");
|
||||
while (isspace(ch)) ch = istr.get();
|
||||
while (!isspace(ch) && ch != eof && uri.length() < MAX_URI_LENGTH) { uri += (char) ch; ch = istr.get(); }
|
||||
if (!isspace(ch)) throw MessageException("HTTP request URI too long");
|
||||
while (isspace(ch)) ch = istr.get();
|
||||
while (!isspace(ch) && ch != eof && version.length() < MAX_VERSION_LENGTH) { version += (char) ch; ch = istr.get(); }
|
||||
if (!isspace(ch)) throw MessageException("Invalid HTTP version string");
|
||||
while (ch != '\n' && ch != eof) { ch = istr.get(); }
|
||||
HTTPMessage::read(istr);
|
||||
ch = istr.get();
|
||||
while (ch != '\n' && ch != eof) { ch = istr.get(); }
|
||||
setMethod(method);
|
||||
setURI(uri);
|
||||
setVersion(version);
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
53
Net/src/HTTPRequestHandler.cpp
Normal file
53
Net/src/HTTPRequestHandler.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// HTTPRequestHandler.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/HTTPRequestHandler.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: HTTPServer
|
||||
// Module: HTTPRequestHandler
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/HTTPRequestHandler.h"
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
HTTPRequestHandler::HTTPRequestHandler()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPRequestHandler::~HTTPRequestHandler()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
53
Net/src/HTTPRequestHandlerFactory.cpp
Normal file
53
Net/src/HTTPRequestHandlerFactory.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// HTTPRequestHandlerFactory.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/HTTPRequestHandlerFactory.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: HTTPServer
|
||||
// Module: HTTPRequestHandlerFactory
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/HTTPRequestHandlerFactory.h"
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
HTTPRequestHandlerFactory::HTTPRequestHandlerFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPRequestHandlerFactory::~HTTPRequestHandlerFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
345
Net/src/HTTPResponse.cpp
Normal file
345
Net/src/HTTPResponse.cpp
Normal file
@@ -0,0 +1,345 @@
|
||||
//
|
||||
// HTTPResponse.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/HTTPResponse.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: HTTP
|
||||
// Module: HTTPResponse
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/HTTPResponse.h"
|
||||
#include "Net/NetException.h"
|
||||
#include "Foundation/NumberFormatter.h"
|
||||
#include "Foundation/NumberParser.h"
|
||||
#include "Foundation/DateTime.h"
|
||||
#include "Foundation/DateTimeFormatter.h"
|
||||
#include "Foundation/DateTimeFormat.h"
|
||||
#include "Foundation/DateTimeParser.h"
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
using Foundation::DateTime;
|
||||
using Foundation::NumberFormatter;
|
||||
using Foundation::NumberParser;
|
||||
using Foundation::DateTimeFormatter;
|
||||
using Foundation::DateTimeFormat;
|
||||
using Foundation::DateTimeParser;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
const std::string HTTPResponse::HTTP_REASON_CONTINUE = "Continue";
|
||||
const std::string HTTPResponse::HTTP_REASON_SWITCHING_PROTOCOLS = "Switching Protocols";
|
||||
const std::string HTTPResponse::HTTP_REASON_OK = "OK";
|
||||
const std::string HTTPResponse::HTTP_REASON_CREATED = "Created";
|
||||
const std::string HTTPResponse::HTTP_REASON_ACCEPTED = "Accepted";
|
||||
const std::string HTTPResponse::HTTP_REASON_NONAUTHORITATIVE = "Non-Authoritative Information";
|
||||
const std::string HTTPResponse::HTTP_REASON_NO_CONTENT = "No Content";
|
||||
const std::string HTTPResponse::HTTP_REASON_RESET_CONTENT = "Reset Content";
|
||||
const std::string HTTPResponse::HTTP_REASON_PARTIAL_CONTENT = "Partial Content";
|
||||
const std::string HTTPResponse::HTTP_REASON_MULTIPLE_CHOICES = "Multiple Choices";
|
||||
const std::string HTTPResponse::HTTP_REASON_MOVED_PERMANENTLY = "Moved Permanently";
|
||||
const std::string HTTPResponse::HTTP_REASON_FOUND = "Found";
|
||||
const std::string HTTPResponse::HTTP_REASON_SEE_OTHER = "See Other";
|
||||
const std::string HTTPResponse::HTTP_REASON_NOT_MODIFIED = "Not Modified";
|
||||
const std::string HTTPResponse::HTTP_REASON_USEPROXY = "Use Proxy";
|
||||
const std::string HTTPResponse::HTTP_REASON_TEMPORARY_REDIRECT = "Temporary Redirect";
|
||||
const std::string HTTPResponse::HTTP_REASON_BAD_REQUEST = "Bad Request";
|
||||
const std::string HTTPResponse::HTTP_REASON_UNAUTHORIZED = "Unauthorized";
|
||||
const std::string HTTPResponse::HTTP_REASON_PAYMENT_REQUIRED = "Payment Required";
|
||||
const std::string HTTPResponse::HTTP_REASON_FORBIDDEN = "Forbidden";
|
||||
const std::string HTTPResponse::HTTP_REASON_NOT_FOUND = "Not Found";
|
||||
const std::string HTTPResponse::HTTP_REASON_METHOD_NOT_ALLOWED = "Method Not Allowed";
|
||||
const std::string HTTPResponse::HTTP_REASON_NOT_ACCEPTABLE = "Not Acceptable";
|
||||
const std::string HTTPResponse::HTTP_REASON_PROXY_AUTHENTICATION_REQUIRED = "Proxy Authentication Required";
|
||||
const std::string HTTPResponse::HTTP_REASON_REQUEST_TIMEOUT = "Request Time-out";
|
||||
const std::string HTTPResponse::HTTP_REASON_CONFLICT = "Conflict";
|
||||
const std::string HTTPResponse::HTTP_REASON_GONE = "Gone";
|
||||
const std::string HTTPResponse::HTTP_REASON_LENGTH_REQUIRED = "Length Required";
|
||||
const std::string HTTPResponse::HTTP_REASON_PRECONDITION_FAILED = "Precondition Failed";
|
||||
const std::string HTTPResponse::HTTP_REASON_REQUESTENTITYTOOLARGE = "Request Entity Too Large";
|
||||
const std::string HTTPResponse::HTTP_REASON_REQUESTURITOOLONG = "Request-URI Too Large";
|
||||
const std::string HTTPResponse::HTTP_REASON_UNSUPPORTEDMEDIATYPE = "Unsupported Media Type";
|
||||
const std::string HTTPResponse::HTTP_REASON_REQUESTED_RANGE_NOT_SATISFIABLE = "Requested Range Not Satisfiable";
|
||||
const std::string HTTPResponse::HTTP_REASON_EXPECTATION_FAILED = "Expectation Failed";
|
||||
const std::string HTTPResponse::HTTP_REASON_INTERNAL_SERVER_ERROR = "Internal Server Error";
|
||||
const std::string HTTPResponse::HTTP_REASON_NOT_IMPLEMENTED = "Not Implemented";
|
||||
const std::string HTTPResponse::HTTP_REASON_BAD_GATEWAY = "Bad Gateway";
|
||||
const std::string HTTPResponse::HTTP_REASON_SERVICE_UNAVAILABLE = "Service Unavailable";
|
||||
const std::string HTTPResponse::HTTP_REASON_GATEWAY_TIMEOUT = "Gateway Time-out";
|
||||
const std::string HTTPResponse::HTTP_REASON_VERSION_NOT_SUPPORTED = "HTTP Version not supported";
|
||||
const std::string HTTPResponse::HTTP_REASON_UNKNOWN = "???";
|
||||
const std::string HTTPResponse::DATE = "Date";
|
||||
const std::string HTTPResponse::SET_COOKIE = "Set-Cookie";
|
||||
|
||||
|
||||
HTTPResponse::HTTPResponse():
|
||||
_status(HTTP_OK),
|
||||
_reason(getReasonForStatus(HTTP_OK))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPResponse::HTTPResponse(HTTPStatus status, const std::string& reason):
|
||||
_status(status),
|
||||
_reason(reason)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
HTTPResponse::HTTPResponse(const std::string& version, HTTPStatus status, const std::string& reason):
|
||||
HTTPMessage(version),
|
||||
_status(status),
|
||||
_reason(reason)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPResponse::HTTPResponse(HTTPStatus status):
|
||||
_status(status),
|
||||
_reason(getReasonForStatus(status))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPResponse::HTTPResponse(const std::string& version, HTTPStatus status):
|
||||
HTTPMessage(version),
|
||||
_status(status),
|
||||
_reason(getReasonForStatus(status))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPResponse::~HTTPResponse()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void HTTPResponse::setStatus(HTTPStatus status)
|
||||
{
|
||||
_status = status;
|
||||
}
|
||||
|
||||
|
||||
void HTTPResponse::setStatus(const std::string& status)
|
||||
{
|
||||
setStatus((HTTPStatus) NumberParser::parse(status));
|
||||
}
|
||||
|
||||
|
||||
void HTTPResponse::setReason(const std::string& reason)
|
||||
{
|
||||
_reason = reason;
|
||||
}
|
||||
|
||||
|
||||
void HTTPResponse::setStatusAndReason(HTTPStatus status, const std::string& reason)
|
||||
{
|
||||
_status = status;
|
||||
_reason = reason;
|
||||
}
|
||||
|
||||
|
||||
void HTTPResponse::setStatusAndReason(HTTPStatus status)
|
||||
{
|
||||
setStatusAndReason(status, getReasonForStatus(status));
|
||||
}
|
||||
|
||||
|
||||
void HTTPResponse::setDate(const Foundation::Timestamp& dateTime)
|
||||
{
|
||||
set(DATE, DateTimeFormatter::format(dateTime, DateTimeFormat::HTTP_FORMAT));
|
||||
}
|
||||
|
||||
|
||||
Foundation::Timestamp HTTPResponse::getDate() const
|
||||
{
|
||||
const std::string& dateTime = get(DATE);
|
||||
int tzd;
|
||||
return DateTimeParser::parse(dateTime, tzd).timestamp();
|
||||
}
|
||||
|
||||
|
||||
void HTTPResponse::addCookie(const HTTPCookie& cookie)
|
||||
{
|
||||
add(SET_COOKIE, cookie.toString());
|
||||
}
|
||||
|
||||
|
||||
void HTTPResponse::getCookies(std::vector<HTTPCookie>& cookies) const
|
||||
{
|
||||
cookies.clear();
|
||||
NameValueCollection::ConstIterator it = find(SET_COOKIE);
|
||||
while (it != end() && it->first == SET_COOKIE)
|
||||
{
|
||||
NameValueCollection nvc;
|
||||
splitParameters(it->second.begin(), it->second.end(), nvc);
|
||||
cookies.push_back(HTTPCookie(nvc));
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HTTPResponse::write(std::ostream& ostr) const
|
||||
{
|
||||
ostr << getVersion() << " " << NumberFormatter::format((int) _status) << " " << _reason << "\r\n";
|
||||
HTTPMessage::write(ostr);
|
||||
ostr << "\r\n";
|
||||
}
|
||||
|
||||
|
||||
void HTTPResponse::read(std::istream& istr)
|
||||
{
|
||||
static const int eof = std::char_traits<char>::eof();
|
||||
|
||||
std::string version;
|
||||
std::string status;
|
||||
std::string reason;
|
||||
int ch = 0;
|
||||
do
|
||||
{
|
||||
version.clear();
|
||||
status.clear();
|
||||
reason.clear();
|
||||
ch = istr.get();
|
||||
while (isspace(ch)) ch = istr.get();
|
||||
while (!isspace(ch) && ch != eof && version.length() < MAX_VERSION_LENGTH) { version += (char) ch; ch = istr.get(); }
|
||||
if (!isspace(ch)) throw MessageException("Invalid HTTP version string");
|
||||
while (isspace(ch)) ch = istr.get();
|
||||
while (!isspace(ch) && ch != eof && status.length() < MAX_STATUS_LENGTH) { status += (char) ch; ch = istr.get(); }
|
||||
if (!isspace(ch)) throw MessageException("Invalid HTTP status code");
|
||||
while (isspace(ch)) ch = istr.get();
|
||||
while (ch != '\r' && ch != '\n' && ch != eof && reason.length() < MAX_REASON_LENGTH) { reason += (char) ch; ch = istr.get(); }
|
||||
if (!isspace(ch)) throw MessageException("HTTP reason string too long");
|
||||
if (ch == '\r') ch = istr.get();
|
||||
}
|
||||
while (ch != eof && status == "100");
|
||||
HTTPMessage::read(istr);
|
||||
ch = istr.get();
|
||||
while (ch != '\n' && ch != eof) { ch = istr.get(); }
|
||||
setVersion(version);
|
||||
setStatus(status);
|
||||
setReason(reason);
|
||||
}
|
||||
|
||||
|
||||
const std::string& HTTPResponse::getReasonForStatus(HTTPStatus status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case HTTP_CONTINUE:
|
||||
return HTTP_REASON_CONTINUE;
|
||||
case HTTP_SWITCHING_PROTOCOLS:
|
||||
return HTTP_REASON_SWITCHING_PROTOCOLS;
|
||||
case HTTP_OK:
|
||||
return HTTP_REASON_OK;
|
||||
case HTTP_CREATED:
|
||||
return HTTP_REASON_CREATED;
|
||||
case HTTP_ACCEPTED:
|
||||
return HTTP_REASON_ACCEPTED;
|
||||
case HTTP_NONAUTHORITATIVE:
|
||||
return HTTP_REASON_NONAUTHORITATIVE;
|
||||
case HTTP_NO_CONTENT:
|
||||
return HTTP_REASON_NO_CONTENT;
|
||||
case HTTP_RESET_CONTENT:
|
||||
return HTTP_REASON_RESET_CONTENT;
|
||||
case HTTP_PARTIAL_CONTENT:
|
||||
return HTTP_REASON_PARTIAL_CONTENT;
|
||||
case HTTP_MULTIPLE_CHOICES:
|
||||
return HTTP_REASON_MULTIPLE_CHOICES;
|
||||
case HTTP_MOVED_PERMANENTLY:
|
||||
return HTTP_REASON_MOVED_PERMANENTLY;
|
||||
case HTTP_FOUND:
|
||||
return HTTP_REASON_FOUND;
|
||||
case HTTP_SEE_OTHER:
|
||||
return HTTP_REASON_SEE_OTHER;
|
||||
case HTTP_NOT_MODIFIED:
|
||||
return HTTP_REASON_NOT_MODIFIED;
|
||||
case HTTP_USEPROXY:
|
||||
return HTTP_REASON_USEPROXY;
|
||||
case HTTP_TEMPORARY_REDIRECT:
|
||||
return HTTP_REASON_TEMPORARY_REDIRECT;
|
||||
case HTTP_BAD_REQUEST:
|
||||
return HTTP_REASON_BAD_REQUEST;
|
||||
case HTTP_UNAUTHORIZED:
|
||||
return HTTP_REASON_UNAUTHORIZED;
|
||||
case HTTP_PAYMENT_REQUIRED:
|
||||
return HTTP_REASON_PAYMENT_REQUIRED;
|
||||
case HTTP_FORBIDDEN:
|
||||
return HTTP_REASON_FORBIDDEN;
|
||||
case HTTP_NOT_FOUND:
|
||||
return HTTP_REASON_NOT_FOUND;
|
||||
case HTTP_METHOD_NOT_ALLOWED:
|
||||
return HTTP_REASON_METHOD_NOT_ALLOWED;
|
||||
case HTTP_NOT_ACCEPTABLE:
|
||||
return HTTP_REASON_NOT_ACCEPTABLE;
|
||||
case HTTP_PROXY_AUTHENTICATION_REQUIRED:
|
||||
return HTTP_REASON_PROXY_AUTHENTICATION_REQUIRED;
|
||||
case HTTP_REQUEST_TIMEOUT:
|
||||
return HTTP_REASON_REQUEST_TIMEOUT;
|
||||
case HTTP_CONFLICT:
|
||||
return HTTP_REASON_CONFLICT;
|
||||
case HTTP_GONE:
|
||||
return HTTP_REASON_GONE;
|
||||
case HTTP_LENGTH_REQUIRED:
|
||||
return HTTP_REASON_LENGTH_REQUIRED;
|
||||
case HTTP_PRECONDITION_FAILED:
|
||||
return HTTP_REASON_PRECONDITION_FAILED;
|
||||
case HTTP_REQUESTENTITYTOOLARGE:
|
||||
return HTTP_REASON_REQUESTENTITYTOOLARGE;
|
||||
case HTTP_REQUESTURITOOLONG:
|
||||
return HTTP_REASON_REQUESTURITOOLONG;
|
||||
case HTTP_UNSUPPORTEDMEDIATYPE:
|
||||
return HTTP_REASON_UNSUPPORTEDMEDIATYPE;
|
||||
case HTTP_REQUESTED_RANGE_NOT_SATISFIABLE:
|
||||
return HTTP_REASON_REQUESTED_RANGE_NOT_SATISFIABLE;
|
||||
case HTTP_EXPECTATION_FAILED:
|
||||
return HTTP_REASON_EXPECTATION_FAILED;
|
||||
case HTTP_INTERNAL_SERVER_ERROR:
|
||||
return HTTP_REASON_INTERNAL_SERVER_ERROR;
|
||||
case HTTP_NOT_IMPLEMENTED:
|
||||
return HTTP_REASON_NOT_IMPLEMENTED;
|
||||
case HTTP_BAD_GATEWAY:
|
||||
return HTTP_REASON_BAD_GATEWAY;
|
||||
case HTTP_SERVICE_UNAVAILABLE:
|
||||
return HTTP_REASON_SERVICE_UNAVAILABLE;
|
||||
case HTTP_GATEWAY_TIMEOUT:
|
||||
return HTTP_REASON_GATEWAY_TIMEOUT;
|
||||
case HTTP_VERSION_NOT_SUPPORTED:
|
||||
return HTTP_REASON_VERSION_NOT_SUPPORTED;
|
||||
default:
|
||||
return HTTP_REASON_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
62
Net/src/HTTPServer.cpp
Normal file
62
Net/src/HTTPServer.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
//
|
||||
// HTTPServer.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/HTTPServer.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: HTTPServer
|
||||
// Module: HTTPServer
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/HTTPServer.h"
|
||||
#include "Net/HTTPServerParams.h"
|
||||
#include "Net/HTTPServerConnectionFactory.h"
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
HTTPServer::HTTPServer(HTTPRequestHandlerFactory* pFactory, const ServerSocket& socket, HTTPServerParams* pParams):
|
||||
TCPServer(new HTTPServerConnectionFactory(pParams, pFactory), socket, pParams)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPServer::HTTPServer(HTTPRequestHandlerFactory* pFactory, Foundation::ThreadPool& threadPool, const ServerSocket& socket, HTTPServerParams* pParams):
|
||||
TCPServer(new HTTPServerConnectionFactory(pParams, pFactory), threadPool, socket, pParams)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPServer::~HTTPServer()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
102
Net/src/HTTPServerConnection.cpp
Normal file
102
Net/src/HTTPServerConnection.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
//
|
||||
// HTTPServerConnection.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/HTTPServerConnection.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: HTTPServer
|
||||
// Module: HTTPServerConnection
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/HTTPServerConnection.h"
|
||||
#include "Net/HTTPServerSession.h"
|
||||
#include "Net/HTTPServerRequest.h"
|
||||
#include "Net/HTTPServerResponse.h"
|
||||
#include "Net/HTTPRequestHandler.h"
|
||||
#include "Net/HTTPRequestHandlerFactory.h"
|
||||
#include "Net/HTTPServerParams.h"
|
||||
#include "Net/NetException.h"
|
||||
#include "Foundation/NumberFormatter.h"
|
||||
#include <memory>
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
HTTPServerConnection::HTTPServerConnection(const StreamSocket& socket, HTTPServerParams* pParams, HTTPRequestHandlerFactory* pFactory):
|
||||
TCPServerConnection(socket),
|
||||
_pParams(pParams),
|
||||
_pFactory(pFactory)
|
||||
{
|
||||
poco_check_ptr (pFactory);
|
||||
poco_check_ptr (pParams);
|
||||
|
||||
_pParams->duplicate();
|
||||
}
|
||||
|
||||
|
||||
HTTPServerConnection::~HTTPServerConnection()
|
||||
{
|
||||
_pParams->release();
|
||||
}
|
||||
|
||||
|
||||
void HTTPServerConnection::run()
|
||||
{
|
||||
std::string server = _pParams->getSoftwareVersion();
|
||||
HTTPServerSession session(socket(), _pParams);
|
||||
while (session.hasMoreRequests())
|
||||
{
|
||||
HTTPServerRequest request(session, _pParams);
|
||||
HTTPServerResponse response(session);
|
||||
response.setVersion(request.getVersion());
|
||||
response.setKeepAlive(_pParams->getKeepAlive() && request.getKeepAlive());
|
||||
if (!server.empty())
|
||||
response.set("Server", server);
|
||||
std::auto_ptr<HTTPRequestHandler> pHandler(_pFactory->createRequestHandler(request));
|
||||
if (pHandler.get())
|
||||
{
|
||||
if (request.expectContinue())
|
||||
response.sendContinue();
|
||||
|
||||
pHandler->handleRequest(request, response);
|
||||
session.setKeepAlive(_pParams->getKeepAlive() && response.getKeepAlive());
|
||||
}
|
||||
else
|
||||
{
|
||||
response.setStatusAndReason(HTTPResponse::HTTP_NOT_IMPLEMENTED);
|
||||
response.setKeepAlive(false);
|
||||
response.send();
|
||||
session.setKeepAlive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
70
Net/src/HTTPServerConnectionFactory.cpp
Normal file
70
Net/src/HTTPServerConnectionFactory.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
//
|
||||
// HTTPServerConnectionFactory.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/HTTPServerConnectionFactory.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: HTTPServer
|
||||
// Module: HTTPServerConnectionFactory
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/HTTPServerConnectionFactory.h"
|
||||
#include "Net/HTTPServerConnection.h"
|
||||
#include "Net/HTTPServerParams.h"
|
||||
#include "Net/HTTPRequestHandlerFactory.h"
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
HTTPServerConnectionFactory::HTTPServerConnectionFactory(HTTPServerParams* pParams, HTTPRequestHandlerFactory* pFactory):
|
||||
_pParams(pParams),
|
||||
_pFactory(pFactory)
|
||||
{
|
||||
poco_check_ptr (pParams);
|
||||
poco_check_ptr (pFactory);
|
||||
|
||||
_pParams->duplicate();
|
||||
}
|
||||
|
||||
|
||||
HTTPServerConnectionFactory::~HTTPServerConnectionFactory()
|
||||
{
|
||||
_pParams->release();
|
||||
delete _pFactory;
|
||||
}
|
||||
|
||||
|
||||
TCPServerConnection* HTTPServerConnectionFactory::createConnection(const StreamSocket& socket)
|
||||
{
|
||||
return new HTTPServerConnection(socket, _pParams, _pFactory);
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
94
Net/src/HTTPServerParams.cpp
Normal file
94
Net/src/HTTPServerParams.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
//
|
||||
// HTTPServerParams.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/HTTPServerParams.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: HTTPServer
|
||||
// Module: HTTPServerParams
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/HTTPServerParams.h"
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
HTTPServerParams::HTTPServerParams():
|
||||
_timeout(60000000),
|
||||
_keepAlive(true),
|
||||
_maxKeepAliveRequests(0),
|
||||
_keepAliveTimeout(15000000)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPServerParams::~HTTPServerParams()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void HTTPServerParams::setServerName(const std::string& serverName)
|
||||
{
|
||||
_serverName = serverName;
|
||||
}
|
||||
|
||||
|
||||
void HTTPServerParams::setSoftwareVersion(const std::string& softwareVersion)
|
||||
{
|
||||
_softwareVersion = softwareVersion;
|
||||
}
|
||||
|
||||
|
||||
void HTTPServerParams::setTimeout(const Foundation::Timespan& timeout)
|
||||
{
|
||||
_timeout = timeout;
|
||||
}
|
||||
|
||||
|
||||
void HTTPServerParams::setKeepAlive(bool keepAlive)
|
||||
{
|
||||
_keepAlive = keepAlive;
|
||||
}
|
||||
|
||||
|
||||
void HTTPServerParams::setKeepAliveTimeout(const Foundation::Timespan& timeout)
|
||||
{
|
||||
_keepAliveTimeout = timeout;
|
||||
}
|
||||
|
||||
|
||||
void HTTPServerParams::setMaxKeepAliveRequests(int maxKeepAliveRequests)
|
||||
{
|
||||
poco_assert (maxKeepAliveRequests >= 0);
|
||||
_maxKeepAliveRequests = maxKeepAliveRequests;
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
90
Net/src/HTTPServerRequest.cpp
Normal file
90
Net/src/HTTPServerRequest.cpp
Normal file
@@ -0,0 +1,90 @@
|
||||
//
|
||||
// HTTPServerRequest.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/HTTPServerRequest.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: HTTPServer
|
||||
// Module: HTTPServerRequest
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/HTTPServerRequest.h"
|
||||
#include "Net/HTTPServerSession.h"
|
||||
#include "Net/HTTPHeaderStream.h"
|
||||
#include "Net/HTTPStream.h"
|
||||
#include "Net/HTTPFixedLengthStream.h"
|
||||
#include "Net/HTTPChunkedStream.h"
|
||||
#include "Net/HTTPServerParams.h"
|
||||
#include "Foundation/String.h"
|
||||
|
||||
|
||||
using Foundation::icompare;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
HTTPServerRequest::HTTPServerRequest(HTTPServerSession& session, HTTPServerParams* pParams):
|
||||
_pStream(0),
|
||||
_pParams(pParams),
|
||||
_clientAddress(session.clientAddress()),
|
||||
_serverAddress(session.serverAddress())
|
||||
{
|
||||
poco_check_ptr (_pParams);
|
||||
|
||||
_pParams->duplicate();
|
||||
|
||||
HTTPHeaderInputStream hs(session);
|
||||
read(hs);
|
||||
|
||||
if (getChunkedTransferEncoding())
|
||||
_pStream = new HTTPChunkedInputStream(session);
|
||||
else if (getContentLength() != HTTPMessage::UNKNOWN_CONTENT_LENGTH)
|
||||
_pStream = new HTTPFixedLengthInputStream(session, getContentLength());
|
||||
else if (getMethod() == HTTPRequest::HTTP_GET || getMethod() == HTTPRequest::HTTP_HEAD)
|
||||
_pStream = new HTTPFixedLengthInputStream(session, 0);
|
||||
else
|
||||
_pStream = new HTTPInputStream(session);
|
||||
}
|
||||
|
||||
|
||||
HTTPServerRequest::~HTTPServerRequest()
|
||||
{
|
||||
_pParams->release();
|
||||
delete _pStream;
|
||||
}
|
||||
|
||||
|
||||
bool HTTPServerRequest::expectContinue() const
|
||||
{
|
||||
return has("Expect") && icompare(get("Expect"), "100-continue") == 0;
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
150
Net/src/HTTPServerResponse.cpp
Normal file
150
Net/src/HTTPServerResponse.cpp
Normal file
@@ -0,0 +1,150 @@
|
||||
//
|
||||
// HTTPServerResponse.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/HTTPServerResponse.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: HTTPServer
|
||||
// Module: HTTPServerResponse
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/HTTPServerResponse.h"
|
||||
#include "Net/HTTPServerSession.h"
|
||||
#include "Net/HTTPHeaderStream.h"
|
||||
#include "Net/HTTPStream.h"
|
||||
#include "Net/HTTPFixedLengthStream.h"
|
||||
#include "Net/HTTPChunkedStream.h"
|
||||
#include "Foundation/File.h"
|
||||
#include "Foundation/Timestamp.h"
|
||||
#include "Foundation/NumberFormatter.h"
|
||||
#include "Foundation/StreamCopier.h"
|
||||
#include "Foundation/Exception.h"
|
||||
#include <fstream>
|
||||
|
||||
|
||||
using Foundation::File;
|
||||
using Foundation::Timestamp;
|
||||
using Foundation::NumberFormatter;
|
||||
using Foundation::StreamCopier;
|
||||
using Foundation::OpenFileException;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
HTTPServerResponse::HTTPServerResponse(HTTPServerSession& session):
|
||||
_session(session),
|
||||
_pStream(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPServerResponse::~HTTPServerResponse()
|
||||
{
|
||||
delete _pStream;
|
||||
}
|
||||
|
||||
|
||||
void HTTPServerResponse::sendContinue()
|
||||
{
|
||||
HTTPHeaderOutputStream hs(_session);
|
||||
hs << getVersion() << " 100 Continue\r\n";
|
||||
}
|
||||
|
||||
|
||||
std::ostream& HTTPServerResponse::send()
|
||||
{
|
||||
poco_assert (!_pStream);
|
||||
|
||||
if (getChunkedTransferEncoding())
|
||||
{
|
||||
_pStream = new HTTPChunkedOutputStream(_session);
|
||||
}
|
||||
else if (getContentLength() != HTTPMessage::UNKNOWN_CONTENT_LENGTH)
|
||||
{
|
||||
_pStream = new HTTPFixedLengthOutputStream(_session, getContentLength());
|
||||
}
|
||||
else
|
||||
{
|
||||
_pStream = new HTTPOutputStream(_session);
|
||||
setKeepAlive(false);
|
||||
}
|
||||
HTTPHeaderOutputStream hs(_session);
|
||||
write(hs);
|
||||
|
||||
return *_pStream;
|
||||
}
|
||||
|
||||
|
||||
void HTTPServerResponse::sendFile(const std::string& path, const std::string& mediaType)
|
||||
{
|
||||
poco_assert (!_pStream);
|
||||
|
||||
File f(path);
|
||||
Timestamp dateTime = f.getLastModified();
|
||||
File::FileSize length = f.getSize();
|
||||
setDate(dateTime);
|
||||
setContentLength((int) length);
|
||||
setContentType(mediaType);
|
||||
|
||||
std::ifstream istr(path.c_str(), std::ios::binary | std::ios::in);
|
||||
if (istr.good())
|
||||
{
|
||||
send();
|
||||
StreamCopier::copyStream(istr, *_pStream);
|
||||
}
|
||||
else throw OpenFileException(path);
|
||||
}
|
||||
|
||||
|
||||
void HTTPServerResponse::redirect(const std::string& uri)
|
||||
{
|
||||
poco_assert (!_pStream);
|
||||
|
||||
setStatusAndReason(HTTPResponse::HTTP_FOUND);
|
||||
set("Location", uri);
|
||||
|
||||
HTTPHeaderOutputStream hs(_session);
|
||||
write(hs);
|
||||
}
|
||||
|
||||
|
||||
void HTTPServerResponse::requireAuthentication(const std::string& realm)
|
||||
{
|
||||
poco_assert (!_pStream);
|
||||
|
||||
setStatusAndReason(HTTPResponse::HTTP_UNAUTHORIZED);
|
||||
std::string auth("Basic realm=\"");
|
||||
auth.append(realm);
|
||||
auth.append("\"");
|
||||
set("WWW-Authenticate", auth);
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
87
Net/src/HTTPServerSession.cpp
Normal file
87
Net/src/HTTPServerSession.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
//
|
||||
// HTTPServerSession.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/HTTPServerSession.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: HTTPServer
|
||||
// Module: HTTPServerSession
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/HTTPServerSession.h"
|
||||
#include "Net/HTTPServerParams.h"
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
HTTPServerSession::HTTPServerSession(const StreamSocket& socket, HTTPServerParams* pParams):
|
||||
HTTPSession(socket, pParams->getKeepAlive()),
|
||||
_firstRequest(true),
|
||||
_keepAliveTimeout(pParams->getKeepAliveTimeout()),
|
||||
_maxKeepAliveRequests(pParams->getMaxKeepAliveRequests())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPServerSession::~HTTPServerSession()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool HTTPServerSession::hasMoreRequests()
|
||||
{
|
||||
if (_firstRequest)
|
||||
{
|
||||
_firstRequest = false;
|
||||
--_maxKeepAliveRequests;
|
||||
return socket().poll(getTimeout(), Socket::SELECT_READ);
|
||||
}
|
||||
else if (_maxKeepAliveRequests > 0 && getKeepAlive())
|
||||
{
|
||||
--_maxKeepAliveRequests;
|
||||
return socket().poll(_keepAliveTimeout, Socket::SELECT_READ);
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
|
||||
SocketAddress HTTPServerSession::clientAddress()
|
||||
{
|
||||
return socket().peerAddress();
|
||||
}
|
||||
|
||||
|
||||
SocketAddress HTTPServerSession::serverAddress()
|
||||
{
|
||||
return socket().address();
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
190
Net/src/HTTPSession.cpp
Normal file
190
Net/src/HTTPSession.cpp
Normal file
@@ -0,0 +1,190 @@
|
||||
//
|
||||
// HTTPSession.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/HTTPSession.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: HTTP
|
||||
// Module: HTTPSession
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/HTTPSession.h"
|
||||
#include "Net/HTTPBufferAllocator.h"
|
||||
#include "Net/NetException.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
using Foundation::TimeoutException;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
HTTPSession::HTTPSession():
|
||||
_pBuffer(0),
|
||||
_pCurrent(0),
|
||||
_pEnd(0),
|
||||
_keepAlive(false),
|
||||
_timeout(HTTP_DEFAULT_TIMEOUT)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPSession::HTTPSession(const StreamSocket& socket):
|
||||
_socket(socket),
|
||||
_pBuffer(0),
|
||||
_pCurrent(0),
|
||||
_pEnd(0),
|
||||
_keepAlive(false),
|
||||
_timeout(HTTP_DEFAULT_TIMEOUT)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPSession::HTTPSession(const StreamSocket& socket, bool keepAlive):
|
||||
_socket(socket),
|
||||
_pBuffer(0),
|
||||
_pCurrent(0),
|
||||
_pEnd(0),
|
||||
_keepAlive(keepAlive),
|
||||
_timeout(HTTP_DEFAULT_TIMEOUT)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPSession::~HTTPSession()
|
||||
{
|
||||
if (_pBuffer) HTTPBufferAllocator::deallocate(_pBuffer, HTTPBufferAllocator::BUFFER_SIZE);
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
void HTTPSession::setKeepAlive(bool keepAlive)
|
||||
{
|
||||
_keepAlive = keepAlive;
|
||||
}
|
||||
|
||||
|
||||
void HTTPSession::setTimeout(const Foundation::Timespan& timeout)
|
||||
{
|
||||
_timeout = timeout;
|
||||
}
|
||||
|
||||
|
||||
int HTTPSession::get()
|
||||
{
|
||||
if (_pCurrent == _pEnd)
|
||||
refill();
|
||||
|
||||
if (_pCurrent < _pEnd)
|
||||
return *_pCurrent++;
|
||||
else
|
||||
return std::char_traits<char>::eof();
|
||||
}
|
||||
|
||||
|
||||
int HTTPSession::peek()
|
||||
{
|
||||
if (_pCurrent == _pEnd)
|
||||
refill();
|
||||
|
||||
if (_pCurrent < _pEnd)
|
||||
return *_pCurrent;
|
||||
else
|
||||
return std::char_traits<char>::eof();
|
||||
}
|
||||
|
||||
|
||||
int HTTPSession::read(char* buffer, std::streamsize length)
|
||||
{
|
||||
if (_pCurrent < _pEnd)
|
||||
{
|
||||
int n = (int) (_pEnd - _pCurrent);
|
||||
if (n > length) n = (int) length;
|
||||
memcpy(buffer, _pCurrent, n);
|
||||
_pCurrent += n;
|
||||
return n;
|
||||
}
|
||||
else return receive(buffer, (int) length);
|
||||
}
|
||||
|
||||
|
||||
int HTTPSession::write(const char* buffer, std::streamsize length)
|
||||
{
|
||||
return _socket.sendBytes(buffer, (int) length);
|
||||
}
|
||||
|
||||
|
||||
int HTTPSession::receive(char* buffer, int length)
|
||||
{
|
||||
if (_socket.poll(_timeout, Socket::SELECT_READ))
|
||||
return _socket.receiveBytes(buffer, length);
|
||||
else
|
||||
throw TimeoutException();
|
||||
}
|
||||
|
||||
|
||||
void HTTPSession::refill()
|
||||
{
|
||||
if (!_pBuffer)
|
||||
{
|
||||
_pBuffer = HTTPBufferAllocator::allocate(HTTPBufferAllocator::BUFFER_SIZE);
|
||||
}
|
||||
_pCurrent = _pEnd = _pBuffer;
|
||||
int n = receive(_pBuffer, HTTPBufferAllocator::BUFFER_SIZE);
|
||||
_pEnd += n;
|
||||
}
|
||||
|
||||
|
||||
bool HTTPSession::connected() const
|
||||
{
|
||||
return _socket.impl()->initialized();
|
||||
}
|
||||
|
||||
|
||||
void HTTPSession::connect(const SocketAddress& address)
|
||||
{
|
||||
_socket.connect(address, _timeout);
|
||||
}
|
||||
|
||||
|
||||
void HTTPSession::abort()
|
||||
{
|
||||
_socket.shutdown();
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
void HTTPSession::close()
|
||||
{
|
||||
_socket.close();
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
179
Net/src/HTTPStream.cpp
Normal file
179
Net/src/HTTPStream.cpp
Normal file
@@ -0,0 +1,179 @@
|
||||
//
|
||||
// HTTPStream.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/HTTPStream.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: HTTP
|
||||
// Module: HTTPStream
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/HTTPStream.h"
|
||||
#include "Net/HTTPSession.h"
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
//
|
||||
// HTTPStreamBuf
|
||||
//
|
||||
|
||||
|
||||
HTTPStreamBuf::HTTPStreamBuf(HTTPSession& session, openmode mode):
|
||||
HTTPBasicStreamBuf(HTTPBufferAllocator::BUFFER_SIZE, mode),
|
||||
_session(session),
|
||||
_mode(mode)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPStreamBuf::~HTTPStreamBuf()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void HTTPStreamBuf::close()
|
||||
{
|
||||
if (_mode & std::ios::out)
|
||||
{
|
||||
sync();
|
||||
_session.socket().shutdownSend();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int HTTPStreamBuf::readFromDevice(char* buffer, std::streamsize length)
|
||||
{
|
||||
return _session.read(buffer, length);
|
||||
}
|
||||
|
||||
|
||||
int HTTPStreamBuf::writeToDevice(const char* buffer, std::streamsize length)
|
||||
{
|
||||
|
||||
return _session.write(buffer, length);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// HTTPIOS
|
||||
//
|
||||
|
||||
|
||||
HTTPIOS::HTTPIOS(HTTPSession& session, HTTPStreamBuf::openmode mode):
|
||||
_buf(session, mode)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
HTTPIOS::~HTTPIOS()
|
||||
{
|
||||
try
|
||||
{
|
||||
_buf.close();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
HTTPStreamBuf* HTTPIOS::rdbuf()
|
||||
{
|
||||
return &_buf;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// HTTPInputStream
|
||||
//
|
||||
|
||||
|
||||
Foundation::MemoryPool HTTPInputStream::_pool(sizeof(HTTPInputStream));
|
||||
|
||||
|
||||
HTTPInputStream::HTTPInputStream(HTTPSession& session):
|
||||
HTTPIOS(session, std::ios::in),
|
||||
std::istream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPInputStream::~HTTPInputStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void* HTTPInputStream::operator new(size_t size)
|
||||
{
|
||||
return _pool.get();
|
||||
}
|
||||
|
||||
|
||||
void HTTPInputStream::operator delete(void* ptr)
|
||||
{
|
||||
_pool.release(ptr);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// HTTPOutputStream
|
||||
//
|
||||
|
||||
|
||||
Foundation::MemoryPool HTTPOutputStream::_pool(sizeof(HTTPOutputStream));
|
||||
|
||||
|
||||
HTTPOutputStream::HTTPOutputStream(HTTPSession& session):
|
||||
HTTPIOS(session, std::ios::out),
|
||||
std::ostream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPOutputStream::~HTTPOutputStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void* HTTPOutputStream::operator new(size_t size)
|
||||
{
|
||||
return _pool.get();
|
||||
}
|
||||
|
||||
|
||||
void HTTPOutputStream::operator delete(void* ptr)
|
||||
{
|
||||
_pool.release(ptr);
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
126
Net/src/HTTPStreamFactory.cpp
Normal file
126
Net/src/HTTPStreamFactory.cpp
Normal file
@@ -0,0 +1,126 @@
|
||||
//
|
||||
// HTTPStreamFactory.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/HTTPStreamFactory.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: HTTP
|
||||
// Module: HTTPStreamFactory
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/HTTPStreamFactory.h"
|
||||
#include "Net/HTTPClientSession.h"
|
||||
#include "Net/HTTPIOStream.h"
|
||||
#include "Net/HTTPRequest.h"
|
||||
#include "Net/HTTPResponse.h"
|
||||
#include "Net/NetException.h"
|
||||
#include "Foundation/URI.h"
|
||||
#include "Foundation/URIStreamOpener.h"
|
||||
#include "Foundation/UnbufferedStreamBuf.h"
|
||||
|
||||
|
||||
using Foundation::URIStreamFactory;
|
||||
using Foundation::URI;
|
||||
using Foundation::URIStreamOpener;
|
||||
using Foundation::UnbufferedStreamBuf;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
HTTPStreamFactory::HTTPStreamFactory():
|
||||
_proxyPort(HTTPSession::HTTP_PORT)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPStreamFactory::HTTPStreamFactory(const std::string& proxyHost, Foundation::UInt16 proxyPort):
|
||||
_proxyHost(proxyHost),
|
||||
_proxyPort(proxyPort)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPStreamFactory::~HTTPStreamFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
std::istream* HTTPStreamFactory::open(const URI& uri)
|
||||
{
|
||||
poco_assert (uri.getScheme() == "http");
|
||||
|
||||
URI resolvedURI(uri);
|
||||
HTTPClientSession* pSession = 0;
|
||||
try
|
||||
{
|
||||
int redirects = 0;
|
||||
do
|
||||
{
|
||||
pSession = new HTTPClientSession(resolvedURI.getHost(), resolvedURI.getPort());
|
||||
pSession->setProxy(_proxyHost, _proxyPort);
|
||||
std::string path = resolvedURI.getPathAndQuery();
|
||||
if (path.empty()) path = "/";
|
||||
HTTPRequest req(HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1);
|
||||
pSession->sendRequest(req);
|
||||
HTTPResponse res;
|
||||
std::istream& rs = pSession->receiveResponse(res);
|
||||
bool moved = (res.getStatus() == HTTPResponse::HTTP_MOVED_PERMANENTLY ||
|
||||
res.getStatus() == HTTPResponse::HTTP_FOUND ||
|
||||
res.getStatus() == HTTPResponse::HTTP_SEE_OTHER);
|
||||
if (moved)
|
||||
{
|
||||
resolvedURI.resolve(res.get("Location"));
|
||||
delete pSession;
|
||||
++redirects;
|
||||
}
|
||||
else if (res.getStatus() == HTTPResponse::HTTP_OK)
|
||||
{
|
||||
return new HTTPResponseStream(rs, pSession);
|
||||
}
|
||||
else throw HTTPException(res.getReason(), uri.toString());
|
||||
}
|
||||
while (redirects < MAX_REDIRECTS);
|
||||
throw HTTPException("Too many redirects", uri.toString());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
delete pSession;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HTTPStreamFactory::registerFactory()
|
||||
{
|
||||
URIStreamOpener::defaultOpener().registerStreamFactory("http", new HTTPStreamFactory);
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
129
Net/src/HostEntry.cpp
Normal file
129
Net/src/HostEntry.cpp
Normal file
@@ -0,0 +1,129 @@
|
||||
//
|
||||
// HostEntry.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/HostEntry.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: NetCore
|
||||
// Module: HostEntry
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/HostEntry.h"
|
||||
#include "Foundation/Exception.h"
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
HostEntry::HostEntry()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HostEntry::HostEntry(struct hostent* entry)
|
||||
{
|
||||
poco_check_ptr (entry);
|
||||
|
||||
_name = entry->h_name;
|
||||
char** alias = entry->h_aliases;
|
||||
if (alias)
|
||||
{
|
||||
while (*alias)
|
||||
{
|
||||
_aliases.push_back(std::string(*alias));
|
||||
++alias;
|
||||
}
|
||||
}
|
||||
char** address = entry->h_addr_list;
|
||||
if (address)
|
||||
{
|
||||
while (*address)
|
||||
{
|
||||
_addresses.push_back(IPAddress(*address, entry->h_length));
|
||||
++address;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if defined(_WIN32) && defined(POCO_HAVE_IPv6)
|
||||
|
||||
|
||||
HostEntry::HostEntry(struct addrinfo* ainfo)
|
||||
{
|
||||
poco_check_ptr (ainfo);
|
||||
|
||||
for (struct addrinfo* ai = ainfo; ai; ai = ai->ai_next)
|
||||
{
|
||||
if (ai->ai_canonname)
|
||||
_name.assign(ai->ai_canonname);
|
||||
else if (ai->ai_addrlen && ai->ai_addr)
|
||||
_addresses.push_back(IPAddress(ai->ai_addr, (poco_socklen_t) ai->ai_addrlen));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
HostEntry::HostEntry(const HostEntry& entry):
|
||||
_name(entry._name),
|
||||
_aliases(entry._aliases),
|
||||
_addresses(entry._addresses)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HostEntry& HostEntry::operator = (const HostEntry& entry)
|
||||
{
|
||||
if (&entry != this)
|
||||
{
|
||||
_name = entry._name;
|
||||
_aliases = entry._aliases;
|
||||
_addresses = entry._addresses;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void HostEntry::swap(HostEntry& hostEntry)
|
||||
{
|
||||
std::swap(_name, hostEntry._name);
|
||||
std::swap(_aliases, hostEntry._aliases);
|
||||
std::swap(_addresses, hostEntry._addresses);
|
||||
}
|
||||
|
||||
|
||||
HostEntry::~HostEntry()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
744
Net/src/IPAddress.cpp
Normal file
744
Net/src/IPAddress.cpp
Normal file
@@ -0,0 +1,744 @@
|
||||
//
|
||||
// IPAddress.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/IPAddress.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: NetCore
|
||||
// Module: IPAddress
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/IPAddress.h"
|
||||
#include "Net/NetException.h"
|
||||
#include "Foundation/RefCountedObject.h"
|
||||
#include "Foundation/NumberFormatter.h"
|
||||
#include "Foundation/Types.h"
|
||||
#include <algorithm>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
using Foundation::RefCountedObject;
|
||||
using Foundation::NumberFormatter;
|
||||
using Foundation::UInt8;
|
||||
using Foundation::UInt16;
|
||||
using Foundation::UInt32;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
//
|
||||
// IPAddressImpl
|
||||
//
|
||||
|
||||
|
||||
class IPAddressImpl: public RefCountedObject
|
||||
{
|
||||
public:
|
||||
virtual std::string toString() const = 0;
|
||||
virtual poco_socklen_t length() const = 0;
|
||||
virtual const void* addr() const = 0;
|
||||
virtual IPAddress::Family family() const = 0;
|
||||
virtual int af() const = 0;
|
||||
virtual bool isWildcard() const = 0;
|
||||
virtual bool isBroadcast() const = 0;
|
||||
virtual bool isLoopback() const = 0;
|
||||
virtual bool isMulticast() const = 0;
|
||||
virtual bool isLinkLocal() const = 0;
|
||||
virtual bool isSiteLocal() const = 0;
|
||||
virtual bool isIPv4Mapped() const = 0;
|
||||
virtual bool isIPv4Compatible() const = 0;
|
||||
virtual bool isWellKnownMC() const = 0;
|
||||
virtual bool isNodeLocalMC() const = 0;
|
||||
virtual bool isLinkLocalMC() const = 0;
|
||||
virtual bool isSiteLocalMC() const = 0;
|
||||
virtual bool isOrgLocalMC() const = 0;
|
||||
virtual bool isGlobalMC() const = 0;
|
||||
|
||||
protected:
|
||||
IPAddressImpl()
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~IPAddressImpl()
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
IPAddressImpl(const IPAddressImpl&);
|
||||
IPAddressImpl& operator = (const IPAddressImpl&);
|
||||
};
|
||||
|
||||
|
||||
class IPv4AddressImpl: public IPAddressImpl
|
||||
{
|
||||
public:
|
||||
IPv4AddressImpl()
|
||||
{
|
||||
memset(&_addr, 0, sizeof(_addr));
|
||||
}
|
||||
|
||||
IPv4AddressImpl(const void* addr)
|
||||
{
|
||||
memcpy(&_addr, addr, sizeof(_addr));
|
||||
}
|
||||
|
||||
std::string toString() const
|
||||
{
|
||||
const UInt8* bytes = reinterpret_cast<const UInt8*>(&_addr);
|
||||
std::string result;
|
||||
result.reserve(16);
|
||||
result.append(NumberFormatter::format(bytes[0]));
|
||||
result.append(".");
|
||||
result.append(NumberFormatter::format(bytes[1]));
|
||||
result.append(".");
|
||||
result.append(NumberFormatter::format(bytes[2]));
|
||||
result.append(".");
|
||||
result.append(NumberFormatter::format(bytes[3]));
|
||||
return result;
|
||||
}
|
||||
|
||||
poco_socklen_t length() const
|
||||
{
|
||||
return sizeof(_addr);
|
||||
}
|
||||
|
||||
const void* addr() const
|
||||
{
|
||||
return &_addr;
|
||||
}
|
||||
|
||||
IPAddress::Family family() const
|
||||
{
|
||||
return IPAddress::IPv4;
|
||||
}
|
||||
|
||||
int af() const
|
||||
{
|
||||
return AF_INET;
|
||||
}
|
||||
|
||||
bool isWildcard() const
|
||||
{
|
||||
return _addr.s_addr == INADDR_ANY;
|
||||
}
|
||||
|
||||
bool isBroadcast() const
|
||||
{
|
||||
return _addr.s_addr == INADDR_NONE;
|
||||
}
|
||||
|
||||
bool isLoopback() const
|
||||
{
|
||||
return ntohl(_addr.s_addr) == 0x7F000001; // 127.0.0.1
|
||||
}
|
||||
|
||||
bool isMulticast() const
|
||||
{
|
||||
return (ntohl(_addr.s_addr) & 0xF0000000) == 0xE0000000; // 224.0.0.0/24 to 239.0.0.0/24
|
||||
}
|
||||
|
||||
bool isLinkLocal() const
|
||||
{
|
||||
return (ntohl(_addr.s_addr) & 0xFFFF0000) == 0xA9FE0000; // 169.254.0.0/16
|
||||
}
|
||||
|
||||
bool isSiteLocal() const
|
||||
{
|
||||
UInt32 addr = ntohl(_addr.s_addr);
|
||||
return (addr & 0xFF000000) == 0x0A000000 || // 10.0.0.0/24
|
||||
(addr & 0xFFFF0000) == 0xC0A80000 || // 192.68.0.0/16
|
||||
addr >= 0xAC100000 && addr <= 0xAC1FFFFF; // 172.16.0.0 to 172.31.255.255
|
||||
}
|
||||
|
||||
bool isIPv4Compatible() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isIPv4Mapped() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isWellKnownMC() const
|
||||
{
|
||||
return (ntohl(_addr.s_addr) & 0xFFFFFF00) == 0xE0000000; // 224.0.0.0/8
|
||||
}
|
||||
|
||||
bool isNodeLocalMC() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isLinkLocalMC() const
|
||||
{
|
||||
return (ntohl(_addr.s_addr) & 0xFF000000) == 0xE0000000; // 244.0.0.0/24
|
||||
}
|
||||
|
||||
bool isSiteLocalMC() const
|
||||
{
|
||||
return (ntohl(_addr.s_addr) & 0xFFFF0000) == 0xEFFF0000; // 239.255.0.0/16
|
||||
}
|
||||
|
||||
bool isOrgLocalMC() const
|
||||
{
|
||||
return (ntohl(_addr.s_addr) & 0xFFFF0000) == 0xEFC00000; // 239.192.0.0/16
|
||||
}
|
||||
|
||||
bool isGlobalMC() const
|
||||
{
|
||||
UInt32 addr = ntohl(_addr.s_addr);
|
||||
return addr >= 0xE0000100 && addr <= 0xEE000000; // 224.0.1.0 to 238.255.255.255
|
||||
}
|
||||
|
||||
static IPv4AddressImpl* parse(const std::string& addr)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
struct in_addr ia;
|
||||
ia.s_addr = inet_addr(addr.c_str());
|
||||
if (ia.s_addr == INADDR_NONE && addr != "255.255.255.255")
|
||||
return 0;
|
||||
else
|
||||
return new IPv4AddressImpl(&ia);
|
||||
#else
|
||||
struct in_addr ia;
|
||||
if (inet_aton(addr.c_str(), &ia))
|
||||
return new IPv4AddressImpl(&ia);
|
||||
else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
struct in_addr _addr;
|
||||
};
|
||||
|
||||
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
|
||||
|
||||
class IPv6AddressImpl: public IPAddressImpl
|
||||
{
|
||||
public:
|
||||
IPv6AddressImpl()
|
||||
{
|
||||
memset(&_addr, 0, sizeof(_addr));
|
||||
}
|
||||
|
||||
IPv6AddressImpl(const void* addr)
|
||||
{
|
||||
memcpy(&_addr, addr, sizeof(_addr));
|
||||
}
|
||||
|
||||
std::string toString() const
|
||||
{
|
||||
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
|
||||
if (isIPv4Compatible() || isIPv4Mapped())
|
||||
{
|
||||
std::string result;
|
||||
result.reserve(24);
|
||||
if (words[5] == 0)
|
||||
result.append("::");
|
||||
else
|
||||
result.append("::FFFF:");
|
||||
const UInt8* bytes = reinterpret_cast<const UInt8*>(&_addr);
|
||||
result.append(NumberFormatter::format(bytes[12]));
|
||||
result.append(".");
|
||||
result.append(NumberFormatter::format(bytes[13]));
|
||||
result.append(".");
|
||||
result.append(NumberFormatter::format(bytes[14]));
|
||||
result.append(".");
|
||||
result.append(NumberFormatter::format(bytes[15]));
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string result;
|
||||
result.reserve(46);
|
||||
bool zeroSequence = false;
|
||||
int i = 0;
|
||||
while (i < 8)
|
||||
{
|
||||
if (!zeroSequence && words[i] == 0)
|
||||
{
|
||||
int zi = i;
|
||||
while (zi < 8 && words[zi] == 0) ++zi;
|
||||
if (zi > i + 1)
|
||||
{
|
||||
i = zi;
|
||||
result.append(":");
|
||||
zeroSequence = true;
|
||||
}
|
||||
}
|
||||
if (i > 0) result.append(":");
|
||||
if (i < 8) result.append(NumberFormatter::formatHex(words[i++]));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
poco_socklen_t length() const
|
||||
{
|
||||
return sizeof(_addr);
|
||||
}
|
||||
|
||||
const void* addr() const
|
||||
{
|
||||
return &_addr;
|
||||
}
|
||||
|
||||
IPAddress::Family family() const
|
||||
{
|
||||
return IPAddress::IPv6;
|
||||
}
|
||||
|
||||
int af() const
|
||||
{
|
||||
return AF_INET6;
|
||||
}
|
||||
|
||||
bool isWildcard() const
|
||||
{
|
||||
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
|
||||
return words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 &&
|
||||
words[4] == 0 && words[5] == 0 && words[6] == 0 && words[7] == 0;
|
||||
}
|
||||
|
||||
bool isBroadcast() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isLoopback() const
|
||||
{
|
||||
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
|
||||
return words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 &&
|
||||
words[4] == 0 && words[5] == 0 && words[6] == 0 && words[7] == 1;
|
||||
}
|
||||
|
||||
bool isMulticast() const
|
||||
{
|
||||
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
|
||||
return (words[0] & 0xFFE0) == 0xFF00;
|
||||
}
|
||||
|
||||
bool isLinkLocal() const
|
||||
{
|
||||
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
|
||||
return (words[0] & 0xFFE0) == 0xFE80;
|
||||
}
|
||||
|
||||
bool isSiteLocal() const
|
||||
{
|
||||
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
|
||||
return (words[0] & 0xFFE0) == 0xFEC0;
|
||||
}
|
||||
|
||||
bool isIPv4Compatible() const
|
||||
{
|
||||
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
|
||||
return words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 && words[4] == 0 && words[5] == 0;
|
||||
}
|
||||
|
||||
bool isIPv4Mapped() const
|
||||
{
|
||||
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
|
||||
return words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 && words[4] == 0 && words[5] == 0xFFFF;
|
||||
}
|
||||
|
||||
bool isWellKnownMC() const
|
||||
{
|
||||
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
|
||||
return (words[0] & 0xFFF0) == 0xFF00;
|
||||
}
|
||||
|
||||
bool isNodeLocalMC() const
|
||||
{
|
||||
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
|
||||
return (words[0] & 0xFFEF) == 0xFF01;
|
||||
}
|
||||
|
||||
bool isLinkLocalMC() const
|
||||
{
|
||||
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
|
||||
return (words[0] & 0xFFEF) == 0xFF02;
|
||||
}
|
||||
|
||||
bool isSiteLocalMC() const
|
||||
{
|
||||
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
|
||||
return (words[0] & 0xFFEF) == 0xFF05;
|
||||
}
|
||||
|
||||
bool isOrgLocalMC() const
|
||||
{
|
||||
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
|
||||
return (words[0] & 0xFFEF) == 0xFF08;
|
||||
}
|
||||
|
||||
bool isGlobalMC() const
|
||||
{
|
||||
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
|
||||
return (words[0] & 0xFFEF) == 0xFF0F;
|
||||
}
|
||||
|
||||
static IPv6AddressImpl* parse(const std::string& addr)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
struct addrinfo* pAI;
|
||||
struct addrinfo hints;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
int rc = getaddrinfo(addr.c_str(), NULL, &hints, &pAI);
|
||||
if (rc == 0)
|
||||
{
|
||||
IPv6AddressImpl* pResult = new IPv6AddressImpl(&reinterpret_cast<struct sockaddr_in6*>(pAI->ai_addr)->sin6_addr);
|
||||
freeaddrinfo(pAI);
|
||||
return pResult;
|
||||
}
|
||||
else return 0;
|
||||
#else
|
||||
struct in6_addr ia;
|
||||
if (inet_pton(AF_INET6, addr.c_str(), &ia) == 1)
|
||||
return new IPv6AddressImpl(&ia);
|
||||
else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
struct in6_addr _addr;
|
||||
};
|
||||
|
||||
|
||||
#endif // POCO_HAVE_IPv6
|
||||
|
||||
|
||||
//
|
||||
// IPAddress
|
||||
//
|
||||
|
||||
|
||||
IPAddress::IPAddress(): _pImpl(new IPv4AddressImpl)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
IPAddress::IPAddress(const IPAddress& addr): _pImpl(addr._pImpl)
|
||||
{
|
||||
_pImpl->duplicate();
|
||||
}
|
||||
|
||||
|
||||
IPAddress::IPAddress(Family family): _pImpl(0)
|
||||
{
|
||||
if (family == IPv4)
|
||||
_pImpl = new IPv4AddressImpl();
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
else if (family == IPv6)
|
||||
_pImpl = new IPv6AddressImpl();
|
||||
#endif
|
||||
else Foundation::InvalidArgumentException("Invalid or unsupported address family passed to IPAddress()");
|
||||
}
|
||||
|
||||
|
||||
IPAddress::IPAddress(const std::string& addr)
|
||||
{
|
||||
_pImpl = IPv4AddressImpl::parse(addr);
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
if (!_pImpl)
|
||||
_pImpl = IPv6AddressImpl::parse(addr);
|
||||
#endif
|
||||
if (!_pImpl) throw InvalidAddressException(addr);
|
||||
}
|
||||
|
||||
|
||||
IPAddress::IPAddress(const std::string& addr, Family family): _pImpl(0)
|
||||
{
|
||||
if (family == IPv4)
|
||||
_pImpl = IPv4AddressImpl::parse(addr);
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
else if (family == IPv6)
|
||||
_pImpl = IPv6AddressImpl::parse(addr);
|
||||
#endif
|
||||
else throw Foundation::InvalidArgumentException("Invalid or unsupported address family passed to IPAddress()");
|
||||
}
|
||||
|
||||
|
||||
IPAddress::IPAddress(const void* addr, poco_socklen_t length)
|
||||
{
|
||||
if (length == sizeof(struct in_addr))
|
||||
_pImpl = new IPv4AddressImpl(addr);
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
else if (length == sizeof(struct in6_addr))
|
||||
_pImpl = new IPv6AddressImpl(addr);
|
||||
#endif
|
||||
else throw Foundation::InvalidArgumentException("Invalid address length passed to IPAddress()");
|
||||
}
|
||||
|
||||
|
||||
IPAddress::~IPAddress()
|
||||
{
|
||||
_pImpl->release();
|
||||
}
|
||||
|
||||
|
||||
IPAddress& IPAddress::operator = (const IPAddress& addr)
|
||||
{
|
||||
if (&addr != this)
|
||||
{
|
||||
_pImpl->release();
|
||||
_pImpl = addr._pImpl;
|
||||
_pImpl->duplicate();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void IPAddress::swap(IPAddress& address)
|
||||
{
|
||||
std::swap(_pImpl, address._pImpl);
|
||||
}
|
||||
|
||||
|
||||
IPAddress::Family IPAddress::family() const
|
||||
{
|
||||
return _pImpl->family();
|
||||
}
|
||||
|
||||
|
||||
std::string IPAddress::toString() const
|
||||
{
|
||||
return _pImpl->toString();
|
||||
}
|
||||
|
||||
|
||||
bool IPAddress::isWildcard() const
|
||||
{
|
||||
return _pImpl->isWildcard();
|
||||
}
|
||||
|
||||
bool IPAddress::isBroadcast() const
|
||||
{
|
||||
return _pImpl->isBroadcast();
|
||||
}
|
||||
|
||||
|
||||
bool IPAddress::isLoopback() const
|
||||
{
|
||||
return _pImpl->isLoopback();
|
||||
}
|
||||
|
||||
|
||||
bool IPAddress::isMulticast() const
|
||||
{
|
||||
return _pImpl->isMulticast();
|
||||
}
|
||||
|
||||
|
||||
bool IPAddress::isUnicast() const
|
||||
{
|
||||
return !isWildcard() && !isBroadcast() && !isMulticast();
|
||||
}
|
||||
|
||||
|
||||
bool IPAddress::isLinkLocal() const
|
||||
{
|
||||
return _pImpl->isLinkLocal();
|
||||
}
|
||||
|
||||
|
||||
bool IPAddress::isSiteLocal() const
|
||||
{
|
||||
return _pImpl->isSiteLocal();
|
||||
}
|
||||
|
||||
|
||||
bool IPAddress::isIPv4Compatible() const
|
||||
{
|
||||
return _pImpl->isIPv4Compatible();
|
||||
}
|
||||
|
||||
|
||||
bool IPAddress::isIPv4Mapped() const
|
||||
{
|
||||
return _pImpl->isIPv4Mapped();
|
||||
}
|
||||
|
||||
|
||||
bool IPAddress::isWellKnownMC() const
|
||||
{
|
||||
return _pImpl->isWellKnownMC();
|
||||
}
|
||||
|
||||
|
||||
bool IPAddress::isNodeLocalMC() const
|
||||
{
|
||||
return _pImpl->isNodeLocalMC();
|
||||
}
|
||||
|
||||
|
||||
bool IPAddress::isLinkLocalMC() const
|
||||
{
|
||||
return _pImpl->isLinkLocalMC();
|
||||
}
|
||||
|
||||
|
||||
bool IPAddress::isSiteLocalMC() const
|
||||
{
|
||||
return _pImpl->isSiteLocalMC();
|
||||
}
|
||||
|
||||
|
||||
bool IPAddress::isOrgLocalMC() const
|
||||
{
|
||||
return _pImpl->isOrgLocalMC();
|
||||
}
|
||||
|
||||
|
||||
bool IPAddress::isGlobalMC() const
|
||||
{
|
||||
return _pImpl->isGlobalMC();
|
||||
}
|
||||
|
||||
|
||||
bool IPAddress::operator == (const IPAddress& a) const
|
||||
{
|
||||
poco_socklen_t l1 = length();
|
||||
poco_socklen_t l2 = a.length();
|
||||
if (l1 == l2)
|
||||
return memcmp(addr(), a.addr(), l1) == 0;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool IPAddress::operator != (const IPAddress& a) const
|
||||
{
|
||||
poco_socklen_t l1 = length();
|
||||
poco_socklen_t l2 = a.length();
|
||||
if (l1 == l2)
|
||||
return memcmp(addr(), a.addr(), l1) != 0;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool IPAddress::operator < (const IPAddress& a) const
|
||||
{
|
||||
poco_socklen_t l1 = length();
|
||||
poco_socklen_t l2 = a.length();
|
||||
if (l1 == l2)
|
||||
return memcmp(addr(), a.addr(), l1) < 0;
|
||||
else
|
||||
return l1 < l2;
|
||||
}
|
||||
|
||||
|
||||
bool IPAddress::operator <= (const IPAddress& a) const
|
||||
{
|
||||
poco_socklen_t l1 = length();
|
||||
poco_socklen_t l2 = a.length();
|
||||
if (l1 == l2)
|
||||
return memcmp(addr(), a.addr(), l1) <= 0;
|
||||
else
|
||||
return l1 < l2;
|
||||
}
|
||||
|
||||
|
||||
bool IPAddress::operator > (const IPAddress& a) const
|
||||
{
|
||||
poco_socklen_t l1 = length();
|
||||
poco_socklen_t l2 = a.length();
|
||||
if (l1 == l2)
|
||||
return memcmp(addr(), a.addr(), l1) > 0;
|
||||
else
|
||||
return l1 > l2;
|
||||
}
|
||||
|
||||
|
||||
bool IPAddress::operator >= (const IPAddress& a) const
|
||||
{
|
||||
poco_socklen_t l1 = length();
|
||||
poco_socklen_t l2 = a.length();
|
||||
if (l1 == l2)
|
||||
return memcmp(addr(), a.addr(), l1) >= 0;
|
||||
else
|
||||
return l1 > l2;
|
||||
}
|
||||
|
||||
|
||||
poco_socklen_t IPAddress::length() const
|
||||
{
|
||||
return _pImpl->length();
|
||||
}
|
||||
|
||||
|
||||
const void* IPAddress::addr() const
|
||||
{
|
||||
return _pImpl->addr();
|
||||
}
|
||||
|
||||
|
||||
int IPAddress::af() const
|
||||
{
|
||||
return _pImpl->af();
|
||||
}
|
||||
|
||||
|
||||
void IPAddress::init(IPAddressImpl* pImpl)
|
||||
{
|
||||
_pImpl->release();
|
||||
_pImpl = pImpl;
|
||||
}
|
||||
|
||||
|
||||
IPAddress IPAddress::parse(const std::string& addr)
|
||||
{
|
||||
return IPAddress(addr);
|
||||
}
|
||||
|
||||
|
||||
bool IPAddress::tryParse(const std::string& addr, IPAddress& result)
|
||||
{
|
||||
IPAddressImpl* pImpl = IPv4AddressImpl::parse(addr);
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
if (!pImpl) pImpl = IPv6AddressImpl::parse(addr);
|
||||
#endif
|
||||
if (pImpl)
|
||||
{
|
||||
result.init(pImpl);
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
492
Net/src/MailMessage.cpp
Normal file
492
Net/src/MailMessage.cpp
Normal file
@@ -0,0 +1,492 @@
|
||||
//
|
||||
// MailMessage.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/MailMessage.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Mail
|
||||
// Module: MailMessage
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/MailMessage.h"
|
||||
#include "Net/MediaType.h"
|
||||
#include "Net/MultipartReader.h"
|
||||
#include "Net/MultipartWriter.h"
|
||||
#include "Net/PartSource.h"
|
||||
#include "Net/PartHandler.h"
|
||||
#include "Net/QuotedPrintableEncoder.h"
|
||||
#include "Net/QuotedPrintableDecoder.h"
|
||||
#include "Foundation/Base64Encoder.h"
|
||||
#include "Foundation/Base64Decoder.h"
|
||||
#include "Foundation/StreamCopier.h"
|
||||
#include "Foundation/DateTimeFormat.h"
|
||||
#include "Foundation/DateTimeFormatter.h"
|
||||
#include "Foundation/DateTimeParser.h"
|
||||
#include "Foundation/String.h"
|
||||
#include <sstream>
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
using Foundation::Base64Encoder;
|
||||
using Foundation::Base64Decoder;
|
||||
using Foundation::StreamCopier;
|
||||
using Foundation::DateTimeFormat;
|
||||
using Foundation::DateTimeFormatter;
|
||||
using Foundation::DateTimeParser;
|
||||
using Foundation::icompare;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
class StringPartHandler: public PartHandler
|
||||
{
|
||||
public:
|
||||
StringPartHandler(std::string& content):
|
||||
_str(content)
|
||||
{
|
||||
}
|
||||
|
||||
~StringPartHandler()
|
||||
{
|
||||
}
|
||||
|
||||
void handlePart(const MessageHeader& header, std::istream& stream)
|
||||
{
|
||||
int ch = stream.get();
|
||||
while (ch >= 0)
|
||||
{
|
||||
_str += (char) ch;
|
||||
ch = stream.get();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::string& _str;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
const std::string MailMessage::HEADER_SUBJECT("Subject");
|
||||
const std::string MailMessage::HEADER_FROM("From");
|
||||
const std::string MailMessage::HEADER_TO("To");
|
||||
const std::string MailMessage::HEADER_CC("CC");
|
||||
const std::string MailMessage::HEADER_BCC("BCC");
|
||||
const std::string MailMessage::HEADER_DATE("Date");
|
||||
const std::string MailMessage::HEADER_CONTENT_TYPE("Content-Type");
|
||||
const std::string MailMessage::HEADER_CONTENT_TRANSFER_ENCODING("Content-Transfer-Encoding");
|
||||
const std::string MailMessage::HEADER_CONTENT_DISPOSITION("Content-Disposition");
|
||||
const std::string MailMessage::HEADER_MIME_VERSION("Mime-Version");
|
||||
const std::string MailMessage::EMPTY_HEADER;
|
||||
const std::string MailMessage::TEXT_PLAIN("text/plain");
|
||||
const std::string MailMessage::CTE_7BIT("7bit");
|
||||
const std::string MailMessage::CTE_8BIT("8bit");
|
||||
const std::string MailMessage::CTE_QUOTED_PRINTABLE("quoted-printable");
|
||||
const std::string MailMessage::CTE_BASE64("base64");
|
||||
|
||||
|
||||
MailMessage::MailMessage()
|
||||
{
|
||||
Foundation::Timestamp now;
|
||||
setDate(now);
|
||||
setContentType("text/plain");
|
||||
}
|
||||
|
||||
|
||||
MailMessage::~MailMessage()
|
||||
{
|
||||
for (PartVec::iterator it = _parts.begin(); it != _parts.end(); ++it)
|
||||
{
|
||||
delete it->pSource;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MailMessage::addRecipient(const MailRecipient& recipient)
|
||||
{
|
||||
_recipients.push_back(recipient);
|
||||
}
|
||||
|
||||
|
||||
void MailMessage::setSender(const std::string& sender)
|
||||
{
|
||||
set(HEADER_FROM, sender);
|
||||
}
|
||||
|
||||
|
||||
const std::string& MailMessage::getSender() const
|
||||
{
|
||||
if (has(HEADER_FROM))
|
||||
return get(HEADER_FROM);
|
||||
else
|
||||
return EMPTY_HEADER;
|
||||
}
|
||||
|
||||
|
||||
void MailMessage::setSubject(const std::string& subject)
|
||||
{
|
||||
set(HEADER_SUBJECT, subject);
|
||||
}
|
||||
|
||||
|
||||
const std::string& MailMessage::getSubject() const
|
||||
{
|
||||
if (has(HEADER_SUBJECT))
|
||||
return get(HEADER_SUBJECT);
|
||||
else
|
||||
return EMPTY_HEADER;
|
||||
}
|
||||
|
||||
|
||||
void MailMessage::setContent(const std::string& content, ContentTransferEncoding encoding)
|
||||
{
|
||||
_content = content;
|
||||
_encoding = encoding;
|
||||
set(HEADER_CONTENT_TRANSFER_ENCODING, contentTransferEncodingToString(encoding));
|
||||
}
|
||||
|
||||
|
||||
void MailMessage::setContentType(const std::string& mediaType)
|
||||
{
|
||||
set(HEADER_CONTENT_TYPE, mediaType);
|
||||
}
|
||||
|
||||
|
||||
void MailMessage::setContentType(const MediaType& mediaType)
|
||||
{
|
||||
setContentType(mediaType.toString());
|
||||
}
|
||||
|
||||
|
||||
const std::string& MailMessage::getContentType() const
|
||||
{
|
||||
if (has(HEADER_CONTENT_TYPE))
|
||||
return get(HEADER_CONTENT_TYPE);
|
||||
else
|
||||
return TEXT_PLAIN;
|
||||
}
|
||||
|
||||
|
||||
void MailMessage::setDate(const Foundation::Timestamp& dateTime)
|
||||
{
|
||||
set(HEADER_DATE, DateTimeFormatter::format(dateTime, DateTimeFormat::RFC1123_FORMAT));
|
||||
}
|
||||
|
||||
|
||||
Foundation::Timestamp MailMessage::getDate() const
|
||||
{
|
||||
const std::string& dateTime = get(HEADER_DATE);
|
||||
int tzd;
|
||||
return DateTimeParser::parse(dateTime, tzd).timestamp();
|
||||
}
|
||||
|
||||
|
||||
bool MailMessage::isMultipart() const
|
||||
{
|
||||
MediaType mediaType = getContentType();
|
||||
return mediaType.matches("multipart");
|
||||
}
|
||||
|
||||
|
||||
void MailMessage::addPart(const std::string& name, PartSource* pSource, ContentDisposition disposition, ContentTransferEncoding encoding)
|
||||
{
|
||||
poco_check_ptr (pSource);
|
||||
|
||||
makeMultipart();
|
||||
Part part;
|
||||
part.name = name;
|
||||
part.pSource = pSource;
|
||||
part.disposition = disposition;
|
||||
part.encoding = encoding;
|
||||
_parts.push_back(part);
|
||||
}
|
||||
|
||||
|
||||
void MailMessage::addContent(PartSource* pSource, ContentTransferEncoding encoding)
|
||||
{
|
||||
addPart("", pSource, CONTENT_INLINE, encoding);
|
||||
}
|
||||
|
||||
|
||||
void MailMessage::addAttachment(const std::string& name, PartSource* pSource, ContentTransferEncoding encoding)
|
||||
{
|
||||
addPart(name, pSource, CONTENT_ATTACHMENT, encoding);
|
||||
}
|
||||
|
||||
|
||||
void MailMessage::read(std::istream& istr, PartHandler& handler)
|
||||
{
|
||||
readHeader(istr);
|
||||
if (isMultipart())
|
||||
{
|
||||
readMultipart(istr, handler);
|
||||
}
|
||||
else
|
||||
{
|
||||
StringPartHandler handler(_content);
|
||||
readPart(istr, *this, handler);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MailMessage::read(std::istream& istr)
|
||||
{
|
||||
readHeader(istr);
|
||||
StringPartHandler handler(_content);
|
||||
readPart(istr, *this, handler);
|
||||
}
|
||||
|
||||
|
||||
void MailMessage::write(std::ostream& ostr) const
|
||||
{
|
||||
MessageHeader header(*this);
|
||||
setRecipientHeaders(header);
|
||||
if (isMultipart())
|
||||
{
|
||||
writeMultipart(header, ostr);
|
||||
}
|
||||
else
|
||||
{
|
||||
writeHeader(header, ostr);
|
||||
std::istringstream istr(_content);
|
||||
writeEncoded(istr, ostr, _encoding);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MailMessage::makeMultipart()
|
||||
{
|
||||
if (!isMultipart())
|
||||
{
|
||||
MediaType mediaType("multipart", "mixed");
|
||||
setContentType(mediaType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MailMessage::writeHeader(const MessageHeader& header, std::ostream& ostr) const
|
||||
{
|
||||
header.write(ostr);
|
||||
ostr << "\r\n";
|
||||
}
|
||||
|
||||
|
||||
void MailMessage::writeMultipart(MessageHeader& header, std::ostream& ostr) const
|
||||
{
|
||||
std::string boundary(MultipartWriter::createBoundary());
|
||||
MediaType mediaType(getContentType());
|
||||
mediaType.setParameter("boundary", boundary);
|
||||
header.set(HEADER_CONTENT_TYPE, mediaType.toString());
|
||||
header.set(HEADER_MIME_VERSION, "1.0");
|
||||
writeHeader(header, ostr);
|
||||
|
||||
MultipartWriter writer(ostr, boundary);
|
||||
for (PartVec::const_iterator it = _parts.begin(); it != _parts.end(); ++it)
|
||||
{
|
||||
writePart(writer, *it);
|
||||
}
|
||||
writer.close();
|
||||
}
|
||||
|
||||
|
||||
void MailMessage::writePart(MultipartWriter& writer, const Part& part) const
|
||||
{
|
||||
MessageHeader partHeader;
|
||||
MediaType mediaType(part.pSource->mediaType());
|
||||
if (!part.name.empty())
|
||||
mediaType.setParameter("name", part.name);
|
||||
partHeader.set(HEADER_CONTENT_TYPE, mediaType.toString());
|
||||
partHeader.set(HEADER_CONTENT_TRANSFER_ENCODING, contentTransferEncodingToString(part.encoding));
|
||||
std::string disposition;
|
||||
if (part.disposition == CONTENT_ATTACHMENT)
|
||||
{
|
||||
disposition = "attachment";
|
||||
const std::string& filename = part.pSource->filename();
|
||||
if (!filename.empty())
|
||||
{
|
||||
disposition.append("; filename=");
|
||||
quote(filename, disposition);
|
||||
}
|
||||
}
|
||||
else disposition = "inline";
|
||||
partHeader.set(HEADER_CONTENT_DISPOSITION, disposition);
|
||||
writer.nextPart(partHeader);
|
||||
writeEncoded(part.pSource->stream(), writer.stream(), part.encoding);
|
||||
}
|
||||
|
||||
|
||||
void MailMessage::writeEncoded(std::istream& istr, std::ostream& ostr, ContentTransferEncoding encoding) const
|
||||
{
|
||||
switch (encoding)
|
||||
{
|
||||
case ENCODING_7BIT:
|
||||
case ENCODING_8BIT:
|
||||
StreamCopier::copyStream(istr, ostr);
|
||||
break;
|
||||
case ENCODING_QUOTED_PRINTABLE:
|
||||
{
|
||||
QuotedPrintableEncoder encoder(ostr);
|
||||
StreamCopier::copyStream(istr, encoder);
|
||||
}
|
||||
break;
|
||||
case ENCODING_BASE64:
|
||||
{
|
||||
Base64Encoder encoder(ostr);
|
||||
StreamCopier::copyStream(istr, encoder);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MailMessage::readHeader(std::istream& istr)
|
||||
{
|
||||
clear();
|
||||
MessageHeader::read(istr);
|
||||
istr.get(); // \r
|
||||
istr.get(); // \n
|
||||
}
|
||||
|
||||
|
||||
void MailMessage::readMultipart(std::istream& istr, PartHandler& handler)
|
||||
{
|
||||
MediaType contentType(getContentType());
|
||||
std::string boundary = contentType.getParameter("boundary");
|
||||
MultipartReader reader(istr, boundary);
|
||||
while (reader.hasNextPart())
|
||||
{
|
||||
MessageHeader partHeader;
|
||||
reader.nextPart(partHeader);
|
||||
readPart(reader.stream(), partHeader, handler);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MailMessage::readPart(std::istream& istr, const MessageHeader& header, PartHandler& handler)
|
||||
{
|
||||
std::string encoding;
|
||||
if (header.has(HEADER_CONTENT_TRANSFER_ENCODING))
|
||||
{
|
||||
encoding = header.get(HEADER_CONTENT_TRANSFER_ENCODING);
|
||||
// get rid of a parameter if one is set
|
||||
std::string::size_type pos = encoding.find(';');
|
||||
if (pos != std::string::npos)
|
||||
encoding.resize(pos);
|
||||
}
|
||||
if (icompare(encoding, CTE_QUOTED_PRINTABLE) == 0)
|
||||
{
|
||||
QuotedPrintableDecoder decoder(istr);
|
||||
handler.handlePart(header, decoder);
|
||||
}
|
||||
else if (icompare(encoding, CTE_BASE64) == 0)
|
||||
{
|
||||
Base64Decoder decoder(istr);
|
||||
handler.handlePart(header, decoder);
|
||||
}
|
||||
else
|
||||
{
|
||||
handler.handlePart(header, istr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MailMessage::setRecipientHeaders(MessageHeader& headers) const
|
||||
{
|
||||
std::string to;
|
||||
std::string cc;
|
||||
std::string bcc;
|
||||
|
||||
for (Recipients::const_iterator it = _recipients.begin(); it != _recipients.end(); ++it)
|
||||
{
|
||||
switch (it->getType())
|
||||
{
|
||||
case MailRecipient::PRIMARY_RECIPIENT:
|
||||
appendRecipient(*it, to);
|
||||
break;
|
||||
case MailRecipient::CC_RECIPIENT:
|
||||
appendRecipient(*it, cc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!to.empty()) headers.set(HEADER_TO, to);
|
||||
if (!cc.empty()) headers.set(HEADER_CC, cc);
|
||||
}
|
||||
|
||||
|
||||
const std::string& MailMessage::contentTransferEncodingToString(ContentTransferEncoding encoding)
|
||||
{
|
||||
switch (encoding)
|
||||
{
|
||||
case ENCODING_7BIT:
|
||||
return CTE_8BIT;
|
||||
case ENCODING_8BIT:
|
||||
return CTE_8BIT;
|
||||
case ENCODING_QUOTED_PRINTABLE:
|
||||
return CTE_QUOTED_PRINTABLE;
|
||||
case ENCODING_BASE64:
|
||||
return CTE_BASE64;
|
||||
default:
|
||||
poco_bugcheck();
|
||||
}
|
||||
return CTE_7BIT;
|
||||
}
|
||||
|
||||
|
||||
int MailMessage::lineLength(const std::string& str)
|
||||
{
|
||||
int n = 0;
|
||||
std::string::const_reverse_iterator it = str.rbegin();
|
||||
std::string::const_reverse_iterator end = str.rend();
|
||||
while (it != end && *it != '\n') { ++n; ++it; }
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
void MailMessage::appendRecipient(const MailRecipient& recipient, std::string& str)
|
||||
{
|
||||
if (!str.empty()) str.append(", ");
|
||||
const std::string& realName = recipient.getRealName();
|
||||
const std::string& address = recipient.getAddress();
|
||||
std::string rec;
|
||||
if (!realName.empty())
|
||||
{
|
||||
quote(realName, rec, true);
|
||||
rec.append(" ");
|
||||
}
|
||||
rec.append("<");
|
||||
rec.append(address);
|
||||
rec.append(">");
|
||||
if (lineLength(str) + rec.length() > 70) str.append("\r\n\t");
|
||||
str.append(rec);
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
115
Net/src/MailRecipient.cpp
Normal file
115
Net/src/MailRecipient.cpp
Normal file
@@ -0,0 +1,115 @@
|
||||
//
|
||||
// MailRecipient.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/MailRecipient.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Mail
|
||||
// Module: MailRecipient
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/MailRecipient.h"
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
MailRecipient::MailRecipient():
|
||||
_type(PRIMARY_RECIPIENT)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MailRecipient::MailRecipient(const MailRecipient& recipient):
|
||||
_type(recipient._type),
|
||||
_address(recipient._address),
|
||||
_realName(recipient._realName)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MailRecipient::MailRecipient(RecipientType type, const std::string& address):
|
||||
_type(type),
|
||||
_address(address)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MailRecipient::MailRecipient(RecipientType type, const std::string& address, const std::string& realName):
|
||||
_type(type),
|
||||
_address(address),
|
||||
_realName(realName)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MailRecipient::~MailRecipient()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MailRecipient& MailRecipient::operator = (const MailRecipient& recipient)
|
||||
{
|
||||
if (this != &recipient)
|
||||
{
|
||||
MailRecipient tmp(recipient);
|
||||
swap(tmp);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void MailRecipient::swap(MailRecipient& recipient)
|
||||
{
|
||||
std::swap(_type, recipient._type);
|
||||
std::swap(_address, recipient._address);
|
||||
std::swap(_realName, recipient._realName);
|
||||
}
|
||||
|
||||
|
||||
void MailRecipient::setType(RecipientType type)
|
||||
{
|
||||
_type = type;
|
||||
}
|
||||
|
||||
|
||||
void MailRecipient::setAddress(const std::string& address)
|
||||
{
|
||||
_address = address;
|
||||
}
|
||||
|
||||
|
||||
void MailRecipient::setRealName(const std::string& realName)
|
||||
{
|
||||
_realName = realName;
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
240
Net/src/MailStream.cpp
Normal file
240
Net/src/MailStream.cpp
Normal file
@@ -0,0 +1,240 @@
|
||||
//
|
||||
// MailStream.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/MailStream.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Mail
|
||||
// Module: MailStream
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/MailStream.h"
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
MailStreamBuf::MailStreamBuf(std::istream& istr):
|
||||
_pIstr(&istr),
|
||||
_pOstr(0),
|
||||
_state(ST_CR_LF)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MailStreamBuf::MailStreamBuf(std::ostream& ostr):
|
||||
_pIstr(0),
|
||||
_pOstr(&ostr),
|
||||
_state(ST_CR_LF)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MailStreamBuf::~MailStreamBuf()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void MailStreamBuf::close()
|
||||
{
|
||||
if (_pOstr && _state != ST_CR_LF_DOT_CR_LF)
|
||||
{
|
||||
if (!_buffer.empty())
|
||||
_pOstr->write(_buffer.data(), (std::streamsize) _buffer.length());
|
||||
if (_state != ST_CR_LF)
|
||||
_pOstr->write("\r\n", 2);
|
||||
_pOstr->write(".\r\n", 3);
|
||||
_state = ST_CR_LF_DOT_CR_LF;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int MailStreamBuf::readFromDevice()
|
||||
{
|
||||
int c = std::char_traits<char>::eof();
|
||||
if (!_buffer.empty())
|
||||
{
|
||||
c = _buffer[0];
|
||||
_buffer.erase(0, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
c = readOne();
|
||||
while (c != std::char_traits<char>::eof() && _state != ST_DATA && _state != ST_CR_LF_DOT_CR_LF)
|
||||
c = readOne();
|
||||
if (!_buffer.empty())
|
||||
{
|
||||
c = _buffer[0];
|
||||
_buffer.erase(0, 1);
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
int MailStreamBuf::readOne()
|
||||
{
|
||||
int c = std::char_traits<char>::eof();
|
||||
if (_state != ST_CR_LF_DOT_CR_LF)
|
||||
{
|
||||
c = _pIstr->get();
|
||||
switch (c)
|
||||
{
|
||||
case '\r':
|
||||
if (_state == ST_CR_LF_DOT)
|
||||
_state = ST_CR_LF_DOT_CR;
|
||||
else
|
||||
_state = ST_CR;
|
||||
break;
|
||||
case '\n':
|
||||
if (_state == ST_CR)
|
||||
_state = ST_CR_LF;
|
||||
else if (_state == ST_CR_LF_DOT_CR)
|
||||
_state = ST_CR_LF_DOT_CR_LF;
|
||||
else
|
||||
_state = ST_DATA;
|
||||
break;
|
||||
case '.':
|
||||
if (_state == ST_CR_LF)
|
||||
_state = ST_CR_LF_DOT;
|
||||
else if (_state == ST_CR_LF_DOT)
|
||||
_state = ST_CR_LF_DOT_DOT;
|
||||
else
|
||||
_state = ST_DATA;
|
||||
break;
|
||||
default:
|
||||
_state = ST_DATA;
|
||||
}
|
||||
if (_state == ST_CR_LF_DOT_DOT)
|
||||
_state = ST_DATA;
|
||||
else if (_state == ST_CR_LF_DOT_CR_LF)
|
||||
_buffer.resize(_buffer.size() - 2);
|
||||
else if (c != std::char_traits<char>::eof())
|
||||
_buffer += (char) c;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
int MailStreamBuf::writeToDevice(char c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '\r':
|
||||
_state = ST_CR;
|
||||
break;
|
||||
case '\n':
|
||||
if (_state == ST_CR)
|
||||
_state = ST_CR_LF;
|
||||
else
|
||||
_state = ST_DATA;
|
||||
break;
|
||||
case '.':
|
||||
if (_state == ST_CR_LF)
|
||||
_state = ST_CR_LF_DOT;
|
||||
else
|
||||
_state = ST_DATA;
|
||||
break;
|
||||
default:
|
||||
_state = ST_DATA;
|
||||
}
|
||||
if (_state == ST_DATA)
|
||||
{
|
||||
if (!_buffer.empty())
|
||||
{
|
||||
_pOstr->write(_buffer.data(), (std::streamsize) _buffer.length());
|
||||
_buffer.clear();
|
||||
}
|
||||
_pOstr->put(c);
|
||||
}
|
||||
else if (_state == ST_CR_LF_DOT)
|
||||
{
|
||||
_pOstr->write("\r\n..", 4);
|
||||
_state = ST_DATA;
|
||||
_buffer.clear();
|
||||
}
|
||||
else _buffer += c;
|
||||
return charToInt(c);
|
||||
}
|
||||
|
||||
|
||||
MailIOS::MailIOS(std::istream& istr): _buf(istr)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
MailIOS::MailIOS(std::ostream& ostr): _buf(ostr)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
MailIOS::~MailIOS()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void MailIOS::close()
|
||||
{
|
||||
_buf.close();
|
||||
}
|
||||
|
||||
|
||||
MailStreamBuf* MailIOS::rdbuf()
|
||||
{
|
||||
return &_buf;
|
||||
}
|
||||
|
||||
|
||||
MailInputStream::MailInputStream(std::istream& istr):
|
||||
MailIOS(istr),
|
||||
std::istream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MailInputStream::~MailInputStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MailOutputStream::MailOutputStream(std::ostream& ostr):
|
||||
MailIOS(ostr),
|
||||
std::ostream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MailOutputStream::~MailOutputStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
190
Net/src/MediaType.cpp
Normal file
190
Net/src/MediaType.cpp
Normal file
@@ -0,0 +1,190 @@
|
||||
//
|
||||
// MediaType.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/MediaType.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Messages
|
||||
// Module: MediaType
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/MediaType.h"
|
||||
#include "Net/MessageHeader.h"
|
||||
#include "Foundation/String.h"
|
||||
#include <algorithm>
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
using Foundation::icompare;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
MediaType::MediaType(const std::string& mediaType)
|
||||
{
|
||||
parse(mediaType);
|
||||
}
|
||||
|
||||
|
||||
MediaType::MediaType(const std::string& type, const std::string& subType):
|
||||
_type(type),
|
||||
_subType(subType)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MediaType::MediaType(const MediaType& mediaType):
|
||||
_type(mediaType._type),
|
||||
_subType(mediaType._subType),
|
||||
_parameters(mediaType._parameters)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MediaType::~MediaType()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MediaType& MediaType::operator = (const MediaType& mediaType)
|
||||
{
|
||||
if (&mediaType != this)
|
||||
{
|
||||
_type = mediaType._type;
|
||||
_subType = mediaType._subType;
|
||||
_parameters = mediaType._parameters;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
MediaType& MediaType::operator = (const std::string& mediaType)
|
||||
{
|
||||
parse(mediaType);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void MediaType::swap(MediaType& mediaType)
|
||||
{
|
||||
std::swap(_type, mediaType._type);
|
||||
std::swap(_subType, mediaType._subType);
|
||||
_parameters.swap(mediaType._parameters);
|
||||
}
|
||||
|
||||
|
||||
void MediaType::setType(const std::string& type)
|
||||
{
|
||||
_type = type;
|
||||
}
|
||||
|
||||
|
||||
void MediaType::setSubType(const std::string& subType)
|
||||
{
|
||||
_subType = subType;
|
||||
}
|
||||
|
||||
|
||||
void MediaType::setParameter(const std::string& name, const std::string& value)
|
||||
{
|
||||
_parameters.set(name, value);
|
||||
}
|
||||
|
||||
|
||||
const std::string& MediaType::getParameter(const std::string& name) const
|
||||
{
|
||||
return _parameters.get(name);
|
||||
}
|
||||
|
||||
|
||||
bool MediaType::hasParameter(const std::string& name) const
|
||||
{
|
||||
return _parameters.has(name);
|
||||
}
|
||||
|
||||
|
||||
void MediaType::removeParameter(const std::string& name)
|
||||
{
|
||||
_parameters.erase(name);
|
||||
}
|
||||
|
||||
|
||||
std::string MediaType::toString() const
|
||||
{
|
||||
std::string result;
|
||||
result.append(_type);
|
||||
result.append("/");
|
||||
result.append(_subType);
|
||||
for (NameValueCollection::ConstIterator it = _parameters.begin(); it != _parameters.end(); ++it)
|
||||
{
|
||||
result.append("; ");
|
||||
result.append(it->first);
|
||||
result.append("=");
|
||||
MessageHeader::quote(it->second, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool MediaType::matches(const MediaType& mediaType) const
|
||||
{
|
||||
return matches(mediaType._type, mediaType._subType);
|
||||
}
|
||||
|
||||
|
||||
bool MediaType::matches(const std::string& type, const std::string& subType) const
|
||||
{
|
||||
return icompare(_type, type) == 0 && icompare(_subType, subType) == 0;
|
||||
}
|
||||
|
||||
|
||||
bool MediaType::matches(const std::string& type) const
|
||||
{
|
||||
return icompare(_type, type) == 0;
|
||||
}
|
||||
|
||||
|
||||
void MediaType::parse(const std::string& mediaType)
|
||||
{
|
||||
_type.clear();
|
||||
_subType.clear();
|
||||
_parameters.clear();
|
||||
std::string::const_iterator it = mediaType.begin();
|
||||
std::string::const_iterator end = mediaType.end();
|
||||
while (it != end && isspace(*it)) ++it;
|
||||
while (it != end && *it != '/') _type += *it++;
|
||||
if (it != end) ++it;
|
||||
while (it != end && *it != ';' && !isspace(*it)) _subType += *it++;
|
||||
while (it != end && *it != ';') ++it;
|
||||
MessageHeader::splitParameters(it, end, _parameters);
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
229
Net/src/MessageHeader.cpp
Normal file
229
Net/src/MessageHeader.cpp
Normal file
@@ -0,0 +1,229 @@
|
||||
//
|
||||
// MessageHeader.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/MessageHeader.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Messages
|
||||
// Module: MessageHeader
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/MessageHeader.h"
|
||||
#include "Net/NetException.h"
|
||||
#include "Foundation/String.h"
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
MessageHeader::MessageHeader()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MessageHeader::MessageHeader(const MessageHeader& messageHeader):
|
||||
NameValueCollection(messageHeader)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MessageHeader::~MessageHeader()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MessageHeader& MessageHeader::operator = (const MessageHeader& messageHeader)
|
||||
{
|
||||
NameValueCollection::operator = (messageHeader);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void MessageHeader::write(std::ostream& ostr) const
|
||||
{
|
||||
NameValueCollection::ConstIterator it = begin();
|
||||
while (it != end())
|
||||
{
|
||||
ostr << it->first << ": " << it->second << "\r\n";
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MessageHeader::read(std::istream& istr)
|
||||
{
|
||||
static const int eof = std::char_traits<char>::eof();
|
||||
int ch = istr.get();
|
||||
while (ch != eof && ch != '\r' && ch != '\n')
|
||||
{
|
||||
std::string name;
|
||||
std::string value;
|
||||
while (ch != eof && ch != ':' && name.length() < MAX_NAME_LENGTH) { name += ch; ch = istr.get(); }
|
||||
if (ch != ':') throw MessageException("Field name too long/no colon found");
|
||||
if (ch != eof) ch = istr.get(); // ':'
|
||||
while (isspace(ch)) ch = istr.get();
|
||||
while (ch != eof && ch != '\r' && ch != '\n' && value.length() < MAX_VALUE_LENGTH) { value += ch; ch = istr.get(); }
|
||||
if (ch == '\r') ch = istr.get();
|
||||
if (ch == '\n')
|
||||
ch = istr.get();
|
||||
else if (ch != eof)
|
||||
throw MessageException("Field value too long/no CRLF found");
|
||||
while (ch == ' ' || ch == '\t') // folding
|
||||
{
|
||||
while (ch != eof && ch != '\r' && ch != '\n' && value.length() < MAX_VALUE_LENGTH) { value += ch; ch = istr.get(); }
|
||||
if (ch == '\r') ch = istr.get();
|
||||
if (ch == '\n')
|
||||
ch = istr.get();
|
||||
else if (ch != eof)
|
||||
throw MessageException("Folded field value too long/no CRLF found");
|
||||
}
|
||||
add(name, value);
|
||||
}
|
||||
istr.putback(ch);
|
||||
}
|
||||
|
||||
|
||||
void MessageHeader::splitElements(const std::string& s, std::vector<std::string>& elements, bool ignoreEmpty)
|
||||
{
|
||||
elements.clear();
|
||||
std::string::const_iterator it = s.begin();
|
||||
std::string::const_iterator end = s.end();
|
||||
std::string elem;
|
||||
while (it != end)
|
||||
{
|
||||
if (*it == '"')
|
||||
{
|
||||
elem += *it++;
|
||||
while (it != end && *it != '"')
|
||||
{
|
||||
if (*it == '\\')
|
||||
{
|
||||
++it;
|
||||
if (it != end) elem += *it++;
|
||||
}
|
||||
else elem += *it++;
|
||||
}
|
||||
if (it != end) elem += *it++;
|
||||
}
|
||||
else if (*it == '\\')
|
||||
{
|
||||
++it;
|
||||
if (it != end) elem += *it++;
|
||||
}
|
||||
else if (*it == ',')
|
||||
{
|
||||
Foundation::trimInPlace(elem);
|
||||
if (!ignoreEmpty || !elem.empty())
|
||||
elements.push_back(elem);
|
||||
elem.clear();
|
||||
++it;
|
||||
}
|
||||
else elem += *it++;
|
||||
}
|
||||
if (!elem.empty())
|
||||
{
|
||||
Foundation::trimInPlace(elem);
|
||||
if (!ignoreEmpty || !elem.empty())
|
||||
elements.push_back(elem);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MessageHeader::splitParameters(const std::string& s, std::string& value, NameValueCollection& parameters)
|
||||
{
|
||||
value.clear();
|
||||
parameters.clear();
|
||||
std::string::const_iterator it = s.begin();
|
||||
std::string::const_iterator end = s.end();
|
||||
while (it != end && isspace(*it)) ++it;
|
||||
while (it != end && *it != ';') value += *it++;
|
||||
Foundation::trimRightInPlace(value);
|
||||
if (it != end) ++it;
|
||||
splitParameters(it, end, parameters);
|
||||
}
|
||||
|
||||
|
||||
void MessageHeader::splitParameters(const std::string::const_iterator& begin, const std::string::const_iterator& end, NameValueCollection& parameters)
|
||||
{
|
||||
std::string::const_iterator it = begin;
|
||||
while (it != end)
|
||||
{
|
||||
std::string pname;
|
||||
std::string pvalue;
|
||||
while (it != end && isspace(*it)) ++it;
|
||||
while (it != end && *it != '=' && *it != ';') pname += *it++;
|
||||
Foundation::trimRightInPlace(pname);
|
||||
if (it != end && *it != ';') ++it;
|
||||
while (it != end && isspace(*it)) ++it;
|
||||
while (it != end && *it != ';')
|
||||
{
|
||||
if (*it == '"')
|
||||
{
|
||||
++it;
|
||||
while (it != end && *it != '"')
|
||||
{
|
||||
if (*it == '\\')
|
||||
{
|
||||
++it;
|
||||
if (it != end) pvalue += *it++;
|
||||
}
|
||||
else pvalue += *it++;
|
||||
}
|
||||
if (it != end) ++it;
|
||||
}
|
||||
else if (*it == '\\')
|
||||
{
|
||||
++it;
|
||||
if (it != end) pvalue += *it++;
|
||||
}
|
||||
else pvalue += *it++;
|
||||
}
|
||||
Foundation::trimRightInPlace(pvalue);
|
||||
if (!pname.empty()) parameters.add(pname, pvalue);
|
||||
if (it != end) ++it;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MessageHeader::quote(const std::string& value, std::string& result, bool allowSpace)
|
||||
{
|
||||
bool mustQuote = false;
|
||||
for (std::string::const_iterator it = value.begin(); !mustQuote && it != value.end(); ++it)
|
||||
{
|
||||
if (!isalnum(*it) && *it != '.' && *it != '_' && *it != '-' && !(isspace(*it) && allowSpace))
|
||||
mustQuote = true;
|
||||
}
|
||||
if (mustQuote) result += '"';
|
||||
result.append(value);
|
||||
if (mustQuote) result += '"';
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
260
Net/src/MulticastSocket.cpp
Normal file
260
Net/src/MulticastSocket.cpp
Normal file
@@ -0,0 +1,260 @@
|
||||
//
|
||||
// MulticastSocket.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/MulticastSocket.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Sockets
|
||||
// Module: MulticastSocket
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/MulticastSocket.h"
|
||||
#include "Net/NetException.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#if defined(hpux) && defined(_XOPEN_SOURCE_EXTENDED)
|
||||
// netinet/in.h does not define struct ip_mreq if
|
||||
// _XOPEN_SOURCE_EXTENDED is #define'd.
|
||||
struct ip_mreq
|
||||
{
|
||||
struct in_addr imr_multiaddr;
|
||||
struct in_addr imr_interface;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
// some Unix variants don't have IPV6_ADD_MEMBERSHIP/IPV6_DROP_MEMBERSHIP
|
||||
#if defined(IPV6_JOIN_GROUP) && !defined(IPV6_ADD_MEMBERSHIP)
|
||||
#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
|
||||
#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
|
||||
#endif
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
MulticastSocket::MulticastSocket()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MulticastSocket::MulticastSocket(IPAddress::Family family): DatagramSocket(family)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MulticastSocket::MulticastSocket(const SocketAddress& address, bool reuseAddress): DatagramSocket(address, reuseAddress)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MulticastSocket::MulticastSocket(const Socket& socket): DatagramSocket(socket)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MulticastSocket::~MulticastSocket()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MulticastSocket& MulticastSocket::operator = (const Socket& socket)
|
||||
{
|
||||
DatagramSocket::operator = (socket);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void MulticastSocket::setInterface(const NetworkInterface& interface)
|
||||
{
|
||||
if (!interface.supportsIPv6())
|
||||
{
|
||||
impl()->setOption(IPPROTO_IP, IP_MULTICAST_IF, interface.address());
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
impl()->setOption(IPPROTO_IPV6, IPV6_MULTICAST_IF, interface.index());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NetworkInterface MulticastSocket::getInterface() const
|
||||
{
|
||||
try
|
||||
{
|
||||
IPAddress addr;
|
||||
impl()->getOption(IPPROTO_IP, IP_MULTICAST_IF, addr);
|
||||
return NetworkInterface::forAddress(addr);
|
||||
}
|
||||
catch (Foundation::Exception&)
|
||||
{
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
int ix;
|
||||
impl()->getOption(IPPROTO_IPV6, IPV6_MULTICAST_IF, ix);
|
||||
return NetworkInterface::forIndex(ix);
|
||||
#else
|
||||
throw;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MulticastSocket::setLoopback(bool flag)
|
||||
{
|
||||
if (address().af() == AF_INET)
|
||||
{
|
||||
unsigned char uflag = flag ? 1 : 0;
|
||||
impl()->setOption(IPPROTO_IP, IP_MULTICAST_LOOP, uflag);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
unsigned uflag = flag ? 1 : 0;
|
||||
impl()->setOption(IPPROTO_IPV6, IPV6_MULTICAST_LOOP, uflag);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool MulticastSocket::getLoopback() const
|
||||
{
|
||||
bool flag = false;
|
||||
if (address().af() == AF_INET)
|
||||
{
|
||||
unsigned char uflag;
|
||||
impl()->getOption(IPPROTO_IP, IP_MULTICAST_LOOP, uflag);
|
||||
flag = uflag != 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
unsigned uflag;
|
||||
impl()->getOption(IPPROTO_IPV6, IPV6_MULTICAST_LOOP, uflag);
|
||||
flag = uflag != 0;
|
||||
#endif
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
|
||||
void MulticastSocket::setTimeToLive(unsigned value)
|
||||
{
|
||||
if (address().af() == AF_INET)
|
||||
{
|
||||
unsigned char ttl = (unsigned char) value;
|
||||
impl()->setOption(IPPROTO_IP, IP_MULTICAST_TTL, ttl);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
impl()->setOption(IPPROTO_IPV6, IPV6_MULTICAST_HOPS, value);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned MulticastSocket::getTimeToLive() const
|
||||
{
|
||||
unsigned ttl;
|
||||
if (address().af() == AF_INET)
|
||||
{
|
||||
unsigned char cttl;
|
||||
impl()->getOption(IPPROTO_IP, IP_MULTICAST_TTL, cttl);
|
||||
ttl = cttl;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
impl()->getOption(IPPROTO_IPV6, IPV6_MULTICAST_HOPS, ttl);
|
||||
#endif
|
||||
}
|
||||
return ttl;
|
||||
}
|
||||
|
||||
|
||||
void MulticastSocket::joinGroup(const IPAddress& groupAddress)
|
||||
{
|
||||
NetworkInterface intf;
|
||||
joinGroup(groupAddress, intf);
|
||||
}
|
||||
|
||||
|
||||
void MulticastSocket::joinGroup(const IPAddress& groupAddress, const NetworkInterface& interface)
|
||||
{
|
||||
if (groupAddress.af() == AF_INET)
|
||||
{
|
||||
struct ip_mreq mr;
|
||||
memcpy(&mr.imr_multiaddr, groupAddress.addr(), groupAddress.length());
|
||||
memcpy(&mr.imr_interface, interface.address().addr(), interface.address().length());
|
||||
impl()->setRawOption(IPPROTO_IP, IP_ADD_MEMBERSHIP, &mr, sizeof(mr));
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
struct ipv6_mreq mr;
|
||||
memcpy(&mr.ipv6mr_multiaddr, groupAddress.addr(), groupAddress.length());
|
||||
mr.ipv6mr_interface = interface.index();
|
||||
impl()->setRawOption(IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mr, sizeof(mr));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MulticastSocket::leaveGroup(const IPAddress& groupAddress)
|
||||
{
|
||||
NetworkInterface intf;
|
||||
leaveGroup(groupAddress, intf);
|
||||
}
|
||||
|
||||
|
||||
void MulticastSocket::leaveGroup(const IPAddress& groupAddress, const NetworkInterface& interface)
|
||||
{
|
||||
if (groupAddress.af() == AF_INET)
|
||||
{
|
||||
struct ip_mreq mr;
|
||||
memcpy(&mr.imr_multiaddr, groupAddress.addr(), groupAddress.length());
|
||||
memcpy(&mr.imr_interface, interface.address().addr(), interface.address().length());
|
||||
impl()->setRawOption(IPPROTO_IP, IP_DROP_MEMBERSHIP, &mr, sizeof(mr));
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
struct ipv6_mreq mr;
|
||||
memcpy(&mr.ipv6mr_multiaddr, groupAddress.addr(), groupAddress.length());
|
||||
mr.ipv6mr_interface = interface.index();
|
||||
impl()->setRawOption(IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &mr, sizeof(mr));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
316
Net/src/MultipartReader.cpp
Normal file
316
Net/src/MultipartReader.cpp
Normal file
@@ -0,0 +1,316 @@
|
||||
//
|
||||
// MultipartReader.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/MultipartReader.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Messages
|
||||
// Module: MultipartReader
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/MultipartReader.h"
|
||||
#include "Net/MessageHeader.h"
|
||||
#include "Net/NetException.h"
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
using Foundation::BufferedStreamBuf;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
//
|
||||
// MultipartStreamBuf
|
||||
//
|
||||
|
||||
|
||||
MultipartStreamBuf::MultipartStreamBuf(std::istream& istr, const std::string& boundary):
|
||||
BufferedStreamBuf(STREAM_BUFFER_SIZE, std::ios::in),
|
||||
_istr(istr),
|
||||
_boundary(boundary),
|
||||
_lastPart(false)
|
||||
{
|
||||
poco_assert (!boundary.empty() && boundary.length() < STREAM_BUFFER_SIZE - 6);
|
||||
}
|
||||
|
||||
|
||||
MultipartStreamBuf::~MultipartStreamBuf()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int MultipartStreamBuf::readFromDevice(char* buffer, std::streamsize length)
|
||||
{
|
||||
poco_assert_dbg (length >= _boundary.length() + 6);
|
||||
|
||||
static const int eof = std::char_traits<char>::eof();
|
||||
int n = 0;
|
||||
int ch = _istr.get();
|
||||
*buffer++ = (char) ch; ++n;
|
||||
if (ch == '\n' || ch == '\r' && _istr.peek() == '\n')
|
||||
{
|
||||
if (ch == '\r')
|
||||
{
|
||||
ch = _istr.get(); // '\n'
|
||||
*buffer++ = (char) ch; ++n;
|
||||
}
|
||||
ch = _istr.peek();
|
||||
if (ch == '\r' || ch == '\n') return n;
|
||||
*buffer++ = (char) _istr.get(); ++n;
|
||||
if (ch == '-' && _istr.peek() == '-')
|
||||
{
|
||||
ch = _istr.get(); // '-'
|
||||
*buffer++ = (char) ch; ++n;
|
||||
std::string::const_iterator it = _boundary.begin();
|
||||
std::string::const_iterator end = _boundary.end();
|
||||
ch = _istr.get();
|
||||
*buffer++ = (char) ch; ++n;
|
||||
while (it != end && ch == *it)
|
||||
{
|
||||
++it;
|
||||
ch = _istr.get();
|
||||
*buffer++ = (char) ch; ++n;
|
||||
}
|
||||
if (it == end)
|
||||
{
|
||||
if (ch == '\n' || ch == '\r' && _istr.peek() == '\n')
|
||||
{
|
||||
if (ch == '\r')
|
||||
{
|
||||
ch = _istr.get(); // '\n'
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (ch == '-' && _istr.peek() == '-')
|
||||
{
|
||||
ch = _istr.get(); // '-'
|
||||
_lastPart = true;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ch = _istr.peek();
|
||||
while (ch != eof && ch != '\r' && ch != '\n' && n < length)
|
||||
{
|
||||
*buffer++ = (char) _istr.get(); ++n;
|
||||
ch = _istr.peek();
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
bool MultipartStreamBuf::lastPart() const
|
||||
{
|
||||
return _lastPart;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// MultipartIOS
|
||||
//
|
||||
|
||||
|
||||
MultipartIOS::MultipartIOS(std::istream& istr, const std::string& boundary):
|
||||
_buf(istr, boundary)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
MultipartIOS::~MultipartIOS()
|
||||
{
|
||||
_buf.sync();
|
||||
}
|
||||
|
||||
|
||||
MultipartStreamBuf* MultipartIOS::rdbuf()
|
||||
{
|
||||
return &_buf;
|
||||
}
|
||||
|
||||
|
||||
bool MultipartIOS::lastPart() const
|
||||
{
|
||||
return _buf.lastPart();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// MultipartInputStream
|
||||
//
|
||||
|
||||
|
||||
MultipartInputStream::MultipartInputStream(std::istream& istr, const std::string& boundary):
|
||||
MultipartIOS(istr, boundary),
|
||||
std::istream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MultipartInputStream::~MultipartInputStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// MultipartReader
|
||||
//
|
||||
|
||||
|
||||
MultipartReader::MultipartReader(std::istream& istr):
|
||||
_istr(istr),
|
||||
_pMPI(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MultipartReader::MultipartReader(std::istream& istr, const std::string& boundary):
|
||||
_istr(istr),
|
||||
_boundary(boundary),
|
||||
_pMPI(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MultipartReader::~MultipartReader()
|
||||
{
|
||||
delete _pMPI;
|
||||
}
|
||||
|
||||
|
||||
void MultipartReader::nextPart(MessageHeader& messageHeader)
|
||||
{
|
||||
if (!_pMPI)
|
||||
{
|
||||
if (_boundary.empty())
|
||||
guessBoundary();
|
||||
else
|
||||
findFirstBoundary();
|
||||
}
|
||||
else if (_pMPI->lastPart())
|
||||
{
|
||||
throw MultipartException("No more parts available");
|
||||
}
|
||||
parseHeader(messageHeader);
|
||||
delete _pMPI;
|
||||
_pMPI = new MultipartInputStream(_istr, _boundary);
|
||||
}
|
||||
|
||||
|
||||
bool MultipartReader::hasNextPart()
|
||||
{
|
||||
return (!_pMPI || !_pMPI->lastPart()) && _istr.good();
|
||||
}
|
||||
|
||||
|
||||
std::istream& MultipartReader::stream() const
|
||||
{
|
||||
poco_check_ptr (_pMPI);
|
||||
|
||||
return *_pMPI;
|
||||
}
|
||||
|
||||
|
||||
const std::string& MultipartReader::boundary() const
|
||||
{
|
||||
return _boundary;
|
||||
}
|
||||
|
||||
|
||||
void MultipartReader::findFirstBoundary()
|
||||
{
|
||||
std::string expect("--");
|
||||
expect.append(_boundary);
|
||||
std::string line;
|
||||
line.reserve(expect.length());
|
||||
bool ok = true;
|
||||
do
|
||||
{
|
||||
ok = readLine(line, expect.length());
|
||||
}
|
||||
while (ok && line != expect);
|
||||
|
||||
if (!ok) throw MultipartException("No boundary line found");
|
||||
}
|
||||
|
||||
|
||||
void MultipartReader::guessBoundary()
|
||||
{
|
||||
static const int eof = std::char_traits<char>::eof();
|
||||
int ch = _istr.get();
|
||||
while (isspace(ch))
|
||||
ch = _istr.get();
|
||||
if (ch == '-' && _istr.peek() == '-')
|
||||
{
|
||||
_istr.get();
|
||||
ch = _istr.peek();
|
||||
while (ch != eof && ch != '\r' && ch != '\n')
|
||||
{
|
||||
_boundary += (char) _istr.get();
|
||||
ch = _istr.peek();
|
||||
}
|
||||
if (ch == '\r' || ch == '\n')
|
||||
ch = _istr.get();
|
||||
if (_istr.peek() == '\n')
|
||||
_istr.get();
|
||||
}
|
||||
else throw MultipartException("No boundary line found");
|
||||
}
|
||||
|
||||
|
||||
void MultipartReader::parseHeader(MessageHeader& messageHeader)
|
||||
{
|
||||
messageHeader.clear();
|
||||
messageHeader.read(_istr);
|
||||
int ch = _istr.get();
|
||||
if (ch == '\r' && _istr.peek() == '\n') ch = _istr.get();
|
||||
}
|
||||
|
||||
|
||||
bool MultipartReader::readLine(std::string& line, std::string::size_type n)
|
||||
{
|
||||
static const int eof = std::char_traits<char>::eof();
|
||||
|
||||
line.clear();
|
||||
int ch = _istr.peek();
|
||||
while (ch != eof && ch != '\r' && ch != '\n')
|
||||
{
|
||||
ch = (char) _istr.get();
|
||||
if (line.length() < n) line += ch;
|
||||
ch = _istr.peek();
|
||||
}
|
||||
if (ch != eof) _istr.get();
|
||||
if (ch == '\r' && _istr.peek() == '\n') _istr.get();
|
||||
return ch != eof;
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
101
Net/src/MultipartWriter.cpp
Normal file
101
Net/src/MultipartWriter.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
//
|
||||
// MultipartWriter.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/MultipartWriter.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Messages
|
||||
// Module: MultipartWriter
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/MultipartWriter.h"
|
||||
#include "Net/MessageHeader.h"
|
||||
#include "Foundation/Random.h"
|
||||
#include "Foundation/NumberFormatter.h"
|
||||
|
||||
|
||||
using Foundation::Random;
|
||||
using Foundation::NumberFormatter;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
MultipartWriter::MultipartWriter(std::ostream& ostr):
|
||||
_ostr(ostr),
|
||||
_boundary(createBoundary())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MultipartWriter::MultipartWriter(std::ostream& ostr, const std::string& boundary):
|
||||
_ostr(ostr),
|
||||
_boundary(boundary)
|
||||
{
|
||||
if (_boundary.empty())
|
||||
_boundary = createBoundary();
|
||||
}
|
||||
|
||||
|
||||
MultipartWriter::~MultipartWriter()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void MultipartWriter::nextPart(const MessageHeader& header)
|
||||
{
|
||||
_ostr << "\r\n--" << _boundary << "\r\n";
|
||||
header.write(_ostr);
|
||||
_ostr << "\r\n";
|
||||
}
|
||||
|
||||
|
||||
void MultipartWriter::close()
|
||||
{
|
||||
_ostr << "\r\n--" << _boundary << "--\r\n";
|
||||
}
|
||||
|
||||
|
||||
const std::string& MultipartWriter::boundary() const
|
||||
{
|
||||
return _boundary;
|
||||
}
|
||||
|
||||
|
||||
std::string MultipartWriter::createBoundary()
|
||||
{
|
||||
std::string boundary("MIME_boundary_");
|
||||
Random rnd;
|
||||
boundary.append(NumberFormatter::formatHex(rnd.next(), 8));
|
||||
boundary.append(NumberFormatter::formatHex(rnd.next(), 8));
|
||||
return boundary;
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
163
Net/src/NameValueCollection.cpp
Normal file
163
Net/src/NameValueCollection.cpp
Normal file
@@ -0,0 +1,163 @@
|
||||
//
|
||||
// NameValueCollection.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/NameValueCollection.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Messages
|
||||
// Module: NameValueCollection
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/NameValueCollection.h"
|
||||
#include "Foundation/Exception.h"
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
using Foundation::NotFoundException;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
NameValueCollection::NameValueCollection()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
NameValueCollection::NameValueCollection(const NameValueCollection& nvc):
|
||||
_map(nvc._map)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
NameValueCollection::~NameValueCollection()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
NameValueCollection& NameValueCollection::operator = (const NameValueCollection& nvc)
|
||||
{
|
||||
if (&nvc != this)
|
||||
{
|
||||
_map = nvc._map;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void NameValueCollection::swap(NameValueCollection& nvc)
|
||||
{
|
||||
std::swap(_map, nvc._map);
|
||||
}
|
||||
|
||||
|
||||
const std::string& NameValueCollection::operator [] (const std::string& name) const
|
||||
{
|
||||
ConstIterator it = _map.find(name);
|
||||
if (it != _map.end())
|
||||
return it->second;
|
||||
else
|
||||
throw NotFoundException(name);
|
||||
}
|
||||
|
||||
|
||||
void NameValueCollection::set(const std::string& name, const std::string& value)
|
||||
{
|
||||
Iterator it = _map.find(name);
|
||||
if (it != _map.end())
|
||||
_map.erase(it);
|
||||
_map.insert(HeaderMap::value_type(name, value));
|
||||
}
|
||||
|
||||
|
||||
void NameValueCollection::add(const std::string& name, const std::string& value)
|
||||
{
|
||||
_map.insert(HeaderMap::value_type(name, value));
|
||||
}
|
||||
|
||||
|
||||
const std::string& NameValueCollection::get(const std::string& name) const
|
||||
{
|
||||
ConstIterator it = _map.find(name);
|
||||
if (it != _map.end())
|
||||
return it->second;
|
||||
else
|
||||
throw NotFoundException(name);
|
||||
}
|
||||
|
||||
|
||||
bool NameValueCollection::has(const std::string& name) const
|
||||
{
|
||||
return _map.find(name) != _map.end();
|
||||
}
|
||||
|
||||
|
||||
NameValueCollection::ConstIterator NameValueCollection::find(const std::string& name) const
|
||||
{
|
||||
return _map.find(name);
|
||||
}
|
||||
|
||||
|
||||
NameValueCollection::ConstIterator NameValueCollection::begin() const
|
||||
{
|
||||
return _map.begin();
|
||||
}
|
||||
|
||||
|
||||
NameValueCollection::ConstIterator NameValueCollection::end() const
|
||||
{
|
||||
return _map.end();
|
||||
}
|
||||
|
||||
|
||||
bool NameValueCollection::empty() const
|
||||
{
|
||||
return _map.empty();
|
||||
}
|
||||
|
||||
|
||||
int NameValueCollection::size() const
|
||||
{
|
||||
return (int) _map.size();
|
||||
}
|
||||
|
||||
|
||||
void NameValueCollection::erase(const std::string& name)
|
||||
{
|
||||
_map.erase(name);
|
||||
}
|
||||
|
||||
|
||||
void NameValueCollection::clear()
|
||||
{
|
||||
_map.clear();
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
66
Net/src/NetException.cpp
Normal file
66
Net/src/NetException.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
//
|
||||
// NetException.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/NetException.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: NetCore
|
||||
// Module: NetException
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/NetException.h"
|
||||
#include <typeinfo>
|
||||
|
||||
|
||||
using Foundation::IOException;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
POCO_IMPLEMENT_EXCEPTION(NetException, IOException, "Net Exception")
|
||||
POCO_IMPLEMENT_EXCEPTION(InvalidAddressException, NetException, "Invalid address")
|
||||
POCO_IMPLEMENT_EXCEPTION(ServiceNotFoundException, NetException, "Service not found")
|
||||
POCO_IMPLEMENT_EXCEPTION(ConnectionAbortedException, NetException, "Software caused connection abort")
|
||||
POCO_IMPLEMENT_EXCEPTION(ConnectionResetException, NetException, "Connection reset by peer")
|
||||
POCO_IMPLEMENT_EXCEPTION(ConnectionRefusedException, NetException, "Connection refused")
|
||||
POCO_IMPLEMENT_EXCEPTION(DNSException, NetException, "DNS error")
|
||||
POCO_IMPLEMENT_EXCEPTION(HostNotFoundException, DNSException, "Host not found")
|
||||
POCO_IMPLEMENT_EXCEPTION(NoAddressFoundException, DNSException, "No address found")
|
||||
POCO_IMPLEMENT_EXCEPTION(InterfaceNotFoundException, NetException, "Interface not found")
|
||||
POCO_IMPLEMENT_EXCEPTION(MessageException, NetException, "Malformed message")
|
||||
POCO_IMPLEMENT_EXCEPTION(MultipartException, MessageException, "Malformed multipart message")
|
||||
POCO_IMPLEMENT_EXCEPTION(HTTPException, NetException, "HTTP Exception")
|
||||
POCO_IMPLEMENT_EXCEPTION(NotAuthenticatedException, HTTPException, "No authentication information found")
|
||||
POCO_IMPLEMENT_EXCEPTION(FTPException, NetException, "FTP Exception")
|
||||
POCO_IMPLEMENT_EXCEPTION(SMTPException, NetException, "SMTP Exception")
|
||||
POCO_IMPLEMENT_EXCEPTION(POP3Exception, NetException, "POP3 Exception")
|
||||
|
||||
|
||||
Net_END
|
||||
497
Net/src/NetworkInterface.cpp
Normal file
497
Net/src/NetworkInterface.cpp
Normal file
@@ -0,0 +1,497 @@
|
||||
//
|
||||
// NetworkInterface.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/NetworkInterface.cpp#3 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Sockets
|
||||
// Module: NetworkInterface
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/NetworkInterface.h"
|
||||
#include "Net/DatagramSocket.h"
|
||||
#include "Net/NetException.h"
|
||||
#include "Foundation/NumberFormatter.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
using Foundation::NumberFormatter;
|
||||
using Foundation::FastMutex;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
FastMutex NetworkInterface::_mutex;
|
||||
|
||||
|
||||
NetworkInterface::NetworkInterface():
|
||||
_index(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
NetworkInterface::NetworkInterface(const std::string& name, const IPAddress& address, int index):
|
||||
_name(name),
|
||||
_address(address),
|
||||
_index(index)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
NetworkInterface::NetworkInterface(const NetworkInterface& interface):
|
||||
_index(interface._index),
|
||||
_name(interface._name),
|
||||
_address(interface._address)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
NetworkInterface::~NetworkInterface()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
NetworkInterface& NetworkInterface::operator = (const NetworkInterface& interface)
|
||||
{
|
||||
if (&interface != this)
|
||||
{
|
||||
_index = interface._index;
|
||||
_name = interface._name;
|
||||
_address = interface._address;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
NetworkInterface NetworkInterface::forName(const std::string& name, bool requireIPv6)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
NetworkInterfaceList ifs = list();
|
||||
for (NetworkInterfaceList::const_iterator it = ifs.begin(); it != ifs.end(); ++it)
|
||||
{
|
||||
if (it->name() == name && it->supportsIPv6() == requireIPv6)
|
||||
return *it;
|
||||
}
|
||||
throw InterfaceNotFoundException(name);
|
||||
#else
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
struct ifreq ifr;
|
||||
strncpy(ifr.ifr_name, name.c_str(), IFNAMSIZ);
|
||||
DatagramSocket ds(requireIPv6 ? IPAddress::IPv6 : IPAddress::IPv4);
|
||||
ds.impl()->ioctl(SIOCGIFADDR, &ifr);
|
||||
IPAddress addr;
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
if (ifr.ifr_addr.sa_family == AF_INET)
|
||||
addr = IPAddress(&reinterpret_cast<const struct sockaddr_in*>(&ifr.ifr_addr)->sin_addr, sizeof(struct in_addr));
|
||||
else if (ifr.ifr_addr.sa_family == AF_INET6)
|
||||
addr = IPAddress(&reinterpret_cast<const struct sockaddr_in6*>(&ifr.ifr_addr)->sin6_addr, sizeof(struct in6_addr));
|
||||
else throw InterfaceNotFoundException(addr.toString(), "interface has no IP address");
|
||||
int index = if_nametoindex(name.c_str());
|
||||
#else
|
||||
if (ifr.ifr_addr.sa_family == AF_INET)
|
||||
addr = IPAddress(&reinterpret_cast<const struct sockaddr_in*>(&ifr.ifr_addr)->sin_addr, sizeof(struct in_addr));
|
||||
else throw InterfaceNotFoundException(addr.toString(), "interface has no IP address");
|
||||
int index = 0;
|
||||
#endif
|
||||
return NetworkInterface(name, addr, index);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
NetworkInterface NetworkInterface::forAddress(const IPAddress& addr)
|
||||
{
|
||||
NetworkInterfaceList ifs = list();
|
||||
for (NetworkInterfaceList::const_iterator it = ifs.begin(); it != ifs.end(); ++it)
|
||||
{
|
||||
if (it->address() == addr)
|
||||
return *it;
|
||||
}
|
||||
throw InterfaceNotFoundException(addr.toString());
|
||||
}
|
||||
|
||||
|
||||
NetworkInterface NetworkInterface::forIndex(int i)
|
||||
{
|
||||
if (i != 0)
|
||||
{
|
||||
NetworkInterfaceList ifs = list();
|
||||
for (NetworkInterfaceList::const_iterator it = ifs.begin(); it != ifs.end(); ++it)
|
||||
{
|
||||
if (it->index() == i)
|
||||
return *it;
|
||||
}
|
||||
throw InterfaceNotFoundException("#" + NumberFormatter::format(i));
|
||||
}
|
||||
else return NetworkInterface();
|
||||
}
|
||||
|
||||
|
||||
Foundation_END
|
||||
|
||||
|
||||
//
|
||||
// platform-specific code below
|
||||
//
|
||||
|
||||
|
||||
#if defined(POCO_OS_FAMILY_WINDOWS)
|
||||
//
|
||||
// Windows
|
||||
//
|
||||
#include <iphlpapi.h>
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
NetworkInterface::NetworkInterfaceList NetworkInterface::list()
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
NetworkInterfaceList result;
|
||||
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
// On Windows XP/Server 2003 and later we use GetAdaptersAddresses.
|
||||
PIP_ADAPTER_ADDRESSES pAdapterAddresses;
|
||||
PIP_ADAPTER_ADDRESSES pAdapter = 0;
|
||||
ULONG len = sizeof(IP_ADAPTER_ADDRESSES);
|
||||
pAdapterAddresses = reinterpret_cast<IP_ADAPTER_ADDRESSES*>(new char[len]);
|
||||
// Make an initial call to GetAdaptersAddresses to get
|
||||
// the necessary size into len
|
||||
DWORD rc = GetAdaptersAddresses(AF_UNSPEC, 0, 0, pAdapterAddresses, &len);
|
||||
if (rc == ERROR_BUFFER_OVERFLOW)
|
||||
{
|
||||
delete [] reinterpret_cast<char*>(pAdapterAddresses);
|
||||
pAdapterAddresses = reinterpret_cast<IP_ADAPTER_ADDRESSES*>(new char[len]);
|
||||
}
|
||||
else if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
throw NetException("cannot get network adapter list");
|
||||
}
|
||||
try
|
||||
{
|
||||
if (GetAdaptersAddresses(AF_UNSPEC, 0, 0, pAdapterAddresses, &len) == NO_ERROR)
|
||||
{
|
||||
pAdapter = pAdapterAddresses;
|
||||
while (pAdapter)
|
||||
{
|
||||
if (pAdapter->FirstUnicastAddress)
|
||||
{
|
||||
IPAddress addr(pAdapter->FirstUnicastAddress->Address.lpSockaddr, pAdapter->FirstUnicastAddress->Address.iSockaddrLength);
|
||||
result.push_back(NetworkInterface(std::string(pAdapter->AdapterName), addr, pAdapter->Ipv6IfIndex));
|
||||
pAdapter = pAdapter->Next;
|
||||
}
|
||||
}
|
||||
}
|
||||
else throw NetException("cannot get network adapter list");
|
||||
}
|
||||
catch (Foundation::Exception&)
|
||||
{
|
||||
delete [] reinterpret_cast<char*>(pAdapterAddresses);
|
||||
throw;
|
||||
}
|
||||
delete [] reinterpret_cast<char*>(pAdapterAddresses);
|
||||
#else
|
||||
// On Windows 2000 we use GetAdaptersInfo.
|
||||
PIP_ADAPTER_INFO pAdapterInfo;
|
||||
PIP_ADAPTER_INFO pAdapter = 0;
|
||||
ULONG len = sizeof(IP_ADAPTER_INFO);
|
||||
pAdapterInfo = reinterpret_cast<IP_ADAPTER_INFO*>(new char[len]);
|
||||
// Make an initial call to GetAdaptersInfo to get
|
||||
// the necessary size into len
|
||||
DWORD rc = GetAdaptersInfo(pAdapterInfo, &len);
|
||||
if (rc == ERROR_BUFFER_OVERFLOW)
|
||||
{
|
||||
delete [] reinterpret_cast<char*>(pAdapterInfo);
|
||||
pAdapterInfo = reinterpret_cast<IP_ADAPTER_INFO*>(new char[len]);
|
||||
}
|
||||
else if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
throw NetException("cannot get network adapter list");
|
||||
}
|
||||
try
|
||||
{
|
||||
if (GetAdaptersInfo(pAdapterInfo, &len) == NO_ERROR)
|
||||
{
|
||||
pAdapter = pAdapterInfo;
|
||||
while (pAdapter)
|
||||
{
|
||||
IPAddress addr(std::string(pAdapter->IpAddressList.IpAddress.String));
|
||||
result.push_back(NetworkInterface(std::string(pAdapter->AdapterName), addr));
|
||||
pAdapter = pAdapter->Next;
|
||||
}
|
||||
}
|
||||
else throw NetException("cannot get network adapter list");
|
||||
}
|
||||
catch (Foundation::Exception&)
|
||||
{
|
||||
delete [] reinterpret_cast<char*>(pAdapterInfo);
|
||||
throw;
|
||||
}
|
||||
delete [] reinterpret_cast<char*>(pAdapterInfo);
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
|
||||
|
||||
#elif defined(POCO_OS_FAMILY_BSD) || POCO_OS == POCO_OS_QNX
|
||||
//
|
||||
// BSD variants
|
||||
//
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <net/if_dl.h>
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
NetworkInterface::NetworkInterfaceList NetworkInterface::list()
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
NetworkInterfaceList result;
|
||||
|
||||
struct ifaddrs* ifaphead;
|
||||
int rc = getifaddrs(&ifaphead);
|
||||
if (rc) throw NetException("cannot get network adapter list");
|
||||
|
||||
for (struct ifaddrs* ifap = ifaphead; ifap; ifap = ifap->ifa_next)
|
||||
{
|
||||
if (ifap->ifa_addr)
|
||||
{
|
||||
if (ifap->ifa_addr->sa_family == AF_INET)
|
||||
{
|
||||
IPAddress addr(&reinterpret_cast<struct sockaddr_in*>(ifap->ifa_addr)->sin_addr, sizeof(struct in_addr));
|
||||
result.push_back(NetworkInterface(std::string(ifap->ifa_name), addr));
|
||||
}
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
else if (ifap->ifa_addr->sa_family == AF_INET6)
|
||||
{
|
||||
IPAddress addr(&reinterpret_cast<struct sockaddr_in6*>(ifap->ifa_addr)->sin6_addr, sizeof(struct in6_addr));
|
||||
result.push_back(NetworkInterface(std::string(ifap->ifa_name), addr, if_nametoindex(ifap->ifa_name)));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
freeifaddrs(ifaphead);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
|
||||
|
||||
#elif POCO_OS == POCO_OS_LINUX
|
||||
//
|
||||
// Linux
|
||||
//
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
NetworkInterface::NetworkInterfaceList NetworkInterface::list()
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
NetworkInterfaceList result;
|
||||
DatagramSocket socket;
|
||||
// the following code is loosely based
|
||||
// on W. Richard Stevens, UNIX Network Programming, pp 434ff.
|
||||
int lastlen = 0;
|
||||
int len = 100*sizeof(struct ifreq);
|
||||
char* buf = 0;
|
||||
try
|
||||
{
|
||||
struct ifconf ifc;
|
||||
for (;;)
|
||||
{
|
||||
buf = new char[len];
|
||||
ifc.ifc_len = len;
|
||||
ifc.ifc_buf = buf;
|
||||
if (::ioctl(socket.impl()->sockfd(), SIOCGIFCONF, &ifc) < 0)
|
||||
{
|
||||
if (errno != EINVAL || lastlen != 0)
|
||||
throw NetException("cannot get network adapter list");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ifc.ifc_len == lastlen)
|
||||
break;
|
||||
lastlen = ifc.ifc_len;
|
||||
}
|
||||
len += 10*sizeof(struct ifreq);
|
||||
delete [] buf;
|
||||
}
|
||||
for (const char* ptr = buf; ptr < buf + ifc.ifc_len;)
|
||||
{
|
||||
const struct ifreq* ifr = reinterpret_cast<const struct ifreq*>(ptr);
|
||||
IPAddress addr;
|
||||
bool haveAddr = false;
|
||||
switch (ifr->ifr_addr.sa_family)
|
||||
{
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
case AF_INET6:
|
||||
addr = IPAddress(&reinterpret_cast<const struct sockaddr_in6*>(&ifr->ifr_addr)->sin6_addr, sizeof(struct in6_addr));
|
||||
haveAddr = true;
|
||||
break;
|
||||
#endif
|
||||
case AF_INET:
|
||||
addr = IPAddress(&reinterpret_cast<const struct sockaddr_in*>(&ifr->ifr_addr)->sin_addr, sizeof(struct in_addr));
|
||||
haveAddr = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (haveAddr)
|
||||
{
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
int index = if_nametoindex(ifr->ifr_name);
|
||||
#else
|
||||
int index = -1;
|
||||
#endif
|
||||
result.push_back(NetworkInterface(std::string(ifr->ifr_name), addr, index));
|
||||
}
|
||||
ptr += sizeof(struct ifreq);
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
delete [] buf;
|
||||
throw;
|
||||
}
|
||||
delete [] buf;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
|
||||
|
||||
#else
|
||||
//
|
||||
// Non-BSD Unix variants
|
||||
//
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
NetworkInterface::NetworkInterfaceList NetworkInterface::list()
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
NetworkInterfaceList result;
|
||||
DatagramSocket socket;
|
||||
// the following code is loosely based
|
||||
// on W. Richard Stevens, UNIX Network Programming, pp 434ff.
|
||||
int lastlen = 0;
|
||||
int len = 100*sizeof(struct ifreq);
|
||||
char* buf = 0;
|
||||
try
|
||||
{
|
||||
struct ifconf ifc;
|
||||
for (;;)
|
||||
{
|
||||
buf = new char[len];
|
||||
ifc.ifc_len = len;
|
||||
ifc.ifc_buf = buf;
|
||||
if (::ioctl(socket.impl()->sockfd(), SIOCGIFCONF, &ifc) < 0)
|
||||
{
|
||||
if (errno != EINVAL || lastlen != 0)
|
||||
throw NetException("cannot get network adapter list");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ifc.ifc_len == lastlen)
|
||||
break;
|
||||
lastlen = ifc.ifc_len;
|
||||
}
|
||||
len += 10*sizeof(struct ifreq);
|
||||
delete [] buf;
|
||||
}
|
||||
for (const char* ptr = buf; ptr < buf + ifc.ifc_len;)
|
||||
{
|
||||
const struct ifreq* ifr = reinterpret_cast<const struct ifreq*>(ptr);
|
||||
#if defined(POCO_HAVE_SALEN)
|
||||
len = ifr->ifr_addr.sa_len;
|
||||
if (sizeof(struct sockaddr) > len) len = sizeof(struct sockaddr);
|
||||
#else
|
||||
len = sizeof(struct sockaddr);
|
||||
#endif
|
||||
IPAddress addr;
|
||||
bool haveAddr = false;
|
||||
switch (ifr->ifr_addr.sa_family)
|
||||
{
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
case AF_INET6:
|
||||
if (len < sizeof(struct sockaddr_in6)) len = sizeof(struct sockaddr_in6);
|
||||
addr = IPAddress(&reinterpret_cast<const struct sockaddr_in6*>(&ifr->ifr_addr)->sin6_addr, sizeof(struct in6_addr));
|
||||
haveAddr = true;
|
||||
break;
|
||||
#endif
|
||||
case AF_INET:
|
||||
if (len < sizeof(struct sockaddr_in)) len = sizeof(struct sockaddr_in);
|
||||
addr = IPAddress(&reinterpret_cast<const struct sockaddr_in*>(&ifr->ifr_addr)->sin_addr, sizeof(struct in_addr));
|
||||
haveAddr = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (haveAddr)
|
||||
{
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
int index = if_nametoindex(ifr->ifr_name);
|
||||
#else
|
||||
int index = -1;
|
||||
#endif
|
||||
result.push_back(NetworkInterface(std::string(ifr->ifr_name), addr, index));
|
||||
}
|
||||
len += sizeof(ifr->ifr_name);
|
||||
ptr += len;
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
delete [] buf;
|
||||
throw;
|
||||
}
|
||||
delete [] buf;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
|
||||
|
||||
#endif
|
||||
67
Net/src/NullPartHandler.cpp
Normal file
67
Net/src/NullPartHandler.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
//
|
||||
// NullPartHandler.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/NullPartHandler.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Messages
|
||||
// Module: NullPartHandler
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/NullPartHandler.h"
|
||||
#include "Net/MessageHeader.h"
|
||||
#include "Foundation/NullStream.h"
|
||||
#include "Foundation/StreamCopier.h"
|
||||
|
||||
|
||||
using Foundation::NullOutputStream;
|
||||
using Foundation::StreamCopier;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
NullPartHandler::NullPartHandler()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
NullPartHandler::~NullPartHandler()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void NullPartHandler::handlePart(const MessageHeader& header, std::istream& stream)
|
||||
{
|
||||
NullOutputStream ostr;
|
||||
StreamCopier::copyStream(stream, ostr);
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
299
Net/src/POP3ClientSession.cpp
Normal file
299
Net/src/POP3ClientSession.cpp
Normal file
@@ -0,0 +1,299 @@
|
||||
//
|
||||
// POP3ClientSession.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/POP3ClientSession.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Mail
|
||||
// Module: POP3ClientSession
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/POP3ClientSession.h"
|
||||
#include "Net/MailMessage.h"
|
||||
#include "Net/MailStream.h"
|
||||
#include "Net/SocketAddress.h"
|
||||
#include "Net/NetException.h"
|
||||
#include "Foundation/StreamCopier.h"
|
||||
#include "Foundation/NumberFormatter.h"
|
||||
#include "Foundation/UnbufferedStreamBuf.h"
|
||||
#include <istream>
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
using Foundation::NumberFormatter;
|
||||
using Foundation::StreamCopier;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
class DialogStreamBuf: public Foundation::UnbufferedStreamBuf
|
||||
{
|
||||
public:
|
||||
DialogStreamBuf(DialogSocket& socket):
|
||||
_socket(socket)
|
||||
{
|
||||
}
|
||||
|
||||
~DialogStreamBuf()
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
int readFromDevice()
|
||||
{
|
||||
return _socket.get();
|
||||
}
|
||||
|
||||
DialogSocket& _socket;
|
||||
};
|
||||
|
||||
|
||||
class DialogIOS: public virtual std::ios
|
||||
{
|
||||
public:
|
||||
DialogIOS(DialogSocket& socket):
|
||||
_buf(socket)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
~DialogIOS()
|
||||
{
|
||||
}
|
||||
|
||||
DialogStreamBuf* rdbuf()
|
||||
{
|
||||
return &_buf;
|
||||
}
|
||||
|
||||
protected:
|
||||
DialogStreamBuf _buf;
|
||||
};
|
||||
|
||||
|
||||
class DialogInputStream: public DialogIOS, public std::istream
|
||||
{
|
||||
public:
|
||||
DialogInputStream(DialogSocket& socket):
|
||||
DialogIOS(socket),
|
||||
std::istream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
~DialogInputStream()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
POP3ClientSession::POP3ClientSession(const StreamSocket& socket):
|
||||
_socket(socket),
|
||||
_isOpen(true)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
POP3ClientSession::POP3ClientSession(const std::string& host, Foundation::UInt16 port):
|
||||
_socket(SocketAddress(host, port)),
|
||||
_isOpen(true)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
POP3ClientSession::~POP3ClientSession()
|
||||
{
|
||||
try
|
||||
{
|
||||
close();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void POP3ClientSession::setTimeout(const Foundation::Timespan& timeout)
|
||||
{
|
||||
_socket.setReceiveTimeout(timeout);
|
||||
}
|
||||
|
||||
|
||||
Foundation::Timespan POP3ClientSession::getTimeout() const
|
||||
{
|
||||
return _socket.getReceiveTimeout();
|
||||
}
|
||||
|
||||
|
||||
void POP3ClientSession::login(const std::string& username, const std::string& password)
|
||||
{
|
||||
std::string response;
|
||||
_socket.receiveMessage(response);
|
||||
if (!isPositive(response)) throw SMTPException("The POP3 service is unavailable", response);
|
||||
sendCommand("USER", username, response);
|
||||
if (!isPositive(response)) throw POP3Exception("Login rejected for user", response);
|
||||
sendCommand("PASS", password, response);
|
||||
if (!isPositive(response)) throw POP3Exception("Password rejected for user", response);
|
||||
}
|
||||
|
||||
|
||||
void POP3ClientSession::close()
|
||||
{
|
||||
if (_isOpen)
|
||||
{
|
||||
std::string response;
|
||||
sendCommand("QUIT", response);
|
||||
_socket.close();
|
||||
_isOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int POP3ClientSession::messageCount()
|
||||
{
|
||||
std::string response;
|
||||
sendCommand("STAT", response);
|
||||
if (!isPositive(response)) throw POP3Exception("Cannot determine message count", response);
|
||||
std::string::const_iterator it = response.begin();
|
||||
std::string::const_iterator end = response.end();
|
||||
int count = 0;
|
||||
while (it != end && !isspace(*it)) ++it;
|
||||
while (it != end && isspace(*it)) ++it;
|
||||
while (it != end && isdigit(*it)) count = count*10 + *it++ - '0';
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
void POP3ClientSession::listMessages(MessageInfoVec& messages)
|
||||
{
|
||||
messages.clear();
|
||||
std::string response;
|
||||
sendCommand("LIST", response);
|
||||
if (!isPositive(response)) throw POP3Exception("Cannot get message list", response);
|
||||
_socket.receiveMessage(response);
|
||||
while (response != ".")
|
||||
{
|
||||
MessageInfo info = {0, 0};
|
||||
std::string::const_iterator it = response.begin();
|
||||
std::string::const_iterator end = response.end();
|
||||
while (it != end && isdigit(*it)) info.id = info.id*10 + *it++ - '0';
|
||||
while (it != end && isspace(*it)) ++it;
|
||||
while (it != end && isdigit(*it)) info.size = info.size*10 + *it++ - '0';
|
||||
messages.push_back(info);
|
||||
_socket.receiveMessage(response);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void POP3ClientSession::retrieveMessage(int id, MailMessage& message)
|
||||
{
|
||||
std::string response;
|
||||
sendCommand("RETR", NumberFormatter::format(id), response);
|
||||
if (!isPositive(response)) throw POP3Exception("Cannot get message list", response);
|
||||
DialogInputStream sis(_socket);
|
||||
MailInputStream mis(sis);
|
||||
message.read(mis);
|
||||
}
|
||||
|
||||
|
||||
void POP3ClientSession::retrieveMessage(int id, MailMessage& message, PartHandler& handler)
|
||||
{
|
||||
std::string response;
|
||||
sendCommand("RETR", NumberFormatter::format(id), response);
|
||||
if (!isPositive(response)) throw POP3Exception("Cannot get message list", response);
|
||||
DialogInputStream sis(_socket);
|
||||
MailInputStream mis(sis);
|
||||
message.read(mis, handler);
|
||||
}
|
||||
|
||||
|
||||
void POP3ClientSession::retrieveMessage(int id, std::ostream& ostr)
|
||||
{
|
||||
std::string response;
|
||||
sendCommand("RETR", NumberFormatter::format(id), response);
|
||||
if (!isPositive(response)) throw POP3Exception("Cannot get message list", response);
|
||||
DialogInputStream sis(_socket);
|
||||
MailInputStream mis(sis);
|
||||
StreamCopier::copyStream(mis, ostr);
|
||||
}
|
||||
|
||||
|
||||
void POP3ClientSession::retrieveHeader(int id, MessageHeader& header)
|
||||
{
|
||||
std::string response;
|
||||
sendCommand("TOP", NumberFormatter::format(id), "0", response);
|
||||
if (!isPositive(response)) throw POP3Exception("Cannot get message list", response);
|
||||
DialogInputStream sis(_socket);
|
||||
MailInputStream mis(sis);
|
||||
header.read(mis);
|
||||
// skip stuff following header
|
||||
mis.get(); // \r
|
||||
mis.get(); // \n
|
||||
}
|
||||
|
||||
|
||||
void POP3ClientSession::deleteMessage(int id)
|
||||
{
|
||||
std::string response;
|
||||
sendCommand("DELE", NumberFormatter::format(id), response);
|
||||
if (!isPositive(response)) throw POP3Exception("Cannot mark message for deletion", response);
|
||||
}
|
||||
|
||||
|
||||
bool POP3ClientSession::sendCommand(const std::string& command, std::string& response)
|
||||
{
|
||||
_socket.sendMessage(command);
|
||||
_socket.receiveMessage(response);
|
||||
return isPositive(response);
|
||||
}
|
||||
|
||||
|
||||
bool POP3ClientSession::sendCommand(const std::string& command, const std::string& arg, std::string& response)
|
||||
{
|
||||
_socket.sendMessage(command, arg);
|
||||
_socket.receiveMessage(response);
|
||||
return isPositive(response);
|
||||
}
|
||||
|
||||
|
||||
bool POP3ClientSession::sendCommand(const std::string& command, const std::string& arg1, const std::string& arg2, std::string& response)
|
||||
{
|
||||
_socket.sendMessage(command, arg1, arg2);
|
||||
_socket.receiveMessage(response);
|
||||
return isPositive(response);
|
||||
}
|
||||
|
||||
|
||||
bool POP3ClientSession::isPositive(const std::string& response)
|
||||
{
|
||||
return response.length() > 0 && response[0] == '+';
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
53
Net/src/PartHandler.cpp
Normal file
53
Net/src/PartHandler.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// PartHandler.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/PartHandler.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Messages
|
||||
// Module: PartHandler
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/PartHandler.h"
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
PartHandler::PartHandler()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
PartHandler::~PartHandler()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
67
Net/src/PartSource.cpp
Normal file
67
Net/src/PartSource.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
//
|
||||
// PartSource.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/PartSource.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Messages
|
||||
// Module: PartSource
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/PartSource.h"
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
PartSource::PartSource():
|
||||
_mediaType("application/octet-stream")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
PartSource::PartSource(const std::string& mediaType):
|
||||
_mediaType(mediaType)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
PartSource::~PartSource()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const std::string& PartSource::filename()
|
||||
{
|
||||
static const std::string empty;
|
||||
return empty;
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
125
Net/src/QuotedPrintableDecoder.cpp
Normal file
125
Net/src/QuotedPrintableDecoder.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
//
|
||||
// QuotedPrintableDecoder.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/QuotedPrintableDecoder.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Messages
|
||||
// Module: QuotedPrintableDecoder
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/QuotedPrintableDecoder.h"
|
||||
#include "Foundation/NumberParser.h"
|
||||
#include "Foundation/Exception.h"
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
using Foundation::UnbufferedStreamBuf;
|
||||
using Foundation::NumberParser;
|
||||
using Foundation::DataFormatException;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
QuotedPrintableDecoderBuf::QuotedPrintableDecoderBuf(std::istream& istr):
|
||||
_istr(istr)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
QuotedPrintableDecoderBuf::~QuotedPrintableDecoderBuf()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int QuotedPrintableDecoderBuf::readFromDevice()
|
||||
{
|
||||
static const int eof = std::char_traits<char>::eof();
|
||||
|
||||
int ch = _istr.get();
|
||||
while (ch == '=')
|
||||
{
|
||||
ch = _istr.get();
|
||||
if (ch == '\r')
|
||||
{
|
||||
ch = _istr.get(); // read \n
|
||||
}
|
||||
else if (isxdigit(ch))
|
||||
{
|
||||
std::string hex;
|
||||
hex += (char) ch;
|
||||
ch = _istr.get();
|
||||
if (isxdigit(ch))
|
||||
{
|
||||
hex += (char) ch;
|
||||
return NumberParser::parseHex(hex);
|
||||
}
|
||||
throw DataFormatException("Incomplete hex number in quoted-printable encoded stream");
|
||||
}
|
||||
else if (ch != '\n')
|
||||
{
|
||||
throw DataFormatException("Invalid occurrence of '=' in quoted-printable encoded stream");
|
||||
}
|
||||
ch = _istr.get();
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
|
||||
|
||||
QuotedPrintableDecoderIOS::QuotedPrintableDecoderIOS(std::istream& istr): _buf(istr)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
QuotedPrintableDecoderIOS::~QuotedPrintableDecoderIOS()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
QuotedPrintableDecoderBuf* QuotedPrintableDecoderIOS::rdbuf()
|
||||
{
|
||||
return &_buf;
|
||||
}
|
||||
|
||||
|
||||
QuotedPrintableDecoder::QuotedPrintableDecoder(std::istream& istr):
|
||||
QuotedPrintableDecoderIOS(istr),
|
||||
std::istream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
QuotedPrintableDecoder::~QuotedPrintableDecoder()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
171
Net/src/QuotedPrintableEncoder.cpp
Normal file
171
Net/src/QuotedPrintableEncoder.cpp
Normal file
@@ -0,0 +1,171 @@
|
||||
//
|
||||
// QuotedPrintableEncoder.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/QuotedPrintableEncoder.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Messages
|
||||
// Module: QuotedPrintableEncoder
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/QuotedPrintableEncoder.h"
|
||||
#include "Foundation/NumberFormatter.h"
|
||||
|
||||
|
||||
using Foundation::UnbufferedStreamBuf;
|
||||
using Foundation::NumberFormatter;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
QuotedPrintableEncoderBuf::QuotedPrintableEncoderBuf(std::ostream& ostr):
|
||||
_pending(-1),
|
||||
_lineLength(0),
|
||||
_ostr(ostr)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
QuotedPrintableEncoderBuf::~QuotedPrintableEncoderBuf()
|
||||
{
|
||||
try
|
||||
{
|
||||
close();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int QuotedPrintableEncoderBuf::writeToDevice(char c)
|
||||
{
|
||||
if (_pending != -1)
|
||||
{
|
||||
if (_pending == '\r' && c == '\n')
|
||||
writeRaw((char) _pending);
|
||||
else if (c == '\r' || c == '\n')
|
||||
writeEncoded((char) _pending);
|
||||
else
|
||||
writeRaw((char) _pending);
|
||||
_pending = -1;
|
||||
}
|
||||
if (c == '\t' || c == ' ')
|
||||
{
|
||||
_pending = charToInt(c);
|
||||
return _pending;
|
||||
}
|
||||
else if (c == '\r' || c == '\n' || c > 32 && c < 127 && c != '=')
|
||||
{
|
||||
writeRaw(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
writeEncoded(c);
|
||||
}
|
||||
return charToInt(c);
|
||||
}
|
||||
|
||||
|
||||
void QuotedPrintableEncoderBuf::writeEncoded(char c)
|
||||
{
|
||||
if (_lineLength >= 73)
|
||||
{
|
||||
_ostr << "=\r\n";
|
||||
_lineLength = 3;
|
||||
}
|
||||
else _lineLength += 3;
|
||||
_ostr << '=' << NumberFormatter::formatHex((unsigned) charToInt(c), 2);
|
||||
}
|
||||
|
||||
|
||||
void QuotedPrintableEncoderBuf::writeRaw(char c)
|
||||
{
|
||||
if (c == '\r' || c == '\n')
|
||||
{
|
||||
_ostr.put(c);
|
||||
_lineLength = 0;
|
||||
}
|
||||
else if (_lineLength < 75)
|
||||
{
|
||||
_ostr.put(c);
|
||||
++_lineLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
_ostr << "=\r\n" << c;
|
||||
_lineLength = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int QuotedPrintableEncoderBuf::close()
|
||||
{
|
||||
sync();
|
||||
return _ostr ? 0 : -1;
|
||||
}
|
||||
|
||||
|
||||
QuotedPrintableEncoderIOS::QuotedPrintableEncoderIOS(std::ostream& ostr): _buf(ostr)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
QuotedPrintableEncoderIOS::~QuotedPrintableEncoderIOS()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int QuotedPrintableEncoderIOS::close()
|
||||
{
|
||||
return _buf.close();
|
||||
}
|
||||
|
||||
|
||||
QuotedPrintableEncoderBuf* QuotedPrintableEncoderIOS::rdbuf()
|
||||
{
|
||||
return &_buf;
|
||||
}
|
||||
|
||||
|
||||
QuotedPrintableEncoder::QuotedPrintableEncoder(std::ostream& ostr):
|
||||
QuotedPrintableEncoderIOS(ostr),
|
||||
std::ostream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
QuotedPrintableEncoder::~QuotedPrintableEncoder()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
163
Net/src/SMTPClientSession.cpp
Normal file
163
Net/src/SMTPClientSession.cpp
Normal file
@@ -0,0 +1,163 @@
|
||||
//
|
||||
// SMTPClientSession.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/SMTPClientSession.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Mail
|
||||
// Module: SMTPClientSession
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/SMTPClientSession.h"
|
||||
#include "Net/MailMessage.h"
|
||||
#include "Net/MailRecipient.h"
|
||||
#include "Net/MailStream.h"
|
||||
#include "Net/SocketAddress.h"
|
||||
#include "Net/SocketStream.h"
|
||||
#include "Net/NetException.h"
|
||||
#include "Foundation/Environment.h"
|
||||
|
||||
|
||||
using Foundation::Environment;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
SMTPClientSession::SMTPClientSession(const StreamSocket& socket):
|
||||
_socket(socket),
|
||||
_isOpen(true)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SMTPClientSession::SMTPClientSession(const std::string& host, Foundation::UInt16 port):
|
||||
_socket(SocketAddress(host, port)),
|
||||
_isOpen(true)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SMTPClientSession::~SMTPClientSession()
|
||||
{
|
||||
try
|
||||
{
|
||||
close();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SMTPClientSession::setTimeout(const Foundation::Timespan& timeout)
|
||||
{
|
||||
_socket.setReceiveTimeout(timeout);
|
||||
}
|
||||
|
||||
|
||||
Foundation::Timespan SMTPClientSession::getTimeout() const
|
||||
{
|
||||
return _socket.getReceiveTimeout();
|
||||
}
|
||||
|
||||
|
||||
void SMTPClientSession::login(const std::string& hostname)
|
||||
{
|
||||
std::string response;
|
||||
int status = _socket.receiveStatusMessage(response);
|
||||
if (!isPositiveCompletion(status)) throw SMTPException("The mail service is unavailable", response);
|
||||
status = sendCommand("EHLO", hostname, response);
|
||||
if (isPermanentNegative(status))
|
||||
status = sendCommand("HELO", hostname, response);
|
||||
if (!isPositiveCompletion(status)) throw SMTPException("Login failed", response);
|
||||
}
|
||||
|
||||
|
||||
void SMTPClientSession::login()
|
||||
{
|
||||
login(Environment::nodeName());
|
||||
}
|
||||
|
||||
|
||||
void SMTPClientSession::close()
|
||||
{
|
||||
if (_isOpen)
|
||||
{
|
||||
std::string response;
|
||||
sendCommand("QUIT", response);
|
||||
_socket.close();
|
||||
_isOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SMTPClientSession::sendMessage(const MailMessage& message)
|
||||
{
|
||||
std::string response;
|
||||
std::string sender("<");
|
||||
sender.append(message.getSender());
|
||||
sender.append(">");
|
||||
int status = sendCommand("MAIL FROM:", sender, response);
|
||||
if (!isPositiveCompletion(status)) throw SMTPException("Cannot send message", response);
|
||||
for (MailMessage::Recipients::const_iterator it = message.recipients().begin(); it != message.recipients().end(); ++it)
|
||||
{
|
||||
std::string recipient("<");
|
||||
recipient.append(it->getAddress());
|
||||
recipient.append(">");
|
||||
int status = sendCommand("RCPT TO:", recipient, response);
|
||||
if (!isPositiveCompletion(status)) throw SMTPException(std::string("Recipient rejected: ") + recipient, response);
|
||||
}
|
||||
status = sendCommand("DATA", response);
|
||||
if (!isPositiveIntermediate(status)) throw SMTPException("Cannot send message data", response);
|
||||
SocketOutputStream socketStream(_socket);
|
||||
MailOutputStream mailStream(socketStream);
|
||||
message.write(mailStream);
|
||||
mailStream.close();
|
||||
socketStream.flush();
|
||||
status = _socket.receiveStatusMessage(response);
|
||||
if (!isPositiveCompletion(status)) throw SMTPException("The server rejected the message", response);
|
||||
}
|
||||
|
||||
|
||||
int SMTPClientSession::sendCommand(const std::string& command, std::string& response)
|
||||
{
|
||||
_socket.sendMessage(command);
|
||||
return _socket.receiveStatusMessage(response);
|
||||
}
|
||||
|
||||
|
||||
int SMTPClientSession::sendCommand(const std::string& command, const std::string& arg, std::string& response)
|
||||
{
|
||||
_socket.sendMessage(command, arg);
|
||||
return _socket.receiveStatusMessage(response);
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
129
Net/src/ServerSocket.cpp
Normal file
129
Net/src/ServerSocket.cpp
Normal file
@@ -0,0 +1,129 @@
|
||||
//
|
||||
// ServerSocket.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/ServerSocket.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Sockets
|
||||
// Module: ServerSocket
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/ServerSocket.h"
|
||||
#include "Net/ServerSocketImpl.h"
|
||||
#include "Foundation/Exception.h"
|
||||
|
||||
|
||||
using Foundation::InvalidArgumentException;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
ServerSocket::ServerSocket(): Socket(new ServerSocketImpl)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ServerSocket::ServerSocket(const Socket& socket): Socket(socket)
|
||||
{
|
||||
if (!dynamic_cast<ServerSocketImpl*>(impl()))
|
||||
throw InvalidArgumentException("Cannot assign incompatible socket");
|
||||
}
|
||||
|
||||
|
||||
ServerSocket::ServerSocket(const SocketAddress& address, int backlog): Socket(new ServerSocketImpl)
|
||||
{
|
||||
impl()->bind(address, true);
|
||||
impl()->listen(backlog);
|
||||
}
|
||||
|
||||
|
||||
ServerSocket::ServerSocket(Foundation::UInt16 port, int backlog): Socket(new ServerSocketImpl)
|
||||
{
|
||||
IPAddress wildcardAddr;
|
||||
SocketAddress address(wildcardAddr, port);
|
||||
impl()->bind(address, true);
|
||||
impl()->listen(backlog);
|
||||
}
|
||||
|
||||
|
||||
ServerSocket::ServerSocket(SocketImpl* pImpl, bool ignore): Socket(pImpl)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ServerSocket::~ServerSocket()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ServerSocket& ServerSocket::operator = (const Socket& socket)
|
||||
{
|
||||
if (dynamic_cast<ServerSocketImpl*>(socket.impl()))
|
||||
Socket::operator = (socket);
|
||||
else
|
||||
throw InvalidArgumentException("Cannot assign incompatible socket");
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void ServerSocket::bind(const SocketAddress& address, bool reuseAddress)
|
||||
{
|
||||
impl()->bind(address, reuseAddress);
|
||||
}
|
||||
|
||||
|
||||
void ServerSocket::bind(Foundation::UInt16 port, bool reuseAddress)
|
||||
{
|
||||
IPAddress wildcardAddr;
|
||||
SocketAddress address(wildcardAddr, port);
|
||||
impl()->bind(address, reuseAddress);
|
||||
}
|
||||
|
||||
|
||||
void ServerSocket::listen(int backlog)
|
||||
{
|
||||
impl()->listen(backlog);
|
||||
}
|
||||
|
||||
|
||||
StreamSocket ServerSocket::acceptConnection(SocketAddress& clientAddr)
|
||||
{
|
||||
return StreamSocket(impl()->acceptConnection(clientAddr));
|
||||
}
|
||||
|
||||
|
||||
StreamSocket ServerSocket::acceptConnection()
|
||||
{
|
||||
SocketAddress clientAddr;
|
||||
return StreamSocket(impl()->acceptConnection(clientAddr));
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
53
Net/src/ServerSocketImpl.cpp
Normal file
53
Net/src/ServerSocketImpl.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// ServerSocketImpl.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/ServerSocketImpl.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Sockets
|
||||
// Module: ServerSocketImpl
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/ServerSocketImpl.h"
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
ServerSocketImpl::ServerSocketImpl()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ServerSocketImpl::~ServerSocketImpl()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
144
Net/src/Socket.cpp
Normal file
144
Net/src/Socket.cpp
Normal file
@@ -0,0 +1,144 @@
|
||||
//
|
||||
// Socket.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/Socket.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Sockets
|
||||
// Module: Socket
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/Socket.h"
|
||||
#include "Net/StreamSocketImpl.h"
|
||||
#include <algorithm>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
Socket::Socket():
|
||||
_pImpl(new StreamSocketImpl)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Socket::Socket(SocketImpl* pImpl):
|
||||
_pImpl(pImpl)
|
||||
{
|
||||
poco_check_ptr (_pImpl);
|
||||
}
|
||||
|
||||
|
||||
Socket::Socket(const Socket& socket):
|
||||
_pImpl(socket._pImpl)
|
||||
{
|
||||
poco_check_ptr (_pImpl);
|
||||
|
||||
_pImpl->duplicate();
|
||||
}
|
||||
|
||||
|
||||
Socket& Socket::operator = (const Socket& socket)
|
||||
{
|
||||
if (&socket != this)
|
||||
{
|
||||
if (_pImpl) _pImpl->release();
|
||||
_pImpl = socket._pImpl;
|
||||
if (_pImpl) _pImpl->duplicate();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Socket::~Socket()
|
||||
{
|
||||
_pImpl->release();
|
||||
}
|
||||
|
||||
|
||||
int Socket::select(SocketList& readList, SocketList& writeList, SocketList& exceptList, const Foundation::Timespan& timeout)
|
||||
{
|
||||
fd_set fdRead;
|
||||
fd_set fdWrite;
|
||||
fd_set fdExcept;
|
||||
int nfd = 0;
|
||||
FD_ZERO(&fdRead);
|
||||
for (SocketList::const_iterator it = readList.begin(); it != readList.end(); ++it)
|
||||
{
|
||||
if (int(it->sockfd()) > nfd)
|
||||
nfd = int(it->sockfd());
|
||||
FD_SET(it->sockfd(), &fdRead);
|
||||
}
|
||||
FD_ZERO(&fdWrite);
|
||||
for (SocketList::const_iterator it = writeList.begin(); it != writeList.end(); ++it)
|
||||
{
|
||||
if (int(it->sockfd()) > nfd)
|
||||
nfd = int(it->sockfd());
|
||||
FD_SET(it->sockfd(), &fdWrite);
|
||||
}
|
||||
FD_ZERO(&fdExcept);
|
||||
for (SocketList::const_iterator it = exceptList.begin(); it != exceptList.end(); ++it)
|
||||
{
|
||||
if (int(it->sockfd()) > nfd)
|
||||
nfd = int(it->sockfd());
|
||||
FD_SET(it->sockfd(), &fdExcept);
|
||||
}
|
||||
struct timeval tv;
|
||||
tv.tv_sec = (long) timeout.totalSeconds();
|
||||
tv.tv_usec = (long) timeout.useconds();
|
||||
int rc = ::select(nfd + 1, &fdRead, &fdWrite, &fdExcept, &tv);
|
||||
if (rc < 0) SocketImpl::error();
|
||||
|
||||
SocketList readyReadList;
|
||||
for (SocketList::const_iterator it = readList.begin(); it != readList.end(); ++it)
|
||||
{
|
||||
if (FD_ISSET(it->sockfd(), &fdRead))
|
||||
readyReadList.push_back(*it);
|
||||
}
|
||||
std::swap(readList, readyReadList);
|
||||
SocketList readyWriteList;
|
||||
for (SocketList::const_iterator it = writeList.begin(); it != writeList.end(); ++it)
|
||||
{
|
||||
if (FD_ISSET(it->sockfd(), &fdWrite))
|
||||
readyWriteList.push_back(*it);
|
||||
}
|
||||
std::swap(writeList, readyWriteList);
|
||||
SocketList readyExceptList;
|
||||
for (SocketList::const_iterator it = exceptList.begin(); it != exceptList.end(); ++it)
|
||||
{
|
||||
if (FD_ISSET(it->sockfd(), &fdExcept))
|
||||
readyExceptList.push_back(*it);
|
||||
}
|
||||
std::swap(exceptList, readyExceptList);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
350
Net/src/SocketAddress.cpp
Normal file
350
Net/src/SocketAddress.cpp
Normal file
@@ -0,0 +1,350 @@
|
||||
//
|
||||
// SocketAddress.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/SocketAddress.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: NetCore
|
||||
// Module: SocketAddress
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/SocketAddress.h"
|
||||
#include "Net/IPAddress.h"
|
||||
#include "Net/NetException.h"
|
||||
#include "Net/DNS.h"
|
||||
#include "Foundation/RefCountedObject.h"
|
||||
#include "Foundation/NumberParser.h"
|
||||
#include "Foundation/NumberFormatter.h"
|
||||
#include <algorithm>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
using Foundation::RefCountedObject;
|
||||
using Foundation::NumberParser;
|
||||
using Foundation::NumberFormatter;
|
||||
using Foundation::UInt16;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
//
|
||||
// SocketAddressImpl
|
||||
//
|
||||
|
||||
|
||||
class SocketAddressImpl: public RefCountedObject
|
||||
{
|
||||
public:
|
||||
virtual IPAddress host() const = 0;
|
||||
virtual UInt16 port() const = 0;
|
||||
virtual poco_socklen_t length() const = 0;
|
||||
virtual const struct sockaddr* addr() const = 0;
|
||||
virtual int af() const = 0;
|
||||
|
||||
protected:
|
||||
SocketAddressImpl()
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~SocketAddressImpl()
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
SocketAddressImpl(const SocketAddressImpl&);
|
||||
SocketAddressImpl& operator = (const SocketAddressImpl&);
|
||||
};
|
||||
|
||||
|
||||
class IPv4SocketAddressImpl: public SocketAddressImpl
|
||||
{
|
||||
public:
|
||||
IPv4SocketAddressImpl()
|
||||
{
|
||||
memset(&_addr, 0, sizeof(_addr));
|
||||
_addr.sin_family = AF_INET;
|
||||
poco_set_sin_len(&_addr);
|
||||
}
|
||||
|
||||
IPv4SocketAddressImpl(const struct sockaddr_in* addr)
|
||||
{
|
||||
memcpy(&_addr, addr, sizeof(_addr));
|
||||
}
|
||||
|
||||
IPv4SocketAddressImpl(const void* addr, UInt16 port)
|
||||
{
|
||||
memset(&_addr, 0, sizeof(_addr));
|
||||
_addr.sin_family = AF_INET;
|
||||
memcpy(&_addr.sin_addr, addr, sizeof(_addr.sin_addr));
|
||||
_addr.sin_port = port;
|
||||
}
|
||||
|
||||
IPAddress host() const
|
||||
{
|
||||
return IPAddress(&_addr.sin_addr, sizeof(_addr.sin_addr));
|
||||
}
|
||||
|
||||
UInt16 port() const
|
||||
{
|
||||
return _addr.sin_port;
|
||||
}
|
||||
|
||||
poco_socklen_t length() const
|
||||
{
|
||||
return sizeof(_addr);
|
||||
}
|
||||
|
||||
const struct sockaddr* addr() const
|
||||
{
|
||||
return reinterpret_cast<const struct sockaddr*>(&_addr);
|
||||
}
|
||||
|
||||
int af() const
|
||||
{
|
||||
return _addr.sin_family;
|
||||
}
|
||||
|
||||
private:
|
||||
struct sockaddr_in _addr;
|
||||
};
|
||||
|
||||
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
|
||||
|
||||
class IPv6SocketAddressImpl: public SocketAddressImpl
|
||||
{
|
||||
public:
|
||||
IPv6SocketAddressImpl(const struct sockaddr_in6* addr)
|
||||
{
|
||||
memcpy(&_addr, addr, sizeof(_addr));
|
||||
}
|
||||
|
||||
IPv6SocketAddressImpl(const void* addr, UInt16 port)
|
||||
{
|
||||
memset(&_addr, 0, sizeof(_addr));
|
||||
_addr.sin6_family = AF_INET6;
|
||||
poco_set_sin6_len(&_addr);
|
||||
memcpy(&_addr.sin6_addr, addr, sizeof(_addr.sin6_addr));
|
||||
_addr.sin6_port = port;
|
||||
}
|
||||
|
||||
IPAddress host() const
|
||||
{
|
||||
return IPAddress(&_addr.sin6_addr, sizeof(_addr.sin6_addr));
|
||||
}
|
||||
|
||||
UInt16 port() const
|
||||
{
|
||||
return _addr.sin6_port;
|
||||
}
|
||||
|
||||
poco_socklen_t length() const
|
||||
{
|
||||
return sizeof(_addr);
|
||||
}
|
||||
|
||||
const struct sockaddr* addr() const
|
||||
{
|
||||
return reinterpret_cast<const struct sockaddr*>(&_addr);
|
||||
}
|
||||
|
||||
int af() const
|
||||
{
|
||||
return _addr.sin6_family;
|
||||
}
|
||||
|
||||
private:
|
||||
struct sockaddr_in6 _addr;
|
||||
};
|
||||
|
||||
|
||||
#endif // POCO_HAVE_IPv6
|
||||
|
||||
|
||||
//
|
||||
// SocketAddress
|
||||
//
|
||||
|
||||
|
||||
SocketAddress::SocketAddress()
|
||||
{
|
||||
_pImpl = new IPv4SocketAddressImpl;
|
||||
}
|
||||
|
||||
|
||||
SocketAddress::SocketAddress(const IPAddress& addr, Foundation::UInt16 port)
|
||||
{
|
||||
init(addr, port);
|
||||
}
|
||||
|
||||
|
||||
SocketAddress::SocketAddress(const std::string& addr, Foundation::UInt16 port)
|
||||
{
|
||||
init(addr, port);
|
||||
}
|
||||
|
||||
|
||||
SocketAddress::SocketAddress(const std::string& addr, const std::string& port)
|
||||
{
|
||||
init(addr, resolveService(port));
|
||||
}
|
||||
|
||||
|
||||
SocketAddress::SocketAddress(const SocketAddress& addr)
|
||||
{
|
||||
_pImpl = addr._pImpl;
|
||||
_pImpl->duplicate();
|
||||
}
|
||||
|
||||
|
||||
SocketAddress::SocketAddress(const struct sockaddr* addr, poco_socklen_t length)
|
||||
{
|
||||
if (length == sizeof(struct sockaddr_in))
|
||||
_pImpl = new IPv4SocketAddressImpl(reinterpret_cast<const struct sockaddr_in*>(addr));
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
else if (length == sizeof(struct sockaddr_in6))
|
||||
_pImpl = new IPv6SocketAddressImpl(reinterpret_cast<const struct sockaddr_in6*>(addr));
|
||||
#endif
|
||||
else throw Foundation::InvalidArgumentException("Invalid address length passed to SocketAddress()");
|
||||
}
|
||||
|
||||
|
||||
SocketAddress::~SocketAddress()
|
||||
{
|
||||
_pImpl->release();
|
||||
}
|
||||
|
||||
|
||||
SocketAddress& SocketAddress::operator = (const SocketAddress& addr)
|
||||
{
|
||||
if (&addr != this)
|
||||
{
|
||||
_pImpl->release();
|
||||
_pImpl = addr._pImpl;
|
||||
_pImpl->duplicate();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void SocketAddress::swap(SocketAddress& addr)
|
||||
{
|
||||
std::swap(_pImpl, addr._pImpl);
|
||||
}
|
||||
|
||||
|
||||
IPAddress SocketAddress::host() const
|
||||
{
|
||||
return _pImpl->host();
|
||||
}
|
||||
|
||||
|
||||
Foundation::UInt16 SocketAddress::port() const
|
||||
{
|
||||
return ntohs(_pImpl->port());
|
||||
}
|
||||
|
||||
|
||||
poco_socklen_t SocketAddress::length() const
|
||||
{
|
||||
return _pImpl->length();
|
||||
}
|
||||
|
||||
|
||||
const struct sockaddr* SocketAddress::addr() const
|
||||
{
|
||||
return _pImpl->addr();
|
||||
}
|
||||
|
||||
|
||||
int SocketAddress::af() const
|
||||
{
|
||||
return _pImpl->af();
|
||||
}
|
||||
|
||||
|
||||
std::string SocketAddress::toString() const
|
||||
{
|
||||
std::string result = host().toString();
|
||||
result.append(":");
|
||||
result.append(NumberFormatter::format(port()));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void SocketAddress::init(const IPAddress& host, Foundation::UInt16 port)
|
||||
{
|
||||
if (host.family() == IPAddress::IPv4)
|
||||
_pImpl = new IPv4SocketAddressImpl(host.addr(), htons(port));
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
else if (host.family() == IPAddress::IPv6)
|
||||
_pImpl = new IPv6SocketAddressImpl(host.addr(), htons(port));
|
||||
#endif
|
||||
else throw Foundation::NotImplementedException("unsupported IP address family");
|
||||
}
|
||||
|
||||
|
||||
void SocketAddress::init(const std::string& host, Foundation::UInt16 port)
|
||||
{
|
||||
IPAddress ip;
|
||||
if (IPAddress::tryParse(host, ip))
|
||||
{
|
||||
init(ip, port);
|
||||
}
|
||||
else
|
||||
{
|
||||
HostEntry he = DNS::hostByName(host);
|
||||
if (he.addresses().size() > 0)
|
||||
init(he.addresses()[0], port);
|
||||
else throw HostNotFoundException("No address found for host", host);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foundation::UInt16 SocketAddress::resolveService(const std::string& service)
|
||||
{
|
||||
unsigned port;
|
||||
if (NumberParser::tryParseUnsigned(service, port) && port <= 0xFFFF)
|
||||
{
|
||||
return (UInt16) port;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct servent* se = getservbyname(service.c_str(), NULL);
|
||||
if (se)
|
||||
return ntohs(se->s_port);
|
||||
else
|
||||
throw ServiceNotFoundException(service);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
845
Net/src/SocketImpl.cpp
Normal file
845
Net/src/SocketImpl.cpp
Normal file
@@ -0,0 +1,845 @@
|
||||
//
|
||||
// SocketImpl.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/SocketImpl.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Sockets
|
||||
// Module: SocketImpl
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/SocketImpl.h"
|
||||
#include "Net/NetException.h"
|
||||
#include "Net/StreamSocketImpl.h"
|
||||
#include "Foundation/NumberFormatter.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
using Foundation::IOException;
|
||||
using Foundation::TimeoutException;
|
||||
using Foundation::InvalidArgumentException;
|
||||
using Foundation::NumberFormatter;
|
||||
using Foundation::Timespan;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
SocketImpl::SocketImpl():
|
||||
_sockfd(POCO_INVALID_SOCKET)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SocketImpl::SocketImpl(poco_socket_t sockfd):
|
||||
_sockfd(sockfd)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SocketImpl::~SocketImpl()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
SocketImpl* SocketImpl::acceptConnection(SocketAddress& clientAddr)
|
||||
{
|
||||
poco_assert (_sockfd != POCO_INVALID_SOCKET);
|
||||
|
||||
char buffer[SocketAddress::MAX_ADDRESS_LENGTH];
|
||||
struct sockaddr* pSA = reinterpret_cast<struct sockaddr*>(buffer);
|
||||
poco_socklen_t saLen = sizeof(buffer);
|
||||
poco_socket_t sd;
|
||||
do
|
||||
{
|
||||
sd = ::accept(_sockfd, pSA, &saLen);
|
||||
}
|
||||
while (sd == POCO_INVALID_SOCKET && lastError() == POCO_EINTR);
|
||||
if (sd != POCO_INVALID_SOCKET)
|
||||
{
|
||||
clientAddr = SocketAddress(pSA, saLen);
|
||||
return new StreamSocketImpl(sd);
|
||||
}
|
||||
error(); // will throw
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::connect(const SocketAddress& address)
|
||||
{
|
||||
if (_sockfd == POCO_INVALID_SOCKET)
|
||||
{
|
||||
init(address.af());
|
||||
}
|
||||
int rc;
|
||||
do
|
||||
{
|
||||
rc = ::connect(_sockfd, address.addr(), address.length());
|
||||
}
|
||||
while (rc != 0 && lastError() == POCO_EINTR);
|
||||
if (rc != 0) error(address.toString());
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::connect(const SocketAddress& address, const Foundation::Timespan& timeout)
|
||||
{
|
||||
poco_assert (_sockfd == POCO_INVALID_SOCKET);
|
||||
|
||||
init(address.af());
|
||||
setBlocking(false);
|
||||
try
|
||||
{
|
||||
int rc = ::connect(_sockfd, address.addr(), address.length());
|
||||
if (rc != 0)
|
||||
{
|
||||
if (lastError() != POCO_EINPROGRESS && lastError() != POCO_EWOULDBLOCK)
|
||||
error(address.toString());
|
||||
if (!poll(timeout, SELECT_READ | SELECT_WRITE))
|
||||
throw Foundation::TimeoutException("connect timed out", address.toString());
|
||||
int err = socketError();
|
||||
if (err != 0) error(err);
|
||||
}
|
||||
}
|
||||
catch (Foundation::Exception&)
|
||||
{
|
||||
setBlocking(true);
|
||||
throw;
|
||||
}
|
||||
setBlocking(true);
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::connectNB(const SocketAddress& address)
|
||||
{
|
||||
if (_sockfd == POCO_INVALID_SOCKET)
|
||||
{
|
||||
init(address.af());
|
||||
}
|
||||
setBlocking(false);
|
||||
int rc = ::connect(_sockfd, address.addr(), address.length());
|
||||
if (rc != 0)
|
||||
{
|
||||
if (lastError() != POCO_EINPROGRESS && lastError() != POCO_EWOULDBLOCK)
|
||||
error(address.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::bind(const SocketAddress& address, bool reuseAddress)
|
||||
{
|
||||
if (_sockfd == POCO_INVALID_SOCKET)
|
||||
{
|
||||
init(address.af());
|
||||
}
|
||||
if (reuseAddress)
|
||||
{
|
||||
setReuseAddress(true);
|
||||
setReusePort(true);
|
||||
}
|
||||
int rc = ::bind(_sockfd, address.addr(), address.length());
|
||||
if (rc != 0) error(address.toString());
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::listen(int backlog)
|
||||
{
|
||||
poco_assert (_sockfd != POCO_INVALID_SOCKET);
|
||||
|
||||
int rc = ::listen(_sockfd, backlog);
|
||||
if (rc != 0) error();
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::close()
|
||||
{
|
||||
if (_sockfd != POCO_INVALID_SOCKET)
|
||||
{
|
||||
poco_closesocket(_sockfd);
|
||||
_sockfd = POCO_INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::shutdownReceive()
|
||||
{
|
||||
poco_assert (_sockfd != POCO_INVALID_SOCKET);
|
||||
|
||||
int rc = ::shutdown(_sockfd, 0);
|
||||
if (rc != 0) error();
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::shutdownSend()
|
||||
{
|
||||
poco_assert (_sockfd != POCO_INVALID_SOCKET);
|
||||
|
||||
int rc = ::shutdown(_sockfd, 1);
|
||||
if (rc != 0) error();
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::shutdown()
|
||||
{
|
||||
poco_assert (_sockfd != POCO_INVALID_SOCKET);
|
||||
|
||||
int rc = ::shutdown(_sockfd, 2);
|
||||
if (rc != 0) error();
|
||||
}
|
||||
|
||||
|
||||
int SocketImpl::sendBytes(const void* buffer, int length, int flags)
|
||||
{
|
||||
poco_assert (_sockfd != POCO_INVALID_SOCKET);
|
||||
|
||||
int rc;
|
||||
do
|
||||
{
|
||||
rc = ::send(_sockfd, reinterpret_cast<const char*>(buffer), length, flags);
|
||||
}
|
||||
while (rc < 0 && lastError() == POCO_EINTR);
|
||||
if (rc < 0) error();
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int SocketImpl::receiveBytes(void* buffer, int length, int flags)
|
||||
{
|
||||
poco_assert (_sockfd != POCO_INVALID_SOCKET);
|
||||
|
||||
#if defined(POCO_BROKEN_TIMEOUTS)
|
||||
if (_recvTimeout.totalMicroseconds() != 0)
|
||||
{
|
||||
if (!poll(_recvTimeout, SELECT_READ))
|
||||
throw TimeoutException();
|
||||
}
|
||||
#endif
|
||||
|
||||
int rc;
|
||||
do
|
||||
{
|
||||
rc = ::recv(_sockfd, reinterpret_cast<char*>(buffer), length, flags);
|
||||
}
|
||||
while (rc < 0 && lastError() == POCO_EINTR);
|
||||
if (rc < 0)
|
||||
{
|
||||
if (lastError() == POCO_EAGAIN || lastError() == POCO_ETIMEDOUT)
|
||||
throw TimeoutException();
|
||||
else
|
||||
error();
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int SocketImpl::sendTo(const void* buffer, int length, const SocketAddress& address, int flags)
|
||||
{
|
||||
poco_assert (_sockfd != POCO_INVALID_SOCKET);
|
||||
|
||||
int rc;
|
||||
do
|
||||
{
|
||||
rc = ::sendto(_sockfd, reinterpret_cast<const char*>(buffer), length, flags, address.addr(), address.length());
|
||||
}
|
||||
while (rc < 0 && lastError() == POCO_EINTR);
|
||||
if (rc < 0) error();
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int SocketImpl::receiveFrom(void* buffer, int length, SocketAddress& address, int flags)
|
||||
{
|
||||
poco_assert (_sockfd != POCO_INVALID_SOCKET);
|
||||
|
||||
#if defined(POCO_BROKEN_TIMEOUTS)
|
||||
if (_recvTimeout.totalMicroseconds() != 0)
|
||||
{
|
||||
if (!poll(_recvTimeout, SELECT_READ))
|
||||
throw TimeoutException();
|
||||
}
|
||||
#endif
|
||||
|
||||
char abuffer[SocketAddress::MAX_ADDRESS_LENGTH];
|
||||
struct sockaddr* pSA = reinterpret_cast<struct sockaddr*>(abuffer);
|
||||
poco_socklen_t saLen = sizeof(abuffer);
|
||||
int rc;
|
||||
do
|
||||
{
|
||||
rc = ::recvfrom(_sockfd, reinterpret_cast<char*>(buffer), length, flags, pSA, &saLen);
|
||||
}
|
||||
while (rc < 0 && lastError() == POCO_EINTR);
|
||||
if (rc >= 0)
|
||||
{
|
||||
address = SocketAddress(pSA, saLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lastError() == POCO_EAGAIN || lastError() == POCO_ETIMEDOUT)
|
||||
throw TimeoutException();
|
||||
else
|
||||
error();
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::sendUrgent(unsigned char data)
|
||||
{
|
||||
int rc = ::send(_sockfd, reinterpret_cast<const char*>(&data), sizeof(data), MSG_OOB);
|
||||
if (rc < 0) error();
|
||||
}
|
||||
|
||||
|
||||
int SocketImpl::available()
|
||||
{
|
||||
int result;
|
||||
ioctl(FIONREAD, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool SocketImpl::poll(const Foundation::Timespan& timeout, int mode)
|
||||
{
|
||||
fd_set fdRead;
|
||||
fd_set fdWrite;
|
||||
fd_set fdExcept;
|
||||
FD_ZERO(&fdRead);
|
||||
FD_ZERO(&fdWrite);
|
||||
FD_ZERO(&fdExcept);
|
||||
if (mode & SELECT_READ)
|
||||
{
|
||||
FD_SET(_sockfd, &fdRead);
|
||||
}
|
||||
if (mode & SELECT_WRITE)
|
||||
{
|
||||
FD_SET(_sockfd, &fdWrite);
|
||||
}
|
||||
if (mode & SELECT_ERROR)
|
||||
{
|
||||
FD_SET(_sockfd, &fdExcept);
|
||||
}
|
||||
struct timeval tv;
|
||||
tv.tv_sec = (long) timeout.totalSeconds();
|
||||
tv.tv_usec = (long) timeout.useconds();
|
||||
int rc = ::select(int(_sockfd) + 1, &fdRead, &fdWrite, &fdExcept, &tv);
|
||||
if (rc < 0) error();
|
||||
return rc > 0;
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::setSendBufferSize(int size)
|
||||
{
|
||||
setOption(SOL_SOCKET, SO_SNDBUF, size);
|
||||
}
|
||||
|
||||
|
||||
int SocketImpl::getSendBufferSize()
|
||||
{
|
||||
int result;
|
||||
getOption(SOL_SOCKET, SO_SNDBUF, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::setReceiveBufferSize(int size)
|
||||
{
|
||||
setOption(SOL_SOCKET, SO_RCVBUF, size);
|
||||
}
|
||||
|
||||
|
||||
int SocketImpl::getReceiveBufferSize()
|
||||
{
|
||||
int result;
|
||||
getOption(SOL_SOCKET, SO_RCVBUF, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::setSendTimeout(const Foundation::Timespan& timeout)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
int value = (int) timeout.totalMilliseconds();
|
||||
setOption(SOL_SOCKET, SO_SNDTIMEO, value);
|
||||
#else
|
||||
setOption(SOL_SOCKET, SO_SNDTIMEO, timeout);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
Foundation::Timespan SocketImpl::getSendTimeout()
|
||||
{
|
||||
Timespan result;
|
||||
#if defined(_WIN32)
|
||||
int value;
|
||||
getOption(SOL_SOCKET, SO_SNDTIMEO, value);
|
||||
result = Timespan::TimeDiff(value)*1000;
|
||||
#else
|
||||
getOption(SOL_SOCKET, SO_SNDTIMEO, result);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::setReceiveTimeout(const Foundation::Timespan& timeout)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
int value = (int) timeout.totalMilliseconds();
|
||||
setOption(SOL_SOCKET, SO_RCVTIMEO, value);
|
||||
#else
|
||||
setOption(SOL_SOCKET, SO_RCVTIMEO, timeout);
|
||||
#endif
|
||||
#if defined(POCO_BROKEN_TIMEOUTS)
|
||||
_recvTimeout = timeout;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
Foundation::Timespan SocketImpl::getReceiveTimeout()
|
||||
{
|
||||
Timespan result;
|
||||
#if defined(_WIN32)
|
||||
int value;
|
||||
getOption(SOL_SOCKET, SO_RCVTIMEO, value);
|
||||
result = Timespan::TimeDiff(value)*1000;
|
||||
#elif defined(POCO_BROKEN_TIMEOUTS)
|
||||
result = _recvTimeout;
|
||||
#else
|
||||
getOption(SOL_SOCKET, SO_RCVTIMEO, result);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
SocketAddress SocketImpl::address()
|
||||
{
|
||||
poco_assert (_sockfd != POCO_INVALID_SOCKET);
|
||||
|
||||
char buffer[SocketAddress::MAX_ADDRESS_LENGTH];
|
||||
struct sockaddr* pSA = reinterpret_cast<struct sockaddr*>(buffer);
|
||||
poco_socklen_t saLen = sizeof(buffer);
|
||||
int rc = ::getsockname(_sockfd, pSA, &saLen);
|
||||
if (rc == 0)
|
||||
return SocketAddress(pSA, saLen);
|
||||
else
|
||||
error();
|
||||
return SocketAddress();
|
||||
}
|
||||
|
||||
|
||||
SocketAddress SocketImpl::peerAddress()
|
||||
{
|
||||
poco_assert (_sockfd != POCO_INVALID_SOCKET);
|
||||
|
||||
char buffer[SocketAddress::MAX_ADDRESS_LENGTH];
|
||||
struct sockaddr* pSA = reinterpret_cast<struct sockaddr*>(buffer);
|
||||
poco_socklen_t saLen = sizeof(buffer);
|
||||
int rc = ::getpeername(_sockfd, pSA, &saLen);
|
||||
if (rc == 0)
|
||||
return SocketAddress(pSA, saLen);
|
||||
else
|
||||
error();
|
||||
return SocketAddress();
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::setOption(int level, int option, int value)
|
||||
{
|
||||
setRawOption(level, option, &value, sizeof(value));
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::setOption(int level, int option, unsigned value)
|
||||
{
|
||||
setRawOption(level, option, &value, sizeof(value));
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::setOption(int level, int option, unsigned char value)
|
||||
{
|
||||
setRawOption(level, option, &value, sizeof(value));
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::setOption(int level, int option, const IPAddress& value)
|
||||
{
|
||||
setRawOption(level, option, value.addr(), value.length());
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::setOption(int level, int option, const Foundation::Timespan& value)
|
||||
{
|
||||
struct timeval tv;
|
||||
tv.tv_sec = (long) value.totalSeconds();
|
||||
tv.tv_usec = (long) value.useconds();
|
||||
|
||||
setRawOption(level, option, &tv, sizeof(tv));
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::setRawOption(int level, int option, const void* value, poco_socklen_t length)
|
||||
{
|
||||
poco_assert (_sockfd != POCO_INVALID_SOCKET);
|
||||
|
||||
int rc = ::setsockopt(_sockfd, level, option, reinterpret_cast<const char*>(value), length);
|
||||
if (rc == -1) error();
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::getOption(int level, int option, int& value)
|
||||
{
|
||||
poco_socklen_t len = sizeof(value);
|
||||
getRawOption(level, option, &value, len);
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::getOption(int level, int option, unsigned& value)
|
||||
{
|
||||
poco_socklen_t len = sizeof(value);
|
||||
getRawOption(level, option, &value, len);
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::getOption(int level, int option, unsigned char& value)
|
||||
{
|
||||
poco_socklen_t len = sizeof(value);
|
||||
getRawOption(level, option, &value, len);
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::getOption(int level, int option, Foundation::Timespan& value)
|
||||
{
|
||||
struct timeval tv;
|
||||
poco_socklen_t len = sizeof(tv);
|
||||
getRawOption(level, option, &tv, len);
|
||||
value.assign(tv.tv_sec, tv.tv_usec);
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::getOption(int level, int option, IPAddress& value)
|
||||
{
|
||||
char buffer[IPAddress::MAX_ADDRESS_LENGTH];
|
||||
poco_socklen_t len = sizeof(buffer);
|
||||
getRawOption(level, option, buffer, len);
|
||||
value = IPAddress(buffer, len);
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::getRawOption(int level, int option, void* value, poco_socklen_t& length)
|
||||
{
|
||||
poco_assert (_sockfd != POCO_INVALID_SOCKET);
|
||||
|
||||
int rc = ::getsockopt(_sockfd, level, option, reinterpret_cast<char*>(value), &length);
|
||||
if (rc == -1) error();
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::setLinger(bool on, int seconds)
|
||||
{
|
||||
struct linger l;
|
||||
l.l_onoff = on ? 1 : 0;
|
||||
l.l_linger = seconds;
|
||||
setRawOption(SOL_SOCKET, SO_LINGER, &l, sizeof(l));
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::getLinger(bool& on, int& seconds)
|
||||
{
|
||||
struct linger l;
|
||||
poco_socklen_t len = sizeof(l);
|
||||
getRawOption(SOL_SOCKET, SO_LINGER, &l, len);
|
||||
on = l.l_onoff != 0;
|
||||
seconds = l.l_linger;
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::setNoDelay(bool flag)
|
||||
{
|
||||
int value = flag ? 1 : 0;
|
||||
setOption(IPPROTO_TCP, TCP_NODELAY, value);
|
||||
}
|
||||
|
||||
|
||||
bool SocketImpl::getNoDelay()
|
||||
{
|
||||
int value;
|
||||
getOption(IPPROTO_TCP, TCP_NODELAY, value);
|
||||
return value != 0;
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::setKeepAlive(bool flag)
|
||||
{
|
||||
int value = flag ? 1 : 0;
|
||||
setOption(SOL_SOCKET, SO_KEEPALIVE, value);
|
||||
}
|
||||
|
||||
|
||||
bool SocketImpl::getKeepAlive()
|
||||
{
|
||||
int value;
|
||||
getOption(SOL_SOCKET, SO_KEEPALIVE, value);
|
||||
return value != 0;
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::setReuseAddress(bool flag)
|
||||
{
|
||||
int value = flag ? 1 : 0;
|
||||
setOption(SOL_SOCKET, SO_REUSEADDR, value);
|
||||
}
|
||||
|
||||
|
||||
bool SocketImpl::getReuseAddress()
|
||||
{
|
||||
int value;
|
||||
getOption(SOL_SOCKET, SO_REUSEADDR, value);
|
||||
return value != 0;
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::setReusePort(bool flag)
|
||||
{
|
||||
#ifdef SO_REUSEPORT
|
||||
try
|
||||
{
|
||||
int value = flag ? 1 : 0;
|
||||
setOption(SOL_SOCKET, SO_REUSEPORT, value);
|
||||
}
|
||||
catch (IOException&)
|
||||
{
|
||||
// ignore error, since not all implementations
|
||||
// support SO_REUSEPORT, even if the macro
|
||||
// is defined.
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SocketImpl::getReusePort()
|
||||
{
|
||||
#ifdef SO_REUSEPORT
|
||||
int value;
|
||||
getOption(SOL_SOCKET, SO_REUSEPORT, value);
|
||||
return value != 0;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::setOOBInline(bool flag)
|
||||
{
|
||||
int value = flag ? 1 : 0;
|
||||
setOption(SOL_SOCKET, SO_OOBINLINE, value);
|
||||
}
|
||||
|
||||
|
||||
bool SocketImpl::getOOBInline()
|
||||
{
|
||||
int value;
|
||||
getOption(SOL_SOCKET, SO_OOBINLINE, value);
|
||||
return value != 0;
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::setBroadcast(bool flag)
|
||||
{
|
||||
int value = flag ? 1 : 0;
|
||||
setOption(SOL_SOCKET, SO_BROADCAST, value);
|
||||
}
|
||||
|
||||
|
||||
bool SocketImpl::getBroadcast()
|
||||
{
|
||||
int value;
|
||||
getOption(SOL_SOCKET, SO_BROADCAST, value);
|
||||
return value != 0;
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::setBlocking(bool flag)
|
||||
{
|
||||
int arg = flag ? 0 : 1;
|
||||
ioctl(FIONBIO, arg);
|
||||
}
|
||||
|
||||
|
||||
int SocketImpl::socketError()
|
||||
{
|
||||
int result;
|
||||
getOption(SOL_SOCKET, SO_ERROR, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::init(int af)
|
||||
{
|
||||
initSocket(af, SOCK_STREAM);
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::initSocket(int af, int type, int proto)
|
||||
{
|
||||
poco_assert (_sockfd == POCO_INVALID_SOCKET);
|
||||
|
||||
_sockfd = ::socket(af, type, proto);
|
||||
if (_sockfd == POCO_INVALID_SOCKET)
|
||||
error();
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::ioctl(int request, int& arg)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
int rc = ioctlsocket(_sockfd, request, reinterpret_cast<u_long*>(&arg));
|
||||
#else
|
||||
int rc = ::ioctl(_sockfd, request, &arg);
|
||||
#endif
|
||||
if (rc != 0) error();
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::ioctl(int request, void* arg)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
int rc = ioctlsocket(_sockfd, request, reinterpret_cast<u_long*>(arg));
|
||||
#else
|
||||
int rc = ::ioctl(_sockfd, request, arg);
|
||||
#endif
|
||||
if (rc != 0) error();
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::setSockfd(poco_socket_t aSocket)
|
||||
{
|
||||
poco_assert(sockfd() == POCO_INVALID_SOCKET);
|
||||
_sockfd = aSocket;
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::error()
|
||||
{
|
||||
std::string empty;
|
||||
error(lastError(), empty);
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::error(const std::string& arg)
|
||||
{
|
||||
error(lastError(), arg);
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::error(int code)
|
||||
{
|
||||
std::string arg;
|
||||
error(code, arg);
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::error(int code, const std::string& arg)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case POCO_ESYSNOTREADY:
|
||||
throw NetException("Net subsystem not ready");
|
||||
case POCO_ENOTINIT:
|
||||
throw NetException("Net subsystem not initialized");
|
||||
case POCO_EINTR:
|
||||
throw IOException("Interrupted");
|
||||
case POCO_EACCES:
|
||||
throw IOException("Permission denied");
|
||||
case POCO_EFAULT:
|
||||
throw IOException("Bad address");
|
||||
case POCO_EINVAL:
|
||||
throw InvalidArgumentException();
|
||||
case POCO_EMFILE:
|
||||
throw IOException("Too many open files");
|
||||
case POCO_EWOULDBLOCK:
|
||||
throw IOException("Operation would block");
|
||||
case POCO_EINPROGRESS:
|
||||
throw IOException("Operation now in progress");
|
||||
case POCO_EALREADY:
|
||||
throw IOException("Operation already in progress");
|
||||
case POCO_ENOTSOCK:
|
||||
throw IOException("Socket operation attempted on non-socket");
|
||||
case POCO_EDESTADDRREQ:
|
||||
throw NetException("Destination address required");
|
||||
case POCO_EMSGSIZE:
|
||||
throw NetException("Message too long");
|
||||
case POCO_EPROTOTYPE:
|
||||
throw NetException("Wrong protocol type");
|
||||
case POCO_ENOPROTOOPT:
|
||||
throw NetException("Protocol not available");
|
||||
case POCO_EPROTONOSUPPORT:
|
||||
throw NetException("Protocol not supported");
|
||||
case POCO_ESOCKTNOSUPPORT:
|
||||
throw NetException("Socket type not supported");
|
||||
case POCO_ENOTSUP:
|
||||
throw NetException("Operation not supported");
|
||||
case POCO_EPFNOSUPPORT:
|
||||
throw NetException("Protocol family not supported");
|
||||
case POCO_EAFNOSUPPORT:
|
||||
throw NetException("Address family not supported");
|
||||
case POCO_EADDRINUSE:
|
||||
throw NetException("Address already in use", arg);
|
||||
case POCO_EADDRNOTAVAIL:
|
||||
throw NetException("Cannot assign requested address", arg);
|
||||
case POCO_ENETDOWN:
|
||||
throw NetException("Network is down");
|
||||
case POCO_ENETUNREACH:
|
||||
throw NetException("Network is unreachable");
|
||||
case POCO_ENETRESET:
|
||||
throw NetException("Network dropped connection on reset");
|
||||
case POCO_ECONNABORTED:
|
||||
throw ConnectionAbortedException();
|
||||
case POCO_ECONNRESET:
|
||||
throw ConnectionResetException();
|
||||
case POCO_ENOBUFS:
|
||||
throw IOException("No buffer space available");
|
||||
case POCO_EISCONN:
|
||||
throw NetException("Socket is already connected");
|
||||
case POCO_ENOTCONN:
|
||||
throw NetException("Socket is not connected");
|
||||
case POCO_ESHUTDOWN:
|
||||
throw NetException("Cannot send after socket shutdown");
|
||||
case POCO_ETIMEDOUT:
|
||||
throw TimeoutException();
|
||||
case POCO_ECONNREFUSED:
|
||||
throw ConnectionRefusedException(arg);
|
||||
case POCO_EHOSTDOWN:
|
||||
throw NetException("Host is down");
|
||||
case POCO_EHOSTUNREACH:
|
||||
throw NetException("No route to host");
|
||||
default:
|
||||
throw IOException(NumberFormatter::format(code) + arg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
115
Net/src/SocketNotification.cpp
Normal file
115
Net/src/SocketNotification.cpp
Normal file
@@ -0,0 +1,115 @@
|
||||
//
|
||||
// SocketNotification.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/SocketNotification.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Reactor
|
||||
// Module: SocketNotification
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/SocketNotification.h"
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
SocketNotification::SocketNotification(SocketReactor* pReactor):
|
||||
_pReactor(pReactor)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SocketNotification::~SocketNotification()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void SocketNotification::setSocket(const Socket& socket)
|
||||
{
|
||||
_socket = socket;
|
||||
}
|
||||
|
||||
|
||||
ReadableNotification::ReadableNotification(SocketReactor* pReactor):
|
||||
SocketNotification(pReactor)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ReadableNotification::~ReadableNotification()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
WritableNotification::WritableNotification(SocketReactor* pReactor):
|
||||
SocketNotification(pReactor)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
WritableNotification::~WritableNotification()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ErrorNotification::ErrorNotification(SocketReactor* pReactor):
|
||||
SocketNotification(pReactor)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ErrorNotification::~ErrorNotification()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TimeoutNotification::TimeoutNotification(SocketReactor* pReactor):
|
||||
SocketNotification(pReactor)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TimeoutNotification::~TimeoutNotification()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ShutdownNotification::ShutdownNotification(SocketReactor* pReactor):
|
||||
SocketNotification(pReactor)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ShutdownNotification::~ShutdownNotification()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
95
Net/src/SocketNotifier.cpp
Normal file
95
Net/src/SocketNotifier.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
//
|
||||
// SocketNotifier.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/SocketNotifier.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Reactor
|
||||
// Module: SocketNotifier
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/SocketNotifier.h"
|
||||
#include "Net/SocketReactor.h"
|
||||
#include "Net/SocketNotification.h"
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
SocketNotifier::SocketNotifier(const Socket& socket):
|
||||
_socket(socket)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SocketNotifier::~SocketNotifier()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void SocketNotifier::addObserver(SocketReactor* pReactor, const Foundation::AbstractObserver& observer)
|
||||
{
|
||||
_nc.addObserver(observer);
|
||||
if (observer.accepts(pReactor->_pReadableNotification))
|
||||
_events.insert(pReactor->_pReadableNotification.get());
|
||||
else if (observer.accepts(pReactor->_pWritableNotification))
|
||||
_events.insert(pReactor->_pWritableNotification.get());
|
||||
else if (observer.accepts(pReactor->_pErrorNotification))
|
||||
_events.insert(pReactor->_pErrorNotification.get());
|
||||
else if (observer.accepts(pReactor->_pTimeoutNotification))
|
||||
_events.insert(pReactor->_pErrorNotification.get());
|
||||
}
|
||||
|
||||
|
||||
void SocketNotifier::removeObserver(SocketReactor* pReactor, const Foundation::AbstractObserver& observer)
|
||||
{
|
||||
_nc.removeObserver(observer);
|
||||
EventSet::iterator it = _events.end();
|
||||
if (observer.accepts(pReactor->_pReadableNotification))
|
||||
it = _events.find(pReactor->_pReadableNotification.get());
|
||||
else if (observer.accepts(pReactor->_pWritableNotification))
|
||||
it = _events.find(pReactor->_pWritableNotification.get());
|
||||
else if (observer.accepts(pReactor->_pErrorNotification))
|
||||
it = _events.find(pReactor->_pErrorNotification.get());
|
||||
else if (observer.accepts(pReactor->_pTimeoutNotification))
|
||||
it = _events.find(pReactor->_pTimeoutNotification.get());
|
||||
if (it != _events.end())
|
||||
_events.erase(it);
|
||||
}
|
||||
|
||||
|
||||
void SocketNotifier::dispatch(SocketNotification* pNotification)
|
||||
{
|
||||
pNotification->setSocket(_socket);
|
||||
pNotification->duplicate();
|
||||
_nc.postNotification(pNotification);
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
232
Net/src/SocketReactor.cpp
Normal file
232
Net/src/SocketReactor.cpp
Normal file
@@ -0,0 +1,232 @@
|
||||
//
|
||||
// SocketReactor.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/SocketReactor.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Reactor
|
||||
// Module: SocketReactor
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/SocketReactor.h"
|
||||
#include "Net/SocketNotification.h"
|
||||
#include "Net/SocketNotifier.h"
|
||||
#include "Foundation/ErrorHandler.h"
|
||||
#include "Foundation/Exception.h"
|
||||
|
||||
|
||||
using Foundation::FastMutex;
|
||||
using Foundation::Exception;
|
||||
using Foundation::ErrorHandler;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
SocketReactor::SocketReactor():
|
||||
_stop(false),
|
||||
_timeout(DEFAULT_TIMEOUT),
|
||||
_pReadableNotification(new ReadableNotification(this)),
|
||||
_pWritableNotification(new WritableNotification(this)),
|
||||
_pErrorNotification(new ErrorNotification(this)),
|
||||
_pTimeoutNotification(new TimeoutNotification(this)),
|
||||
_pShutdownNotification(new ShutdownNotification(this))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SocketReactor::SocketReactor(const Foundation::Timespan& timeout):
|
||||
_stop(false),
|
||||
_timeout(timeout),
|
||||
_pReadableNotification(new ReadableNotification(this)),
|
||||
_pWritableNotification(new WritableNotification(this)),
|
||||
_pErrorNotification(new ErrorNotification(this)),
|
||||
_pTimeoutNotification(new TimeoutNotification(this)),
|
||||
_pShutdownNotification(new ShutdownNotification(this))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SocketReactor::~SocketReactor()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void SocketReactor::run()
|
||||
{
|
||||
Socket::SocketList readable;
|
||||
Socket::SocketList writable;
|
||||
Socket::SocketList except;
|
||||
|
||||
while (!_stop)
|
||||
{
|
||||
readable.clear();
|
||||
writable.clear();
|
||||
except.clear();
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
for (EventHandlerMap::iterator it = _handlers.begin(); it != _handlers.end(); ++it)
|
||||
{
|
||||
if (it->second->accepts(_pReadableNotification))
|
||||
readable.push_back(it->first);
|
||||
if (it->second->accepts(_pWritableNotification))
|
||||
writable.push_back(it->first);
|
||||
if (it->second->accepts(_pErrorNotification))
|
||||
except.push_back(it->first);
|
||||
}
|
||||
}
|
||||
if (Socket::select(readable, writable, except, _timeout))
|
||||
{
|
||||
for (Socket::SocketList::iterator it = readable.begin(); it != readable.end(); ++it)
|
||||
dispatch(*it, _pReadableNotification);
|
||||
for (Socket::SocketList::iterator it = writable.begin(); it != writable.end(); ++it)
|
||||
dispatch(*it, _pWritableNotification);
|
||||
for (Socket::SocketList::iterator it = except.begin(); it != except.end(); ++it)
|
||||
dispatch(*it, _pErrorNotification);
|
||||
}
|
||||
else onTimeout();
|
||||
}
|
||||
onShutdown();
|
||||
}
|
||||
|
||||
|
||||
void SocketReactor::stop()
|
||||
{
|
||||
_stop = true;
|
||||
}
|
||||
|
||||
|
||||
void SocketReactor::setTimeout(const Foundation::Timespan& timeout)
|
||||
{
|
||||
_timeout = timeout;
|
||||
}
|
||||
|
||||
|
||||
const Foundation::Timespan& SocketReactor::getTimeout() const
|
||||
{
|
||||
return _timeout;
|
||||
}
|
||||
|
||||
|
||||
void SocketReactor::addEventHandler(const Socket& socket, const Foundation::AbstractObserver& observer)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
NotifierPtr pNotifier;
|
||||
EventHandlerMap::iterator it = _handlers.find(socket);
|
||||
if (it == _handlers.end())
|
||||
{
|
||||
pNotifier = new SocketNotifier(socket);
|
||||
_handlers[socket] = pNotifier;
|
||||
}
|
||||
else pNotifier = it->second;
|
||||
pNotifier->addObserver(this, observer);
|
||||
}
|
||||
|
||||
|
||||
void SocketReactor::removeEventHandler(const Socket& socket, const Foundation::AbstractObserver& observer)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
EventHandlerMap::iterator it = _handlers.find(socket);
|
||||
if (it != _handlers.end())
|
||||
{
|
||||
NotifierPtr pNotifier = it->second;
|
||||
pNotifier->removeObserver(this, observer);
|
||||
if (!pNotifier->hasObservers())
|
||||
_handlers.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SocketReactor::onTimeout()
|
||||
{
|
||||
dispatch(_pTimeoutNotification);
|
||||
}
|
||||
|
||||
|
||||
void SocketReactor::onShutdown()
|
||||
{
|
||||
dispatch(_pShutdownNotification);
|
||||
}
|
||||
|
||||
|
||||
void SocketReactor::dispatch(const Socket& socket, SocketNotification* pNotification)
|
||||
{
|
||||
NotifierPtr pNotifier;
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
EventHandlerMap::iterator it = _handlers.find(socket);
|
||||
if (it != _handlers.end())
|
||||
pNotifier = it->second;
|
||||
else
|
||||
return;
|
||||
}
|
||||
dispatch(pNotifier, pNotification);
|
||||
}
|
||||
|
||||
|
||||
void SocketReactor::dispatch(SocketNotification* pNotification)
|
||||
{
|
||||
std::vector<NotifierPtr> delegates;
|
||||
delegates.reserve(_handlers.size());
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
for (EventHandlerMap::iterator it = _handlers.begin(); it != _handlers.end(); ++it)
|
||||
delegates.push_back(it->second);
|
||||
}
|
||||
for (std::vector<NotifierPtr>::iterator it = delegates.begin(); it != delegates.end(); ++it)
|
||||
{
|
||||
dispatch(*it, pNotification);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SocketReactor::dispatch(NotifierPtr& pNotifier, SocketNotification* pNotification)
|
||||
{
|
||||
try
|
||||
{
|
||||
pNotifier->dispatch(pNotification);
|
||||
}
|
||||
catch (Exception& exc)
|
||||
{
|
||||
ErrorHandler::handle(exc);
|
||||
}
|
||||
catch (std::exception& exc)
|
||||
{
|
||||
ErrorHandler::handle(exc);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
ErrorHandler::handle();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
177
Net/src/SocketStream.cpp
Normal file
177
Net/src/SocketStream.cpp
Normal file
@@ -0,0 +1,177 @@
|
||||
//
|
||||
// SocketStream.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/SocketStream.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Sockets
|
||||
// Module: SocketStream
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/SocketStream.h"
|
||||
#include "Net/StreamSocketImpl.h"
|
||||
#include "Foundation/Exception.h"
|
||||
|
||||
|
||||
using Foundation::BufferedBidirectionalStreamBuf;
|
||||
using Foundation::InvalidArgumentException;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
//
|
||||
// SocketStreamBuf
|
||||
//
|
||||
|
||||
|
||||
SocketStreamBuf::SocketStreamBuf(const Socket& socket):
|
||||
BufferedBidirectionalStreamBuf(STREAM_BUFFER_SIZE, std::ios::in | std::ios::out),
|
||||
_pImpl(dynamic_cast<StreamSocketImpl*>(socket.impl()))
|
||||
{
|
||||
if (_pImpl)
|
||||
_pImpl->duplicate();
|
||||
else
|
||||
throw InvalidArgumentException("Invalid or null SocketImpl passed to SocketStreamBuf");
|
||||
}
|
||||
|
||||
|
||||
SocketStreamBuf::~SocketStreamBuf()
|
||||
{
|
||||
_pImpl->release();
|
||||
}
|
||||
|
||||
|
||||
int SocketStreamBuf::readFromDevice(char* buffer, std::streamsize length)
|
||||
{
|
||||
return _pImpl->receiveBytes(buffer, (int) length);
|
||||
}
|
||||
|
||||
|
||||
int SocketStreamBuf::writeToDevice(const char* buffer, std::streamsize length)
|
||||
{
|
||||
return _pImpl->sendBytes(buffer, (int) length);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// SocketIOS
|
||||
//
|
||||
|
||||
|
||||
SocketIOS::SocketIOS(const Socket& socket):
|
||||
_buf(socket)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
SocketIOS::~SocketIOS()
|
||||
{
|
||||
try
|
||||
{
|
||||
_buf.sync();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SocketStreamBuf* SocketIOS::rdbuf()
|
||||
{
|
||||
return &_buf;
|
||||
}
|
||||
|
||||
|
||||
void SocketIOS::close()
|
||||
{
|
||||
_buf.sync();
|
||||
_buf.socketImpl()->close();
|
||||
}
|
||||
|
||||
|
||||
StreamSocket SocketIOS::socket() const
|
||||
{
|
||||
return StreamSocket(_buf.socketImpl());
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// SocketOutputStream
|
||||
//
|
||||
|
||||
|
||||
SocketOutputStream::SocketOutputStream(const Socket& socket):
|
||||
SocketIOS(socket),
|
||||
std::ostream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SocketOutputStream::~SocketOutputStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// SocketInputStream
|
||||
//
|
||||
|
||||
|
||||
SocketInputStream::SocketInputStream(const Socket& socket):
|
||||
SocketIOS(socket),
|
||||
std::istream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SocketInputStream::~SocketInputStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// SocketStream
|
||||
//
|
||||
|
||||
|
||||
SocketStream::SocketStream(const Socket& socket):
|
||||
SocketIOS(socket),
|
||||
std::iostream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SocketStream::~SocketStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
142
Net/src/StreamSocket.cpp
Normal file
142
Net/src/StreamSocket.cpp
Normal file
@@ -0,0 +1,142 @@
|
||||
//
|
||||
// StreamSocket.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/StreamSocket.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Sockets
|
||||
// Module: StreamSocket
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/StreamSocket.h"
|
||||
#include "Net/StreamSocketImpl.h"
|
||||
#include "Foundation/Exception.h"
|
||||
|
||||
|
||||
using Foundation::InvalidArgumentException;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
StreamSocket::StreamSocket(): Socket(new StreamSocketImpl)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
StreamSocket::StreamSocket(const SocketAddress& address): Socket(new StreamSocketImpl)
|
||||
{
|
||||
connect(address);
|
||||
}
|
||||
|
||||
|
||||
StreamSocket::StreamSocket(const Socket& socket): Socket(socket)
|
||||
{
|
||||
if (!dynamic_cast<StreamSocketImpl*>(impl()))
|
||||
throw InvalidArgumentException("Cannot assign incompatible socket");
|
||||
}
|
||||
|
||||
|
||||
StreamSocket::StreamSocket(SocketImpl* pImpl): Socket(pImpl)
|
||||
{
|
||||
if (!dynamic_cast<StreamSocketImpl*>(impl()))
|
||||
throw InvalidArgumentException("Cannot assign incompatible socket");
|
||||
}
|
||||
|
||||
|
||||
StreamSocket::~StreamSocket()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
StreamSocket& StreamSocket::operator = (const Socket& socket)
|
||||
{
|
||||
if (dynamic_cast<StreamSocketImpl*>(socket.impl()))
|
||||
Socket::operator = (socket);
|
||||
else
|
||||
throw InvalidArgumentException("Cannot assign incompatible socket");
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void StreamSocket::connect(const SocketAddress& address)
|
||||
{
|
||||
impl()->connect(address);
|
||||
}
|
||||
|
||||
|
||||
void StreamSocket::connect(const SocketAddress& address, const Foundation::Timespan& timeout)
|
||||
{
|
||||
impl()->connect(address, timeout);
|
||||
}
|
||||
|
||||
|
||||
void StreamSocket::connectNB(const SocketAddress& address)
|
||||
{
|
||||
impl()->connectNB(address);
|
||||
}
|
||||
|
||||
|
||||
void StreamSocket::shutdownReceive()
|
||||
{
|
||||
impl()->shutdownReceive();
|
||||
}
|
||||
|
||||
|
||||
void StreamSocket::shutdownSend()
|
||||
{
|
||||
impl()->shutdownSend();
|
||||
}
|
||||
|
||||
|
||||
void StreamSocket::shutdown()
|
||||
{
|
||||
impl()->shutdown();
|
||||
}
|
||||
|
||||
|
||||
int StreamSocket::sendBytes(const void* buffer, int length, int flags)
|
||||
{
|
||||
return impl()->sendBytes(buffer, length, flags);
|
||||
}
|
||||
|
||||
|
||||
int StreamSocket::receiveBytes(void* buffer, int length, int flags)
|
||||
{
|
||||
return impl()->receiveBytes(buffer, length, flags);
|
||||
}
|
||||
|
||||
|
||||
void StreamSocket::sendUrgent(unsigned char data)
|
||||
{
|
||||
impl()->sendUrgent(data);
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
72
Net/src/StreamSocketImpl.cpp
Normal file
72
Net/src/StreamSocketImpl.cpp
Normal file
@@ -0,0 +1,72 @@
|
||||
//
|
||||
// StreamSocketImpl.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/StreamSocketImpl.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Sockets
|
||||
// Module: StreamSocketImpl
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/StreamSocketImpl.h"
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
StreamSocketImpl::StreamSocketImpl()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
StreamSocketImpl::StreamSocketImpl(poco_socket_t sockfd): SocketImpl(sockfd)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
StreamSocketImpl::~StreamSocketImpl()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int StreamSocketImpl::sendBytes(const void* buffer, int length, int flags)
|
||||
{
|
||||
const char* p = reinterpret_cast<const char*>(buffer);
|
||||
int remaining = length;
|
||||
while (remaining > 0)
|
||||
{
|
||||
int n = SocketImpl::sendBytes(p, length, flags);
|
||||
p += n;
|
||||
remaining -= n;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
82
Net/src/StringPartSource.cpp
Normal file
82
Net/src/StringPartSource.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
//
|
||||
// StringPartSource.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/StringPartSource.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Messages
|
||||
// Module: StringPartSource
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/StringPartSource.h"
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
StringPartSource::StringPartSource(const std::string& str):
|
||||
PartSource("text/plain"),
|
||||
_istr(str)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
StringPartSource::StringPartSource(const std::string& str, const std::string& mediaType):
|
||||
PartSource(mediaType),
|
||||
_istr(str)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
StringPartSource::StringPartSource(const std::string& str, const std::string& mediaType, const std::string& filename):
|
||||
PartSource(mediaType),
|
||||
_istr(str),
|
||||
_filename(filename)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
StringPartSource::~StringPartSource()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
std::istream& StringPartSource::stream()
|
||||
{
|
||||
return _istr;
|
||||
}
|
||||
|
||||
|
||||
const std::string& StringPartSource::filename()
|
||||
{
|
||||
return _filename;
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
175
Net/src/TCPServer.cpp
Normal file
175
Net/src/TCPServer.cpp
Normal file
@@ -0,0 +1,175 @@
|
||||
//
|
||||
// TCPServer.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/TCPServer.cpp#3 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: TCPServer
|
||||
// Module: TCPServer
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/TCPServer.h"
|
||||
#include "Net/TCPServerDispatcher.h"
|
||||
#include "Net/TCPServerConnection.h"
|
||||
#include "Net/TCPServerConnectionFactory.h"
|
||||
#include "Foundation/Timespan.h"
|
||||
#include "Foundation/Exception.h"
|
||||
#include "Foundation/ErrorHandler.h"
|
||||
|
||||
|
||||
using Foundation::ErrorHandler;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
TCPServer::TCPServer(TCPServerConnectionFactory* pFactory, const ServerSocket& socket, TCPServerParams* pParams):
|
||||
_pDispatcher(new TCPServerDispatcher(pFactory, Foundation::ThreadPool::defaultPool(), pParams)),
|
||||
_socket(socket),
|
||||
_thread(threadName(socket)),
|
||||
_stopped(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TCPServer::TCPServer(TCPServerConnectionFactory* pFactory, Foundation::ThreadPool& threadPool, const ServerSocket& socket, TCPServerParams* pParams):
|
||||
_pDispatcher(new TCPServerDispatcher(pFactory, threadPool, pParams)),
|
||||
_socket(socket),
|
||||
_thread(threadName(socket)),
|
||||
_stopped(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TCPServer::~TCPServer()
|
||||
{
|
||||
stop();
|
||||
_pDispatcher->release();
|
||||
}
|
||||
|
||||
|
||||
const TCPServerParams& TCPServer::params() const
|
||||
{
|
||||
return _pDispatcher->params();
|
||||
}
|
||||
|
||||
|
||||
void TCPServer::start()
|
||||
{
|
||||
poco_assert (!_stopped);
|
||||
|
||||
_thread.start(*this);
|
||||
}
|
||||
|
||||
|
||||
void TCPServer::stop()
|
||||
{
|
||||
if (!_stopped)
|
||||
{
|
||||
_stopped = true;
|
||||
_thread.join();
|
||||
_pDispatcher->stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TCPServer::run()
|
||||
{
|
||||
while (!_stopped)
|
||||
{
|
||||
Foundation::Timespan timeout(250000);
|
||||
if (_socket.poll(timeout, Socket::SELECT_READ))
|
||||
{
|
||||
try
|
||||
{
|
||||
StreamSocket ss = _socket.acceptConnection();
|
||||
_pDispatcher->enqueue(ss);
|
||||
}
|
||||
catch (Foundation::Exception& exc)
|
||||
{
|
||||
ErrorHandler::handle(exc);
|
||||
}
|
||||
catch (std::exception& exc)
|
||||
{
|
||||
ErrorHandler::handle(exc);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
ErrorHandler::handle();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int TCPServer::currentThreads() const
|
||||
{
|
||||
return _pDispatcher->currentThreads();
|
||||
}
|
||||
|
||||
|
||||
int TCPServer::totalConnections() const
|
||||
{
|
||||
return _pDispatcher->totalConnections();
|
||||
}
|
||||
|
||||
|
||||
int TCPServer::currentConnections() const
|
||||
{
|
||||
return _pDispatcher->currentConnections();
|
||||
}
|
||||
|
||||
|
||||
int TCPServer::maxConcurrentConnections() const
|
||||
{
|
||||
return _pDispatcher->maxConcurrentConnections();
|
||||
}
|
||||
|
||||
|
||||
int TCPServer::queuedConnections() const
|
||||
{
|
||||
return _pDispatcher->queuedConnections();
|
||||
}
|
||||
|
||||
|
||||
int TCPServer::refusedConnections() const
|
||||
{
|
||||
return _pDispatcher->refusedConnections();
|
||||
}
|
||||
|
||||
|
||||
std::string TCPServer::threadName(const ServerSocket& socket)
|
||||
{
|
||||
std::string name("TCPServer: ");
|
||||
name.append(socket.address().toString());
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
81
Net/src/TCPServerConnection.cpp
Normal file
81
Net/src/TCPServerConnection.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
//
|
||||
// TCPServerConnection.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/TCPServerConnection.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: TCPServer
|
||||
// Module: TCPServerConnection
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/TCPServerConnection.h"
|
||||
#include "Foundation/Exception.h"
|
||||
#include "Foundation/ErrorHandler.h"
|
||||
|
||||
|
||||
using Foundation::Exception;
|
||||
using Foundation::ErrorHandler;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
TCPServerConnection::TCPServerConnection(const StreamSocket& socket):
|
||||
_socket(socket)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TCPServerConnection::~TCPServerConnection()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void TCPServerConnection::start()
|
||||
{
|
||||
try
|
||||
{
|
||||
run();
|
||||
}
|
||||
catch (Exception& exc)
|
||||
{
|
||||
ErrorHandler::handle(exc);
|
||||
}
|
||||
catch (std::exception& exc)
|
||||
{
|
||||
ErrorHandler::handle(exc);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
ErrorHandler::handle();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
53
Net/src/TCPServerConnectionFactory.cpp
Normal file
53
Net/src/TCPServerConnectionFactory.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// TCPServerConnectionFactory.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/TCPServerConnectionFactory.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: TCPServer
|
||||
// Module: TCPServerConnectionFactory
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/TCPServerConnectionFactory.h"
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
TCPServerConnectionFactory::TCPServerConnectionFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TCPServerConnectionFactory::~TCPServerConnectionFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
255
Net/src/TCPServerDispatcher.cpp
Normal file
255
Net/src/TCPServerDispatcher.cpp
Normal file
@@ -0,0 +1,255 @@
|
||||
//
|
||||
// TCPServerDispatcher.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/TCPServerDispatcher.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: TCPServer
|
||||
// Module: TCPServerDispatcher
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/TCPServerDispatcher.h"
|
||||
#include "Net/TCPServerConnectionFactory.h"
|
||||
#include "Net/TCPServerParams.h"
|
||||
#include "Foundation/Notification.h"
|
||||
#include "Foundation/AutoPtr.h"
|
||||
#include <memory>
|
||||
|
||||
|
||||
using Foundation::Notification;
|
||||
using Foundation::FastMutex;
|
||||
using Foundation::AutoPtr;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
class TCPConnectionNotification: public Notification
|
||||
{
|
||||
public:
|
||||
TCPConnectionNotification(const StreamSocket& socket):
|
||||
_socket(socket)
|
||||
{
|
||||
}
|
||||
|
||||
~TCPConnectionNotification()
|
||||
{
|
||||
}
|
||||
|
||||
const StreamSocket& socket() const
|
||||
{
|
||||
return _socket;
|
||||
}
|
||||
|
||||
private:
|
||||
StreamSocket _socket;
|
||||
};
|
||||
|
||||
|
||||
TCPServerDispatcher::TCPServerDispatcher(TCPServerConnectionFactory* pFactory, Foundation::ThreadPool& threadPool, TCPServerParams* pParams):
|
||||
_rc(1),
|
||||
_pParams(pParams),
|
||||
_currentThreads(0),
|
||||
_totalConnections(0),
|
||||
_currentConnections(0),
|
||||
_maxConcurrentConnections(0),
|
||||
_refusedConnections(0),
|
||||
_stopped(false),
|
||||
_pConnectionFactory(pFactory),
|
||||
_threadPool(threadPool)
|
||||
{
|
||||
poco_check_ptr (pFactory);
|
||||
|
||||
if (!_pParams)
|
||||
_pParams = new TCPServerParams;
|
||||
|
||||
if (_pParams->getMaxThreads() == 0)
|
||||
_pParams->setMaxThreads(threadPool.capacity());
|
||||
}
|
||||
|
||||
|
||||
TCPServerDispatcher::~TCPServerDispatcher()
|
||||
{
|
||||
_pParams->release();
|
||||
delete _pConnectionFactory;
|
||||
}
|
||||
|
||||
|
||||
void TCPServerDispatcher::duplicate()
|
||||
{
|
||||
_mutex.lock();
|
||||
++_rc;
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
|
||||
void TCPServerDispatcher::release()
|
||||
{
|
||||
_mutex.lock();
|
||||
int rc = --_rc;
|
||||
_mutex.unlock();
|
||||
if (rc == 0) delete this;
|
||||
}
|
||||
|
||||
|
||||
void TCPServerDispatcher::run()
|
||||
{
|
||||
AutoPtr<TCPServerDispatcher> guard(this, true); // ensure object stays alive
|
||||
|
||||
int idleTime = (int) _pParams->getThreadIdleTime().totalMilliseconds();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
AutoPtr<Notification> pNf = _queue.waitDequeueNotification(idleTime);
|
||||
if (pNf)
|
||||
{
|
||||
TCPConnectionNotification* pCNf = dynamic_cast<TCPConnectionNotification*>(pNf.get());
|
||||
if (pCNf)
|
||||
{
|
||||
std::auto_ptr<TCPServerConnection> pConnection(_pConnectionFactory->createConnection(pCNf->socket()));
|
||||
poco_check_ptr(pConnection.get());
|
||||
beginConnection();
|
||||
pConnection->start();
|
||||
endConnection();
|
||||
}
|
||||
}
|
||||
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
if (_stopped || _currentThreads > 1 && _queue.empty())
|
||||
{
|
||||
--_currentThreads;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TCPServerDispatcher::enqueue(const StreamSocket& socket)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
if (_queue.size() < _pParams->getMaxQueued())
|
||||
{
|
||||
_queue.enqueueNotification(new TCPConnectionNotification(socket));
|
||||
if (!_queue.hasIdleThreads() && _currentThreads < _pParams->getMaxThreads())
|
||||
{
|
||||
try
|
||||
{
|
||||
static const std::string threadName("TCPServerConnection");
|
||||
_threadPool.start(*this, threadName);
|
||||
++_currentThreads;
|
||||
}
|
||||
catch (Foundation::Exception&)
|
||||
{
|
||||
// no problem here, connection is already queued
|
||||
// and a new thread might be available later.
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++_refusedConnections;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TCPServerDispatcher::stop()
|
||||
{
|
||||
_stopped = true;
|
||||
_queue.clear();
|
||||
_queue.wakeUpAll();
|
||||
}
|
||||
|
||||
|
||||
int TCPServerDispatcher::currentThreads() const
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
return _currentThreads;
|
||||
}
|
||||
|
||||
|
||||
int TCPServerDispatcher::totalConnections() const
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
return _totalConnections;
|
||||
}
|
||||
|
||||
|
||||
int TCPServerDispatcher::currentConnections() const
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
return _currentConnections;
|
||||
}
|
||||
|
||||
|
||||
int TCPServerDispatcher::maxConcurrentConnections() const
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
return _maxConcurrentConnections;
|
||||
}
|
||||
|
||||
|
||||
int TCPServerDispatcher::queuedConnections() const
|
||||
{
|
||||
return _queue.size();
|
||||
}
|
||||
|
||||
|
||||
int TCPServerDispatcher::refusedConnections() const
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
return _refusedConnections;
|
||||
}
|
||||
|
||||
|
||||
void TCPServerDispatcher::beginConnection()
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
++_totalConnections;
|
||||
++_currentConnections;
|
||||
if (_currentConnections > _maxConcurrentConnections)
|
||||
_maxConcurrentConnections = _currentConnections;
|
||||
}
|
||||
|
||||
|
||||
void TCPServerDispatcher::endConnection()
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
--_currentConnections;
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
80
Net/src/TCPServerParams.cpp
Normal file
80
Net/src/TCPServerParams.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
//
|
||||
// TCPServerParams.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/TCPServerParams.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: TCPServer
|
||||
// Module: TCPServerParams
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/TCPServerParams.h"
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
TCPServerParams::TCPServerParams():
|
||||
_threadIdleTime(10000000),
|
||||
_maxThreads(0),
|
||||
_maxQueued(64)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TCPServerParams::~TCPServerParams()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void TCPServerParams::setThreadIdleTime(const Foundation::Timespan& milliseconds)
|
||||
{
|
||||
_threadIdleTime = milliseconds;
|
||||
}
|
||||
|
||||
|
||||
void TCPServerParams::setMaxThreads(int count)
|
||||
{
|
||||
poco_assert (count > 0);
|
||||
|
||||
_maxThreads = count;
|
||||
}
|
||||
|
||||
|
||||
void TCPServerParams::setMaxQueued(int count)
|
||||
{
|
||||
poco_assert (count > 0);
|
||||
|
||||
_maxQueued = count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Net_END
|
||||
Reference in New Issue
Block a user