1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-07-06 17:07:12 +02:00

Update POCO library.

This commit is contained in:
Sandu Liviu Catalin
2023-03-23 20:19:11 +02:00
parent 8d15f4b6e9
commit 233fc103f9
2521 changed files with 257092 additions and 72789 deletions

View File

@ -30,7 +30,7 @@ class HTMLForm;
class Net_API AbstractHTTPRequestHandler: public HTTPRequestHandler
/// The abstract base class for AbstractHTTPRequestHandlers
/// The abstract base class for AbstractHTTPRequestHandlers
/// created by HTTPServer.
///
/// Derived classes must override the run() method.
@ -41,7 +41,7 @@ class Net_API AbstractHTTPRequestHandler: public HTTPRequestHandler
/// HTMLForm object is created for use by subclasses.
///
/// The run() method must perform the complete handling
/// of the HTTP request connection. As soon as the run()
/// of the HTTP request connection. As soon as the run()
/// method returns, the request handler object is destroyed.
///
/// A new AbstractHTTPRequestHandler object will be created for
@ -89,7 +89,7 @@ public:
/// <P>message</P>
/// </BODY>
/// </HTML>
protected:
virtual void run() = 0;
/// Must be overridden by subclasses.
@ -117,7 +117,7 @@ private:
inline HTTPServerRequest& AbstractHTTPRequestHandler::request()
{
poco_check_ptr (_pRequest);
return *_pRequest;
}

View File

@ -48,19 +48,14 @@ public:
/// The socket will be created for the
/// given address family.
DatagramSocket(const SocketAddress& address, bool reuseAddress = false);
/// Creates a datagram socket and binds it
/// to the given address.
///
/// Depending on the address family, the socket
/// will be either an IPv4 or an IPv6 socket.
DatagramSocket(const SocketAddress& address, bool reuseAddress, bool reusePort);
DatagramSocket(const SocketAddress& address, bool reuseAddress, bool reusePort = false, bool ipV6Only = false);
/// Creates a datagram socket and binds it
/// to the given address.
///
/// Depending on the address family, the socket
/// will be either an IPv4 or an IPv6 socket.
/// If ipV6Only is true, socket will be bound
/// to the IPv6 address only.
DatagramSocket(const Socket& socket);
/// Creates the DatagramSocket with the SocketImpl
@ -68,6 +63,10 @@ public:
/// a DatagramSocketImpl, otherwise an InvalidArgumentException
/// will be thrown.
DatagramSocket(const DatagramSocket& socket);
/// Creates the DatagramSocket with the SocketImpl
/// from another socket.
~DatagramSocket();
/// Destroys the DatagramSocket.
@ -78,6 +77,43 @@ public:
/// attaches the SocketImpl from the other socket and
/// increments the reference count of the SocketImpl.
#if POCO_NEW_STATE_ON_MOVE
DatagramSocket(Socket&& socket);
/// Creates the DatagramSocket with the SocketImpl
/// from another socket and zeroes the other socket's
/// SocketImpl.The SocketImpl must be
/// a DatagramSocketImpl, otherwise an InvalidArgumentException
/// will be thrown.
DatagramSocket(DatagramSocket&& socket);
/// Creates the DatagramSocket with the SocketImpl
/// from another socket and zeroes the other socket's
/// SocketImpl.
DatagramSocket& operator = (Socket&& socket);
/// Assignment move operator.
///
/// Releases the socket's SocketImpl and
/// attaches the SocketImpl from the other socket and
/// zeroes the other socket's SocketImpl.
DatagramSocket& operator = (DatagramSocket&& socket);
/// Assignment move operator.
///
/// Releases the socket's SocketImpl and
/// attaches the SocketImpl from the other socket and
/// zeroes the other socket's SocketImpl.
#endif // POCO_NEW_STATE_ON_MOVE
DatagramSocket& operator = (const DatagramSocket& socket);
/// Assignment operator.
///
/// Releases the socket's SocketImpl and
/// attaches the SocketImpl from the other socket and
/// increments the reference count of the SocketImpl.
void connect(const SocketAddress& address);
/// Restricts incoming and outgoing
/// packets to the specified address.
@ -109,6 +145,23 @@ public:
///
/// Calls to connect cannot() come before calls to bind().
void bind6(const SocketAddress& address, bool reuseAddress, bool reusePort, bool ipV6Only = false);
/// Bind a local address to the socket.
///
/// This is usually only done when establishing a server
/// socket.
///
/// If reuseAddress is true, sets the SO_REUSEADDR
/// socket option.
///
/// If reusePort is true, sets the SO_REUSEPORT
/// socket option.
///
/// Sets the IPV6_V6ONLY socket option in accordance with
/// the supplied ipV6Only value.
///
/// Calls to connect cannot() come before calls to bind().
int sendBytes(const void* buffer, int length, int flags = 0);
/// Sends the contents of the given buffer through
/// the socket.
@ -231,7 +284,7 @@ protected:
/// Creates the Socket and attaches the given SocketImpl.
/// The socket takes ownership of the SocketImpl.
///
/// The SocketImpl must be a StreamSocketImpl, otherwise
/// The SocketImpl must be a DatagramSocketImpl, otherwise
/// an InvalidArgumentException will be thrown.
};

View File

@ -41,10 +41,10 @@ public:
DatagramSocketImpl(poco_socket_t sockfd);
/// Creates a StreamSocketImpl using the given native socket.
protected:
void init(int af);
~DatagramSocketImpl();
};

View File

@ -75,11 +75,11 @@ public:
///
/// Releases the socket's SocketImpl and
/// attaches the SocketImpl from the other socket and
/// increments the reference count of the SocketImpl.
/// increments the reference count of the SocketImpl.
DialogSocket& operator = (const DialogSocket& socket);
/// Assignment operator.
void sendByte(unsigned char ch);
/// Sends a single byte over the socket connection.
@ -101,34 +101,34 @@ public:
void sendMessage(const std::string& message, const std::string& arg1, const std::string& arg2);
/// Concatenates message and args, separated by a space, appends a
/// CR-LF sequence, and sends the result over the socket connection.
bool receiveMessage(std::string& message);
/// Receives a single-line message, terminated by CR-LF,
/// from the socket connection and appends it to response.
///
///
/// Returns true if a message has been read or false if
/// the connection has been closed by the peer.
int receiveStatusMessage(std::string& message);
/// Receives a single-line or multi-line response from
/// the socket connection. The format must be according to
/// one of the response formats specified in the FTP (RFC 959)
/// one of the response formats specified in the FTP (RFC 959)
/// or SMTP (RFC 2821) specifications.
///
/// The first line starts with a 3-digit status code.
/// Following the status code is either a space character (' ' )
/// Following the status code is either a space character (' ' )
/// (in case of a single-line response) or a minus character ('-')
/// in case of a multi-line response. The following lines can have
/// a three-digit status code followed by a minus-sign and some
/// text, or some arbitrary text only. The last line again begins
/// with a three-digit status code (which must be the same as the
/// one in the first line), followed by a space and some arbitrary
/// one in the first line), followed by a space and some arbitrary
/// text. All lines must be terminated by a CR-LF sequence.
///
/// The response contains all response lines, separated by a newline
/// character, including the status code. The status code is returned.
/// If the response line does not contain a status code, 0 is returned.
int get();
/// Reads one character from the connection.
///
@ -156,7 +156,7 @@ public:
///
/// According to RFC 854, a TELNET_DM char is sent
/// via sendUrgent().
void sendTelnetCommand(unsigned char command);
/// Sends a TELNET command sequence (TELNET_IAC followed
/// by the given command) over the connection.
@ -198,7 +198,7 @@ private:
MAX_LINE_LENGTH = 4096,
EOF_CHAR = -1
};
char* _pBuffer;
char* _pNext;
char* _pEnd;

View File

@ -58,18 +58,21 @@ public:
TYPE_BINARY /// TYPE I (Image/binary data)
};
FTPClientSession();
FTPClientSession(Poco::UInt16 activeDataPort = 0);
/// Creates an FTPClientSession.
///
/// Passive mode will be used for data transfers.
FTPClientSession(const StreamSocket& socket, bool readWelcomeMessage = true);
FTPClientSession(const StreamSocket& socket, bool readWelcomeMessage = true,
Poco::UInt16 activeDataPort = 0);
/// Creates an FTPClientSession using the given
/// connected socket for the control connection.
///
/// Passive mode will be used for data transfers.
FTPClientSession(const std::string& host, Poco::UInt16 port = FTP_PORT, const std::string& username = "", const std::string& password = "");
FTPClientSession(const std::string& host, Poco::UInt16 port = FTP_PORT,
const std::string& username = "", const std::string& password = "",
Poco::UInt16 activeDataPort = 0);
/// Creates an FTPClientSession using a socket connected
/// to the given host and port. If username is supplied,
/// login is attempted.
@ -350,6 +353,7 @@ private:
std::string _host;
Poco::UInt16 _port = FTP_PORT;
Poco::UInt16 _activeDataPort = 0;
bool _passiveMode = true;
FileType _fileType = TYPE_BINARY;
bool _supports1738 = true;

View File

@ -38,7 +38,7 @@ public:
/// The MIME type is set to application/octet-stream.
///
/// Throws an OpenFileException if the file cannot be opened.
FilePartSource(const std::string& path, const std::string& mediaType);
/// Creates the FilePartSource for the given
/// path and MIME type.
@ -47,7 +47,7 @@ public:
FilePartSource(const std::string& path, const std::string& filename, const std::string& mediaType);
/// Creates the FilePartSource for the given
/// path and MIME type. The given filename is
/// path and MIME type. The given filename is
/// used as part filename (see filename()) only.
///
/// Throws an OpenFileException if the file cannot be opened.
@ -57,7 +57,7 @@ public:
std::istream& stream();
/// Returns a file input stream for the given file.
const std::string& filename() const;
/// Returns the filename portion of the path.

View File

@ -31,6 +31,7 @@ namespace Net {
class HTTPSession;
class MessageHeader;
class Net_API HTTPChunkedStreamBuf: public HTTPBasicStreamBuf
@ -40,7 +41,7 @@ class Net_API HTTPChunkedStreamBuf: public HTTPBasicStreamBuf
public:
using openmode = HTTPBasicStreamBuf::openmode;
HTTPChunkedStreamBuf(HTTPSession& session, openmode mode);
HTTPChunkedStreamBuf(HTTPSession& session, openmode mode, MessageHeader* pTrailer = nullptr);
~HTTPChunkedStreamBuf();
void close();
@ -53,6 +54,7 @@ private:
openmode _mode;
std::streamsize _chunk;
std::string _chunkBuffer;
MessageHeader* _pTrailer;
};
@ -60,7 +62,7 @@ class Net_API HTTPChunkedIOS: public virtual std::ios
/// The base class for HTTPInputStream.
{
public:
HTTPChunkedIOS(HTTPSession& session, HTTPChunkedStreamBuf::openmode mode);
HTTPChunkedIOS(HTTPSession& session, HTTPChunkedStreamBuf::openmode mode, MessageHeader* pTrailer = nullptr);
~HTTPChunkedIOS();
HTTPChunkedStreamBuf* rdbuf();
@ -73,12 +75,12 @@ class Net_API HTTPChunkedInputStream: public HTTPChunkedIOS, public std::istream
/// This class is for internal use by HTTPSession only.
{
public:
HTTPChunkedInputStream(HTTPSession& session);
HTTPChunkedInputStream(HTTPSession& session, MessageHeader* pTrailer = nullptr);
~HTTPChunkedInputStream();
void* operator new(std::size_t size);
void operator delete(void* ptr);
private:
static Poco::MemoryPool _pool;
};
@ -88,12 +90,12 @@ class Net_API HTTPChunkedOutputStream: public HTTPChunkedIOS, public std::ostrea
/// This class is for internal use by HTTPSession only.
{
public:
HTTPChunkedOutputStream(HTTPSession& session);
HTTPChunkedOutputStream(HTTPSession& session, MessageHeader* pTrailer = nullptr);
~HTTPChunkedOutputStream();
void* operator new(std::size_t size);
void operator delete(void* ptr);
private:
static Poco::MemoryPool _pool;
};

View File

@ -116,6 +116,9 @@ public:
HTTPClientSession(const std::string& host, Poco::UInt16 port, const ProxyConfig& proxyConfig);
/// Creates a HTTPClientSession using the given host, port and proxy configuration.
HTTPClientSession(const StreamSocket& socket, const ProxyConfig& proxyConfig);
/// Creates a HTTPClientSession using the given socket and proxy configuration.
virtual ~HTTPClientSession();
/// Destroys the HTTPClientSession and closes
/// the underlying socket.
@ -138,6 +141,32 @@ public:
Poco::UInt16 getPort() const;
/// Returns the port number of the target HTTP server.
void setSourceAddress(const SocketAddress& address);
/// Sets the source IP address and source port for the HTTPClientSession
/// socket.
///
/// Function can be called repeatedly to set one source address value for
/// IPv4 and one for IPv6, in the case where it is not known ahead of time
/// which type of address family the target host is part of.
///
/// The source address must not be changed once there
/// is an open connection to the server.
///
/// Note: Both the source IP address and source port can be set
/// using this function, but the typical client use is to set
/// the source IP address only and the source port portion
/// would normally be passed as 0 meaning that any port value
/// can be used on the source side of the socket.
const SocketAddress& getSourceAddress();
/// Returns the last source address set with setSourceAddress
const SocketAddress& getSourceAddress4();
/// Returns the last IPv4 source address set with setSourceAddress
const SocketAddress& getSourceAddress6();
/// Returns the last IPV6 source address set with setSourceAddress
void setProxy(const std::string& host, Poco::UInt16 port = HTTPSession::HTTP_PORT);
/// Sets the proxy host name and port number.
@ -335,21 +364,27 @@ protected:
/// to the HTTPClientSession.
private:
std::string _host;
Poco::UInt16 _port;
ProxyConfig _proxyConfig;
Poco::Timespan _keepAliveTimeout;
Poco::Timestamp _lastRequest;
bool _reconnect;
bool _mustReconnect;
bool _expectResponseBody;
bool _responseReceived;
Poco::SharedPtr<std::ostream> _pRequestStream;
Poco::SharedPtr<std::istream> _pResponseStream;
using OStreamPtr = Poco::SharedPtr<std::ostream>;
using IStreamPtr = Poco::SharedPtr<std::istream>;
std::string _host;
Poco::UInt16 _port;
SocketAddress _sourceAddress;
SocketAddress _sourceAddress4;
SocketAddress _sourceAddress6;
ProxyConfig _proxyConfig;
Poco::Timespan _keepAliveTimeout;
Poco::Timestamp _lastRequest;
bool _reconnect;
bool _mustReconnect;
bool _expectResponseBody;
bool _responseReceived;
OStreamPtr _pRequestStream;
IStreamPtr _pResponseStream;
HTTPBasicCredentials _proxyBasicCreds;
HTTPDigestCredentials _proxyDigestCreds;
HTTPNTLMCredentials _proxyNTLMCreds;
bool _ntlmProxyAuthenticated;
bool _ntlmProxyAuthenticated;
static ProxyConfig _globalProxyConfig;

View File

@ -120,6 +120,9 @@ public:
/// and HTTPAuthenticationParams by recomputing the response and comparing
/// it with what's in the request.
bool isAlgorithmSupported(const std::string& algorithm) const;
/// Check if digest algorithm is supported
static std::string createNonce();
/// Creates a random nonce string.
@ -133,7 +136,19 @@ private:
void updateAuthParams(const HTTPRequest& request);
int updateNonceCounter(const std::string& nonce);
static const std::string DEFAULT_ALGORITHM;
class DigestEngineProvider;
static const std::string MD_5_ALGORITHM;
static const std::string MD_5_SESS_ALGORITHM;
static const std::string SHA_ALGORITHM;
static const std::string SHA_SESS_ALGORITHM;
static const std::string SHA_256_ALGORITHM;
static const std::string SHA_256_SESS_ALGORITHM;
static const std::string SHA_512_256_ALGORITHM;
static const std::string SHA_512_256_SESS_ALGORITHM;
static const std::string SHA_512_ALGORITHM;
static const std::string SHA_512_SESS_ALGORITHM;
static const std::vector<std::string> SUPPORTED_ALGORITHMS;
static const std::string DEFAULT_QOP;
static const std::string NONCE_PARAM;
static const std::string REALM_PARAM;

View File

@ -49,7 +49,7 @@ public:
HTTPFixedLengthStreamBuf(HTTPSession& session, ContentLength length, openmode mode);
~HTTPFixedLengthStreamBuf();
protected:
int readFromDevice(char* buffer, std::streamsize length);
int writeToDevice(const char* buffer, std::streamsize length);
@ -80,10 +80,10 @@ class Net_API HTTPFixedLengthInputStream: public HTTPFixedLengthIOS, public std:
public:
HTTPFixedLengthInputStream(HTTPSession& session, HTTPFixedLengthStreamBuf::ContentLength length);
~HTTPFixedLengthInputStream();
void* operator new(std::size_t size);
void operator delete(void* ptr);
private:
static Poco::MemoryPool _pool;
};
@ -98,7 +98,7 @@ public:
void* operator new(std::size_t size);
void operator delete(void* ptr);
private:
static Poco::MemoryPool _pool;
};

View File

@ -42,7 +42,7 @@ public:
HTTPHeaderStreamBuf(HTTPSession& session, openmode mode);
~HTTPHeaderStreamBuf();
protected:
int readFromDevice(char* buffer, std::streamsize length);
int writeToDevice(const char* buffer, std::streamsize length);
@ -75,7 +75,7 @@ public:
void* operator new(std::size_t size);
void operator delete(void* ptr);
private:
static Poco::MemoryPool _pool;
};
@ -90,7 +90,7 @@ public:
void* operator new(std::size_t size);
void operator delete(void* ptr);
private:
static Poco::MemoryPool _pool;
};

View File

@ -34,12 +34,12 @@ class Net_API HTTPResponseStreamBuf: public Poco::UnbufferedStreamBuf
{
public:
HTTPResponseStreamBuf(std::istream& istr);
~HTTPResponseStreamBuf();
private:
int readFromDevice();
std::istream& _istr;
};
@ -54,9 +54,9 @@ class Net_API HTTPResponseIOS: public virtual std::ios
{
public:
HTTPResponseIOS(std::istream& istr);
~HTTPResponseIOS();
HTTPResponseStreamBuf* rdbuf();
protected:
@ -74,9 +74,9 @@ class Net_API HTTPResponseStream: public HTTPResponseIOS, public std::istream
{
public:
HTTPResponseStream(std::istream& istr, HTTPClientSession* pSession);
~HTTPResponseStream();
private:
HTTPClientSession* _pSession;
};

View File

@ -30,14 +30,14 @@ class HTTPServerResponse;
class Net_API HTTPRequestHandler
/// The abstract base class for HTTPRequestHandlers
/// The abstract base class for HTTPRequestHandlers
/// created by HTTPServer.
///
/// Derived classes must override the handleRequest() method.
/// Furthermore, a HTTPRequestHandlerFactory must be provided.
///
/// The handleRequest() method must perform the complete handling
/// of the HTTP request connection. As soon as the handleRequest()
/// of the HTTP request connection. As soon as the handleRequest()
/// method returns, the request handler object is destroyed.
///
/// A new HTTPRequestHandler object will be created for

View File

@ -39,7 +39,7 @@ class Net_API HTTPRequestHandlerFactory
{
public:
using Ptr = Poco::SharedPtr<HTTPRequestHandlerFactory>;
HTTPRequestHandlerFactory();
/// Creates the HTTPRequestHandlerFactory.
@ -56,8 +56,8 @@ public:
/// request.
///
/// If the request contains a "Expect: 100-continue" header, it's possible
/// to prevent the server from sending the default 100 Continue response
/// by setting the status of the response object that can be obtained through
/// to prevent the server from sending the default 100 Continue response
/// by setting the status of the response object that can be obtained through
/// the request object (request.response()) to something other than 200 OK.
protected:
@ -66,7 +66,7 @@ protected:
private:
HTTPRequestHandlerFactory(const HTTPRequestHandlerFactory&);
HTTPRequestHandlerFactory& operator = (const HTTPRequestHandlerFactory&);
friend class HTTPServer;
friend class HTTPServerConnection;
};

View File

@ -93,6 +93,7 @@ public:
HTTP_UNPROCESSABLE_ENTITY = 422,
HTTP_LOCKED = 423,
HTTP_FAILED_DEPENDENCY = 424,
HTTP_TOO_EARLY = 425,
HTTP_UPGRADE_REQUIRED = 426,
HTTP_PRECONDITION_REQUIRED = 428,
HTTP_TOO_MANY_REQUESTS = 429,
@ -243,6 +244,7 @@ public:
static const std::string HTTP_REASON_UNPROCESSABLE_ENTITY;
static const std::string HTTP_REASON_LOCKED;
static const std::string HTTP_REASON_FAILED_DEPENDENCY;
static const std::string HTTP_REASON_TOO_EARLY;
static const std::string HTTP_REASON_UPGRADE_REQUIRED;
static const std::string HTTP_REASON_PRECONDITION_REQUIRED;
static const std::string HTTP_REASON_TOO_MANY_REQUESTS;

View File

@ -43,7 +43,7 @@ public:
virtual ~HTTPServerConnection();
/// Destroys the HTTPServerConnection.
void run();
/// Handles all HTTP requests coming in.

View File

@ -42,7 +42,7 @@ public:
TCPServerConnection* createConnection(const StreamSocket& socket);
/// Creates an instance of HTTPServerConnection
/// using the given StreamSocket.
private:
HTTPServerParams::Ptr _pParams;
HTTPRequestHandlerFactory::Ptr _pFactory;

View File

@ -46,26 +46,26 @@ public:
~HTTPServerRequest();
/// Destroys the HTTPServerRequest.
virtual std::istream& stream() = 0;
/// Returns the input stream for reading
/// the request body.
///
/// The stream must be valid until the HTTPServerRequest
/// object is destroyed.
virtual const SocketAddress& clientAddress() const = 0;
/// Returns the client's address.
virtual const SocketAddress& serverAddress() const = 0;
/// Returns the server's address.
virtual const HTTPServerParams& serverParams() const = 0;
/// Returns a reference to the server parameters.
virtual HTTPServerResponse& response() const = 0;
/// Returns a reference to the associated response.
virtual bool secure() const = 0;
/// Returns true if the request is using a secure
/// connection. Returns false if no secure connection

View File

@ -49,39 +49,39 @@ public:
~HTTPServerRequestImpl();
/// Destroys the HTTPServerRequestImpl.
std::istream& stream();
/// Returns the input stream for reading
/// the request body.
///
/// The stream is valid until the HTTPServerRequestImpl
/// object is destroyed.
const SocketAddress& clientAddress() const;
/// Returns the client's address.
const SocketAddress& serverAddress() const;
/// Returns the server's address.
const HTTPServerParams& serverParams() const;
/// Returns a reference to the server parameters.
HTTPServerResponse& response() const;
/// Returns a reference to the associated response.
bool secure() const;
/// Returns true if the request is using a secure
/// connection. Returns false if no secure connection
/// is used, or if it is not known whether a secure
/// connection is used.
/// connection is used.
StreamSocket& socket();
/// Returns a reference to the underlying socket.
StreamSocket detachSocket();
/// Returns the underlying socket after detaching
/// it from the server session.
HTTPServerSession& session();
/// Returns the underlying HTTPServerSession.
@ -101,7 +101,7 @@ private:
inline std::istream& HTTPServerRequestImpl::stream()
{
poco_check_ptr (_pStream);
return *_pStream;
}

View File

@ -53,7 +53,7 @@ public:
virtual void sendContinue() = 0;
/// Sends a 100 Continue response to the
/// client.
virtual std::ostream& send() = 0;
/// Sends the response header to the client and
/// returns an output stream for sending the
@ -62,20 +62,20 @@ public:
/// The returned stream is valid until the response
/// object is destroyed.
///
/// Must not be called after sendFile(), sendBuffer()
/// Must not be called after sendFile(), sendBuffer()
/// or redirect() has been called.
virtual void sendFile(const std::string& path, const std::string& mediaType) = 0;
/// Sends the response header to the client, followed
/// by the content of the given file.
///
/// Must not be called after send(), sendBuffer()
/// Must not be called after send(), sendBuffer()
/// or redirect() has been called.
///
/// Throws a FileNotFoundException if the file
/// cannot be found, or an OpenFileException if
/// the file cannot be opened.
virtual void sendBuffer(const void* pBuffer, std::size_t length) = 0;
/// Sends the response header to the client, followed
/// by the contents of the given buffer.
@ -84,12 +84,12 @@ public:
/// to length and chunked transfer encoding is disabled.
///
/// If both the HTTP message header and body (from the
/// given buffer) fit into one single network packet, the
/// given buffer) fit into one single network packet, the
/// complete response can be sent in one network packet.
///
/// Must not be called after send(), sendFile()
/// Must not be called after send(), sendFile()
/// or redirect() has been called.
virtual void redirect(const std::string& uri, HTTPStatus status = HTTP_FOUND) = 0;
/// Sets the status code, which must be one of
/// HTTP_MOVED_PERMANENTLY (301), HTTP_FOUND (302),
@ -99,12 +99,12 @@ public:
/// the HTTP specification, must be absolute.
///
/// Must not be called after send() has been called.
virtual void requireAuthentication(const std::string& realm) = 0;
/// Sets the status code to 401 (Unauthorized)
/// and sets the "WWW-Authenticate" header field
/// according to the given realm.
virtual bool sent() const = 0;
/// Returns true if the response (header) has been sent.
};

View File

@ -51,7 +51,7 @@ public:
void sendContinue();
/// Sends a 100 Continue response to the
/// client.
std::ostream& send();
/// Sends the response header to the client and
/// returns an output stream for sending the
@ -60,20 +60,20 @@ public:
/// The returned stream is valid until the response
/// object is destroyed.
///
/// Must not be called after sendFile(), sendBuffer()
/// Must not be called after sendFile(), sendBuffer()
/// or redirect() has been called.
void sendFile(const std::string& path, const std::string& mediaType);
/// Sends the response header to the client, followed
/// by the content of the given file.
///
/// Must not be called after send(), sendBuffer()
/// Must not be called after send(), sendBuffer()
/// or redirect() has been called.
///
/// Throws a FileNotFoundException if the file
/// cannot be found, or an OpenFileException if
/// the file cannot be opened.
void sendBuffer(const void* pBuffer, std::size_t length);
/// Sends the response header to the client, followed
/// by the contents of the given buffer.
@ -82,12 +82,12 @@ public:
/// to length and chunked transfer encoding is disabled.
///
/// If both the HTTP message header and body (from the
/// given buffer) fit into one single network packet, the
/// given buffer) fit into one single network packet, the
/// complete response can be sent in one network packet.
///
/// Must not be called after send(), sendFile()
/// Must not be called after send(), sendFile()
/// or redirect() has been called.
void redirect(const std::string& uri, HTTPStatus status = HTTP_FOUND);
/// Sets the status code, which must be one of
/// HTTP_MOVED_PERMANENTLY (301), HTTP_FOUND (302),
@ -97,23 +97,23 @@ public:
/// the HTTP specification, must be absolute.
///
/// Must not be called after send() has been called.
void requireAuthentication(const std::string& realm);
/// Sets the status code to 401 (Unauthorized)
/// and sets the "WWW-Authenticate" header field
/// according to the given realm.
bool sent() const;
/// Returns true if the response (header) has been sent.
protected:
void attachRequest(HTTPServerRequestImpl* pRequest);
private:
HTTPServerSession& _session;
HTTPServerRequestImpl* _pRequest;
std::ostream* _pStream;
friend class HTTPServerRequestImpl;
};

View File

@ -41,19 +41,19 @@ public:
virtual ~HTTPServerSession();
/// Destroys the HTTPServerSession.
bool hasMoreRequests();
/// Returns true if there are requests available.
bool canKeepAlive() const;
/// Returns true if the session can be kept alive.
SocketAddress clientAddress();
/// Returns the client's address.
SocketAddress serverAddress();
/// Returns the server's address.
private:
bool _firstRequest;
Poco::Timespan _keepAliveTimeout;

View File

@ -19,6 +19,7 @@
#include "Poco/Net/Net.h"
#include "Poco/Net/MessageHeader.h"
#include "Poco/Net/StreamSocket.h"
#include "Poco/Timespan.h"
#include "Poco/Exception.h"
@ -47,43 +48,61 @@ public:
///
/// If the keep-alive flag is enabled, persistent
/// HTTP/1.1 connections are supported.
bool getKeepAlive() const;
/// Returns the value of the keep-alive flag for
/// this session.
void setTimeout(const Poco::Timespan& timeout);
/// Sets the timeout for the HTTP session.
void setTimeout(const Poco::Timespan& connectionTimeout, const Poco::Timespan& sendTimeout, const Poco::Timespan& receiveTimeout);
/// Sets different timeouts for the HTTP session.
Poco::Timespan getTimeout() const;
/// Returns the timeout for the HTTP session.
void setConnectTimeout(const Poco::Timespan& timeout);
/// Sets the connect timeout.
Poco::Timespan getConnectTimeout() const;
/// Gets the connect timeout.
void setSendTimeout(const Poco::Timespan& timeout);
/// Sets the send timeout.
Poco::Timespan getSendTimeout() const;
/// Gets the send timeout.
void setReceiveTimeout(const Poco::Timespan& timeout);
/// Sets the receive timeout.
Poco::Timespan getReceiveTimeout() const;
/// Gets the receive timeout.
bool connected() const;
/// Returns true if the underlying socket is connected.
virtual void abort();
/// Aborts a session in progress by shutting down
/// and closing the underlying socket.
const Poco::Exception* networkException() const;
/// If sending or receiving data over the underlying
/// socket connection resulted in an exception, a
/// pointer to this exception is returned.
///
///
/// Otherwise, NULL is returned.
void attachSessionData(const Poco::Any& data);
/// Allows to attach an application-specific data
/// Allows to attach an application-specific data
/// item to the session.
///
/// On the server side, this can be used to manage
/// data that must be maintained over the entire
/// lifetime of a persistent connection (that is,
/// multiple requests sent over the same connection).
const Poco::Any& sessionData() const;
/// Returns the data attached with attachSessionData(),
/// or an empty Poco::Any if no user data has been
@ -93,7 +112,7 @@ public:
{
HTTP_PORT = 80
};
StreamSocket detachSocket();
/// Detaches the socket from the session.
///
@ -102,7 +121,7 @@ public:
StreamSocket& socket();
/// Returns a reference to the underlying socket.
void drainBuffer(Poco::Buffer<char>& buffer);
/// Copies all bytes remaining in the internal buffer to the
/// given Poco::Buffer, resizing it as necessary.
@ -111,6 +130,26 @@ public:
/// obtain any data already read from the socket, but not
/// yet processed.
const MessageHeader& requestTrailer() const;
/// Returns the trailer for a request sent using chunked
/// transfer encoding. This method must be called after
/// the entire content of the message has been read.
MessageHeader& requestTrailer();
/// Returns the trailer for a request sent using chunked
/// transfer encoding. The trailer fields to be sent must be set
/// before the request body has been fully written.
const MessageHeader& responseTrailer() const;
/// Returns the trailer for a response sent using chunked
/// transfer encoding. This method must be called after
/// the entire content of the message has been read.
MessageHeader& responseTrailer();
/// Returns the trailer for a response sent using chunked
/// transfer encoding. The trailer fields to be sent must be set
/// before the response body has been fully written.
protected:
HTTPSession();
/// Creates a HTTP session using an
@ -136,42 +175,46 @@ protected:
/// Returns the next byte in the buffer.
/// Reads more data from the socket if there are
/// no bytes left in the buffer.
int peek();
/// Peeks at the next character in the buffer.
/// Reads more data from the socket if there are
/// no bytes left in the buffer.
virtual int read(char* buffer, std::streamsize length);
/// Reads up to length bytes.
///
/// If there is data in the buffer, this data
/// is returned. Otherwise, data is read from
/// the socket to avoid unnecessary buffering.
virtual int write(const char* buffer, std::streamsize length);
/// Writes data to the socket.
int receive(char* buffer, int length);
/// Reads up to length bytes.
int buffered() const;
/// Returns the number of bytes in the buffer.
void refill();
/// Refills the internal buffer.
virtual void connect(const SocketAddress& address);
/// Connects the underlying socket to the given address
/// and sets the socket's receive timeout.
/// and sets the socket's receive timeout.
void connect(const SocketAddress& targetAddress, const SocketAddress& sourceAddress);
/// Binds the underlying socket to the source address
/// and connects to the targetAddress.
void attachSocket(const StreamSocket& socket);
/// Attaches a socket to the session, replacing the
/// previously attached socket.
void close();
/// Closes the underlying socket.
void setException(const Poco::Exception& exc);
/// Stores a clone of the exception.
@ -184,10 +227,10 @@ private:
HTTP_DEFAULT_TIMEOUT = 60000000,
HTTP_DEFAULT_CONNECTION_TIMEOUT = 30000000
};
HTTPSession(const HTTPSession&);
HTTPSession& operator = (const HTTPSession&);
StreamSocket _socket;
char* _pBuffer;
char* _pCurrent;
@ -197,8 +240,10 @@ private:
Poco::Timespan _receiveTimeout;
Poco::Timespan _sendTimeout;
Poco::Exception* _pException;
MessageHeader _requestTrailer;
MessageHeader _responseTrailer;
Poco::Any _data;
friend class HTTPStreamBuf;
friend class HTTPHeaderStreamBuf;
friend class HTTPFixedLengthStreamBuf;
@ -221,6 +266,42 @@ inline Poco::Timespan HTTPSession::getTimeout() const
}
inline void HTTPSession::setConnectTimeout(const Poco::Timespan& timeout)
{
_connectionTimeout = timeout;
}
inline Poco::Timespan HTTPSession::getConnectTimeout() const
{
return _connectionTimeout;
}
inline void HTTPSession::setSendTimeout(const Poco::Timespan& timeout)
{
_sendTimeout = timeout;
}
inline Poco::Timespan HTTPSession::getSendTimeout() const
{
return _sendTimeout;
}
inline void HTTPSession::setReceiveTimeout(const Poco::Timespan& timeout)
{
_receiveTimeout = timeout;
}
inline Poco::Timespan HTTPSession::getReceiveTimeout() const
{
return _receiveTimeout;
}
inline StreamSocket& HTTPSession::socket()
{
return _socket;
@ -245,6 +326,30 @@ inline const Poco::Any& HTTPSession::sessionData() const
}
inline const MessageHeader& HTTPSession::requestTrailer() const
{
return _requestTrailer;
}
inline MessageHeader& HTTPSession::requestTrailer()
{
return _requestTrailer;
}
inline const MessageHeader& HTTPSession::responseTrailer() const
{
return _responseTrailer;
}
inline MessageHeader& HTTPSession::responseTrailer()
{
return _responseTrailer;
}
} } // namespace Poco::Net

View File

@ -43,7 +43,7 @@ public:
HTTPStreamBuf(HTTPSession& session, openmode mode);
~HTTPStreamBuf();
void close();
protected:
int readFromDevice(char* buffer, std::streamsize length);
int writeToDevice(const char* buffer, std::streamsize length);
@ -76,7 +76,7 @@ public:
void* operator new(std::size_t size);
void operator delete(void* ptr);
private:
static Poco::MemoryPool _pool;
};
@ -91,7 +91,7 @@ public:
void* operator new(std::size_t size);
void operator delete(void* ptr);
private:
static Poco::MemoryPool _pool;
};

View File

@ -49,7 +49,7 @@ public:
virtual ~HTTPStreamFactory();
/// Destroys the HTTPStreamFactory.
virtual std::istream* open(const Poco::URI& uri);
/// Creates and opens a HTTP stream for the given URI.
/// The URI must be a http://... URI.
@ -60,25 +60,25 @@ public:
/// location is automatically resolved, as long
/// as the redirect location is still accessible
/// via the HTTP protocol. If a redirection to
/// a non http://... URI is received, a
/// a non http://... URI is received, a
/// UnsupportedRedirectException exception is thrown.
/// The offending URI can then be obtained via the message()
/// method of UnsupportedRedirectException.
static void registerFactory();
/// Registers the HTTPStreamFactory with the
/// default URIStreamOpener instance.
/// default URIStreamOpener instance.
static void unregisterFactory();
/// Unregisters the HTTPStreamFactory with the
/// default URIStreamOpener instance.
/// default URIStreamOpener instance.
private:
enum
{
MAX_REDIRECTS = 10
};
std::string _proxyHost;
Poco::UInt16 _proxyPort;
std::string _proxyUsername;

View File

@ -36,10 +36,10 @@ class Net_API HostEntry
public:
using AliasList = std::vector<std::string>;
using AddressList = std::vector<IPAddress>;
HostEntry();
/// Creates an empty HostEntry.
HostEntry(struct hostent* entry);
/// Creates the HostEntry from the data in a hostent structure.
@ -58,8 +58,8 @@ public:
HostEntry& operator = (const HostEntry& entry);
/// Assigns another HostEntry.
void swap(HostEntry& hostEntry);
/// Swaps the HostEntry with another one.
void swap(HostEntry& hostEntry) noexcept;
/// Swaps the HostEntry with another one.
~HostEntry();
/// Destroys the HostEntry.
@ -111,7 +111,7 @@ inline const HostEntry::AddressList& HostEntry::addresses() const
}
inline void swap(HostEntry& h1, HostEntry& h2)
inline void swap(HostEntry& h1, HostEntry& h2) noexcept
{
h1.swap(h2);
}

View File

@ -34,7 +34,7 @@ class Net_API ICMPClient
///
/// The events are available when class is instantiated
/// and non-static member functions are called.
///
///
/// A "lightweight" alternative is direct (without instantiation)
/// use of static member functions.
{
@ -53,13 +53,13 @@ public:
int ping(SocketAddress& address, int repeat = 1) const;
/// Pings the specified address [repeat] times.
/// Notifications are posted for events.
///
///
/// Returns the number of valid replies.
int ping(const std::string& address, int repeat = 1) const;
/// Calls ICMPClient::ping(SocketAddress&, int) and
/// returns the result.
///
///
/// Returns the number of valid replies.
static int ping(SocketAddress& address,
@ -70,7 +70,7 @@ public:
int timeout = 100000);
/// Pings the specified address [repeat] times.
/// Notifications are not posted for events.
///
///
/// Returns the number of valid replies.
static int pingIPv4(const std::string& address,
@ -80,7 +80,7 @@ public:
int timeout = 100000);
/// Calls ICMPClient::ping(SocketAddress&, int) and
/// returns the result.
///
///
/// Returns the number of valid replies.
private:

View File

@ -31,7 +31,7 @@ namespace Net {
class Net_API ICMPEventArgs
/// The purpose of the ICMPEventArgs class is to be used as template parameter
/// to instantiate event members in ICMPClient class.
/// When clients register for an event notification, the reference to the class is
/// When clients register for an event notification, the reference to the class is
/// passed to the handler function to provide information about the event.
{
public:
@ -43,7 +43,7 @@ public:
std::string hostName() const;
/// Tries to resolve the target IP address into host name.
/// If unsuccessful, all exceptions are silently ignored and
/// If unsuccessful, all exceptions are silently ignored and
/// the IP address is returned.
std::string hostAddress() const;

View File

@ -28,7 +28,7 @@ namespace Net {
class Net_API ICMPPacket
/// This class is the ICMP packet abstraction.
/// This class is the ICMP packet abstraction.
{
public:
ICMPPacket(SocketAddress::Family family, int dataSize = 48);
@ -57,13 +57,13 @@ public:
struct timeval time(Poco::UInt8* buffer = 0, int length = 0) const;
/// Returns current epoch time if either buffer or length are equal to zero.
/// Otherwise, it extracts the time value from the supplied buffer and
/// Otherwise, it extracts the time value from the supplied buffer and
/// returns the extracted value.
///
/// Supplied buffer includes IP header, ICMP header and data.
bool validReplyID(Poco::UInt8* buffer, int length) const;
/// Returns true if the extracted id is recognized
/// Returns true if the extracted id is recognized
/// (equals the process id).
///
/// Supplied buffer includes IP header, ICMP header and data.

View File

@ -51,7 +51,7 @@ public:
///
/// Releases the socket's SocketImpl and
/// attaches the SocketImpl from the other socket and
/// increments the reference count of the SocketImpl.
/// increments the reference count of the SocketImpl.
int sendTo(const SocketAddress& address, int flags = 0);
/// Sends an ICMP request through
@ -63,7 +63,7 @@ public:
/// Receives data from the socket.
/// Stores the address of the sender in address.
///
/// Returns the time elapsed since the originating
/// Returns the time elapsed since the originating
/// request was sent.
int dataSize() const;

View File

@ -41,7 +41,7 @@ public:
/// Sends an ICMP request through the socket to the given address.
///
/// Returns the number of bytes sent.
int receiveFrom(void*, int, SocketAddress& address, int flags = 0);
/// Receives data from the socket.
/// Stores the address of the sender in address.

View File

@ -24,6 +24,7 @@
#include "Poco/AutoPtr.h"
#include "Poco/Exception.h"
#include <vector>
#include <array>
#include <ostream>
@ -42,7 +43,7 @@ class Net_API IPAddress
///
/// Relational operators (==, !=, <, <=, >, >=) are
/// supported. However, you must not interpret any
/// special meaning into the result of these
/// special meaning into the result of these
/// operations, other than that the results are
/// consistent.
///
@ -56,6 +57,13 @@ class Net_API IPAddress
public:
using List = std::vector<IPAddress>;
using RawIP = std::vector<unsigned char>;
static const unsigned IPv4Size = sizeof(in_addr);
static const unsigned IPv6Size = sizeof(in6_addr);
using RawIPv4 = std::array<unsigned char, IPv4Size>;
using RawIPv6 = std::array<unsigned char, IPv6Size>;
// The following declarations keep the Family type
// backwards compatible with the previously used
// enum declaration.
@ -64,13 +72,16 @@ public:
#if defined(POCO_HAVE_IPv6)
static const Family IPv6 = AddressFamily::IPv6;
#endif
IPAddress();
/// Creates a wildcard (zero) IPv4 IPAddress.
IPAddress(const IPAddress& addr);
/// Creates an IPAddress by copying another one.
IPAddress(IPAddress&& addr);
/// Creates an IPAddress by moving another one.
explicit IPAddress(Family family);
/// Creates a wildcard (zero) IPAddress for the
/// given address family.
@ -79,7 +90,7 @@ public:
/// Creates an IPAddress from the string containing
/// an IP address in presentation format (dotted decimal
/// for IPv4, hex string for IPv6).
///
///
/// Depending on the format of addr, either an IPv4 or
/// an IPv6 address is created.
///
@ -94,12 +105,12 @@ public:
IPAddress(const void* addr, poco_socklen_t length);
/// Creates an IPAddress from a native internet address.
/// A pointer to a in_addr or a in6_addr structure may be
/// A pointer to a in_addr or a in6_addr structure may be
/// passed.
IPAddress(const void* addr, poco_socklen_t length, Poco::UInt32 scope);
/// Creates an IPAddress from a native internet address.
/// A pointer to a in_addr or a in6_addr structure may be
/// A pointer to a in_addr or a in6_addr structure may be
/// passed. Additionally, for an IPv6 address, a scope ID
/// may be specified. The scope ID will be ignored if an IPv4
/// address is specified.
@ -121,7 +132,16 @@ public:
IPAddress& operator = (const IPAddress& addr);
/// Assigns an IPAddress.
IPAddress& operator = (IPAddress&& addr);
/// Move-assigns an IPAddress.
bool isV4() const;
bool isV6() const;
RawIPv4 toV4Bytes() const;
RawIPv6 toV6Bytes() const;
RawIP toBytes() const;
Family family() const;
/// Returns the address family (IPv4 or IPv6) of the address.
@ -139,23 +159,23 @@ public:
///
/// Textual representation of IPv6 address is one of the following forms:
///
/// The preferred form is x:x:x:x:x:x:x:x, where the 'x's are the hexadecimal
/// The preferred form is x:x:x:x:x:x:x:x, where the 'x's are the hexadecimal
/// values of the eight 16-bit pieces of the address. This is the full form.
/// Example: 1080:0:0:0:8:600:200A:425C
///
/// It is not necessary to write the leading zeros in an individual field.
/// It is not necessary to write the leading zeros in an individual field.
/// However, there must be at least one numeral in every field, except as described below.
///
/// It is common for IPv6 addresses to contain long strings of zero bits.
/// In order to make writing addresses containing zero bits easier, a special syntax is
/// available to compress the zeros. The use of "::" indicates multiple groups of 16-bits of zeros.
/// The "::" can only appear once in an address. The "::" can also be used to compress the leading
///
/// It is common for IPv6 addresses to contain long strings of zero bits.
/// In order to make writing addresses containing zero bits easier, a special syntax is
/// available to compress the zeros. The use of "::" indicates multiple groups of 16-bits of zeros.
/// The "::" can only appear once in an address. The "::" can also be used to compress the leading
/// and/or trailing zeros in an address. Example: 1080::8:600:200A:425C
///
/// For dealing with IPv4 compatible addresses in a mixed environment,
/// a special syntax is available: x:x:x:x:x:x:d.d.d.d, where the 'x's are the
/// hexadecimal values of the six high-order 16-bit pieces of the address,
/// and the 'd's are the decimal values of the four low-order 8-bit pieces of the
/// a special syntax is available: x:x:x:x:x:x:d.d.d.d, where the 'x's are the
/// hexadecimal values of the six high-order 16-bit pieces of the address,
/// and the 'd's are the decimal values of the four low-order 8-bit pieces of the
/// standard IPv4 representation address. Example: ::FFFF:192.168.1.120
///
/// If an IPv6 address contains a non-zero scope identifier, it is added
@ -163,11 +183,11 @@ public:
/// the numeric value (which specifies an interface index) is directly
/// appended. On Unix platforms, the name of the interface corresponding
/// to the index (interpretation of the scope identifier) is added.
bool isWildcard() const;
/// Returns true iff the address is a wildcard (all zero)
/// address.
bool isBroadcast() const;
/// Returns true iff the address is a broadcast address.
///
@ -175,14 +195,14 @@ public:
/// address, all bits are one.
///
/// For an IPv6 address, returns always false.
bool isLoopback() const;
/// Returns true iff the address is a loopback address.
///
/// For IPv4, the loopback address is 127.0.0.1.
///
/// For IPv6, the loopback address is ::1.
bool isMulticast() const;
/// Returns true iff the address is a multicast address.
///
@ -192,13 +212,13 @@ public:
///
/// IPv6 multicast addresses are in the
/// FFxx:x:x:x:x:x:x:x range.
bool isUnicast() const;
/// Returns true iff the address is a unicast address.
///
/// An address is unicast if it is neither a wildcard,
/// broadcast or multicast address.
bool isLinkLocal() const;
/// Returns true iff the address is a link local unicast address.
///
@ -207,18 +227,18 @@ public:
///
/// IPv6 link local addresses have 1111 1110 10 as the first
/// 10 bits, followed by 54 zeros.
bool isSiteLocal() const;
/// Returns true iff the address is a site local unicast address.
///
/// IPv4 site local addresses are in on of the 10.0.0.0/24,
/// 192.168.0.0/16 or 172.16.0.0 to 172.31.255.255 ranges.
///
/// Originally, IPv6 site-local addresses had FEC0/10 (1111 1110 11)
/// prefix (RFC 4291), followed by 38 zeros. Interfaces using
/// Originally, IPv6 site-local addresses had FEC0/10 (1111 1110 11)
/// prefix (RFC 4291), followed by 38 zeros. Interfaces using
/// this mask are supported, but obsolete; RFC 4193 prescribes
/// fc00::/7 (1111 110) as local unicast prefix.
bool isIPv4Compatible() const;
/// Returns true iff the address is IPv4 compatible.
///
@ -233,16 +253,16 @@ public:
/// For IPv4 addresses, this is always true.
///
/// For IPv6, the address must be in the ::FFFF:x:x range.
bool isWellKnownMC() const;
/// Returns true iff the address is a well-known multicast address.
///
/// For IPv4, well-known multicast addresses are in the
/// For IPv4, well-known multicast addresses are in the
/// 224.0.0.0/8 range.
///
/// For IPv6, well-known multicast addresses are in the
/// For IPv6, well-known multicast addresses are in the
/// FF0x:x:x:x:x:x:x:x range.
bool isNodeLocalMC() const;
/// Returns true iff the address is a node-local multicast address.
///
@ -251,7 +271,7 @@ public:
///
/// For IPv6, node-local multicast addresses are in the
/// FFx1:x:x:x:x:x:x:x range.
bool isLinkLocalMC() const;
/// Returns true iff the address is a link-local multicast address.
///
@ -283,13 +303,13 @@ public:
bool isGlobalMC() const;
/// Returns true iff the address is a global multicast address.
///
/// For IPv4, global multicast addresses are in the
/// For IPv4, global multicast addresses are in the
/// 224.0.1.0 to 238.255.255.255 range.
///
/// For IPv6, global multicast addresses are in the
/// FFxF:x:x:x:x:x:x:x range.
bool operator == (const IPAddress& addr) const;
bool operator == (const IPAddress& addr) const;
bool operator != (const IPAddress& addr) const;
bool operator < (const IPAddress& addr) const;
bool operator <= (const IPAddress& addr) const;
@ -299,36 +319,36 @@ public:
IPAddress operator | (const IPAddress& addr) const;
IPAddress operator ^ (const IPAddress& addr) const;
IPAddress operator ~ () const;
poco_socklen_t length() const;
/// Returns the length in bytes of the internal socket address structure.
/// Returns the length in bytes of the internal socket address structure.
const void* addr() const;
/// Returns the internal address structure.
int af() const;
/// Returns the address family (AF_INET or AF_INET6) of the address.
unsigned prefixLength() const;
/// Returns the prefix length.
void mask(const IPAddress& mask);
/// Masks the IP address using the given netmask, which is usually
/// a IPv4 subnet mask. Only supported for IPv4 addresses.
///
/// The new address is (address & mask).
void mask(const IPAddress& mask, const IPAddress& set);
/// Masks the IP address using the given netmask, which is usually
/// a IPv4 subnet mask. Only supported for IPv4 addresses.
///
/// The new address is (address & mask) | (set & ~mask).
static IPAddress parse(const std::string& addr);
/// Creates an IPAddress from the string containing
/// an IP address in presentation format (dotted decimal
/// for IPv4, hex string for IPv6).
///
///
/// Depending on the format of addr, either an IPv4 or
/// an IPv6 address is created.
///
@ -348,13 +368,13 @@ public:
static IPAddress wildcard(Family family = IPv4);
/// Returns a wildcard IPv4 or IPv6 address (0.0.0.0).
static IPAddress broadcast();
/// Returns a broadcast IPv4 address (255.255.255.255).
enum
{
MAX_ADDRESS_LENGTH =
MAX_ADDRESS_LENGTH =
#if defined(POCO_HAVE_IPv6)
sizeof(struct in6_addr)
#else
@ -376,6 +396,8 @@ private:
void newIPv6(const void* hostAddr);
void newIPv6(const void* hostAddr, Poco::UInt32 scope);
void newIPv6(unsigned prefix);
static std::string& compressV6(std::string& v6addr);
static std::string trimIPv6(const std::string v6Addr);
#endif
Ptr _pImpl;
};
@ -384,6 +406,19 @@ private:
//
// inlines
//
inline bool IPAddress::isV4() const
{
return family() == IPv4;
}
inline bool IPAddress::isV6() const
{
return family() == IPv6;
}
inline IPAddress::Ptr IPAddress::pImpl() const
{
if (_pImpl) return _pImpl;

View File

@ -33,7 +33,7 @@ class IPAddressImpl : public Poco::RefCountedObject
{
public:
using Family = AddressFamily::Family;
virtual ~IPAddressImpl();
virtual IPAddressImpl* clone() const = 0;
@ -112,7 +112,7 @@ public:
bool operator == (const IPv4AddressImpl& addr) const;
bool operator != (const IPv4AddressImpl& addr) const;
private:
private:
struct in_addr _addr;
};

View File

@ -43,10 +43,10 @@ public:
MailRecipient();
/// Creates an empty MailRecipient.
MailRecipient(const MailRecipient& recipient);
/// Creates a MailRecipient by copying another one.
MailRecipient(RecipientType type, const std::string& address);
/// Creates a MailRecipient of the given type.
@ -55,28 +55,28 @@ public:
~MailRecipient();
/// Destroys the MailRecipient.
MailRecipient& operator = (const MailRecipient& recipient);
/// Assigns another recipient.
void swap(MailRecipient& recipient);
void swap(MailRecipient& recipient) noexcept;
/// Exchanges the content of two recipients.
RecipientType getType() const;
/// Returns the type of the recipient.
void setType(RecipientType type);
/// Sets the type of the recipient.
const std::string& getAddress() const;
/// Returns the address of the recipient.
void setAddress(const std::string& address);
/// Sets the address of the recipient.
const std::string& getRealName() const;
/// Returns the real name of the recipient.
void setRealName(const std::string& realName);
/// Sets the real name of the recipient.
@ -108,7 +108,7 @@ inline const std::string& MailRecipient::getRealName() const
}
inline void swap(MailRecipient& r1, MailRecipient& r2)
inline void swap(MailRecipient& r1, MailRecipient& r2) noexcept
{
r1.swap(r2);
}

View File

@ -29,7 +29,7 @@ namespace Net {
class Net_API MailStreamBuf: public Poco::UnbufferedStreamBuf
/// The sole purpose of this stream buffer is to replace
/// The sole purpose of this stream buffer is to replace
/// a "\r\n.\r\n" character sequence with a "\r\n..\r\n" sequence for
/// output streams and vice-versa for input streams.
///
@ -50,11 +50,11 @@ public:
~MailStreamBuf();
/// Destroys the MailStreamBuf.
void close();
/// Writes the terminating period, followed by
/// CR-LF.
protected:
int readFromDevice();
int writeToDevice(char c);
@ -71,7 +71,7 @@ private:
ST_CR_LF_DOT_CR,
ST_CR_LF_DOT_CR_LF
};
std::istream* _pIstr;
std::ostream* _pOstr;
std::string _buffer;
@ -82,7 +82,7 @@ private:
class Net_API MailIOS: public virtual std::ios
/// The base class for MailInputStream and MailOutputStream.
///
/// This class provides common methods and is also needed to ensure
/// This class provides common methods and is also needed to ensure
/// the correct initialization order of the stream buffer and base classes.
{
public:

View File

@ -37,7 +37,7 @@ public:
MediaType(const std::string& mediaType);
/// Creates the MediaType from the given string, which
/// must have the format <type>/<subtype>{;<parameter>=<value>}.
MediaType(const std::string& type, const std::string& subType);
/// Creates the MediaType, using the given type and subtype.
@ -55,51 +55,51 @@ public:
MediaType& operator = (MediaType&& mediaType) noexcept;
/// Assigns another media type.
MediaType& operator = (const std::string& mediaType);
/// Assigns another media type.
void swap(MediaType& mediaType);
void swap(MediaType& mediaType) noexcept;
/// Swaps the MediaType with another one.
void setType(const std::string& type);
/// Sets the top-level type.
const std::string& getType() const;
/// Returns the top-level type.
void setSubType(const std::string& subType);
/// Sets the sub type.
const std::string& getSubType() const;
/// Returns the sub type.
void setParameter(const std::string& name, const std::string& value);
/// Sets the parameter with the given name.
const std::string& getParameter(const std::string& name) const;
/// Returns the parameter with the given name.
///
/// Throws a NotFoundException if the parameter does not exist.
bool hasParameter(const std::string& name) const;
/// Returns true iff a parameter with the given name exists.
void removeParameter(const std::string& name);
/// Removes the parameter with the given name.
/// Removes the parameter with the given name.
const NameValueCollection& parameters() const;
/// Returns the parameters.
std::string toString() const;
/// Returns the string representation of the media type
/// which is <type>/<subtype>{;<parameter>=<value>}
bool matches(const MediaType& mediaType) const;
/// Returns true iff the type and subtype match
/// the type and subtype of the given media type.
/// Matching is case insensitive.
bool matches(const std::string& type, const std::string& subType) const;
/// Returns true iff the type and subtype match
/// the given type and subtype.
@ -132,10 +132,10 @@ public:
protected:
void parse(const std::string& mediaType);
private:
MediaType();
std::string _type;
std::string _subType;
NameValueCollection _parameters;
@ -163,7 +163,7 @@ inline const NameValueCollection& MediaType::parameters() const
}
inline void swap(MediaType& m1, MediaType& m2)
inline void swap(MediaType& m1, MediaType& m2) noexcept
{
m1.swap(m2);
}

View File

@ -35,7 +35,7 @@ class Net_API MessageHeader: public NameValueCollection
///
/// The name is case-insensitive.
///
/// There can be more than one name-value pair with the
/// There can be more than one name-value pair with the
/// same name.
///
/// MessageHeader supports writing and reading the
@ -67,9 +67,9 @@ public:
///
/// The format is one name-value pair per line, with
/// name and value separated by a colon and lines
/// delimited by a carriage return and a linefeed
/// delimited by a carriage return and a linefeed
/// character. See RFC 2822 for details.
virtual void read(std::istream& istr);
/// Reads the message header from the given input stream.
///
@ -86,13 +86,13 @@ public:
///
/// Throws a MessageException if the input stream is
/// malformed.
int getFieldLimit() const;
/// Returns the maximum number of header fields
/// allowed.
///
/// See setFieldLimit() for more information.
void setFieldLimit(int limit);
/// Sets the maximum number of header fields
/// allowed. This limit is used to defend certain
@ -100,7 +100,27 @@ public:
/// Specify 0 for unlimited (not recommended).
///
/// The default limit is 100.
int getNameLengthLimit() const;
/// Returns the maximum length of a field name.
///
/// See setNameLengthLimit() for more information.
void setNameLengthLimit(int limit);
/// Sets the maximum length of a field name.
///
/// The default limit is 256.
int getValueLengthLimit() const;
/// Returns the maximum length of a field value.
///
/// See setValueLengthLimit() for more information.
void setValueLengthLimit(int limit);
/// Sets the maximum length of a field value.
///
/// The default limit is 8192.
bool hasToken(const std::string& fieldName, const std::string& token) const;
/// Returns true iff the field with the given fieldName contains
/// the given token. Tokens in a header field are expected to be
@ -110,7 +130,7 @@ public:
/// Splits the given string into separate elements. Elements are expected
/// to be separated by commas.
///
/// For example, the string
/// For example, the string
/// text/plain; q=0.5, text/html, text/x-dvi; q=0.8
/// is split into the elements
/// text/plain; q=0.5
@ -120,7 +140,7 @@ public:
/// Commas enclosed in double quotes do not split elements.
///
/// If ignoreEmpty is true, empty elements are not returned.
static void splitParameters(const std::string& s, std::string& value, NameValueCollection& parameters);
/// Splits the given string into a value and a collection of parameters.
/// Parameters are expected to be separated by semicolons.
@ -144,22 +164,25 @@ public:
/// Checks if the value must be quoted. If so, the value is
/// appended to result, enclosed in double-quotes.
/// Otherwise, the value is appended to result as-is.
static void decodeRFC2047(const std::string& ins, std::string& outs, const std::string& charset = "UTF-8");
static std::string decodeWord(const std::string& text, const std::string& charset = "UTF-8");
/// Decode RFC2047 string.
private:
enum Limits
/// Limits for basic sanity checks when reading a header
{
MAX_NAME_LENGTH = 256,
MAX_VALUE_LENGTH = 8192,
DFL_FIELD_LIMIT = 100
DFL_NAME_LENGTH_LIMIT = 256,
DFL_VALUE_LENGTH_LIMIT = 8192,
DFL_FIELD_LIMIT = 100
};
int _fieldLimit;
int _nameLengthLimit;
int _valueLengthLimit;
};

View File

@ -30,7 +30,7 @@ namespace Net {
template <std::size_t S = POCO_UDP_BUF_SIZE>
class MultiSocketPoller
/// MultiSocketPoller, as its name indicates, repeatedly polls a set of
/// sockets for readability and/or eror. If socket is readable or in error
/// sockets for readability and/or error. If socket is readable or in error
/// state, the reading/error handling actions are delegated to the reader.
{
public:

View File

@ -47,7 +47,7 @@ public:
/// Notice: The behavior of this constructor has changed
/// in release 2.0. Previously, the constructor created
/// an unbound IPv4 multicast socket.
explicit MulticastSocket(SocketAddress::Family family);
/// Creates an unconnected datagram socket.
///
@ -107,7 +107,7 @@ public:
unsigned getTimeToLive() const;
/// Returns the TTL/hop limit for outgoing packets.
void joinGroup(const IPAddress& groupAddress);
/// Joins the specified multicast group at the default interface.

View File

@ -37,12 +37,12 @@ public:
MultipartStreamBuf(std::istream& istr, const std::string& boundary);
~MultipartStreamBuf();
bool lastPart() const;
protected:
int readFromDevice(char* buffer, std::streamsize length);
private:
enum
enum
{
STREAM_BUFFER_SIZE = 1024
};
@ -98,7 +98,7 @@ class Net_API MultipartReader
public:
explicit MultipartReader(std::istream& istr);
/// Creates the MultipartReader and attaches it to the
/// given input stream.
/// given input stream.
///
/// The boundary string is determined from the input
/// stream. The message must not contain a preamble
@ -119,13 +119,13 @@ public:
/// Throws an MultipartException if there are no more parts
/// available, or if no boundary line can be found in
/// the input stream.
bool hasNextPart();
/// Returns true iff more parts are available.
///
/// Before the first call to nextPart(), returns
/// always true.
std::istream& stream() const;
/// Returns a reference to the reader's stream that
/// can be used to read the current part.
@ -142,7 +142,7 @@ protected:
void guessBoundary();
void parseHeader(MessageHeader& messageHeader);
bool readLine(std::string& line, std::string::size_type n);
private:
MultipartReader();
MultipartReader(const MultipartReader&);

View File

@ -40,7 +40,7 @@ class Net_API MultipartWriter
/// a MultipartWriter object.
/// Then, for each part, call nextPart() and
/// write the content to the output stream.
/// Repeat for all parts.
/// Repeat for all parts.
/// After the last part has been written,
/// call close() to finish the multipart message.
{
@ -57,12 +57,12 @@ public:
~MultipartWriter();
/// Destroys the MultipartWriter.
void nextPart(const MessageHeader& header);
/// Opens a new message part and writes
/// the message boundary string, followed
/// by the message header to the stream.
void close();
/// Closes the multipart message and writes
/// the terminating boundary string.
@ -82,7 +82,7 @@ public:
/// MIME_boundary_XXXXXXXXXXXX, where
/// XXXXXXXXXXXX is a random hexadecimal
/// number.
private:
MultipartWriter();
MultipartWriter(const MultipartWriter&);

View File

@ -43,13 +43,13 @@ public:
int request(SocketAddress& address) const;
/// Request the time from the server at address.
/// Notifications are posted for events.
///
///
/// Returns the number of valid replies.
int request(const std::string& address) const;
/// Request the time from the server at address.
/// Notifications are posted for events.
///
///
/// Returns the number of valid replies.
private:

View File

@ -30,7 +30,7 @@ namespace Net {
class Net_API NTPEventArgs
/// The purpose of the NTPEventArgs class is to be used as template parameter
/// to instantiate event members in NTPClient class.
/// When clients register for an event notification, the reference to the class is
/// When clients register for an event notification, the reference to the class is
/// passed to the handler function to provide information about the event.
{
public:
@ -42,7 +42,7 @@ public:
std::string hostName() const;
/// Tries to resolve the target IP address into host name.
/// If unsuccessful, all exceptions are silently ignored and
/// If unsuccessful, all exceptions are silently ignored and
/// the IP address is returned.
std::string hostAddress() const;

View File

@ -27,7 +27,7 @@ namespace Net {
class Net_API NTPPacket
/// This class is the NTP packet abstraction.
/// This class is the NTP packet abstraction.
{
public:
NTPPacket();

View File

@ -34,14 +34,14 @@ class Net_API NameValueCollection
///
/// The name is case-insensitive.
///
/// There can be more than one name-value pair with the
/// There can be more than one name-value pair with the
/// same name.
{
public:
using HeaderMap = Poco::ListMap<std::string, std::string>;
using Iterator = HeaderMap::Iterator;
using ConstIterator = HeaderMap::ConstIterator;
NameValueCollection();
/// Creates an empty NameValueCollection.
@ -59,21 +59,21 @@ public:
NameValueCollection& operator = (NameValueCollection&& nvc) noexcept;
/// Moves the name-value pairs of another NameValueCollection to this one.
void swap(NameValueCollection& nvc);
void swap(NameValueCollection& nvc) noexcept;
/// Swaps the NameValueCollection with another one.
const std::string& operator [] (const std::string& name) const;
/// Returns the value of the (first) name-value pair with the given name.
///
/// Throws a NotFoundException if the name-value pair does not exist.
void set(const std::string& name, const std::string& value);
void set(const std::string& name, const std::string& value);
/// Sets the value of the (first) name-value pair with the given name.
void add(const std::string& name, const std::string& value);
/// Adds a new name-value pair with the given name and value.
const std::string& get(const std::string& name) const;
/// Returns the value of the first name-value pair with the given name.
///
@ -90,15 +90,15 @@ public:
ConstIterator find(const std::string& name) const;
/// Returns an iterator pointing to the first name-value pair
/// with the given name.
ConstIterator begin() const;
/// Returns an iterator pointing to the begin of
/// the name-value pair collection.
ConstIterator end() const;
/// Returns an iterator pointing to the end of
/// Returns an iterator pointing to the end of
/// the name-value pair collection.
bool empty() const;
/// Returns true iff the header does not have any content.
@ -120,7 +120,7 @@ private:
//
// inlines
//
inline void swap(NameValueCollection& nvc1, NameValueCollection& nvc2)
inline void swap(NameValueCollection& nvc1, NameValueCollection& nvc2) noexcept
{
nvc1.swap(nvc2);
}

View File

@ -67,6 +67,14 @@
#endif // POCO_NET_NO_IPv6, POCO_HAVE_IPv6
// Default to enabled local socket support if not explicitly disabled
#if !defined(POCO_NET_NO_UNIX_SOCKET) && !defined (POCO_HAVE_UNIX_SOCKET)
#define POCO_HAVE_UNIX_SOCKET
#elif defined(POCO_NET_NO_UNIX_SOCKET) && defined (POCO_HAVE_UNIX_SOCKET)
#undef POCO_HAVE_UNIX_SOCKET
#endif // POCO_NET_NO_UNIX_SOCKET, POCO_HAVE_UNIX_SOCKET
namespace Poco {
namespace Net {
@ -124,4 +132,16 @@ POCO_NET_FORCE_SYMBOL(pocoNetworkInitializer)
#endif
#if (POCO_OS == POCO_OS_LINUX) || (POCO_OS == POCO_OS_WINDOWS_NT)
#define POCO_HAVE_FD_EPOLL 1
#endif
#if defined(POCO_OS_FAMILY_BSD)
#ifndef POCO_HAVE_FD_POLL
#define POCO_HAVE_FD_POLL 1
#endif
#endif
#endif // Net_Net_INCLUDED

View File

@ -40,18 +40,18 @@ class NetworkInterfaceImpl;
class Net_API NetworkInterface
/// This class represents a network interface.
///
///
/// NetworkInterface is used with MulticastSocket to specify
/// multicast interfaces for sending and receiving multicast
/// messages.
///
///
/// The class also provides static member functions for
/// enumerating or searching network interfaces and their
/// respective configuration values.
///
/// On Windows, detection capabilities vary depending on the
/// OS version/service pack. Although the best effort is made
/// not to attempt access to non-existent features through a
/// not to attempt access to non-existent features through a
/// combination of compile/runtime checks, when running binaries
/// compiled on a newer version of the OS on an older one
/// problems may occur; if possible, it is best to run
@ -110,7 +110,7 @@ public:
///
/// The name is empty, the IP address is the wildcard
/// address and the index is max value of unsigned integer.
NetworkInterface(const NetworkInterface& interfc);
/// Creates the NetworkInterface by copying another one.
@ -119,28 +119,28 @@ public:
NetworkInterface& operator = (const NetworkInterface& interfc);
/// Assigns another NetworkInterface.
bool operator < (const NetworkInterface& other) const;
/// Operator less-than.
bool operator == (const NetworkInterface& other) const;
/// Operator equal. Compares interface indices.
void swap(NetworkInterface& other);
/// Swaps the NetworkInterface with another one.
void swap(NetworkInterface& other) noexcept;
/// Swaps the NetworkInterface with another one.
unsigned index() const;
/// Returns the interface OS index.
const std::string& name() const;
/// Returns the interface name.
const std::string& displayName() const;
/// Returns the interface display name.
///
/// On Windows platforms, this is currently the network adapter
/// name. This may change to the "friendly name" of the network
/// connection in a future version, however.
/// connection in a future version, however.
///
/// On other platforms this is the same as name().
@ -148,7 +148,7 @@ public:
/// Returns the interface adapter name.
///
/// On Windows platforms, this is the network adapter LUID.
/// The adapter name is used by some Windows Net APIs like DHCP.
/// The adapter name is used by some Windows Net APIs like DHCP.
///
/// On other platforms this is the same as name().
@ -199,7 +199,7 @@ public:
/// Returns true if the interface supports IPv4.
bool supportsIPv6() const;
/// Returns true if the interface supports IPv6.
/// Returns true if the interface supports IPv6.
bool supportsBroadcast() const;
/// Returns true if the interface supports broadcast.
@ -221,7 +221,7 @@ public:
static NetworkInterface forName(const std::string& name, bool requireIPv6 = false);
/// Returns the NetworkInterface for the given name.
///
///
/// If requireIPv6 is false, an IPv4 interface is returned.
/// Otherwise, an IPv6 interface is returned.
///
@ -230,14 +230,14 @@ public:
static NetworkInterface forName(const std::string& name, IPVersion ipVersion);
/// Returns the NetworkInterface for the given name.
///
///
/// The ipVersion argument can be used to specify whether
/// an IPv4 (IPv4_ONLY) or IPv6 (IPv6_ONLY) interface is required,
/// an IPv4 (IPv4_ONLY) or IPv6 (IPv6_ONLY) interface is required,
/// or whether the caller does not care (IPv4_OR_IPv6).
///
/// Throws an InterfaceNotFoundException if an interface
/// with the give name does not exist.
static NetworkInterface forAddress(const IPAddress& address);
/// Returns the NetworkInterface for the given IP address.
///
@ -277,7 +277,7 @@ public:
/// Otherwise, both interfaces being up and down are returned.
///
/// If there are multiple addresses bound to one interface,
/// they are contained within the NetworkInterface (second)
/// they are contained within the NetworkInterface (second)
/// member of the pair.
protected:

View File

@ -32,10 +32,10 @@ class Net_API NullPartHandler: public PartHandler
public:
NullPartHandler();
/// Creates the NullPartHandler.
~NullPartHandler();
/// Destroys the NullPartHandler.
void handlePart(const MessageHeader& header, std::istream& stream);
/// Reads and discards all data from the stream.
};

View File

@ -33,7 +33,7 @@ class HTMLForm;
class Net_API OAuth10Credentials
/// This class implements OAuth 1.0A authentication for HTTP requests,
/// according to RFC 5849.
///
///
/// Only PLAINTEXT and HMAC-SHA1 signature methods are
/// supported. The RSA-SHA1 signature method is not supported.
///
@ -68,9 +68,9 @@ class Net_API OAuth10Credentials
/// 7. The response will contain the request token and request token secret.
/// These can be extracted from the response body using a HTMLForm object.
///
/// Requesting the access token and secret (temporary credentials) from the server
/// is analogous to signing a client request using consumer key, consumer secret,
/// request token and request token secret.
/// Requesting the access token and secret (temporary credentials) from the server
/// is analogous to signing a client request using consumer key, consumer secret,
/// request token and request token secret.
/// The server response will contain the access token and access token secret,
/// which can again be extracted from the response body using a HTMLForm object.
///
@ -80,7 +80,7 @@ class Net_API OAuth10Credentials
/// HTTPRequest object. This will extract the consumer key and token (if
/// provided).
/// 2. Provide the consumer secret and token secret (if required) matching the
/// consumer key and token to the OAuth10Credentials object using the
/// consumer key and token to the OAuth10Credentials object using the
/// setter methods.
/// 3. Create an URI object containing the full request URI.
/// 4. Call verify() to verify the signature.
@ -95,7 +95,7 @@ public:
SIGN_PLAINTEXT, /// OAuth 1.0A PLAINTEXT signature method
SIGN_HMAC_SHA1 /// OAuth 1.0A HMAC-SHA1 signature method
};
OAuth10Credentials();
/// Creates an empty OAuth10Credentials object.
@ -105,7 +105,7 @@ public:
/// The token and tokenSecret will be left empty.
OAuth10Credentials(const std::string& consumerKey, const std::string& consumerSecret, const std::string& token, const std::string& tokenSecret);
/// Creates an OAuth10Credentials object with the given consumer key and
/// Creates an OAuth10Credentials object with the given consumer key and
/// consumer secret, as well as token and token secret.
explicit OAuth10Credentials(const HTTPRequest& request);
@ -121,50 +121,50 @@ public:
void setConsumerKey(const std::string& consumerKey);
/// Sets the consumer key.
const std::string& getConsumerKey() const;
/// Returns the consumer key.
void setConsumerSecret(const std::string& consumerSecret);
/// Sets the consumer secret.
const std::string& getConsumerSecret() const;
/// Returns the consumer secret.
void setToken(const std::string& token);
/// Sets the token.
const std::string& getToken() const;
/// Returns the token.
void setTokenSecret(const std::string& tokenSecret);
/// Sets the token.
const std::string& getTokenSecret() const;
/// Returns the token secret.
void setRealm(const std::string& realm);
/// Sets the optional realm to be included in the Authorization header.
const std::string& getRealm() const;
/// Returns the optional realm to be included in the Authorization header.
void setCallback(const std::string& uri);
/// Sets the callback URI.
const std::string& getCallback() const;
/// Returns the callback URI.
void authenticate(HTTPRequest& request, const Poco::URI& uri, SignatureMethod method = SIGN_HMAC_SHA1);
/// Adds an OAuth 1.0A Authentication header to the given request, using
/// the given signature method.
void authenticate(HTTPRequest& request, const Poco::URI& uri, const Poco::Net::HTMLForm& params, SignatureMethod method = SIGN_HMAC_SHA1);
/// Adds an OAuth 1.0A Authentication header to the given request, using
/// the given signature method.
bool verify(const HTTPRequest& request, const Poco::URI& uri);
/// Verifies the signature of the given request.
/// Verifies the signature of the given request.
///
/// The consumer key, consumer secret, token and token secret must have been set.
///
@ -172,9 +172,9 @@ public:
///
/// Throws a NotAuthenticatedException if the request does not contain OAuth
/// credentials, or in case of an unsupported OAuth version or signature method.
bool verify(const HTTPRequest& request, const Poco::URI& uri, const Poco::Net::HTMLForm& params);
/// Verifies the signature of the given request.
/// Verifies the signature of the given request.
///
/// The consumer key, consumer secret, token and token secret must have been set.
///
@ -209,7 +209,7 @@ protected:
std::string createSignature(const Poco::Net::HTTPRequest& request, const std::string& uri, const Poco::Net::HTMLForm& params, const std::string& nonce, const std::string& timestamp) const;
/// Creates a OAuth signature for the given request and its parameters, according
/// to <https://dev.twitter.com/docs/auth/creating-signature>.
static std::string percentEncode(const std::string& str);
/// Percent-encodes the given string according to Twitter API's rules,
/// given in <https://dev.twitter.com/docs/auth/percent-encoding-parameters>.
@ -217,7 +217,7 @@ protected:
private:
OAuth10Credentials(const OAuth10Credentials&);
OAuth10Credentials& operator = (const OAuth10Credentials&);
std::string _consumerKey;
std::string _consumerSecret;
std::string _token;

View File

@ -30,7 +30,7 @@ class HTTPRequest;
class Net_API OAuth20Credentials
/// This class implements OAuth 2.0 authentication for HTTP requests,
/// via Bearer tokens in the Authorization header,
/// via Bearer tokens in the Authorization header,
/// according to RFC 6749 and RFC 6750.
///
/// To add an Authorization header containing a bearer token
@ -42,7 +42,7 @@ class Net_API OAuth20Credentials
/// object containing a "Bearer" Authorization header and
/// calling getBearerToken().
///
/// The authorization header scheme can be changed from
/// The authorization header scheme can be changed from
/// "Bearer" to a custom value. For example, GitHub uses
/// the "token" scheme.
{
@ -82,16 +82,16 @@ public:
void setBearerToken(const std::string& bearerToken);
/// Sets the bearer token.
const std::string& getBearerToken() const;
/// Returns the bearer token.
void setScheme(const std::string& scheme);
/// Sets the Authorization header scheme.
const std::string& getScheme() const;
/// Returns the Authorization header scheme.
void authenticate(HTTPRequest& request);
/// Adds an Authorization header containing the bearer token to
/// the HTTPRequest.
@ -101,11 +101,11 @@ public:
protected:
void extractBearerToken(const HTTPRequest& request);
/// Extracts the bearer token from the HTTPRequest.
private:
OAuth20Credentials(const OAuth20Credentials&);
OAuth20Credentials& operator = (const OAuth20Credentials&);
std::string _bearerToken;
std::string _scheme;
};

View File

@ -44,14 +44,14 @@ public:
{
POP3_PORT = 110
};
struct MessageInfo
/// Information returned by listMessages().
{
int id;
int size;
};
using MessageInfoVec = std::vector<MessageInfo>;
explicit POP3ClientSession(const StreamSocket& socket);
@ -68,7 +68,7 @@ public:
void setTimeout(const Poco::Timespan& timeout);
/// Sets the timeout for socket read operations.
Poco::Timespan getTimeout() const;
/// Returns the timeout for socket read operations.
@ -80,7 +80,7 @@ public:
/// NetException in case of a general network communication failure.
void close();
/// Sends a QUIT command and closes the connection to the server.
/// Sends a QUIT command and closes the connection to the server.
///
/// Throws a POP3Exception in case of a POP3-specific error, or a
/// NetException in case of a general network communication failure.
@ -172,7 +172,7 @@ public:
protected:
static bool isPositive(const std::string& response);
private:
DialogSocket _socket;
bool _isOpen;

View File

@ -42,14 +42,14 @@ namespace Net {
template <class ServiceHandler, class SR>
class ParallelSocketAcceptor
/// This class implements the Acceptor part of the Acceptor-Connector design pattern.
/// Only the difference from single-threaded version is documented here, For full
/// Only the difference from single-threaded version is documented here, For full
/// description see Poco::Net::SocketAcceptor documentation.
///
///
/// This is a multi-threaded version of SocketAcceptor, it differs from the
/// single-threaded version in number of reactors (defaulting to number of processors)
/// that can be specified at construction time and is rotated in a round-robin fashion
/// by event handler. See ParallelSocketAcceptor::onAccept and
/// ParallelSocketAcceptor::createServiceHandler documentation and implementation for
/// by event handler. See ParallelSocketAcceptor::onAccept and
/// ParallelSocketAcceptor::createServiceHandler documentation and implementation for
/// details.
{
public:
@ -57,12 +57,14 @@ public:
using Observer = Poco::Observer<ParallelSocketAcceptor, ReadableNotification>;
explicit ParallelSocketAcceptor(ServerSocket& socket,
unsigned threads = Poco::Environment::processorCount()):
unsigned threads = Poco::Environment::processorCount(),
const std::string& threadName = ""):
_threadName(threadName),
_socket(socket),
_pReactor(0),
_threads(threads),
_next(0)
/// Creates a ParallelSocketAcceptor using the given ServerSocket,
/// Creates a ParallelSocketAcceptor using the given ServerSocket,
/// sets number of threads and populates the reactors vector.
{
init();
@ -70,13 +72,14 @@ public:
ParallelSocketAcceptor(ServerSocket& socket,
SocketReactor& reactor,
unsigned threads = Poco::Environment::processorCount()):
unsigned threads = Poco::Environment::processorCount(), const std::string& threadName = ""):
_threadName(threadName),
_socket(socket),
_pReactor(&reactor),
_threads(threads),
_next(0)
/// Creates a ParallelSocketAcceptor using the given ServerSocket, sets the
/// number of threads, populates the reactors vector and registers itself
/// Creates a ParallelSocketAcceptor using the given ServerSocket, sets the
/// number of threads, populates the reactors vector and registers itself
/// with the given SocketReactor.
{
init();
@ -110,7 +113,7 @@ public:
///
/// A subclass can override this function to e.g.
/// register an event handler for timeout event.
///
///
/// The overriding method must either call the base class
/// implementation or register the accept handler on its own.
{
@ -120,13 +123,13 @@ public:
_pReactor->addEventHandler(_socket, Observer(*this, &ParallelSocketAcceptor::onAccept));
}
}
virtual void unregisterAcceptor()
/// Unregisters the ParallelSocketAcceptor.
///
/// A subclass can override this function to e.g.
/// unregister its event handler for a timeout event.
///
///
/// The overriding method must either call the base class
/// implementation or unregister the accept handler on its own.
{
@ -135,7 +138,7 @@ public:
_pReactor->removeEventHandler(_socket, Observer(*this, &ParallelSocketAcceptor::onAccept));
}
}
void onAccept(ReadableNotification* pNotification)
/// Accepts connection and creates event handler.
{
@ -202,7 +205,7 @@ protected:
poco_assert (_threads > 0);
for (unsigned i = 0; i < _threads; ++i)
_reactors.push_back(new ParallelReactor);
_reactors.push_back(new ParallelReactor(_threadName + "#" + std::to_string(i)));
}
ReactorVec& reactors()
@ -228,6 +231,8 @@ private:
ParallelSocketAcceptor(const ParallelSocketAcceptor&);
ParallelSocketAcceptor& operator = (const ParallelSocketAcceptor&);
std::string _threadName;
/// Name prefix of sub SocketReactor threads
ServerSocket _socket;
SocketReactor* _pReactor;
unsigned _threads;

View File

@ -48,17 +48,21 @@ class ParallelSocketReactor: public SR
public:
using Ptr = Poco::SharedPtr<ParallelSocketReactor>;
ParallelSocketReactor()
ParallelSocketReactor(const std::string& threadName = "")
{
_thread.start(*this);
if (!threadName.empty())
_thread.setName(threadName);
}
ParallelSocketReactor(const Poco::Timespan& timeout):
ParallelSocketReactor(const Poco::Timespan& timeout, const std::string& threadName = ""):
SR(timeout)
{
_thread.start(*this);
if (!threadName.empty())
_thread.setName(threadName);
}
~ParallelSocketReactor()
{
try
@ -71,14 +75,14 @@ public:
poco_unexpected();
}
}
protected:
void onIdle()
{
SR::onIdle();
Poco::Thread::yield();
}
private:
Poco::Thread _thread;
};

View File

@ -32,8 +32,8 @@ class MessageHeader;
class Net_API PartHandler
/// The base class for all part or attachment handlers.
///
/// Part handlers are used for handling email parts and
/// attachments in MIME multipart messages, as well as file
/// Part handlers are used for handling email parts and
/// attachments in MIME multipart messages, as well as file
/// uploads via HTML forms.
///
/// Subclasses must override handlePart().
@ -48,7 +48,7 @@ public:
/// from header depends on the kind of part.
///
/// The content of the part can be read from stream.
protected:
PartHandler();
/// Creates the PartHandler.

View File

@ -39,9 +39,9 @@ class Net_API PollSet
public:
enum Mode
{
POLL_READ = 0x01,
POLL_WRITE = 0x02,
POLL_ERROR = 0x04
POLL_READ = Socket::SELECT_READ,
POLL_WRITE = Socket::SELECT_WRITE,
POLL_ERROR = Socket::SELECT_ERROR
};
using SocketModeMap = std::map<Poco::Net::Socket, int>;
@ -56,12 +56,36 @@ public:
/// Adds the given socket to the set, for polling with
/// the given mode, which can be an OR'd combination of
/// POLL_READ, POLL_WRITE and POLL_ERROR.
/// Subsequent socket additions to the PollSet are mode-cumulative,
/// so the following code:
///
/// StreamSocket ss;
/// PollSet ps;
/// ps.add(ss, PollSet::POLL_READ);
/// ps.add(ss, PollSet::POLL_WRITE);
///
/// shall result in the socket being monitored for read and write,
/// equivalent to this:
///
/// ps.update(ss, PollSet::POLL_READ | PollSet::POLL_WRITE);
void remove(const Poco::Net::Socket& socket);
/// Removes the given socket from the set.
void update(const Poco::Net::Socket& socket, int mode);
/// Updates the mode of the given socket.
/// Updates the mode of the given socket. If socket does
/// not exist in the PollSet, it is silently added. For
/// an existing socket, any prior mode is overwritten.
/// Updating socket is non-mode-cumulative.
///
/// The following code:
///
/// StreamSocket ss;
/// PollSet ps;
/// ps.update(ss, PollSet::POLL_READ);
/// ps.update(ss, PollSet::POLL_WRITE);
///
/// shall result in the socket being monitored for write only.
bool has(const Socket& socket) const;
/// Returns true if socket is registered for polling.
@ -78,6 +102,14 @@ public:
/// Returns a PollMap containing the sockets that have had
/// their state changed.
int count() const;
/// Returns the number of sockets monitored.
void wakeUp();
/// Wakes up a waiting PollSet.
/// Any errors that occur during this call are ignored.
/// On platforms/implementations where this functionality
/// is not available, it does nothing.
private:
PollSetImpl* _pImpl;

View File

@ -28,11 +28,11 @@ namespace Net {
class Net_API QuotedPrintableDecoderBuf: public Poco::UnbufferedStreamBuf
/// This streambuf decodes all quoted-printable (see RFC 2045)
/// This streambuf decodes all quoted-printable (see RFC 2045)
/// encoded data read from the istream connected to it.
///
/// Note: For performance reasons, the characters
/// are read directly from the given istream's
/// Note: For performance reasons, the characters
/// are read directly from the given istream's
/// underlying streambuf, so the state
/// of the istream will not reflect that of
/// its streambuf.
@ -40,7 +40,7 @@ class Net_API QuotedPrintableDecoderBuf: public Poco::UnbufferedStreamBuf
public:
QuotedPrintableDecoderBuf(std::istream& istr);
~QuotedPrintableDecoderBuf();
private:
int readFromDevice();
@ -68,8 +68,8 @@ class Net_API QuotedPrintableDecoder: public QuotedPrintableDecoderIOS, public s
/// This istream decodes all quoted-printable (see RFC 2045)
/// encoded data read from the istream connected to it.
///
/// Note: For performance reasons, the characters
/// are read directly from the given istream's
/// Note: For performance reasons, the characters
/// are read directly from the given istream's
/// underlying streambuf, so the state
/// of the istream will not reflect that of
/// its streambuf.

View File

@ -36,7 +36,7 @@ public:
QuotedPrintableEncoderBuf(std::ostream& ostr);
~QuotedPrintableEncoderBuf();
int close();
private:
int writeToDevice(char c);
void writeEncoded(char c);

View File

@ -53,6 +53,10 @@ public:
/// a RawSocketImpl, otherwise an InvalidArgumentException
/// will be thrown.
RawSocket(const RawSocket& socket);
/// Creates the RawSocket with the SocketImpl
/// from another socket.
~RawSocket();
/// Destroys the RawSocket.
@ -61,7 +65,44 @@ public:
///
/// Releases the socket's SocketImpl and
/// attaches the SocketImpl from the other socket and
/// increments the reference count of the SocketImpl.
/// increments the reference count of the SocketImpl.
RawSocket& operator = (const RawSocket& socket);
/// Assignment operator.
///
/// Releases the socket's SocketImpl and
/// attaches the SocketImpl from the other socket and
/// increments the reference count of the SocketImpl.
#if POCO_NEW_STATE_ON_MOVE
RawSocket(Socket&& socket);
/// Creates the RawSocket with the SocketImpl
/// from another socket and zeroes the other socket's
/// SocketImpl.The SocketImpl must be
/// a RawSocketImpl, otherwise an InvalidArgumentException
/// will be thrown.
RawSocket(RawSocket&& socket);
/// Creates the RawSocket with the SocketImpl
/// from another socket and zeroes the other socket's
/// SocketImpl.
RawSocket& operator = (Socket&& socket);
/// Assignment move operator.
///
/// Releases the socket's SocketImpl and
/// attaches the SocketImpl from the other socket and
/// zeroes the other socket's SocketImpl.
RawSocket& operator = (RawSocket&& socket);
/// Assignment move operator.
///
/// Releases the socket's SocketImpl and
/// attaches the SocketImpl from the other socket and
/// zeroes the other socket's SocketImpl.
#endif //POCO_NEW_STATE_ON_MOVE
void connect(const SocketAddress& address);
/// Restricts incoming and outgoing
@ -73,7 +114,7 @@ public:
/// Bind a local address to the socket.
///
/// This is usually only done when establishing a server
/// socket.
/// socket.
///
/// If reuseAddress is true, sets the SO_REUSEADDR
/// socket option.
@ -84,7 +125,7 @@ public:
/// Bind a local address to the socket.
///
/// This is usually only done when establishing a server
/// socket.
/// socket.
///
/// If reuseAddress is true, sets the SO_REUSEADDR
/// socket option.
@ -126,7 +167,7 @@ public:
///
/// Setting this flag allows sending datagrams to
/// the broadcast address.
bool getBroadcast() const;
/// Returns the value of the SO_BROADCAST socket option.
@ -135,7 +176,7 @@ protected:
/// Creates the Socket and attaches the given SocketImpl.
/// The socket takes ownership of the SocketImpl.
///
/// The SocketImpl must be a StreamSocketImpl, otherwise
/// The SocketImpl must be a RawSocketImpl, otherwise
/// an InvalidArgumentException will be thrown.
};

View File

@ -32,7 +32,7 @@ class Net_API RawSocketImpl: public SocketImpl
public:
RawSocketImpl();
/// Creates an unconnected IPv4 raw socket with IPPROTO_RAW.
RawSocketImpl(SocketAddress::Family family, int proto = IPPROTO_RAW);
/// Creates an unconnected raw socket.
///
@ -41,11 +41,11 @@ public:
RawSocketImpl(poco_socket_t sockfd);
/// Creates a RawSocketImpl using the given native socket.
protected:
void init(int af);
void init2(int af, int proto);
~RawSocketImpl();
};

View File

@ -132,6 +132,9 @@ public:
static void registerChannel();
/// Registers the channel with the global LoggingFactory.
static const char* facilityToString(Facility facility);
/// Returns the string describing the SyslogFacility
static const std::string PROP_NAME;
static const std::string PROP_FACILITY;
static const std::string PROP_FORMAT;

View File

@ -110,8 +110,9 @@ public:
static const std::string PROP_THREADS;
static const std::string PROP_BUFFER;
static const std::string LOG_PROP_APP;
static const std::string LOG_PROP_HOST;
static const std::string LOG_PROP_FACILITY;
static const std::string LOG_PROP_APP;
static const std::string LOG_PROP_HOST;
static const std::string LOG_PROP_STRUCTURED_DATA;
protected:

View File

@ -36,19 +36,19 @@ public:
SMTPChannel();
/// Creates a SMTPChannel.
SMTPChannel(const std::string& mailhost, const std::string& sender, const std::string& recipient);
/// Creates a SMTPChannel with the given target mailhost, sender, and recipient.
void open();
/// Opens the SMTPChannel.
void close();
/// Closes the SMTPChannel.
void log(const Message& msg);
/// Sends the message's text to the recipient.
void setProperty(const std::string& name, const std::string& value);
/// Sets the property with the given value.
///
@ -59,11 +59,11 @@ public:
/// * local: If true, local time is used. Default is true.
/// * attachment: Filename of the file to attach.
/// * type: Content type of the file to attach.
/// * delete: Boolean value indicating whether to delete
/// * delete: Boolean value indicating whether to delete
/// the attachment file after sending.
/// * throw: Boolean value indicating whether to throw
/// * throw: Boolean value indicating whether to throw
/// exception upon failure.
std::string getProperty(const std::string& name) const;
/// Returns the value of the property with the given name.

View File

@ -68,7 +68,7 @@ public:
///
/// Releases the socket's SocketImpl and
/// attaches the SocketImpl from the other socket and
/// increments the reference count of the SocketImpl.
/// increments the reference count of the SocketImpl.
virtual void bind(const SocketAddress& address, bool reuseAddress = false);
/// Binds a local address to the socket.
@ -97,7 +97,7 @@ public:
/// Binds a local port to the socket.
///
/// This is usually only done when establishing a server
/// socket.
/// socket.
///
/// If reuseAddress is true, sets the SO_REUSEADDR
/// socket option.
@ -106,7 +106,7 @@ public:
/// Binds a local port to the socket.
///
/// This is usually only done when establishing a server
/// socket.
/// socket.
///
/// If reuseAddress is true, sets the SO_REUSEADDR
/// socket option.
@ -155,7 +155,7 @@ public:
/// Binds a local IPv6 port to the socket.
///
/// This is usually only done when establishing a server
/// socket.
/// socket.
///
/// If reuseAddress is true, sets the SO_REUSEADDR
/// socket option.
@ -166,12 +166,12 @@ public:
///
/// If the library has not been built with IPv6 support,
/// a Poco::NotImplementedException will be thrown.
virtual void bind6(Poco::UInt16 port, bool reuseAddress, bool reusePort, bool ipV6Only);
/// Binds a local IPv6 port to the socket.
///
/// This is usually only done when establishing a server
/// socket.
/// socket.
///
/// If reuseAddress is true, sets the SO_REUSEADDR
/// socket option.

View File

@ -30,7 +30,7 @@ namespace Net {
template <std::size_t S = POCO_UDP_BUF_SIZE>
class SingleSocketPoller
/// SinlgeSocketPoller, as its name indicates, repeatedly polls a single
/// SingleSocketPoller, as its name indicates, repeatedly polls a single
/// socket for readability; if the socket is readable, the reading action
/// is delegated to the reader.
{

View File

@ -22,6 +22,11 @@
#include "Poco/Net/SocketImpl.h"
#include <vector>
#ifdef POCO_NEW_STATE_ON_MOVE
#define POCO_CHECK_NEW_STATE_ON_MOVE poco_assert_dbg(POCO_NEW_STATE_ON_MOVE && _pImpl);
#else
#define POCO_CHECK_NEW_STATE_ON_MOVE
#endif
namespace Poco {
namespace Net {
@ -36,6 +41,8 @@ class Net_API Socket
{
public:
using BufVec = SocketBufVec;
using Type = SocketImpl::Type;
using SocketList = std::vector<Socket>;
enum SelectMode
/// The mode argument to poll() and select().
@ -44,8 +51,6 @@ public:
SELECT_WRITE = 2,
SELECT_ERROR = 4
};
using SocketList = std::vector<Socket>;
Socket();
/// Creates an uninitialized socket.
@ -55,18 +60,35 @@ public:
///
/// Attaches the SocketImpl from the other socket and
/// increments the reference count of the SocketImpl.
Socket& operator = (const Socket& socket);
/// Assignment operator.
///
/// Releases the socket's SocketImpl and
/// attaches the SocketImpl from the other socket and
/// increments the reference count of the SocketImpl.
#if POCO_NEW_STATE_ON_MOVE
Socket(Socket&& socket);
/// Move constructor.
///
/// Attaches the SocketImpl from the other socket and
/// zeroes the other socket's SocketImpl.
Socket& operator = (Socket&& socket);
/// Assignment move operator.
///
/// Releases the socket's SocketImpl,
/// attaches the SocketImpl from the other socket,
/// and zeroes the other socket's SocketImpl.
#endif // POCO_NEW_STATE_ON_MOVE
virtual ~Socket();
/// Destroys the Socket and releases the
/// SocketImpl.
bool operator == (const Socket& socket) const;
/// Returns true if both sockets share the same
/// SocketImpl, false otherwise.
@ -77,7 +99,7 @@ public:
bool operator < (const Socket& socket) const;
/// Compares the SocketImpl pointers.
bool operator <= (const Socket& socket) const;
/// Compares the SocketImpl pointers.
@ -86,12 +108,31 @@ public:
bool operator >= (const Socket& socket) const;
/// Compares the SocketImpl pointers.
bool isNull() const;
/// Returns true if pointer to implementation is null.
Type type() const;
/// Returns the socket type.
bool isStream() const;
/// Returns true if socket is a stream socket,
/// false otherwise.
bool isDatagram() const;
/// Returns true if socket is a datagram socket,
/// false otherwise.
bool isRaw() const;
/// Returns true if socket is a raw socket,
/// false otherwise.
void close();
/// Closes the socket.
//@deprecated
static int select(SocketList& readList, SocketList& writeList, SocketList& exceptList, const Poco::Timespan& timeout);
/// Determines the status of one or more sockets,
/// Determines the status of one or more sockets,
/// using a call to select().
///
/// ReadList contains the list of sockets which should be
@ -105,7 +146,7 @@ public:
///
/// Returns the number of sockets ready.
///
/// After return,
/// After return,
/// * readList contains those sockets ready for reading,
/// * writeList contains those sockets ready for writing,
/// * exceptList contains those sockets with a pending error.
@ -119,11 +160,14 @@ public:
/// the closed socket will not be included in any list.
/// In this case, the return value may be greater than the sum
/// of all sockets in all list.
///
/// This function is deprecated and may be removed in the future releases,
/// please use PollSet class instead.
bool poll(const Poco::Timespan& timeout, int mode) const;
/// Determines the status of the socket, using a
/// Determines the status of the socket, using a
/// call to poll() or select().
///
///
/// The mode argument is constructed by combining the values
/// of the SelectMode enumeration.
///
@ -134,9 +178,12 @@ public:
/// Returns the number of bytes available that can be read
/// without causing the socket to block.
int getError() const;
/// Returns the socket error.
void setSendBufferSize(int size);
/// Sets the size of the send buffer.
int getSendBufferSize() const;
/// Returns the size of the send buffer.
///
@ -146,7 +193,7 @@ public:
void setReceiveBufferSize(int size);
/// Sets the size of the receive buffer.
int getReceiveBufferSize() const;
/// Returns the size of the receive buffer.
///
@ -156,7 +203,7 @@ public:
void setSendTimeout(const Poco::Timespan& timeout);
/// Sets the send timeout for the socket.
Poco::Timespan getSendTimeout() const;
/// Returns the send timeout for the socket.
///
@ -169,7 +216,7 @@ public:
///
/// On systems that do not support SO_RCVTIMEO, a
/// workaround using poll() is provided.
Poco::Timespan getReceiveTimeout() const;
/// Returns the receive timeout for the socket.
///
@ -188,56 +235,56 @@ public:
void setOption(int level, int option, unsigned char value);
/// Sets the socket option specified by level and option
/// to the given integer value.
void setOption(int level, int option, const Poco::Timespan& value);
/// Sets the socket option specified by level and option
/// to the given time value.
void setOption(int level, int option, const IPAddress& value);
/// Sets the socket option specified by level and option
/// to the given time value.
void getOption(int level, int option, int& value) const;
/// Returns the value of the socket option
/// Returns the value of the socket option
/// specified by level and option.
void getOption(int level, int option, unsigned& value) const;
/// Returns the value of the socket option
/// Returns the value of the socket option
/// specified by level and option.
void getOption(int level, int option, unsigned char& value) const;
/// Returns the value of the socket option
/// Returns the value of the socket option
/// specified by level and option.
void getOption(int level, int option, Poco::Timespan& value) const;
/// Returns the value of the socket option
/// Returns the value of the socket option
/// specified by level and option.
void getOption(int level, int option, IPAddress& value) const;
/// Returns the value of the socket option
/// Returns the value of the socket option
/// specified by level and option.
void setLinger(bool on, int seconds);
/// Sets the value of the SO_LINGER socket option.
void getLinger(bool& on, int& seconds) const;
/// Returns the value of the SO_LINGER socket option.
void setNoDelay(bool flag);
/// Sets the value of the TCP_NODELAY socket option.
bool getNoDelay() const;
/// Returns the value of the TCP_NODELAY socket option.
void setKeepAlive(bool flag);
/// Sets the value of the SO_KEEPALIVE socket option.
bool getKeepAlive() const;
/// Returns the value of the SO_KEEPALIVE socket option.
void setReuseAddress(bool flag);
/// Sets the value of the SO_REUSEADDR socket option.
bool getReuseAddress() const;
/// Returns the value of the SO_REUSEADDR socket option.
@ -245,16 +292,16 @@ public:
/// Sets the value of the SO_REUSEPORT socket option.
/// Does nothing if the socket implementation does not
/// support SO_REUSEPORT.
bool getReusePort() const;
/// Returns the value of the SO_REUSEPORT socket option.
///
/// Returns false if the socket implementation does not
/// support SO_REUSEPORT.
void setOOBInline(bool flag);
/// Sets the value of the SO_OOBINLINE socket option.
bool getOOBInline() const;
/// Returns the value of the SO_OOBINLINE socket option.
@ -264,25 +311,25 @@ public:
bool getBlocking() const;
/// Returns the blocking mode of the socket.
/// This method will only work if the blocking modes of
/// This method will only work if the blocking modes of
/// the socket are changed via the setBlocking method!
SocketAddress address() const;
/// Returns the IP address and port number of the socket.
SocketAddress peerAddress() const;
/// Returns the IP address and port number of the peer socket.
SocketImpl* impl() const;
/// Returns the SocketImpl for this socket.
bool secure() const;
/// Returns true iff the socket's connection is secure
/// (using SSL or TLS).
static bool supportsIPv4();
/// Returns true if the system supports IPv4.
static bool supportsIPv6();
/// Returns true if the system supports IPv6.
@ -334,6 +381,15 @@ public:
/// of buffers used for writing (ie. reading from socket
/// into buffers).
static int lastError();
/// Returns the last error code.
static std::string lastErrorDesc();
/// Returns the last error description.
static void error();
/// Throws an appropriate exception for the last error.
protected:
Socket(SocketImpl* pImpl);
/// Creates the Socket and attaches the given SocketImpl.
@ -403,212 +459,318 @@ inline bool Socket::operator >= (const Socket& socket) const
}
inline Socket::Type Socket::type() const
{
return _pImpl->type();
}
inline bool Socket::isStream() const
{
return type() == Type::SOCKET_TYPE_STREAM;
}
inline bool Socket::isDatagram() const
{
return type() == Type::SOCKET_TYPE_DATAGRAM;
}
inline bool Socket::isRaw() const
{
return type() == Type::SOCKET_TYPE_RAW;
}
inline bool Socket::isNull() const
{
return _pImpl == nullptr;
}
inline void Socket::close()
{
_pImpl->close();
if (_pImpl) _pImpl->close();
}
inline bool Socket::poll(const Poco::Timespan& timeout, int mode) const
{
POCO_CHECK_NEW_STATE_ON_MOVE;
return _pImpl->poll(timeout, mode);
}
inline int Socket::available() const
{
POCO_CHECK_NEW_STATE_ON_MOVE;
return _pImpl->available();
}
inline int Socket::getError() const
{
POCO_CHECK_NEW_STATE_ON_MOVE;
return _pImpl->getError();
}
inline void Socket::setSendBufferSize(int size)
{
POCO_CHECK_NEW_STATE_ON_MOVE;
_pImpl->setSendBufferSize(size);
}
inline int Socket::getSendBufferSize() const
{
POCO_CHECK_NEW_STATE_ON_MOVE;
return _pImpl->getSendBufferSize();
}
inline void Socket::setReceiveBufferSize(int size)
{
POCO_CHECK_NEW_STATE_ON_MOVE;
_pImpl->setReceiveBufferSize(size);
}
inline int Socket::getReceiveBufferSize() const
{
POCO_CHECK_NEW_STATE_ON_MOVE;
return _pImpl->getReceiveBufferSize();
}
inline void Socket::setSendTimeout(const Poco::Timespan& timeout)
{
POCO_CHECK_NEW_STATE_ON_MOVE;
_pImpl->setSendTimeout(timeout);
}
inline Poco::Timespan Socket::getSendTimeout() const
{
POCO_CHECK_NEW_STATE_ON_MOVE;
return _pImpl->getSendTimeout();
}
inline void Socket::setReceiveTimeout(const Poco::Timespan& timeout)
{
POCO_CHECK_NEW_STATE_ON_MOVE;
_pImpl->setReceiveTimeout(timeout);
}
inline Poco::Timespan Socket::getReceiveTimeout() const
{
POCO_CHECK_NEW_STATE_ON_MOVE;
return _pImpl->getReceiveTimeout();
}
inline void Socket::setOption(int level, int option, int value)
{
POCO_CHECK_NEW_STATE_ON_MOVE;
_pImpl->setOption(level, option, value);
}
inline void Socket::setOption(int level, int option, unsigned value)
{
POCO_CHECK_NEW_STATE_ON_MOVE;
_pImpl->setOption(level, option, value);
}
inline void Socket::setOption(int level, int option, unsigned char value)
{
POCO_CHECK_NEW_STATE_ON_MOVE;
_pImpl->setOption(level, option, value);
}
inline void Socket::setOption(int level, int option, const Poco::Timespan& value)
{
POCO_CHECK_NEW_STATE_ON_MOVE;
_pImpl->setOption(level, option, value);
}
inline void Socket::setOption(int level, int option, const IPAddress& value)
{
POCO_CHECK_NEW_STATE_ON_MOVE;
_pImpl->setOption(level, option, value);
}
inline void Socket::getOption(int level, int option, int& value) const
{
POCO_CHECK_NEW_STATE_ON_MOVE;
_pImpl->getOption(level, option, value);
}
inline void Socket::getOption(int level, int option, unsigned& value) const
{
POCO_CHECK_NEW_STATE_ON_MOVE;
_pImpl->getOption(level, option, value);
}
inline void Socket::getOption(int level, int option, unsigned char& value) const
{
POCO_CHECK_NEW_STATE_ON_MOVE;
_pImpl->getOption(level, option, value);
}
inline void Socket::getOption(int level, int option, Poco::Timespan& value) const
{
POCO_CHECK_NEW_STATE_ON_MOVE;
_pImpl->getOption(level, option, value);
}
inline void Socket::getOption(int level, int option, IPAddress& value) const
{
POCO_CHECK_NEW_STATE_ON_MOVE;
_pImpl->getOption(level, option, value);
}
inline void Socket::setLinger(bool on, int seconds)
{
POCO_CHECK_NEW_STATE_ON_MOVE;
_pImpl->setLinger(on, seconds);
}
inline void Socket::getLinger(bool& on, int& seconds) const
{
POCO_CHECK_NEW_STATE_ON_MOVE;
_pImpl->getLinger(on, seconds);
}
inline void Socket::setNoDelay(bool flag)
{
POCO_CHECK_NEW_STATE_ON_MOVE;
_pImpl->setNoDelay(flag);
}
inline bool Socket::getNoDelay() const
{
POCO_CHECK_NEW_STATE_ON_MOVE;
return _pImpl->getNoDelay();
}
inline void Socket::setKeepAlive(bool flag)
{
POCO_CHECK_NEW_STATE_ON_MOVE;
_pImpl->setKeepAlive(flag);
}
inline bool Socket::getKeepAlive() const
{
POCO_CHECK_NEW_STATE_ON_MOVE;
return _pImpl->getKeepAlive();
}
inline void Socket::setReuseAddress(bool flag)
{
POCO_CHECK_NEW_STATE_ON_MOVE;
_pImpl->setReuseAddress(flag);
}
inline bool Socket::getReuseAddress() const
{
POCO_CHECK_NEW_STATE_ON_MOVE;
return _pImpl->getReuseAddress();
}
inline void Socket::setReusePort(bool flag)
{
POCO_CHECK_NEW_STATE_ON_MOVE;
_pImpl->setReusePort(flag);
}
inline bool Socket::getReusePort() const
{
POCO_CHECK_NEW_STATE_ON_MOVE;
return _pImpl->getReusePort();
}
inline void Socket::setOOBInline(bool flag)
{
POCO_CHECK_NEW_STATE_ON_MOVE;
_pImpl->setOOBInline(flag);
}
inline bool Socket::getOOBInline() const
{
POCO_CHECK_NEW_STATE_ON_MOVE;
return _pImpl->getOOBInline();
}
inline void Socket::setBlocking(bool flag)
{
POCO_CHECK_NEW_STATE_ON_MOVE;
_pImpl->setBlocking(flag);
}
inline bool Socket::getBlocking() const
{
POCO_CHECK_NEW_STATE_ON_MOVE;
return _pImpl->getBlocking();
}
@ -621,24 +783,32 @@ inline SocketImpl* Socket::impl() const
inline poco_socket_t Socket::sockfd() const
{
POCO_CHECK_NEW_STATE_ON_MOVE;
return _pImpl->sockfd();
}
inline SocketAddress Socket::address() const
{
POCO_CHECK_NEW_STATE_ON_MOVE;
return _pImpl->address();
}
inline SocketAddress Socket::peerAddress() const
{
POCO_CHECK_NEW_STATE_ON_MOVE;
return _pImpl->peerAddress();
}
inline bool Socket::secure() const
{
POCO_CHECK_NEW_STATE_ON_MOVE;
return _pImpl->secure();
}
@ -661,6 +831,8 @@ inline bool Socket::supportsIPv6()
inline void Socket::init(int af)
{
POCO_CHECK_NEW_STATE_ON_MOVE;
_pImpl->init(af);
}

View File

@ -42,7 +42,7 @@ class SocketAcceptor
/// The Acceptor-Connector design pattern decouples connection
/// establishment and service initialization in a distributed system
/// from the processing performed once a service is initialized.
/// This decoupling is achieved with three components: Acceptors,
/// This decoupling is achieved with three components: Acceptors,
/// Connectors and Service Handlers.
/// The SocketAcceptor passively waits for connection requests (usually
/// from a remote Connector) and establishes a connection upon
@ -113,7 +113,7 @@ public:
///
/// A subclass can override this function to e.g.
/// register an event handler for timeout event.
///
///
/// If acceptor was constructed without providing reactor to it,
/// the override of this method must either call the base class
/// implementation or directly register the accept handler with
@ -125,13 +125,13 @@ public:
_pReactor->addEventHandler(_socket, Observer(*this, &SocketAcceptor::onAccept));
}
}
virtual void unregisterAcceptor()
/// Unregisters the SocketAcceptor.
///
/// A subclass can override this function to e.g.
/// unregister its event handler for a timeout event.
///
///
/// If the accept handler was registered with the reactor,
/// the overriding method must either call the base class
/// implementation or directly unregister the accept handler.
@ -141,7 +141,7 @@ public:
_pReactor->removeEventHandler(_socket, Observer(*this, &SocketAcceptor::onAccept));
}
}
void onAccept(ReadableNotification* pNotification)
/// Accepts connection and creates event handler.
{
@ -150,7 +150,7 @@ public:
_pReactor->wakeUp();
createServiceHandler(sock);
}
protected:
virtual ServiceHandler* createServiceHandler(StreamSocket& socket)
/// Create and initialize a new ServiceHandler instance.
@ -179,7 +179,7 @@ private:
SocketAcceptor();
SocketAcceptor(const SocketAcceptor&);
SocketAcceptor& operator = (const SocketAcceptor&);
ServerSocket _socket;
SocketReactor* _pReactor;
};

View File

@ -138,6 +138,9 @@ public:
SocketAddress(const SocketAddress& addr);
/// Creates a SocketAddress by copying another one.
SocketAddress(SocketAddress&& addr);
/// Creates a SocketAddress by moving another one.
SocketAddress(const struct sockaddr* addr, poco_socklen_t length);
/// Creates a SocketAddress from a native socket address.
@ -147,6 +150,9 @@ public:
SocketAddress& operator = (const SocketAddress& socketAddress);
/// Assigns another SocketAddress.
SocketAddress& operator = (SocketAddress&& socketAddress);
/// Move-assigns another SocketAddress.
IPAddress host() const;
/// Returns the host IP address.

View File

@ -43,7 +43,7 @@ class SocketConnector
/// The Acceptor-Connector design pattern decouples connection
/// establishment and service initialization in a distributed system
/// from the processing performed once a service is initialized.
/// This decoupling is achieved with three components: Acceptors,
/// This decoupling is achieved with three components: Acceptors,
/// Connectors and Service Handlers.
/// The Connector actively establishes a connection with a remote
/// server socket (usually managed by an Acceptor) and initializes
@ -51,10 +51,10 @@ class SocketConnector
///
/// The SocketConnector sets up a StreamSocket, initiates a non-blocking
/// connect operation and registers itself for ReadableNotification, WritableNotification
/// and ErrorNotification. ReadableNotification or WritableNotification denote the successful
/// and ErrorNotification. ReadableNotification or WritableNotification denote the successful
/// establishment of the connection.
///
/// When the StreamSocket becomes readable or writeable, the SocketConnector
/// When the StreamSocket becomes readable or writeable, the SocketConnector
/// creates a ServiceHandler to service the connection and unregisters
/// itself.
///
@ -82,7 +82,7 @@ public:
SocketConnector(SocketAddress& address, SocketReactor& reactor, bool doRegister = true) :
_pReactor(0)
/// Creates an acceptor, using the given ServerSocket.
/// Creates an connector, using the given ServerSocket.
/// The SocketConnector registers itself with the given SocketReactor.
{
_socket.connectNB(address);
@ -134,39 +134,33 @@ public:
void onReadable(ReadableNotification* pNotification)
{
unregisterConnector();
pNotification->release();
int err = _socket.impl()->socketError();
if (err)
{
onError(err);
unregisterConnector();
}
else
{
onConnect();
}
if (err) onError(err);
else onConnect();
}
void onWritable(WritableNotification* pNotification)
{
unregisterConnector();
pNotification->release();
onConnect();
}
void onError(ErrorNotification* pNotification)
{
unregisterConnector();
pNotification->release();
onError(_socket.impl()->socketError());
}
void onConnect()
{
_socket.setBlocking(true);
createServiceHandler();
unregisterConnector();
}
void onError(ErrorNotification* pNotification)
{
pNotification->release();
onError(_socket.impl()->socketError());
unregisterConnector();
}
protected:
virtual ServiceHandler* createServiceHandler()
/// Create and initialize a new ServiceHandler instance.
@ -182,7 +176,7 @@ protected:
/// Subclasses can override this method.
{
}
SocketReactor* reactor()
/// Returns a pointer to the SocketReactor where
/// this SocketConnector is registered.
@ -191,7 +185,7 @@ protected:
{
return _pReactor;
}
StreamSocket& socket()
/// Returns a reference to the SocketConnector's socket.
{

View File

@ -25,6 +25,10 @@
#if defined(POCO_OS_FAMILY_WINDOWS)
#ifdef FD_SETSIZE
#undef FD_SETSIZE
#endif
#define FD_SETSIZE 1024 // increase as needed
#include "Poco/UnWindows.h"
#include <winsock2.h>
#include <ws2tcpip.h>
@ -364,6 +368,19 @@ namespace Net {
typedef std::vector<SocketBuf> SocketBufVec;
inline int SocketBufVecSize(const SocketBufVec& sbv)
/// Returns total length of all SocketBufs in the vector.
{
std::size_t sz = 0;
for (const auto& v : sbv)
#if defined(POCO_OS_FAMILY_WINDOWS)
sz += v.len;
#elif defined(POCO_OS_FAMILY_UNIX)
sz += v.iov_len;
#endif
return static_cast<int>(sz);
}
struct AddressFamily
/// AddressFamily::Family replaces the previously used IPAddress::Family
/// enumeration and is now used for IPAddress::Family and SocketAddress::Family.
@ -371,16 +388,18 @@ struct AddressFamily
enum Family
/// Possible address families for socket addresses.
{
IPv4,
UNKNOWN = AF_UNSPEC,
/// Unspecified family
#if defined(POCO_OS_FAMILY_UNIX)
UNIX_LOCAL = AF_UNIX,
/// UNIX domain socket address family. Available on UNIX/POSIX platforms only.
#endif
IPv4 = AF_INET,
/// IPv4 address family.
#if defined(POCO_HAVE_IPv6)
IPv6,
IPv6 = AF_INET6
/// IPv6 address family.
#endif
#if defined(POCO_OS_FAMILY_UNIX)
UNIX_LOCAL
/// UNIX domain socket address family. Available on UNIX/POSIX platforms only.
#endif
};
};

View File

@ -39,6 +39,13 @@ class Net_API SocketImpl: public Poco::RefCountedObject
/// You should not create any instances of this class.
{
public:
enum Type
{
SOCKET_TYPE_STREAM = SOCK_STREAM,
SOCKET_TYPE_DATAGRAM = SOCK_DGRAM,
SOCKET_TYPE_RAW = SOCK_RAW
};
enum SelectMode
{
SELECT_READ = 1,
@ -271,6 +278,12 @@ public:
/// Returns true if the next operation corresponding to
/// mode will not block, false otherwise.
Type type();
/// Returns the socket type.
virtual int getError();
/// Returns the socket error.
virtual void setSendBufferSize(int size);
/// Sets the size of the send buffer.
@ -526,6 +539,17 @@ private:
//
// inlines
//
inline SocketImpl::Type SocketImpl::type()
{
int type;
getOption(SOL_SOCKET, SO_TYPE, type);
poco_assert_dbg(type == SOCK_STREAM ||
type == SOCK_DGRAM ||
type == SOCK_RAW);
return static_cast<Type>(type);
}
inline poco_socket_t SocketImpl::sockfd() const
{
return _sockfd;

View File

@ -40,19 +40,20 @@ public:
virtual ~SocketNotification();
/// Destroys the SocketNotification.
SocketReactor& source() const;
/// Returns the SocketReactor that generated the notification.
/// Returns the SocketReactor that generated the notification.
Socket socket() const;
/// Returns the socket that caused the notification.
private:
protected:
void setSocket(const Socket& socket);
private:
SocketReactor* _pReactor;
Socket _socket;
friend class SocketNotifier;
};
@ -85,14 +86,40 @@ class Net_API ErrorNotification: public SocketNotification
/// This notification is sent if a socket has signalled an error.
{
public:
ErrorNotification(SocketReactor* pReactor);
ErrorNotification(SocketReactor* pReactor, int code = 0, const std::string& description = "");
/// Creates the ErrorNotification for the given SocketReactor.
ErrorNotification(SocketReactor* pReactor, const Socket& socket,
int code = 0, const std::string& description = "");
/// Creates the ErrorNotification for the given SocketReactor.
~ErrorNotification();
/// Destroys the ErrorNotification.
int code() const;
/// Returns the error code.
const std::string& description() const;
/// Returns error description.
private:
int _code = 0;
std::string _description;
};
inline int ErrorNotification::code() const
{
return _code;
}
inline const std::string& ErrorNotification::description() const
{
return _description;
}
class Net_API TimeoutNotification: public SocketNotification
/// This notification is sent if no other event has occurred
/// for a specified time.
@ -140,7 +167,7 @@ inline SocketReactor& SocketNotification::source() const
return *_pReactor;
}
inline Socket SocketNotification::socket() const
{
return _socket;

View File

@ -42,25 +42,25 @@ class Net_API SocketNotifier: public Poco::RefCountedObject
public:
explicit SocketNotifier(const Socket& socket);
/// Creates the SocketNotifier for the given socket.
void addObserver(SocketReactor* pReactor, const Poco::AbstractObserver& observer);
/// Adds the given observer.
/// Adds the given observer.
void removeObserver(SocketReactor* pReactor, const Poco::AbstractObserver& observer);
/// Removes the given observer.
/// Removes the given observer.
bool hasObserver(const Poco::AbstractObserver& observer) const;
/// Returns true if the given observer is registered.
bool accepts(SocketNotification* pNotification);
/// Returns true if there is at least one observer for the given notification.
void dispatch(SocketNotification* pNotification);
/// Dispatches the notification to all observers.
bool hasObservers() const;
/// Returns true if there are subscribers.
std::size_t countObservers() const;
/// Returns the number of subscribers;

View File

@ -0,0 +1,503 @@
//
// SocketProactor.h
//
// Library: Net
// Package: Sockets
// Module: SocketProactor
//
// Definition of the SocketProactor class.
//
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Net_SocketProactor_INCLUDED
#define Net_SocketProactor_INCLUDED
#include "Poco/Net/Net.h"
#include "Poco/Net/Socket.h"
#include "Poco/Net/PollSet.h"
#include "Poco/Runnable.h"
#include "Poco/Timespan.h"
#include "Poco/Timestamp.h"
#include "Poco/AutoPtr.h"
#include "Poco/Mutex.h"
#include "Poco/Activity.h"
#include "Poco/NotificationQueue.h"
#include "Poco/ErrorHandler.h"
#include <unordered_map>
#include <atomic>
#include <functional>
#include <deque>
#include <utility>
#include <memory>
#include <iostream>
#include <system_error>
namespace Poco {
class Thread;
namespace Net {
class Socket;
class Worker;
class Net_API SocketProactor final: public Poco::Runnable
/// This class implements the proactor pattern.
/// It may also contain a simple work executor (enabled by default),
/// which executes submitted workload.
{
public:
using Buffer = std::vector<std::uint8_t>;
using Work = std::function<void()>;
using Callback = std::function<void (const std::error_code& failure, int bytesReceived)>;
static const int POLL_READ = PollSet::POLL_READ;
static const int POLL_WRITE = PollSet::POLL_WRITE;
static const int POLL_ERROR = PollSet::POLL_ERROR;
static const Timestamp::TimeDiff PERMANENT_COMPLETION_HANDLER;
explicit SocketProactor(bool worker = true);
/// Creates the SocketProactor.
explicit SocketProactor(const Poco::Timespan& timeout, bool worker = true);
/// Creates the SocketProactor, using the given timeout.
SocketProactor(const SocketProactor&) = delete;
SocketProactor(SocketProactor&&) = delete;
SocketProactor& operator=(const SocketProactor&) = delete;
SocketProactor& operator=(SocketProactor&&) = delete;
~SocketProactor();
/// Destroys the SocketProactor.
void addWork(const Work& ch, Timestamp::TimeDiff ms = PERMANENT_COMPLETION_HANDLER);
/// Adds work to be executed after the next poll() completion.
/// Function will be called until the specified expiration,
/// which defaults to immediately, ie. expiration after the
/// first invocation.
void addWork(Work&& ch, Timestamp::TimeDiff ms = PERMANENT_COMPLETION_HANDLER, int pos = -1);
/// Adds work to be executed after the next poll() completion.
/// Function will be called until the specified expiration,
/// which defaults to immediately, ie. expiration after the
/// first invocation.
void removeWork();
/// Removes all scheduled work.
int scheduledWork();
/// Returns the number of scheduled functions.
int removeScheduledWork(int count = -1);
/// Removes the count scheduled functions
/// from the front of the schedule queue.
/// Default is removal of all scheduled functions.
int permanentWork();
/// Returns the number of permanent functions.
int removePermanentWork(int count = -1);
/// Removes the count permanent functions
/// from the front of the schedule queue.
/// Default is removal of all functions.
int poll(int* pHandled = 0);
/// Polls all registered sockets and calls their respective handlers.
/// If pHandled is not null, after the call it contains the total number
/// of read/write/error socket handlers called.
/// Returns the number of completion handlers invoked.
int runOne();
/// Runs one handler, scheduled or permanent.
/// If there are no available handlers, it blocks
/// until the first handler is encountered and executed.
/// Returns 1 on successful handler invocation, 0 on
/// exception.
void run();
/// Runs the SocketProactor. The reactor will run
/// until stop() is called (in a separate thread).
void stop();
/// Stops the SocketProactor.
///
/// The proactor will be stopped when the next event
/// (including a timeout event) occurs.
void wakeUp();
/// Wakes up idle reactor.
void wait();
/// Blocks and waits for the scheduled I/O completion
/// handlers loop to end.
void setTimeout(const Poco::Timespan& timeout);
/// Sets the timeout.
///
/// If no other event occurs for the given timeout
/// interval, a timeout event is sent to all event listeners.
///
/// The default timeout is 250 milliseconds;
///
/// The timeout is passed to the Socket::select()
/// method.
Poco::Timespan getTimeout() const;
/// Returns the timeout.
void addSocket(Socket sock, int mode);
/// Adds the socket to the poll set.
void updateSocket(Socket sock, int mode);
/// Updates the socket mode in the poll set.
void removeSocket(Socket sock);
/// Removes the socket from the poll set.
void addReceiveFrom(Socket sock, Buffer& buf, SocketAddress& addr, Callback&& onCompletion);
/// Adds the datagram socket and the completion handler to the I/O receive queue.
void addSendTo(Socket sock, const Buffer& message, const SocketAddress& addr, Callback&& onCompletion);
/// Adds the datagram socket and the completion handler to the I/O send queue.
void addSendTo(Socket sock, Buffer&& message, const SocketAddress&& addr, Callback&& onCompletion);
/// Adds the datagram socket and the completion handler to the I/O send queue.
void addSend(Socket sock, Buffer* pMessage, SocketAddress* pAddr, Callback&& onCompletion, bool own = false);
/// Adds the socket and the completion handler to the I/O send queue.
/// For stream socket, pAddr can be nullptr.
/// If `own` is true, message and address are deleted after the I/O completion.
void addReceive(Socket sock, Buffer& buf, Callback&& onCompletion);
/// Adds the stream socket and the completion handler to the I/O receive queue.
void addSend(Socket sock, const Buffer& message, Callback&& onCompletion);
/// Adds the stream socket and the completion handler to the I/O send queue.
void addSend(Socket sock, Buffer&& message, Callback&& onCompletion);
/// Adds the stream socket and the completion handler to the I/O send queue.
bool hasSocketHandlers() const;
/// Returns true if proactor had at least one I/O completion handler.
bool has(const Socket& sock) const;
/// Returns true if socket is registered with this proactor.
bool isRunning() const;
/// Returns true if this proactor is running
bool ioCompletionInProgress() const;
/// Returns true if there are not executed handlers from last IO..
private:
void onShutdown();
/// Called when the SocketProactor is about to terminate.
int doWork(bool handleOne = false, bool expiredOnly = false);
/// Runs the scheduled work.
/// If handleOne is true, only the next scheduled function
/// is called.
/// If expiredOnly is true, only expired temporary functions
/// are called.
typedef Poco::Mutex MutexType;
typedef MutexType::ScopedLock ScopedLock;
static const long DEFAULT_MAX_TIMEOUT_MS = 250;
struct Handler
/// Handler struct holds the scheduled I/O.
/// At the actual I/O, Buffer and SocketAddress
/// are used appropriately, and deleted if owned.
/// Callback is passed to the IOCompletion queue.
{
Buffer* _pBuf = nullptr;
SocketAddress* _pAddr = nullptr;
Callback _onCompletion = nullptr;
bool _owner = false;
};
class IONotification: public Notification
/// IONotification object is used to transfer
/// the I/O completion handlers into the
/// completion handlers queue.
{
public:
IONotification() = delete;
IONotification(Callback&& onCompletion, int bytes, const std::error_code& errorCode):
_onCompletion(std::move(onCompletion)),
_bytes(bytes),
_errorCode(errorCode)
/// Creates the IONotification.
{
}
~IONotification() = default;
void call()
/// Calls the completion handler.
{
_onCompletion(_errorCode, _bytes);
};
private:
Callback _onCompletion;
int _bytes;
std::error_code _errorCode;
};
class IOCompletion
/// IOCompletion utility class accompanies the
/// SocketProactor and serves to execute I/O
/// completion handlers in its own thread.
{
public:
IOCompletion() = delete;
explicit IOCompletion(int maxTimeout):
_activity(this, &IOCompletion::run)
/// Creates IOCompletion.
{
start();
}
~IOCompletion()
{
wakeUp();
}
void start()
/// Starts the I/O completion execution.
{
_activity.start();
}
void stop()
/// Stops the I/O completion execution.
{
_activity.stop();
_nq.wakeUpAll();
}
void wait()
/// Blocks until I/O execution completely stops.
{
_activity.wait();
}
void enqueue(Notification::Ptr pNotification)
/// Enqueues I/O completion.
{
_nq.enqueueNotification(std::move(pNotification));
}
void wakeUp()
/// Wakes up the I/O completion execution loop.
{
_nq.wakeUpAll();
}
int queueSize() const
{
return _nq.size();
}
private:
bool runOne()
/// Runs the next I/O completion handler in the queue.
{
IONotification* pNf = dynamic_cast<IONotification*>(_nq.waitDequeueNotification());
if (_activity.isStopped()) return false;
if (pNf)
{
try
{
pNf->call();
pNf->release();
return true;
}
catch (Exception& exc)
{
ErrorHandler::handle(exc);
}
catch (std::exception& exc)
{
ErrorHandler::handle(exc);
}
catch (...)
{
ErrorHandler::handle();
}
}
return false;
}
void run()
/// Continuously runs enqueued completion handlers.
{
while(!_activity.isStopped()) runOne();
}
Activity<IOCompletion> _activity;
NotificationQueue _nq;
};
using IOHandlerList = std::deque<std::unique_ptr<Handler>>;
using IOHandlerIt = IOHandlerList::iterator;
using SubscriberMap = std::unordered_map<poco_socket_t, std::deque<std::unique_ptr<Handler>>>;
void sleep(bool isAtWork);
/// Sleep policy implementation.
/// If there is currently any work being done,
/// timeout is kept at zero (ie. no timeout),
/// otherwise, the timeout is incremented and
/// - trySleep() is called if proactor runs
/// in a Poco::Thread, which is necessary
/// for trySleep call to be interruptable
/// or
/// - sleep() is called (not interruptable)
///
/// The value of _timeout can grow up to
/// _maxTimeout value.
int error(Socket& sock);
/// Enqueues the completion handlers and removes
/// them from the handlers list after the operation
/// successfully completes.
bool hasHandlers(SubscriberMap& handlers, int sockfd);
void deleteHandler(IOHandlerList& handlers, IOHandlerList::iterator& it);
template <typename T>
int errorImpl(Socket& sock, T& handlerMap, Poco::Mutex& mutex)
{
Poco::Mutex::ScopedLock l(mutex);
auto hIt = handlerMap.find(sock.impl()->sockfd());
if (hIt == handlerMap.end()) return 0;
unsigned err = 0;
sock.getOption(SOL_SOCKET, SO_ERROR, err);
IOHandlerList& handlers = hIt->second;
int handled = static_cast<int>(handlers.size());
auto it = handlers.begin();
auto end = handlers.end();
while (it != end)
{
enqueueIONotification(std::move((*it)->_onCompletion), 0, err);
deleteHandler(handlers, it);
// end iterator is invalidated when the last member
// is removed, so make sure we don't check for it
if (handlers.empty()) break;
}
handled -= static_cast<int>(handlers.size());
if (handled) _ioCompletion.wakeUp();
return handled;
}
int send(Socket& sock);
/// Calls the appropriate output function; enqueues
/// the accompanying completion handler and removes
/// it from the handlers list after the operation
/// successfully completes.
int receive(Socket& sock);
/// Calls the appropriate input function; enqueues
/// the accompanying completion handler and removes
/// it from the handlers list after the operation
/// successfully completes.
void sendTo(SocketImpl& sock, IOHandlerIt& it);
/// Sends data to the datagram socket and enqueues the
/// accompanying completion handler.
void send(SocketImpl& sock, IOHandlerIt& it);
/// Sends data to the stream socket and enqueues the
/// accompanying completion handler.
void receiveFrom(SocketImpl& sock, IOHandlerIt& it, int available);
/// Reads data from the datagram socket and enqueues the
/// accompanying completion handler.
void receive(SocketImpl& sock, IOHandlerIt& it, int available);
/// Reads data from the stream socket and enqueues the
/// accompanying completion handler.
void enqueueIONotification(Callback&& onCompletion, int n, int err);
/// Enqueues the completion handler into the I/O
/// completion handler.
Worker& worker();
std::atomic<bool> _isRunning;
std::atomic<bool> _isStopped;
std::atomic<bool> _stop;
long _timeout;
long _maxTimeout;
PollSet _pollSet;
Poco::Thread* _pThread;
SubscriberMap _readHandlers;
SubscriberMap _writeHandlers;
IOCompletion _ioCompletion;
Poco::Mutex _writeMutex;
Poco::Mutex _readMutex;
std::unique_ptr<Worker> _pWorker;
friend class Worker;
};
//
// inlines
//
inline void SocketProactor::addSocket(Socket sock, int mode)
{
_pollSet.add(sock, mode | PollSet::POLL_ERROR);
}
inline void SocketProactor::updateSocket(Socket sock, int mode)
{
_pollSet.update(sock, mode);
}
inline void SocketProactor::removeSocket(Socket sock)
{
_pollSet.remove(sock);
}
inline void SocketProactor::enqueueIONotification(Callback&& onCompletion, int n, int err)
{
if (onCompletion)
{
_ioCompletion.enqueue(new IONotification(
std::move(onCompletion), n,
std::error_code(err, std::generic_category())));
}
}
inline bool SocketProactor::isRunning() const
{
return _isRunning;
}
} } // namespace Poco::Net
#endif // Net_SocketProactor_INCLUDED

View File

@ -20,11 +20,14 @@
#include "Poco/Net/Net.h"
#include "Poco/Net/Socket.h"
#include "Poco/Net/SocketNotification.h"
#include "Poco/Net/SocketNotifier.h"
#include "Poco/Net/PollSet.h"
#include "Poco/Runnable.h"
#include "Poco/Timespan.h"
#include "Poco/Observer.h"
#include "Poco/AutoPtr.h"
#include "Poco/Event.h"
#include <map>
#include <atomic>
@ -39,8 +42,6 @@ namespace Net {
class Socket;
class SocketNotification;
class SocketNotifier;
class Net_API SocketReactor: public Poco::Runnable
@ -62,7 +63,7 @@ class Net_API SocketReactor: public Poco::Runnable
/// is no base class for event handlers) can be registered
/// with the addEventHandler() method and deregistered with
/// the removeEventHandler() method.
///
///
/// An event handler is always registered for a certain socket,
/// which is given in the call to addEventHandler(). Any method
/// of the event handler class can be registered to handle the
@ -71,62 +72,120 @@ class Net_API SocketReactor: public Poco::Runnable
/// as argument.
///
/// Once started, the SocketReactor waits for events
/// on the registered sockets, using Socket::select().
/// on the registered sockets, using PollSet:poll().
/// If an event is detected, the corresponding event handler
/// is invoked. There are five event types (and corresponding
/// notification classes) defined: ReadableNotification, WritableNotification,
/// ErrorNotification, TimeoutNotification, IdleNotification and
/// ShutdownNotification.
///
/// ErrorNotification, TimeoutNotification and ShutdownNotification.
///
/// The ReadableNotification will be dispatched if a socket becomes
/// readable. The WritableNotification will be dispatched if a socket
/// becomes writable. The ErrorNotification will be dispatched if
/// there is an error condition on a socket.
///
/// If the timeout expires and no event has occurred, a
/// Timeout/sleep strategy operates as follows:
///
/// If the poll timeout expires and no event has occurred, a
/// TimeoutNotification will be dispatched to all event handlers
/// registered for it. This is done in the onTimeout() method
/// which can be overridden by subclasses to perform custom
/// timeout processing.
///
/// If there are no sockets for the SocketReactor to pass to
/// Socket::select(), an IdleNotification will be dispatched to
/// all event handlers registered for it. This is done in the
/// onIdle() method which can be overridden by subclasses
/// to perform custom idle processing. Since onIdle() will be
/// called repeatedly in a loop, it is recommended to do a
/// short sleep or yield in the event handler.
/// By default, the SocketReactor is configured to start sleeping
/// when the poll timeout is zero and there are no socket events for
/// a certain amount of time; sleep duration is progressive, up to
/// the configured limit. This behavior can be disabled through
/// configuration parameters.
///
/// Finally, when the SocketReactor is about to shut down (as a result
/// When there are no registered handlers, the SocketRactor sleeps
/// an incremental amount of milliseconds, up to the sleep limit.
/// Increment step value and sleep limit are configurable.
///
/// Finally, when the SocketReactor is about to shut down (as a result
/// of stop() being called), it dispatches a ShutdownNotification
/// to all event handlers. This is done in the onShutdown() method
/// which can be overridded by subclasses to perform custom
/// shutdown processing.
///
/// The SocketReactor is implemented so that it can
/// run in its own thread. It is also possible to run
/// multiple SocketReactors in parallel, as long as
/// they work on different sockets.
/// The SocketReactor is implemented so that it can run in its own thread.
/// Moreover, the thread affinity to a CPU core can optionally be set for the
/// thread on platforms where that functionality is supported and implemented.
/// It is also possible to run multiple SocketReactors in parallel, as long
/// as they work on different sockets.
///
/// It is safe to call addEventHandler() and removeEventHandler()
/// from another thread while the SocketReactor is running. Also,
/// it is safe to call addEventHandler() and removeEventHandler()
/// from event handlers.
/// It is safe to call addEventHandler() and removeEventHandler() from another
/// thread while the SocketReactor is running. Also, it is safe to call
/// addEventHandler() and removeEventHandler() from event handlers.
///
/// SocketReactor uses NotificationCenter to notify observers. When a handler
/// throws an exception, the NotificationCenter stops notifying the rest of
/// the observers about that particular event instance and propagates the
/// exception, which is eventually caught in the SocketReactor::run() method.
/// This sequence of events is obviously not desirable and it is highly
/// recommended that handlers wrap the code in try/catch and deal with all
/// the exceptions internally, lest they disrupt the notification of the peers.
{
public:
struct Params
/// Reactor parameters.
/// Default values should work well for most scenarios.
///
/// Note: the default behavior on zero poll timeout is to start
/// incrementally sleeping after `idleThreshold` and no socket events.
/// This prevents high CPU usage during periods without network
/// activity. To disable it, set `throttle` to false.
{
Poco::Timespan pollTimeout = DEFAULT_TIMEOUT;
/// Timeout for PolllSet::poll()
long sleep = 0;
/// Amount of milliseconds to sleep, progressively incremented,
/// at `increment` step, up to the `sleepLimit`.
long sleepLimit = DEFAULT_SLEEP_LIMIT;
/// Max sleep duration in milliseconds
/// This is the ceiling value in milliseconds for the sleep algorithm,
/// which kicks in in two cases:
///
/// - when there are no subscribers and the reactor is just idle-spinning
/// - when there are subscribers, but there was no socket events signalled
/// for `sleepLimit` milliseconds and `throttle` is true
int increment = 1;
/// Increment value for the sleep backoff algorithm.
long idleThreshold = DEFAULT_SLEEP_LIMIT;
/// Indicates when to start sleeping (throttling) on zero poll timeout
bool throttle = true;
/// Indicates whether to start sleeping when poll timeout is zero and
/// there's no socket events for a period longer than `idleThreshold`
};
SocketReactor();
/// Creates the SocketReactor.
explicit SocketReactor(const Poco::Timespan& timeout);
/// Creates the SocketReactor, using the given timeout.
explicit SocketReactor(const Poco::Timespan& pollTimeout, int threadAffinity = -1);
/// Creates the SocketReactor, using the given poll timeout.
///
/// The threadAffinity argument, when non-negative, indicates on which CPU core should
/// the run() method run. Nonexisting core or situation when this feature is not implemented
/// are silently ignored and this argument has no effect in such scenarios.
SocketReactor(const Params& params, int threadAffinity = -1);
/// Creates the SocketReactor, using the given parameters.
/// The threadAffinity argument, when non-negative, indicates on which CPU core should
/// the run() method run. Nonexisting core or situation when this feature is not implemented
/// are silently ignored and this argument has no effect in such scenarios.
virtual ~SocketReactor();
/// Destroys the SocketReactor.
void run();
virtual void run();
/// Runs the SocketReactor. The reactor will run
/// until stop() is called (in a separate thread).
/// Can be overriden by inheriting classes.
void stop();
/// Stops the SocketReactor.
///
@ -137,16 +196,15 @@ public:
/// Wakes up idle reactor.
void setTimeout(const Poco::Timespan& timeout);
/// Sets the timeout.
/// Sets the timeout.
///
/// If no other event occurs for the given timeout
/// If no socket event occurs for the given timeout
/// interval, a timeout event is sent to all event listeners.
///
/// The default timeout is 250 milliseconds;
///
/// The timeout is passed to the Socket::select()
/// method.
/// The timeout is passed to the PollSet::poll() method.
const Poco::Timespan& getTimeout() const;
/// Returns the timeout.
@ -178,13 +236,6 @@ protected:
/// dispatches the TimeoutNotification and thus should be called by overriding
/// implementations.
virtual void onIdle();
/// Called if no sockets are available to call select() on.
///
/// Can be overridden by subclasses. The default implementation
/// dispatches the IdleNotification and thus should be called by overriding
/// implementations.
virtual void onShutdown();
/// Called when the SocketReactor is about to terminate.
///
@ -192,52 +243,96 @@ protected:
/// dispatches the ShutdownNotification and thus should be called by overriding
/// implementations.
virtual void onBusy();
/// Called when the SocketReactor is busy and at least one notification
/// has been dispatched.
///
/// Can be overridden by subclasses to perform additional
/// periodic tasks. The default implementation does nothing.
void onError(const Socket& socket, int code, const std::string& description);
/// Notifies all subscribers when the reactor loop throws an exception.
void onError(int code, const std::string& description);
/// Notifies all subscribers when the reactor loop throws an exception.
void dispatch(const Socket& socket, SocketNotification* pNotification);
/// Dispatches the given notification to all observers
/// registered for the given socket.
void dispatch(SocketNotification* pNotification);
/// Dispatches the given notification to all observers.
private:
typedef Poco::AutoPtr<SocketNotifier> NotifierPtr;
typedef Poco::AutoPtr<SocketNotification> NotificationPtr;
typedef std::map<Socket, NotifierPtr> EventHandlerMap;
typedef Poco::FastMutex MutexType;
typedef MutexType::ScopedLock ScopedLock;
typedef Poco::AutoPtr<SocketNotifier> NotifierPtr;
typedef Poco::AutoPtr<SocketNotification> NotificationPtr;
typedef std::map<poco_socket_t, NotifierPtr> EventHandlerMap;
typedef Poco::FastMutex MutexType;
typedef MutexType::ScopedLock ScopedLock;
bool hasSocketHandlers();
void dispatch(NotifierPtr& pNotifier, SocketNotification* pNotification);
NotifierPtr getNotifier(const Socket& socket, bool makeNew = false);
void sleep();
enum
{
DEFAULT_TIMEOUT = 250000
DEFAULT_TIMEOUT = 250000,
/// Default timeout for PollSet::poll()
DEFAULT_SLEEP_LIMIT = 250
/// Default limit for event-based sleeping
};
Params _params;
int _threadAffinity = -1;
std::atomic<bool> _stop;
Poco::Timespan _timeout;
EventHandlerMap _handlers;
PollSet _pollSet;
NotificationPtr _pReadableNotification;
NotificationPtr _pWritableNotification;
NotificationPtr _pErrorNotification;
NotificationPtr _pTimeoutNotification;
NotificationPtr _pIdleNotification;
NotificationPtr _pShutdownNotification;
MutexType _mutex;
Poco::Thread* _pThread;
Poco::Event _event;
friend class SocketNotifier;
};
//
// inlines
//
inline void SocketReactor::setTimeout(const Poco::Timespan& timeout)
{
_params.pollTimeout = timeout;
}
inline const Poco::Timespan& SocketReactor::getTimeout() const
{
return _params.pollTimeout;
}
inline bool SocketReactor::has(const Socket& socket) const
{
return _pollSet.has(socket);
}
inline void SocketReactor::onError(const Socket& socket, int code, const std::string& description)
{
dispatch(new ErrorNotification(this, socket, code, description));
}
inline void SocketReactor::onError(int code, const std::string& description)
{
dispatch(new ErrorNotification(this, code, description));
}
inline void SocketReactor::dispatch(NotifierPtr& pNotifier, SocketNotification* pNotification)
{
pNotifier->dispatch(pNotification);
}
} } // namespace Poco::Net

View File

@ -44,16 +44,16 @@ public:
~SocketStreamBuf();
/// Destroys the SocketStreamBuf.
StreamSocketImpl* socketImpl() const;
/// Returns the internal SocketImpl.
protected:
int readFromDevice(char* buffer, std::streamsize length);
int writeToDevice(const char* buffer, std::streamsize length);
private:
enum
enum
{
STREAM_BUFFER_SIZE = 1024
};
@ -75,18 +75,18 @@ public:
///
/// The socket's SocketImpl must be a StreamSocketImpl,
/// otherwise an InvalidArgumentException is thrown.
~SocketIOS();
/// Destroys the SocketIOS.
///
/// Flushes the buffer, but does not close the socket.
SocketStreamBuf* rdbuf();
/// Returns a pointer to the internal SocketStreamBuf.
void close();
/// Flushes the stream and closes the socket.
StreamSocket socket() const;
/// Returns the underlying socket.

View File

@ -60,6 +60,10 @@ public:
/// a StreamSocketImpl, otherwise an InvalidArgumentException
/// will be thrown.
StreamSocket(const StreamSocket& socket);
/// Creates the StreamSocket with the SocketImpl
/// from another socket.
virtual ~StreamSocket();
/// Destroys the StreamSocket.
@ -70,6 +74,43 @@ public:
/// attaches the SocketImpl from the other socket and
/// increments the reference count of the SocketImpl.
StreamSocket& operator = (const StreamSocket& socket);
/// Assignment operator.
///
/// Releases the socket's SocketImpl and
/// attaches the SocketImpl from the other socket and
/// increments the reference count of the SocketImpl.
#if POCO_NEW_STATE_ON_MOVE
StreamSocket(Socket&& socket);
/// Creates the StreamSocket with the SocketImpl
/// from another socket and zeroes the other socket's
/// SocketImpl.The SocketImpl must be
/// a StreamSocketImpl, otherwise an InvalidArgumentException
/// will be thrown.
StreamSocket(StreamSocket&& socket);
/// Creates the StreamSocket with the SocketImpl
/// from another socket and zeroes the other socket's
/// SocketImpl.
StreamSocket& operator = (Socket&& socket);
/// Assignment move operator.
///
/// Releases the socket's SocketImpl and
/// attaches the SocketImpl from the other socket and
/// zeroes the other socket's SocketImpl.
StreamSocket& operator = (StreamSocket&& socket);
/// Assignment move operator.
///
/// Releases the socket's SocketImpl and
/// attaches the SocketImpl from the other socket and
/// zeroes the other socket's SocketImpl.
#endif //POCO_NEW_STATE_ON_MOVE
void connect(const SocketAddress& address);
/// Initializes the socket and establishes a connection to
/// the TCP server at the given address.
@ -87,6 +128,27 @@ public:
/// the TCP server at the given address. Prior to opening the
/// connection the socket is set to nonblocking mode.
void bind(const SocketAddress& address, bool reuseAddress = false, bool ipV6Only = false);
/// Bind a local address to the socket.
///
/// This is usually only done when establishing a server
/// socket.
///
/// TCP clients normally do not bind to a local address,
/// but in some special advanced cases it may be useful to have
/// this type of functionality. (e.g. in multihoming situations
/// where the traffic will be sent through a particular interface;
/// or in computer clustered environments with active/standby
/// servers and it is desired to make the traffic from either
/// active host present the same source IP address).
///
/// Note: Practical use of client source IP address binding
/// may require OS networking setup outside the scope of
/// the Poco library.
///
/// If reuseAddress is true, sets the SO_REUSEADDR
/// socket option.
void shutdownReceive();
/// Shuts down the receiving part of the socket connection.

View File

@ -36,10 +36,10 @@ public:
explicit StreamSocketImpl(SocketAddress::Family addressFamily);
/// Creates a SocketImpl, with the underlying
/// socket initialized for the given address family.
StreamSocketImpl(poco_socket_t sockfd);
/// Creates a StreamSocketImpl using the given native socket.
virtual int sendBytes(const void* buffer, int length, int flags = 0);
/// Ensures that all data in buffer is sent if the socket
/// is blocking. In case of a non-blocking socket, sends as

View File

@ -35,7 +35,7 @@ public:
/// Creates the StringPartSource for the given string.
///
/// The MIME type is set to text/plain.
StringPartSource(const std::string& str, const std::string& mediaType);
/// Creates the StringPartSource for the given
/// string and MIME type.
@ -49,7 +49,7 @@ public:
std::istream& stream();
/// Returns a string input stream for the string.
const std::string& filename() const;
/// Returns the filename portion of the path.
@ -59,7 +59,7 @@ public:
private:
std::istringstream _istr;
std::string _filename;
StringPartSource(const StringPartSource&);
StringPartSource& operator = (const StringPartSource&);
};

View File

@ -27,6 +27,7 @@
#include "Poco/Runnable.h"
#include "Poco/Thread.h"
#include "Poco/ThreadPool.h"
#include <atomic>
namespace Poco {
@ -48,7 +49,7 @@ class Net_API TCPServerConnectionFilter: public Poco::RefCountedObject
{
public:
using Ptr = Poco::AutoPtr<TCPServerConnectionFilter>;
virtual bool accept(const StreamSocket& socket) = 0;
/// Returns true if the given StreamSocket connection should
/// be handled, and passed on to the TCPServerDispatcher.
@ -92,7 +93,7 @@ class Net_API TCPServer: public Poco::Runnable
/// on the number of connections waiting to be served.
///
/// It is possible to specify a maximum number of queued connections.
/// This prevents the connection queue from overflowing in the
/// This prevents the connection queue from overflowing in the
/// case of an extreme server load. In such a case, connections that
/// cannot be queued are silently and immediately closed.
///
@ -150,7 +151,7 @@ public:
const TCPServerParams& params() const;
/// Returns a const reference to the TCPServerParam object
/// used by the server's TCPServerDispatcher.
/// used by the server's TCPServerDispatcher.
void start();
/// Starts the server. A new thread will be
@ -167,7 +168,7 @@ public:
/// Already handled connections will continue to be served.
///
/// Once the server has been stopped, it cannot be restarted.
int currentThreads() const;
/// Returns the number of currently used connection threads.
@ -176,13 +177,13 @@ public:
int totalConnections() const;
/// Returns the total number of handled connections.
int currentConnections() const;
/// Returns the number of currently handled connections.
int maxConcurrentConnections() const;
/// Returns the maximum number of concurrently handled connections.
/// Returns the maximum number of concurrently handled connections.
int queuedConnections() const;
/// Returns the number of queued connections.
@ -203,9 +204,9 @@ public:
/// be set before the TCPServer is started. Trying to set
/// the filter after start() has been called will trigger
/// an assertion.
TCPServerConnectionFilter::Ptr getConnectionFilter() const;
/// Returns the TCPServerConnectionFilter set with setConnectionFilter(),
/// Returns the TCPServerConnectionFilter set with setConnectionFilter(),
/// or null pointer if no filter has been set.
protected:
@ -222,12 +223,12 @@ private:
TCPServer();
TCPServer(const TCPServer&);
TCPServer& operator = (const TCPServer&);
ServerSocket _socket;
TCPServerDispatcher* _pDispatcher;
TCPServerConnectionFilter::Ptr _pConnectionFilter;
Poco::Thread _thread;
bool _stopped;
std::atomic<bool> _stopped;
};

View File

@ -64,9 +64,9 @@ private:
TCPServerConnection();
TCPServerConnection(const TCPServerConnection&);
TCPServerConnection& operator = (const TCPServerConnection&);
StreamSocket _socket;
friend class TCPServerDispatcher;
};

View File

@ -44,7 +44,7 @@ class Net_API TCPServerConnectionFactory
{
public:
using Ptr = Poco::SharedPtr<TCPServerConnectionFactory>;
virtual ~TCPServerConnectionFactory();
/// Destroys the TCPServerConnectionFactory.
@ -71,11 +71,11 @@ public:
TCPServerConnectionFactoryImpl()
{
}
~TCPServerConnectionFactoryImpl()
{
}
TCPServerConnection* createConnection(const StreamSocket& socket)
{
return new S(socket);

View File

@ -26,6 +26,7 @@
#include "Poco/NotificationQueue.h"
#include "Poco/ThreadPool.h"
#include "Poco/Mutex.h"
#include <atomic>
namespace Poco {
@ -50,35 +51,35 @@ public:
void release();
/// Decrements the object's reference count
/// and deletes the object if the count
/// reaches zero.
/// reaches zero.
void run();
/// Runs the dispatcher.
void enqueue(const StreamSocket& socket);
/// Queues the given socket connection.
void stop();
/// Stops the dispatcher.
int currentThreads() const;
/// Returns the number of currently used threads.
int maxThreads() const;
/// Returns the maximum number of threads available.
int totalConnections() const;
/// Returns the total number of handled connections.
int currentConnections() const;
/// Returns the number of currently handled connections.
/// Returns the number of currently handled connections.
int maxConcurrentConnections() const;
/// Returns the maximum number of concurrently handled connections.
/// Returns the maximum number of concurrently handled connections.
int queuedConnections() const;
/// Returns the number of queued connections.
/// Returns the number of queued connections.
int refusedConnections() const;
/// Returns the number of refused connections.
@ -91,7 +92,7 @@ protected:
void beginConnection();
/// Updates the performance counters.
void endConnection();
/// Updates the performance counters.
@ -100,14 +101,38 @@ private:
TCPServerDispatcher(const TCPServerDispatcher&);
TCPServerDispatcher& operator = (const TCPServerDispatcher&);
int _rc;
class ThreadCountWatcher
{
public:
ThreadCountWatcher(TCPServerDispatcher* pDisp) : _pDisp(pDisp)
{
}
~ThreadCountWatcher()
{
FastMutex::ScopedLock lock(_pDisp->_mutex);
if (_pDisp->_currentThreads > 1 && _pDisp->_queue.empty())
{
--_pDisp->_currentThreads;
}
}
private:
ThreadCountWatcher();
ThreadCountWatcher(const ThreadCountWatcher&);
ThreadCountWatcher& operator=(const ThreadCountWatcher&);
TCPServerDispatcher* _pDisp;
};
std::atomic<int> _rc;
TCPServerParams::Ptr _pParams;
int _currentThreads;
int _totalConnections;
int _currentConnections;
int _maxConcurrentConnections;
int _refusedConnections;
bool _stopped;
std::atomic<int> _currentThreads;
std::atomic<int> _totalConnections;
std::atomic<int> _currentConnections;
std::atomic<int> _maxConcurrentConnections;
std::atomic<int> _refusedConnections;
std::atomic<bool> _stopped;
Poco::NotificationQueue _queue;
TCPServerConnectionFactory::Ptr _pConnectionFactory;
Poco::ThreadPool& _threadPool;

View File

@ -37,7 +37,7 @@ class Net_API TCPServerParams: public Poco::RefCountedObject
{
public:
using Ptr = Poco::AutoPtr<TCPServerParams>;
TCPServerParams();
/// Creates the TCPServerParams.
///
@ -51,7 +51,7 @@ public:
/// it is terminated.
///
/// The default idle time is 10 seconds;
const Poco::Timespan& getThreadIdleTime() const;
/// Returns the maximum thread idle time.
@ -63,7 +63,7 @@ public:
/// in the queue, new connections will be silently discarded.
///
/// The default number is 64.
int getMaxQueued() const;
/// Returns the maximum number of queued connections.
@ -79,18 +79,18 @@ public:
/// The thread pool used by the TCPServerDispatcher
/// must at least have the capacity for the given
/// number of threads.
int getMaxThreads() const;
/// Returns the maximum number of simultaneous threads
/// available for this TCPServerDispatcher.
/// available for this TCPServerDispatcher.
void setThreadPriority(Poco::Thread::Priority prio);
/// Sets the priority of TCP server threads
/// Sets the priority of TCP server threads
/// created by TCPServer.
Poco::Thread::Priority getThreadPriority() const;
/// Returns the priority of TCP server threads
/// created by TCPServer.
/// created by TCPServer.
protected:
virtual ~TCPServerParams();

View File

@ -86,7 +86,7 @@ private:
DatagramSocket _socket;
SocketAddress _address;
Thread* _pThread;
bool _stop;
std::atomic<bool> _stop;
Poco::AtomicCounter _dataBacklog;
Poco::AtomicCounter _errorBacklog;
};

View File

@ -30,6 +30,7 @@
#include "Poco/StringTokenizer.h"
#include <deque>
#include <cstring>
#include <atomic>
namespace Poco {
@ -42,13 +43,14 @@ typedef int UDPMsgSizeT;
template <std::size_t S = POCO_UDP_BUF_SIZE>
class UDPHandlerImpl: public Runnable, public RefCountedObject
/// UDP handler handles the data that arives to the UDP server.
/// UDP handler handles the data that arrives to the UDP server.
/// The class is thread-safe and runs in its own thread, so many handlers
/// can be used in parallel.Handler manages and provides the storage
/// can be used in parallel. Handler manages and provides the storage
/// (fixed-size memory blocks of S size) to the reader, which signals back
/// to the handler when there is data or error ready for processing.
/// Typically, user will inherit from this class and override processData()
/// and processError() members to do the actual work.
/// and processError() members to do the actual work. To auto-start the handler,
/// the inheriting class can call start() in the constructor.
{
public:
typedef UDPMsgSizeT MsgSizeT;
@ -76,7 +78,6 @@ public:
_pErr(pErr)
/// Creates the UDPHandlerImpl.
{
_thread.start(*this);
}
~UDPHandlerImpl()
@ -143,9 +144,9 @@ public:
}
void notify()
/// Sets the ready event.
/// Sets the data ready event.
{
_ready.set();
_dataReady.set();
}
void run()
@ -153,28 +154,31 @@ public:
{
while (!_stop)
{
_ready.wait();
_dataReady.wait();
if (_stop) break;
if (_mutex.tryLock(10))
{
BufMap::iterator it = _buffers.begin();
BufMap::iterator end = _buffers.end();
for (; it != end; ++it)
if (!_stop)
{
BufList::iterator lIt = it->second.begin();
BufList::iterator lEnd = it->second.end();
for (; lIt != lEnd; ++lIt)
BufMap::iterator it = _buffers.begin();
BufMap::iterator end = _buffers.end();
for (; it != end; ++it)
{
if (hasData(*lIt))
BufList::iterator lIt = it->second.begin();
BufList::iterator lEnd = it->second.end();
for (; lIt != lEnd; ++lIt)
{
processData(*lIt);
--_dataBacklog;
setIdle(*lIt);
}
else if (isError(*lIt))
{
processError(*lIt);
++_errorBacklog;
if (hasData(*lIt))
{
processData(*lIt);
--_dataBacklog;
setIdle(*lIt);
}
else if (isError(*lIt))
{
processError(*lIt);
++_errorBacklog;
}
}
}
}
@ -188,7 +192,7 @@ public:
/// Signals the handler to stop.
{
_stop = true;
_ready.set();
_dataReady.set();
}
bool stopped() const
@ -329,6 +333,12 @@ public:
setIdle(buf);
}
void start()
/// Stars the handler run in thread.
{
_thread.start(*this);
}
private:
typedef std::deque<char*> BufList;
typedef std::map<poco_socket_t, BufList> BufMap;
@ -355,10 +365,10 @@ private:
*ret = _buffers[sock].back();
}
Poco::Event _ready;
Poco::Event _dataReady;
Poco::Thread _thread;
bool _stop;
bool _done;
std::atomic<bool> _stop;
std::atomic<bool> _done;
BufMap _buffers;
BufIt _bufIt;
std::size_t _bufListSize;

View File

@ -90,9 +90,9 @@ public:
}
private:
P _poller;
P _poller;
Poco::Thread _thread;
bool _stop;
std::atomic<bool> _stop;
};

View File

@ -176,8 +176,11 @@ public:
/// Creates a WebSocket from another Socket, which must be a WebSocket,
/// otherwise a Poco::InvalidArgumentException will be thrown.
WebSocket(const WebSocket& socket);
/// Creates a WebSocket from another WebSocket.
virtual ~WebSocket();
/// Destroys the StreamSocket.
/// Destroys the WebSocket.
WebSocket& operator = (const Socket& socket);
/// Assignment operator.
@ -185,6 +188,39 @@ public:
/// The other socket must be a WebSocket, otherwise a Poco::InvalidArgumentException
/// will be thrown.
WebSocket& operator = (const WebSocket& socket);
/// Assignment operator.
#if POCO_NEW_STATE_ON_MOVE
WebSocket(Socket&& socket);
/// Creates the WebSocket with the SocketImpl
/// from another socket and zeroes the other socket's
/// SocketImpl.The SocketImpl must be
/// a WebSocketImpl, otherwise an InvalidArgumentException
/// will be thrown.
WebSocket(WebSocket&& socket);
/// Creates the WebSocket with the SocketImpl
/// from another socket and zeroes the other socket's
/// SocketImpl.
WebSocket& operator = (Socket&& socket);
/// Assignment move operator.
///
/// Releases the socket's SocketImpl and
/// attaches the SocketImpl from the other socket and
/// zeroes the other socket's SocketImpl.
WebSocket& operator = (WebSocket&& socket);
/// Assignment move operator.
///
/// Releases the socket's SocketImpl and
/// attaches the SocketImpl from the other socket and
/// zeroes the other socket's SocketImpl.
#endif //POCO_NEW_STATE_ON_MOVE
void shutdown();
/// Sends a Close control frame to the server end of
/// the connection to initiate an orderly shutdown
@ -242,6 +278,9 @@ public:
/// after any previous content in buffer.
/// The buffer will be grown as necessary.
///
/// See the note below if you want the received data
/// to be stored at the beginning of the buffer.
///
/// The frame's payload size must not exceed the
/// maximum payload size set with setMaxPayloadSize().
/// If it does, a WebSocketException (WS_ERR_PAYLOAD_TOO_BIG)
@ -268,6 +307,13 @@ public:
///
/// The frame flags and opcode (FrameFlags and FrameOpcodes)
/// is stored in flags.
///
/// Note: Since the data received from the WebSocket is appended
/// to the given Poco::Buffer, the buffer passed to this method
/// should be created with a size of 0, or resize(0) should be
/// called on the buffer beforehand, if the expectation is that
/// the received data is stored starting at the beginning of the
/// buffer.
Mode mode() const;
/// Returns WS_SERVER if the WebSocket is a server-side

View File

@ -45,7 +45,7 @@ public:
virtual int receiveBytes(void* buffer, int length, int flags);
/// Receives a WebSocket protocol frame.
virtual int receiveBytes(Poco::Buffer<char>& buffer, int flags = 0, const Poco::Timespan& span = 0);
/// Receives a WebSocket protocol frame.