mirror of
https://github.com/pocoproject/poco.git
synced 2024-12-12 18:20:26 +01:00
merge Unix Domain Sockets support and other changes from develop
This commit is contained in:
parent
d172273a75
commit
a460bafa70
@ -32,9 +32,16 @@ class Net_API DatagramSocket: public Socket
|
||||
{
|
||||
public:
|
||||
DatagramSocket();
|
||||
/// Creates an unconnected IPv4 datagram socket.
|
||||
/// Creates an unconnected, unbound datagram socket.
|
||||
///
|
||||
/// Before the datagram socket can be used, bind(),
|
||||
/// bind6() or connect() must be called.
|
||||
///
|
||||
/// Notice: The behavior of this constructor has changed
|
||||
/// in release 2.0. Previously, the constructor created
|
||||
/// an unbound IPv4 datagram socket.
|
||||
|
||||
explicit DatagramSocket(IPAddress::Family family);
|
||||
explicit DatagramSocket(SocketAddress::Family family);
|
||||
/// Creates an unconnected datagram socket.
|
||||
///
|
||||
/// The socket will be created for the
|
||||
@ -80,6 +87,20 @@ public:
|
||||
///
|
||||
/// Calls to connect cannot() come before calls to bind().
|
||||
|
||||
void bind(const SocketAddress& address, bool reuseAddress, bool reusePort);
|
||||
/// 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.
|
||||
///
|
||||
/// 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.
|
||||
|
@ -33,7 +33,7 @@ public:
|
||||
DatagramSocketImpl();
|
||||
/// Creates an unconnected, unbound datagram socket.
|
||||
|
||||
explicit DatagramSocketImpl(IPAddress::Family family);
|
||||
explicit DatagramSocketImpl(SocketAddress::Family family);
|
||||
/// Creates an unconnected datagram socket.
|
||||
///
|
||||
/// The socket will be created for the
|
||||
|
@ -225,6 +225,24 @@ public:
|
||||
/// to ensure a new connection will be set up
|
||||
/// for the next request.
|
||||
|
||||
virtual bool peekResponse(HTTPResponse& response);
|
||||
/// If the request contains a "Expect: 100-continue" header,
|
||||
/// (see HTTPRequest::setExpectContinue()) this method can be
|
||||
/// used to check whether the server has sent a 100 Continue response
|
||||
/// before continuing with the request, i.e. sending the request body,
|
||||
/// after calling sendRequest().
|
||||
///
|
||||
/// Returns true if the server has responded with 100 Continue,
|
||||
/// otherwise false. The HTTPResponse object contains the
|
||||
/// response sent by the server.
|
||||
///
|
||||
/// In any case, receiveResponse() must be called afterwards as well in
|
||||
/// order to complete the request. The same HTTPResponse object
|
||||
/// passed to peekResponse() must also be passed to receiveResponse().
|
||||
///
|
||||
/// This method should only be called if the request contains
|
||||
/// a "Expect: 100-continue" header.
|
||||
|
||||
void reset();
|
||||
/// Resets the session and closes the socket.
|
||||
///
|
||||
@ -289,6 +307,7 @@ private:
|
||||
bool _reconnect;
|
||||
bool _mustReconnect;
|
||||
bool _expectResponseBody;
|
||||
bool _responseReceived;
|
||||
Poco::SharedPtr<std::ostream> _pRequestStream;
|
||||
Poco::SharedPtr<std::istream> _pResponseStream;
|
||||
|
||||
|
@ -103,6 +103,14 @@ public:
|
||||
/// Sets the authentication scheme and information for
|
||||
/// this request.
|
||||
|
||||
bool getExpectContinue() const;
|
||||
/// Returns true if the request contains an
|
||||
/// "Expect: 100-continue" header.
|
||||
|
||||
void setExpectContinue(bool expectContinue);
|
||||
/// Adds a "Expect: 100-continue" header to the request if
|
||||
/// expectContinue is true, otherwise removes the Expect header.
|
||||
|
||||
bool hasProxyCredentials() const;
|
||||
/// Returns true iff the request contains proxy authentication
|
||||
/// information in the form of an Proxy-Authorization header.
|
||||
@ -141,6 +149,7 @@ public:
|
||||
static const std::string AUTHORIZATION;
|
||||
static const std::string PROXY_AUTHORIZATION;
|
||||
static const std::string UPGRADE;
|
||||
static const std::string EXPECT;
|
||||
|
||||
protected:
|
||||
void getCredentials(const std::string& header, std::string& scheme, std::string& authInfo) const;
|
||||
|
@ -54,6 +54,11 @@ public:
|
||||
/// The method should inspect the given HTTPServerRequest object (e.g., method
|
||||
/// and URI) and create an appropriate HTTPRequestHandler object to handle the
|
||||
/// 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
|
||||
/// the request object (request.response()) to something other than 200 OK.
|
||||
|
||||
protected:
|
||||
Poco::BasicEvent<const bool> serverStopped;
|
||||
|
@ -45,6 +45,7 @@ public:
|
||||
{
|
||||
HTTP_CONTINUE = 100,
|
||||
HTTP_SWITCHING_PROTOCOLS = 101,
|
||||
HTTP_PROCESSING = 102,
|
||||
HTTP_OK = 200,
|
||||
HTTP_CREATED = 201,
|
||||
HTTP_ACCEPTED = 202,
|
||||
@ -52,14 +53,19 @@ public:
|
||||
HTTP_NO_CONTENT = 204,
|
||||
HTTP_RESET_CONTENT = 205,
|
||||
HTTP_PARTIAL_CONTENT = 206,
|
||||
HTTP_MULTI_STATUS = 207,
|
||||
HTTP_ALREADY_REPORTED = 208,
|
||||
HTTP_IM_USED = 226,
|
||||
HTTP_MULTIPLE_CHOICES = 300,
|
||||
HTTP_MOVED_PERMANENTLY = 301,
|
||||
HTTP_FOUND = 302,
|
||||
HTTP_SEE_OTHER = 303,
|
||||
HTTP_NOT_MODIFIED = 304,
|
||||
HTTP_USEPROXY = 305,
|
||||
HTTP_USE_PROXY = 305,
|
||||
HTTP_USEPROXY = 305, /// @deprecated
|
||||
// UNUSED: 306
|
||||
HTTP_TEMPORARY_REDIRECT = 307,
|
||||
HTTP_PERMANENT_REDIRECT = 308,
|
||||
HTTP_BAD_REQUEST = 400,
|
||||
HTTP_UNAUTHORIZED = 401,
|
||||
HTTP_PAYMENT_REQUIRED = 402,
|
||||
@ -73,17 +79,36 @@ public:
|
||||
HTTP_GONE = 410,
|
||||
HTTP_LENGTH_REQUIRED = 411,
|
||||
HTTP_PRECONDITION_FAILED = 412,
|
||||
HTTP_REQUESTENTITYTOOLARGE = 413,
|
||||
HTTP_REQUESTURITOOLONG = 414,
|
||||
HTTP_UNSUPPORTEDMEDIATYPE = 415,
|
||||
HTTP_REQUEST_ENTITY_TOO_LARGE = 413,
|
||||
HTTP_REQUESTENTITYTOOLARGE = 413, /// @deprecated
|
||||
HTTP_REQUEST_URI_TOO_LONG = 414,
|
||||
HTTP_REQUESTURITOOLONG = 414, /// @deprecated
|
||||
HTTP_UNSUPPORTED_MEDIA_TYPE = 415,
|
||||
HTTP_UNSUPPORTEDMEDIATYPE = 415, /// @deprecated
|
||||
HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416,
|
||||
HTTP_EXPECTATION_FAILED = 417,
|
||||
HTTP_IM_A_TEAPOT = 418,
|
||||
HTTP_ENCHANCE_YOUR_CALM = 420,
|
||||
HTTP_MISDIRECTED_REQUEST = 421,
|
||||
HTTP_UNPROCESSABLE_ENTITY = 422,
|
||||
HTTP_LOCKED = 423,
|
||||
HTTP_FAILED_DEPENDENCY = 424,
|
||||
HTTP_UPGRADE_REQUIRED = 426,
|
||||
HTTP_PRECONDITION_REQUIRED = 428,
|
||||
HTTP_TOO_MANY_REQUESTS = 429,
|
||||
HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
|
||||
HTTP_UNAVAILABLE_FOR_LEGAL_REASONS = 451,
|
||||
HTTP_INTERNAL_SERVER_ERROR = 500,
|
||||
HTTP_NOT_IMPLEMENTED = 501,
|
||||
HTTP_BAD_GATEWAY = 502,
|
||||
HTTP_SERVICE_UNAVAILABLE = 503,
|
||||
HTTP_GATEWAY_TIMEOUT = 504,
|
||||
HTTP_VERSION_NOT_SUPPORTED = 505
|
||||
HTTP_VERSION_NOT_SUPPORTED = 505,
|
||||
HTTP_VARIANT_ALSO_NEGOTIATES = 506,
|
||||
HTTP_INSUFFICIENT_STORAGE = 507,
|
||||
HTTP_LOOP_DETECTED = 508,
|
||||
HTTP_NOT_EXTENDED = 510,
|
||||
HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511
|
||||
};
|
||||
|
||||
HTTPResponse();
|
||||
@ -169,6 +194,7 @@ public:
|
||||
|
||||
static const std::string HTTP_REASON_CONTINUE;
|
||||
static const std::string HTTP_REASON_SWITCHING_PROTOCOLS;
|
||||
static const std::string HTTP_REASON_PROCESSING;
|
||||
static const std::string HTTP_REASON_OK;
|
||||
static const std::string HTTP_REASON_CREATED;
|
||||
static const std::string HTTP_REASON_ACCEPTED;
|
||||
@ -176,13 +202,17 @@ public:
|
||||
static const std::string HTTP_REASON_NO_CONTENT;
|
||||
static const std::string HTTP_REASON_RESET_CONTENT;
|
||||
static const std::string HTTP_REASON_PARTIAL_CONTENT;
|
||||
static const std::string HTTP_REASON_MULTI_STATUS;
|
||||
static const std::string HTTP_REASON_ALREADY_REPORTED;
|
||||
static const std::string HTTP_REASON_IM_USED;
|
||||
static const std::string HTTP_REASON_MULTIPLE_CHOICES;
|
||||
static const std::string HTTP_REASON_MOVED_PERMANENTLY;
|
||||
static const std::string HTTP_REASON_FOUND;
|
||||
static const std::string HTTP_REASON_SEE_OTHER;
|
||||
static const std::string HTTP_REASON_NOT_MODIFIED;
|
||||
static const std::string HTTP_REASON_USEPROXY;
|
||||
static const std::string HTTP_REASON_USE_PROXY;
|
||||
static const std::string HTTP_REASON_TEMPORARY_REDIRECT;
|
||||
static const std::string HTTP_REASON_PERMANENT_REDIRECT;
|
||||
static const std::string HTTP_REASON_BAD_REQUEST;
|
||||
static const std::string HTTP_REASON_UNAUTHORIZED;
|
||||
static const std::string HTTP_REASON_PAYMENT_REQUIRED;
|
||||
@ -196,17 +226,33 @@ public:
|
||||
static const std::string HTTP_REASON_GONE;
|
||||
static const std::string HTTP_REASON_LENGTH_REQUIRED;
|
||||
static const std::string HTTP_REASON_PRECONDITION_FAILED;
|
||||
static const std::string HTTP_REASON_REQUESTENTITYTOOLARGE;
|
||||
static const std::string HTTP_REASON_REQUESTURITOOLONG;
|
||||
static const std::string HTTP_REASON_UNSUPPORTEDMEDIATYPE;
|
||||
static const std::string HTTP_REASON_REQUEST_ENTITY_TOO_LARGE;
|
||||
static const std::string HTTP_REASON_REQUEST_URI_TOO_LONG;
|
||||
static const std::string HTTP_REASON_UNSUPPORTED_MEDIA_TYPE;
|
||||
static const std::string HTTP_REASON_REQUESTED_RANGE_NOT_SATISFIABLE;
|
||||
static const std::string HTTP_REASON_EXPECTATION_FAILED;
|
||||
static const std::string HTTP_REASON_IM_A_TEAPOT;
|
||||
static const std::string HTTP_REASON_ENCHANCE_YOUR_CALM;
|
||||
static const std::string HTTP_REASON_MISDIRECTED_REQUEST;
|
||||
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_UPGRADE_REQUIRED;
|
||||
static const std::string HTTP_REASON_PRECONDITION_REQUIRED;
|
||||
static const std::string HTTP_REASON_TOO_MANY_REQUESTS;
|
||||
static const std::string HTTP_REASON_REQUEST_HEADER_FIELDS_TOO_LARGE;
|
||||
static const std::string HTTP_REASON_UNAVAILABLE_FOR_LEGAL_REASONS;
|
||||
static const std::string HTTP_REASON_INTERNAL_SERVER_ERROR;
|
||||
static const std::string HTTP_REASON_NOT_IMPLEMENTED;
|
||||
static const std::string HTTP_REASON_BAD_GATEWAY;
|
||||
static const std::string HTTP_REASON_SERVICE_UNAVAILABLE;
|
||||
static const std::string HTTP_REASON_GATEWAY_TIMEOUT;
|
||||
static const std::string HTTP_REASON_VERSION_NOT_SUPPORTED;
|
||||
static const std::string HTTP_REASON_VARIANT_ALSO_NEGOTIATES;
|
||||
static const std::string HTTP_REASON_INSUFFICIENT_STORAGE;
|
||||
static const std::string HTTP_REASON_LOOP_DETECTED;
|
||||
static const std::string HTTP_REASON_NOT_EXTENDED;
|
||||
static const std::string HTTP_REASON_NETWORK_AUTHENTICATION_REQUIRED;
|
||||
static const std::string HTTP_REASON_UNKNOWN;
|
||||
|
||||
static const std::string DATE;
|
||||
|
@ -54,10 +54,6 @@ public:
|
||||
/// The stream must be valid until the HTTPServerRequest
|
||||
/// object is destroyed.
|
||||
|
||||
virtual bool expectContinue() const = 0;
|
||||
/// Returns true if the client expects a
|
||||
/// 100 Continue response.
|
||||
|
||||
virtual const SocketAddress& clientAddress() const = 0;
|
||||
/// Returns the client's address.
|
||||
|
||||
@ -69,6 +65,12 @@ public:
|
||||
|
||||
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
|
||||
/// is used, or if it is not known whether a secure
|
||||
/// connection is used.
|
||||
};
|
||||
|
||||
|
||||
|
@ -57,10 +57,6 @@ public:
|
||||
/// The stream is valid until the HTTPServerRequestImpl
|
||||
/// object is destroyed.
|
||||
|
||||
bool expectContinue() const;
|
||||
/// Returns true if the client expects a
|
||||
/// 100 Continue response.
|
||||
|
||||
const SocketAddress& clientAddress() const;
|
||||
/// Returns the client's address.
|
||||
|
||||
@ -73,6 +69,12 @@ public:
|
||||
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.
|
||||
|
||||
StreamSocket& socket();
|
||||
/// Returns a reference to the underlying socket.
|
||||
|
||||
@ -83,9 +85,6 @@ public:
|
||||
HTTPServerSession& session();
|
||||
/// Returns the underlying HTTPServerSession.
|
||||
|
||||
protected:
|
||||
static const std::string EXPECT;
|
||||
|
||||
private:
|
||||
HTTPServerResponseImpl& _response;
|
||||
HTTPServerSession& _session;
|
||||
|
@ -55,6 +55,9 @@ public:
|
||||
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.
|
||||
|
||||
@ -178,7 +181,8 @@ protected:
|
||||
private:
|
||||
enum
|
||||
{
|
||||
HTTP_DEFAULT_TIMEOUT = 60000000
|
||||
HTTP_DEFAULT_TIMEOUT = 60000000,
|
||||
HTTP_DEFAULT_CONNECTION_TIMEOUT = 30000000
|
||||
};
|
||||
|
||||
HTTPSession(const HTTPSession&);
|
||||
@ -189,7 +193,9 @@ private:
|
||||
char* _pCurrent;
|
||||
char* _pEnd;
|
||||
bool _keepAlive;
|
||||
Poco::Timespan _timeout;
|
||||
Poco::Timespan _connectionTimeout;
|
||||
Poco::Timespan _receiveTimeout;
|
||||
Poco::Timespan _sendTimeout;
|
||||
Poco::Exception* _pException;
|
||||
Poco::Any _data;
|
||||
|
||||
@ -211,7 +217,7 @@ inline bool HTTPSession::getKeepAlive() const
|
||||
|
||||
inline Poco::Timespan HTTPSession::getTimeout() const
|
||||
{
|
||||
return _timeout;
|
||||
return _receiveTimeout;
|
||||
}
|
||||
|
||||
|
||||
|
@ -44,7 +44,7 @@ public:
|
||||
mutable Poco::BasicEvent<ICMPEventArgs> pingError;
|
||||
mutable Poco::BasicEvent<ICMPEventArgs> pingEnd;
|
||||
|
||||
explicit ICMPClient(IPAddress::Family family);
|
||||
explicit ICMPClient(SocketAddress::Family family);
|
||||
/// Creates an ICMP client.
|
||||
|
||||
~ICMPClient();
|
||||
@ -62,7 +62,7 @@ public:
|
||||
///
|
||||
/// Returns the number of valid replies.
|
||||
|
||||
static int ping(SocketAddress& address, IPAddress::Family family, int repeat = 1);
|
||||
static int ping(SocketAddress& address, SocketAddress::Family family, int repeat = 1);
|
||||
/// Pings the specified address [repeat] times.
|
||||
/// Notifications are not posted for events.
|
||||
///
|
||||
@ -75,7 +75,7 @@ public:
|
||||
/// Returns the number of valid replies.
|
||||
|
||||
private:
|
||||
mutable IPAddress::Family _family;
|
||||
mutable SocketAddress::Family _family;
|
||||
};
|
||||
|
||||
|
||||
|
@ -31,7 +31,7 @@ class Net_API ICMPPacket
|
||||
/// This class is the ICMP packet abstraction.
|
||||
{
|
||||
public:
|
||||
ICMPPacket(IPAddress::Family family, int dataSize = 48);
|
||||
ICMPPacket(SocketAddress::Family family, int dataSize = 48);
|
||||
/// Creates an ICMPPacket of specified family.
|
||||
|
||||
~ICMPPacket();
|
||||
|
@ -31,7 +31,7 @@ class Net_API ICMPSocket: public Socket
|
||||
/// ICMP client socket.
|
||||
{
|
||||
public:
|
||||
ICMPSocket(IPAddress::Family family, int dataSize = 48, int ttl = 128, int timeout = 5000000);
|
||||
ICMPSocket(SocketAddress::Family family, int dataSize = 48, int ttl = 128, int timeout = 5000000);
|
||||
/// Creates an unconnected ICMP socket.
|
||||
///
|
||||
/// The socket will be created for the
|
||||
|
@ -32,7 +32,7 @@ class Net_API ICMPSocketImpl: public RawSocketImpl
|
||||
/// This class implements an ICMP socket.
|
||||
{
|
||||
public:
|
||||
ICMPSocketImpl(IPAddress::Family family, int dataSize, int ttl, int timeout);
|
||||
ICMPSocketImpl(SocketAddress::Family family, int dataSize, int ttl, int timeout);
|
||||
/// Creates an unconnected ICMP socket.
|
||||
///
|
||||
/// The socket will be created for the given address family.
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "Poco/AutoPtr.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include <vector>
|
||||
#include <ostream>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
@ -55,14 +56,14 @@ class Net_API IPAddress
|
||||
public:
|
||||
typedef std::vector<IPAddress> List;
|
||||
|
||||
enum Family
|
||||
/// Possible address families for IP addresses.
|
||||
{
|
||||
IPv4 = Poco::Net::Impl::IPAddressImpl::IPv4
|
||||
#ifdef POCO_HAVE_IPv6
|
||||
,IPv6 = Poco::Net::Impl::IPAddressImpl::IPv6
|
||||
// The following declarations keep the Family type
|
||||
// backwards compatible with the previously used
|
||||
// enum declaration.
|
||||
typedef AddressFamily::Family Family;
|
||||
static const Family IPv4 = AddressFamily::IPv4;
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
static const Family IPv6 = AddressFamily::IPv6;
|
||||
#endif
|
||||
};
|
||||
|
||||
IPAddress();
|
||||
/// Creates a wildcard (zero) IPv4 IPAddress.
|
||||
@ -371,13 +372,15 @@ private:
|
||||
#endif
|
||||
|
||||
Ptr pImpl() const;
|
||||
void newIPv4();
|
||||
void newIPv4(const void* hostAddr);
|
||||
void newIPv4(unsigned prefix);
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
void newIPv6();
|
||||
void newIPv6(const void* hostAddr);
|
||||
void newIPv6(const void* hostAddr, Poco::UInt32 scope);
|
||||
void newIPv4(unsigned prefix);
|
||||
void newIPv6(unsigned prefix);
|
||||
void newIPv4();
|
||||
void newIPv6();
|
||||
#endif
|
||||
void destruct();
|
||||
|
||||
#ifdef POCO_HAVE_ALIGNMENT
|
||||
@ -394,7 +397,11 @@ private:
|
||||
AlignerType aligner;
|
||||
}
|
||||
#else // !POCO_ENABLE_CPP11
|
||||
AlignedCharArrayUnion <Poco::Net::Impl::IPv6AddressImpl>
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
AlignedCharArrayUnion <Poco::Net::Impl::IPv6AddressImpl>
|
||||
#else
|
||||
AlignedCharArrayUnion <Poco::Net::Impl::IPv4AddressImpl>
|
||||
#endif
|
||||
#endif // POCO_ENABLE_CPP11
|
||||
_memory;
|
||||
#else // !POCO_HAVE_ALIGNMENT
|
||||
@ -406,6 +413,8 @@ private:
|
||||
//
|
||||
// inlines
|
||||
//
|
||||
|
||||
|
||||
inline void IPAddress::destruct()
|
||||
{
|
||||
#ifdef POCO_HAVE_ALIGNMENT
|
||||
@ -425,6 +434,16 @@ inline IPAddress::Ptr IPAddress::pImpl() const
|
||||
}
|
||||
|
||||
|
||||
inline void IPAddress::newIPv4()
|
||||
{
|
||||
#ifdef POCO_HAVE_ALIGNMENT
|
||||
new (storage()) Poco::Net::Impl::IPv4AddressImpl;
|
||||
#else
|
||||
_pImpl = new Poco::Net::Impl::IPv4AddressImpl;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
inline void IPAddress::newIPv4(const void* hostAddr)
|
||||
{
|
||||
#ifdef POCO_HAVE_ALIGNMENT
|
||||
@ -435,6 +454,29 @@ inline void IPAddress::newIPv4(const void* hostAddr)
|
||||
}
|
||||
|
||||
|
||||
inline void IPAddress::newIPv4(unsigned prefix)
|
||||
{
|
||||
#ifdef POCO_HAVE_ALIGNMENT
|
||||
new (storage()) Poco::Net::Impl::IPv4AddressImpl(prefix);
|
||||
#else
|
||||
_pImpl = new Poco::Net::Impl::IPv4AddressImpl(prefix);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
|
||||
|
||||
inline void IPAddress::newIPv6()
|
||||
{
|
||||
#ifdef POCO_HAVE_ALIGNMENT
|
||||
new (storage()) Poco::Net::Impl::IPv6AddressImpl;
|
||||
#else
|
||||
_pImpl = new Poco::Net::Impl::IPv6AddressImpl;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
inline void IPAddress::newIPv6(const void* hostAddr)
|
||||
{
|
||||
#ifdef POCO_HAVE_ALIGNMENT
|
||||
@ -455,16 +497,6 @@ inline void IPAddress::newIPv6(const void* hostAddr, Poco::UInt32 scope)
|
||||
}
|
||||
|
||||
|
||||
inline void IPAddress::newIPv4(unsigned prefix)
|
||||
{
|
||||
#ifdef POCO_HAVE_ALIGNMENT
|
||||
new (storage()) Poco::Net::Impl::IPv4AddressImpl(prefix);
|
||||
#else
|
||||
_pImpl = new Poco::Net::Impl::IPv4AddressImpl(prefix);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
inline void IPAddress::newIPv6(unsigned prefix)
|
||||
{
|
||||
#ifdef POCO_HAVE_ALIGNMENT
|
||||
@ -475,24 +507,7 @@ inline void IPAddress::newIPv6(unsigned prefix)
|
||||
}
|
||||
|
||||
|
||||
inline void IPAddress::newIPv4()
|
||||
{
|
||||
#ifdef POCO_HAVE_ALIGNMENT
|
||||
new (storage()) Poco::Net::Impl::IPv4AddressImpl;
|
||||
#else
|
||||
_pImpl = new Poco::Net::Impl::IPv4AddressImpl;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
inline void IPAddress::newIPv6()
|
||||
{
|
||||
#ifdef POCO_HAVE_ALIGNMENT
|
||||
new (storage()) Poco::Net::Impl::IPv6AddressImpl;
|
||||
#else
|
||||
_pImpl = new Poco::Net::Impl::IPv6AddressImpl;
|
||||
#endif
|
||||
}
|
||||
#endif // POCO_HAVE_IPv6
|
||||
|
||||
|
||||
#ifdef POCO_HAVE_ALIGNMENT
|
||||
@ -503,11 +518,12 @@ inline char* IPAddress::storage()
|
||||
#endif
|
||||
|
||||
|
||||
BinaryWriter& operator << (BinaryWriter& writer, const IPAddress& value);
|
||||
BinaryReader& operator >> (BinaryReader& reader, IPAddress& value);
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
||||
|
||||
|
||||
Net_API Poco::BinaryWriter& operator << (Poco::BinaryWriter& writer, const Poco::Net::IPAddress& value);
|
||||
Net_API Poco::BinaryReader& operator >> (Poco::BinaryReader& reader, Poco::Net::IPAddress& value);
|
||||
Net_API std::ostream& operator << (std::ostream& ostr, const Poco::Net::IPAddress& addr);
|
||||
|
||||
|
||||
#endif // Net_IPAddress_INCLUDED
|
||||
|
@ -37,14 +37,7 @@ class IPAddressImpl
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
enum Family
|
||||
/// Possible address families for IP addresses.
|
||||
{
|
||||
IPv4
|
||||
#ifdef POCO_HAVE_IPv6
|
||||
,IPv6
|
||||
#endif
|
||||
};
|
||||
typedef AddressFamily::Family Family;
|
||||
|
||||
virtual ~IPAddressImpl();
|
||||
|
||||
@ -129,6 +122,9 @@ private:
|
||||
};
|
||||
|
||||
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
|
||||
|
||||
//
|
||||
// IPv6AddressImpl
|
||||
//
|
||||
@ -179,6 +175,9 @@ private:
|
||||
};
|
||||
|
||||
|
||||
#endif // POCO_HAVE_IPv6
|
||||
|
||||
|
||||
} } } // namespace Poco::Net::Impl
|
||||
|
||||
|
||||
|
@ -145,6 +145,11 @@ public:
|
||||
/// 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
|
||||
|
@ -39,9 +39,16 @@ class Net_API MulticastSocket: public DatagramSocket
|
||||
{
|
||||
public:
|
||||
MulticastSocket();
|
||||
/// Creates the multicast socket.
|
||||
/// Creates an unconnected, unbound multicast socket.
|
||||
///
|
||||
/// Before the multicast socket can be used, bind(),
|
||||
/// bind6() or connect() must be called.
|
||||
///
|
||||
/// Notice: The behavior of this constructor has changed
|
||||
/// in release 2.0. Previously, the constructor created
|
||||
/// an unbound IPv4 multicast socket.
|
||||
|
||||
explicit MulticastSocket(IPAddress::Family family);
|
||||
explicit MulticastSocket(SocketAddress::Family family);
|
||||
/// Creates an unconnected datagram socket.
|
||||
///
|
||||
/// The socket will be created for the
|
||||
|
@ -34,7 +34,7 @@ class Net_API NTPClient
|
||||
public:
|
||||
mutable Poco::BasicEvent<NTPEventArgs> response;
|
||||
|
||||
explicit NTPClient(IPAddress::Family family, int timeout = 3000000);
|
||||
explicit NTPClient(SocketAddress::Family family, int timeout = 3000000);
|
||||
/// Creates an NTP client.
|
||||
|
||||
~NTPClient();
|
||||
@ -53,7 +53,7 @@ public:
|
||||
/// Returns the number of valid replies.
|
||||
|
||||
private:
|
||||
mutable IPAddress::Family _family;
|
||||
mutable SocketAddress::Family _family;
|
||||
int _timeout;
|
||||
};
|
||||
|
||||
|
@ -51,6 +51,7 @@ POCO_DECLARE_EXCEPTION(Net_API, NTPException, NetException)
|
||||
POCO_DECLARE_EXCEPTION(Net_API, HTMLFormException, NetException)
|
||||
POCO_DECLARE_EXCEPTION(Net_API, WebSocketException, NetException)
|
||||
POCO_DECLARE_EXCEPTION(Net_API, UnsupportedFamilyException, NetException)
|
||||
POCO_DECLARE_EXCEPTION(Net_API, AddressFamilyMismatchException, NetException)
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
||||
|
@ -248,8 +248,7 @@ public:
|
||||
/// Returns the NetworkInterface for the given interface index.
|
||||
///
|
||||
/// Throws an InterfaceNotFoundException if an interface
|
||||
/// with the given index does not exist (or IPv6 is not
|
||||
/// available).
|
||||
/// with the given index does not exist.
|
||||
|
||||
static List list(bool ipOnly = true, bool upOnly = true);
|
||||
/// Returns a list with all network interfaces
|
||||
|
@ -34,7 +34,7 @@ public:
|
||||
RawSocket();
|
||||
/// Creates an unconnected IPv4 raw socket.
|
||||
|
||||
RawSocket(IPAddress::Family family, int proto = IPPROTO_RAW);
|
||||
RawSocket(SocketAddress::Family family, int proto = IPPROTO_RAW);
|
||||
/// Creates an unconnected raw socket.
|
||||
///
|
||||
/// The socket will be created for the
|
||||
@ -80,6 +80,20 @@ public:
|
||||
///
|
||||
/// Calls to connect() cannot come before calls to bind().
|
||||
|
||||
void bind(const SocketAddress& address, bool reuseAddress, bool reusePort);
|
||||
/// 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.
|
||||
///
|
||||
/// 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.
|
||||
|
@ -33,7 +33,7 @@ public:
|
||||
RawSocketImpl();
|
||||
/// Creates an unconnected IPv4 raw socket with IPPROTO_RAW.
|
||||
|
||||
RawSocketImpl(IPAddress::Family family, int proto = IPPROTO_RAW);
|
||||
RawSocketImpl(SocketAddress::Family family, int proto = IPPROTO_RAW);
|
||||
/// Creates an unconnected raw socket.
|
||||
///
|
||||
/// The socket will be created for the
|
||||
|
@ -80,6 +80,19 @@ public:
|
||||
/// If reuseAddress is true, sets the SO_REUSEADDR
|
||||
/// socket option.
|
||||
|
||||
virtual void bind(const SocketAddress& address, bool reuseAddress, bool reusePort);
|
||||
/// Binds a local address to the socket.
|
||||
///
|
||||
/// This is usually only done when establishing a server
|
||||
/// socket. TCP clients should not bind a socket to a
|
||||
/// specific address.
|
||||
///
|
||||
/// If reuseAddress is true, sets the SO_REUSEADDR
|
||||
/// socket option.
|
||||
///
|
||||
/// If reuseAddress is true, sets the SO_REUSEPORT
|
||||
/// socket option.
|
||||
|
||||
virtual void bind(Poco::UInt16 port, bool reuseAddress = false);
|
||||
/// Binds a local port to the socket.
|
||||
///
|
||||
@ -89,6 +102,18 @@ public:
|
||||
/// If reuseAddress is true, sets the SO_REUSEADDR
|
||||
/// socket option.
|
||||
|
||||
virtual void bind(Poco::UInt16 port, bool reuseAddress, bool reusePort);
|
||||
/// Binds a local port 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.
|
||||
|
||||
virtual void bind6(const SocketAddress& address, bool reuseAddress = false, bool ipV6Only = false);
|
||||
/// Binds a local IPv6 address to the socket.
|
||||
///
|
||||
@ -106,6 +131,26 @@ public:
|
||||
/// If the library has not been built with IPv6 support,
|
||||
/// a Poco::NotImplementedException will be thrown.
|
||||
|
||||
virtual void bind6(const SocketAddress& address, bool reuseAddress, bool reusePort, bool ipV6Only);
|
||||
/// Binds a local IPv6 address to the socket.
|
||||
///
|
||||
/// This is usually only done when establishing a server
|
||||
/// socket. TCP clients should not bind a socket to a
|
||||
/// specific address.
|
||||
///
|
||||
/// If reuseAddress is true, sets the SO_REUSEADDR
|
||||
/// socket option.
|
||||
///
|
||||
/// If reusePort is true, sets the SO_REUSEPORT
|
||||
/// socket option.
|
||||
///
|
||||
/// The given address must be an IPv6 address. The
|
||||
/// IPPROTO_IPV6/IPV6_V6ONLY option is set on the socket
|
||||
/// according to the ipV6Only parameter.
|
||||
///
|
||||
/// If the library has not been built with IPv6 support,
|
||||
/// a Poco::NotImplementedException will be thrown.
|
||||
|
||||
virtual void bind6(Poco::UInt16 port, bool reuseAddress = false, bool ipV6Only = false);
|
||||
/// Binds a local IPv6 port to the socket.
|
||||
///
|
||||
@ -122,6 +167,24 @@ 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.
|
||||
///
|
||||
/// If reuseAddress is true, sets the SO_REUSEADDR
|
||||
/// socket option.
|
||||
///
|
||||
/// If reusePort is true, sets the SO_REUSEPORT
|
||||
/// socket option.
|
||||
/// The given address must be an IPv6 address. The
|
||||
/// IPPROTO_IPV6/IPV6_V6ONLY option is set on the socket
|
||||
/// according to the ipV6Only parameter.
|
||||
///
|
||||
/// If the library has not been built with IPv6 support,
|
||||
/// a Poco::NotImplementedException will be thrown.
|
||||
|
||||
virtual void listen(int backlog = 64);
|
||||
/// Puts the socket into listening state.
|
||||
///
|
||||
|
@ -20,9 +20,14 @@
|
||||
|
||||
#include "Poco/Net/Net.h"
|
||||
#include "Poco/Net/SocketAddressImpl.h"
|
||||
#include <ostream>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
class BinaryReader;
|
||||
class BinaryWriter;
|
||||
|
||||
namespace Net {
|
||||
|
||||
|
||||
@ -36,9 +41,25 @@ class Net_API SocketAddress
|
||||
/// host address and a port number.
|
||||
{
|
||||
public:
|
||||
// The following declarations keep the Family type
|
||||
// backwards compatible with the previously used
|
||||
// enum declaration.
|
||||
typedef AddressFamily::Family Family;
|
||||
static const Family IPv4 = AddressFamily::IPv4;
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
static const Family IPv6 = AddressFamily::IPv6;
|
||||
#endif
|
||||
#if defined(POCO_OS_FAMILY_UNIX)
|
||||
static const Family UNIX_LOCAL = AddressFamily::UNIX_LOCAL;
|
||||
#endif
|
||||
|
||||
SocketAddress();
|
||||
/// Creates a wildcard (all zero) IPv4 SocketAddress.
|
||||
|
||||
explicit SocketAddress(Family family);
|
||||
/// Creates a SocketAddress with unspecified (wildcard) IP address
|
||||
/// of the given family.
|
||||
|
||||
SocketAddress(const IPAddress& hostAddress, Poco::UInt16 portNumber);
|
||||
/// Creates a SocketAddress from an IP address and given port number.
|
||||
|
||||
@ -46,12 +67,27 @@ public:
|
||||
/// Creates a SocketAddress with unspecified (wildcard) IP address
|
||||
/// and given port number.
|
||||
|
||||
SocketAddress(Family family, Poco::UInt16 port);
|
||||
/// Creates a SocketAddress with unspecified (wildcard) IP address
|
||||
/// of the given family, and given port number.
|
||||
|
||||
SocketAddress(const std::string& hostAddress, Poco::UInt16 portNumber);
|
||||
/// Creates a SocketAddress from an IP address and given port number.
|
||||
///
|
||||
/// The IP address must either be a domain name, or it must
|
||||
/// be in dotted decimal (IPv4) or hex string (IPv6) format.
|
||||
|
||||
SocketAddress(Family family, const std::string& hostAddress, Poco::UInt16 portNumber);
|
||||
/// Creates a SocketAddress from an IP address and given port number.
|
||||
///
|
||||
/// The IP address must either be a domain name, or it must
|
||||
/// be in dotted decimal (IPv4) or hex string (IPv6) format.
|
||||
///
|
||||
/// If a domain name is given in hostAddress, it is resolved and the address
|
||||
/// matching the given family is used. If no address matching the given family
|
||||
/// is found, or the IP address given in hostAddress does not match the given
|
||||
/// family, an AddressFamilyMismatchException is thrown.
|
||||
|
||||
SocketAddress(const std::string& hostAddress, const std::string& portNumber);
|
||||
/// Creates a SocketAddress from an IP address and the
|
||||
/// service name or port number.
|
||||
@ -62,6 +98,21 @@ public:
|
||||
/// The given port must either be a decimal port number, or
|
||||
/// a service name.
|
||||
|
||||
SocketAddress(Family family, const std::string& hostAddress, const std::string& portNumber);
|
||||
/// Creates a SocketAddress from an IP address and the
|
||||
/// service name or port number.
|
||||
///
|
||||
/// The IP address must either be a domain name, or it must
|
||||
/// be in dotted decimal (IPv4) or hex string (IPv6) format.
|
||||
///
|
||||
/// The given port must either be a decimal port number, or
|
||||
/// a service name.
|
||||
///
|
||||
/// If a domain name is given in hostAddress, it is resolved and the address
|
||||
/// matching the given family is used. If no address matching the given family
|
||||
/// is found, or the IP address given in hostAddress does not match the given
|
||||
/// family, an AddressFamilyMismatchException is thrown.
|
||||
|
||||
explicit SocketAddress(const std::string& hostAndPort);
|
||||
/// Creates a SocketAddress from an IP address or host name and the
|
||||
/// port number/service name. Host name/address and port number must
|
||||
@ -72,6 +123,17 @@ public:
|
||||
/// 192.168.1.10:80
|
||||
/// [::ffff:192.168.1.120]:2040
|
||||
/// www.appinf.com:8080
|
||||
///
|
||||
/// On POSIX platforms supporting UNIX_LOCAL sockets, hostAndPort
|
||||
/// can also be the absolute path of a local socket, starting with a
|
||||
/// slash, e.g. "/tmp/local.socket".
|
||||
|
||||
SocketAddress(Family family, const std::string& addr);
|
||||
/// Creates a SocketAddress of the given family from a
|
||||
/// string representation of the address, which is
|
||||
/// either an IP address and port number, separated by
|
||||
/// a colon for IPv4 or IPv6 addresses, or a path for
|
||||
/// UNIX_LOCAL sockets.
|
||||
|
||||
SocketAddress(const SocketAddress& addr);
|
||||
/// Creates a SocketAddress by copying another one.
|
||||
@ -103,7 +165,7 @@ public:
|
||||
std::string toString() const;
|
||||
/// Returns a string representation of the address.
|
||||
|
||||
IPAddress::Family family() const;
|
||||
Family family() const;
|
||||
/// Returns the address family of the host's address.
|
||||
|
||||
bool operator < (const SocketAddress& socketAddress) const;
|
||||
@ -113,7 +175,9 @@ public:
|
||||
enum
|
||||
{
|
||||
MAX_ADDRESS_LENGTH =
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
#if defined(POCO_OS_FAMILY_UNIX)
|
||||
sizeof(struct sockaddr_un)
|
||||
#elif defined(POCO_HAVE_IPv6)
|
||||
sizeof(struct sockaddr_in6)
|
||||
#else
|
||||
sizeof(struct sockaddr_in)
|
||||
@ -124,6 +188,9 @@ public:
|
||||
protected:
|
||||
void init(const IPAddress& hostAddress, Poco::UInt16 portNumber);
|
||||
void init(const std::string& hostAddress, Poco::UInt16 portNumber);
|
||||
void init(Family family, const std::string& hostAddress, Poco::UInt16 portNumber);
|
||||
void init(Family family, const std::string& address);
|
||||
void init(const std::string& hostAndPort);
|
||||
Poco::UInt16 resolveService(const std::string& service);
|
||||
|
||||
private:
|
||||
@ -137,14 +204,18 @@ private:
|
||||
Ptr pImpl() const;
|
||||
|
||||
void newIPv4();
|
||||
|
||||
void newIPv4(const sockaddr_in*);
|
||||
|
||||
void newIPv4(const IPAddress& hostAddress, Poco::UInt16 portNumber);
|
||||
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
void newIPv6(const sockaddr_in6*);
|
||||
|
||||
void newIPv6(const IPAddress& hostAddress, Poco::UInt16 portNumber);
|
||||
#endif
|
||||
|
||||
#if defined(POCO_OS_FAMILY_UNIX)
|
||||
void newLocal(const sockaddr_un* sockAddr);
|
||||
void newLocal(const std::string& path);
|
||||
#endif
|
||||
|
||||
void destruct();
|
||||
|
||||
@ -161,7 +232,11 @@ private:
|
||||
AlignerType aligner;
|
||||
}
|
||||
#else // !POCO_ENABLE_CPP11
|
||||
AlignedCharArrayUnion <Poco::Net::Impl::IPv6SocketAddressImpl>
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
AlignedCharArrayUnion <Poco::Net::Impl::IPv6SocketAddressImpl>
|
||||
#else
|
||||
AlignedCharArrayUnion <Poco::Net::Impl::IPv4SocketAddressImpl>
|
||||
#endif
|
||||
#endif // POCO_ENABLE_CPP11
|
||||
_memory;
|
||||
#else // !POCO_HAVE_ALIGNMENT
|
||||
@ -224,7 +299,7 @@ inline void SocketAddress::newIPv4(const IPAddress& hostAddress, Poco::UInt16 po
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
inline void SocketAddress::newIPv6(const sockaddr_in6* sockAddr)
|
||||
{
|
||||
#ifdef POCO_HAVE_ALIGNMENT
|
||||
@ -243,14 +318,31 @@ inline void SocketAddress::newIPv6(const IPAddress& hostAddress, Poco::UInt16 po
|
||||
_pImpl = new Poco::Net::Impl::IPv6SocketAddressImpl(hostAddress.addr(), htons(portNumber), hostAddress.scope());
|
||||
#endif
|
||||
}
|
||||
#endif // POCO_HAVE_IPv6
|
||||
|
||||
|
||||
inline IPAddress::Family SocketAddress::family() const
|
||||
#if defined(POCO_OS_FAMILY_UNIX)
|
||||
inline void SocketAddress::newLocal(const sockaddr_un* sockAddr)
|
||||
{
|
||||
return host().family();
|
||||
#ifdef POCO_HAVE_ALIGNMENT
|
||||
new (storage()) Poco::Net::Impl::LocalSocketAddressImpl(sockAddr);
|
||||
#else
|
||||
_pImpl = new Poco::Net::Impl::LocalSocketAddressImpl(sockAddr);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
inline void SocketAddress::newLocal(const std::string& path)
|
||||
{
|
||||
#ifdef POCO_HAVE_ALIGNMENT
|
||||
new (storage()) Poco::Net::Impl::LocalSocketAddressImpl(path.c_str());
|
||||
#else
|
||||
_pImpl = new Poco::Net::Impl::LocalSocketAddressImpl(path.c_str());
|
||||
#endif
|
||||
}
|
||||
#endif // POCO_OS_FAMILY_UNIX
|
||||
|
||||
|
||||
#ifdef POCO_HAVE_ALIGNMENT
|
||||
inline char* SocketAddress::storage()
|
||||
{
|
||||
@ -259,19 +351,29 @@ inline char* SocketAddress::storage()
|
||||
#endif
|
||||
|
||||
|
||||
inline bool SocketAddress::operator == (const SocketAddress& socketAddress) const
|
||||
inline bool SocketAddress::operator == (const SocketAddress& socketAddress) const
|
||||
{
|
||||
return host() == socketAddress.host() && port() == socketAddress.port();
|
||||
#if defined(POCO_OS_FAMILY_UNIX)
|
||||
if (family() == UNIX_LOCAL)
|
||||
return toString() == socketAddress.toString();
|
||||
else
|
||||
#endif
|
||||
return host() == socketAddress.host() && port() == socketAddress.port();
|
||||
}
|
||||
|
||||
|
||||
inline bool SocketAddress::operator != (const SocketAddress& socketAddress) const
|
||||
{
|
||||
return host() != socketAddress.host() || port() != socketAddress.port();
|
||||
return !(operator == (socketAddress));
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
||||
|
||||
|
||||
Net_API Poco::BinaryWriter& operator << (Poco::BinaryWriter& writer, const Poco::Net::SocketAddress& value);
|
||||
Net_API Poco::BinaryReader& operator >> (Poco::BinaryReader& reader, Poco::Net::SocketAddress& value);
|
||||
Net_API std::ostream& operator << (std::ostream& ostr, const Poco::Net::SocketAddress& address);
|
||||
|
||||
|
||||
#endif // Net_SocketAddress_INCLUDED
|
||||
|
@ -37,6 +37,8 @@ class Net_API SocketAddressImpl
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
typedef AddressFamily::Family Family;
|
||||
|
||||
virtual ~SocketAddressImpl();
|
||||
|
||||
virtual IPAddress host() const = 0;
|
||||
@ -44,6 +46,8 @@ public:
|
||||
virtual poco_socklen_t length() const = 0;
|
||||
virtual const struct sockaddr* addr() const = 0;
|
||||
virtual int af() const = 0;
|
||||
virtual Family family() const = 0;
|
||||
virtual std::string toString() const = 0;
|
||||
|
||||
protected:
|
||||
SocketAddressImpl();
|
||||
@ -65,7 +69,7 @@ public:
|
||||
poco_socklen_t length() const;
|
||||
const struct sockaddr* addr() const;
|
||||
int af() const;
|
||||
IPAddress::Family family() const;
|
||||
Family family() const;
|
||||
std::string toString() const;
|
||||
|
||||
private:
|
||||
@ -107,6 +111,12 @@ inline int IPv4SocketAddressImpl::af() const
|
||||
}
|
||||
|
||||
|
||||
inline SocketAddressImpl::Family IPv4SocketAddressImpl::family() const
|
||||
{
|
||||
return AddressFamily::IPv4;
|
||||
}
|
||||
|
||||
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
|
||||
|
||||
@ -121,6 +131,8 @@ public:
|
||||
poco_socklen_t length() const;
|
||||
const struct sockaddr* addr() const;
|
||||
int af() const;
|
||||
Family family() const;
|
||||
std::string toString() const;
|
||||
|
||||
private:
|
||||
struct sockaddr_in6 _addr;
|
||||
@ -161,7 +173,87 @@ inline int IPv6SocketAddressImpl::af() const
|
||||
}
|
||||
|
||||
|
||||
#endif //POCO_HAVE_IPv6
|
||||
inline SocketAddressImpl::Family IPv6SocketAddressImpl::family() const
|
||||
{
|
||||
return AddressFamily::IPv6;
|
||||
}
|
||||
|
||||
|
||||
#endif // POCO_HAVE_IPv6
|
||||
|
||||
|
||||
#if defined(POCO_OS_FAMILY_UNIX)
|
||||
|
||||
|
||||
class Net_API LocalSocketAddressImpl: public SocketAddressImpl
|
||||
{
|
||||
public:
|
||||
LocalSocketAddressImpl(const struct sockaddr_un* addr);
|
||||
LocalSocketAddressImpl(const char* path);
|
||||
~LocalSocketAddressImpl();
|
||||
IPAddress host() const;
|
||||
UInt16 port() const;
|
||||
poco_socklen_t length() const;
|
||||
const struct sockaddr* addr() const;
|
||||
int af() const;
|
||||
Family family() const;
|
||||
const char* path() const;
|
||||
std::string toString() const;
|
||||
|
||||
private:
|
||||
struct sockaddr_un* _pAddr;
|
||||
// Note: We allocate struct sockaddr_un on the heap, otherwise we would
|
||||
// waste a lot of memory due to small object optimization in SocketAddress.
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// inlines
|
||||
//
|
||||
|
||||
inline IPAddress LocalSocketAddressImpl::host() const
|
||||
{
|
||||
throw Poco::InvalidAccessException("local socket address does not have host IP address");
|
||||
}
|
||||
|
||||
|
||||
inline UInt16 LocalSocketAddressImpl::port() const
|
||||
{
|
||||
throw Poco::InvalidAccessException("local socket address does not have port number");
|
||||
}
|
||||
|
||||
|
||||
inline poco_socklen_t LocalSocketAddressImpl::length() const
|
||||
{
|
||||
return sizeof(struct sockaddr_un);
|
||||
}
|
||||
|
||||
|
||||
inline const struct sockaddr* LocalSocketAddressImpl::addr() const
|
||||
{
|
||||
return reinterpret_cast<const struct sockaddr*>(_pAddr);
|
||||
}
|
||||
|
||||
|
||||
inline int LocalSocketAddressImpl::af() const
|
||||
{
|
||||
return _pAddr->sun_family;
|
||||
}
|
||||
|
||||
|
||||
inline SocketAddressImpl::Family LocalSocketAddressImpl::family() const
|
||||
{
|
||||
return AddressFamily::UNIX_LOCAL;
|
||||
}
|
||||
|
||||
|
||||
inline const char* LocalSocketAddressImpl::path() const
|
||||
{
|
||||
return _pAddr->sun_path;
|
||||
}
|
||||
|
||||
|
||||
#endif // POCO_OS_FAMILY_UNIX
|
||||
|
||||
|
||||
} } } // namespace Poco::Net::Impl
|
||||
|
@ -132,6 +132,7 @@
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <fcntl.h>
|
||||
#if POCO_OS != POCO_OS_HPUX
|
||||
#include <sys/select.h>
|
||||
@ -269,15 +270,19 @@
|
||||
|
||||
|
||||
#if defined(POCO_HAVE_SALEN)
|
||||
#define poco_set_sa_len(pSA, len) (pSA)->sa_len = (len)
|
||||
#define poco_set_sin_len(pSA) (pSA)->sin_len = sizeof(struct sockaddr_in)
|
||||
#define poco_set_sa_len(pSA, len) (pSA)->sa_len = (len)
|
||||
#define poco_set_sin_len(pSA) (pSA)->sin_len = sizeof(struct sockaddr_in)
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
#define poco_set_sin6_len(pSA) (pSA)->sin6_len = sizeof(struct sockaddr_in6)
|
||||
#endif
|
||||
#if defined(POCO_OS_FAMILY_UNIX)
|
||||
#define poco_set_sun_len(pSA, len) (pSA)->sun_len = (len)
|
||||
#endif
|
||||
#else
|
||||
#define poco_set_sa_len(pSA, len) (void) 0
|
||||
#define poco_set_sin_len(pSA) (void) 0
|
||||
#define poco_set_sin6_len(pSA) (void) 0
|
||||
#define poco_set_sa_len(pSA, len) (void) 0
|
||||
#define poco_set_sin_len(pSA) (void) 0
|
||||
#define poco_set_sin6_len(pSA) (void) 0
|
||||
#define poco_set_sun_len(pSA, len) (void) 0
|
||||
#endif
|
||||
|
||||
|
||||
@ -346,4 +351,32 @@
|
||||
#endif
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
struct AddressFamily
|
||||
/// AddressFamily::Family replaces the previously used IPAddress::Family
|
||||
/// enumeration and is now used for IPAddress::Family and SocketAddress::Family.
|
||||
{
|
||||
enum Family
|
||||
/// Possible address families for socket addresses.
|
||||
{
|
||||
IPv4,
|
||||
/// IPv4 address family.
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
IPv6,
|
||||
/// IPv6 address family.
|
||||
#endif
|
||||
#if defined(POCO_OS_FAMILY_UNIX)
|
||||
UNIX_LOCAL
|
||||
/// UNIX domain socket address family. Available on UNIX/POSIX platforms only.
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
||||
|
||||
|
||||
#endif // Net_SocketDefs_INCLUDED
|
||||
|
@ -84,6 +84,19 @@ public:
|
||||
/// If reuseAddress is true, sets the SO_REUSEADDR
|
||||
/// socket option.
|
||||
|
||||
virtual void bind(const SocketAddress& address, bool reuseAddress, bool reusePort );
|
||||
/// Bind a local address to the socket.
|
||||
///
|
||||
/// This is usually only done when establishing a server
|
||||
/// socket. TCP clients should not bind a socket to a
|
||||
/// specific address.
|
||||
///
|
||||
/// If reuseAddress is true, sets the SO_REUSEADDR
|
||||
/// socket option.
|
||||
///
|
||||
/// If reusePort is true, sets the SO_REUSEPORT
|
||||
/// socket option.
|
||||
|
||||
virtual void bind6(const SocketAddress& address, bool reuseAddress = false, bool ipV6Only = false);
|
||||
/// Bind a local IPv6 address to the socket.
|
||||
///
|
||||
@ -101,6 +114,26 @@ public:
|
||||
/// If the library has not been built with IPv6 support,
|
||||
/// a Poco::NotImplementedException will be thrown.
|
||||
|
||||
virtual void bind6(const SocketAddress& address, bool reuseAddress, bool reusePort, bool ipV6Only);
|
||||
/// Bind a local IPv6 address to the socket.
|
||||
///
|
||||
/// This is usually only done when establishing a server
|
||||
/// socket. TCP clients should not bind a socket to a
|
||||
/// specific address.
|
||||
///
|
||||
/// If reuseAddress is true, sets the SO_REUSEADDR
|
||||
/// socket option.
|
||||
///
|
||||
/// If reusePort is true, sets the SO_REUSEPORT
|
||||
/// socket option.
|
||||
///
|
||||
/// The given address must be an IPv6 address. The
|
||||
/// IPPROTO_IPV6/IPV6_V6ONLY option is set on the socket
|
||||
/// according to the ipV6Only parameter.
|
||||
///
|
||||
/// If the library has not been built with IPv6 support,
|
||||
/// a Poco::NotImplementedException will be thrown.
|
||||
|
||||
virtual void listen(int backlog = 64);
|
||||
/// Puts the socket into listening state.
|
||||
///
|
||||
@ -419,11 +452,10 @@ private:
|
||||
SocketImpl& operator = (const SocketImpl&);
|
||||
|
||||
poco_socket_t _sockfd;
|
||||
#if defined(POCO_BROKEN_TIMEOUTS)
|
||||
Poco::Timespan _recvTimeout;
|
||||
Poco::Timespan _sndTimeout;
|
||||
#endif
|
||||
bool _blocking;
|
||||
bool _isBrokenTimeout;
|
||||
|
||||
friend class Socket;
|
||||
friend class SecureSocketImpl;
|
||||
|
@ -45,7 +45,7 @@ public:
|
||||
/// Creates a stream socket and connects it to
|
||||
/// the socket specified by address.
|
||||
|
||||
explicit StreamSocket(IPAddress::Family family);
|
||||
explicit StreamSocket(SocketAddress::Family family);
|
||||
/// Creates an unconnected stream socket
|
||||
/// for the given address family.
|
||||
///
|
||||
@ -158,7 +158,7 @@ public:
|
||||
|
||||
StreamSocket(SocketImpl* pImpl);
|
||||
/// Creates the Socket and attaches the given SocketImpl.
|
||||
/// The socket takes owership of the SocketImpl.
|
||||
/// The socket takes ownership of the SocketImpl.
|
||||
///
|
||||
/// The SocketImpl must be a StreamSocketImpl, otherwise
|
||||
/// an InvalidArgumentException will be thrown.
|
||||
|
@ -33,7 +33,7 @@ public:
|
||||
StreamSocketImpl();
|
||||
/// Creates a StreamSocketImpl.
|
||||
|
||||
explicit StreamSocketImpl(IPAddress::Family addressFamily);
|
||||
explicit StreamSocketImpl(SocketAddress::Family addressFamily);
|
||||
/// Creates a SocketImpl, with the underlying
|
||||
/// socket initialized for the given address family.
|
||||
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include "Poco/Net/ServerSocket.h"
|
||||
#include "Poco/Net/TCPServerConnectionFactory.h"
|
||||
#include "Poco/Net/TCPServerParams.h"
|
||||
#include "Poco/RefCountedObject.h"
|
||||
#include "Poco/AutoPtr.h"
|
||||
#include "Poco/Runnable.h"
|
||||
#include "Poco/Thread.h"
|
||||
#include "Poco/ThreadPool.h"
|
||||
@ -32,6 +34,35 @@ namespace Net {
|
||||
|
||||
|
||||
class TCPServerDispatcher;
|
||||
class StreamSocket;
|
||||
|
||||
|
||||
class Net_API TCPServerConnectionFilter: public Poco::RefCountedObject
|
||||
/// A TCPServerConnectionFilter can be used to reject incoming connections
|
||||
/// before passing them on to the TCPServerDispatcher and
|
||||
/// starting a thread to handle them.
|
||||
///
|
||||
/// An example use case is white-list or black-list IP address filtering.
|
||||
///
|
||||
/// Subclasses must override the accept() method.
|
||||
{
|
||||
public:
|
||||
typedef Poco::AutoPtr<TCPServerConnectionFilter> Ptr;
|
||||
|
||||
virtual bool accept(const StreamSocket& socket) = 0;
|
||||
/// Returns true if the given StreamSocket connection should
|
||||
/// be handled, and passed on to the TCPServerDispatcher.
|
||||
///
|
||||
/// Returns false if the socket should be closed immediately.
|
||||
///
|
||||
/// The socket can be prevented from being closed immediately
|
||||
/// if false is returned by creating a copy of the socket.
|
||||
/// This can be used to handle certain socket connections in
|
||||
/// a special way, outside the TCPServer framework.
|
||||
|
||||
protected:
|
||||
virtual ~TCPServerConnectionFilter();
|
||||
};
|
||||
|
||||
|
||||
class Net_API TCPServer: public Poco::Runnable
|
||||
@ -164,6 +195,19 @@ public:
|
||||
Poco::UInt16 port() const;
|
||||
/// Returns the port the server socket listens on.
|
||||
|
||||
void setConnectionFilter(const TCPServerConnectionFilter::Ptr& pFilter);
|
||||
/// Sets a TCPServerConnectionFilter. Can also be used to remove
|
||||
/// a filter by passing a null pointer.
|
||||
///
|
||||
/// To avoid a potential race condition, the filter must
|
||||
/// 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(),
|
||||
/// or null pointer if no filter has been set.
|
||||
|
||||
protected:
|
||||
void run();
|
||||
/// Runs the server. The server will run until
|
||||
@ -179,10 +223,11 @@ private:
|
||||
TCPServer(const TCPServer&);
|
||||
TCPServer& operator = (const TCPServer&);
|
||||
|
||||
ServerSocket _socket;
|
||||
ServerSocket _socket;
|
||||
TCPServerDispatcher* _pDispatcher;
|
||||
Poco::Thread _thread;
|
||||
bool _stopped;
|
||||
TCPServerConnectionFilter::Ptr _pConnectionFilter;
|
||||
Poco::Thread _thread;
|
||||
bool _stopped;
|
||||
};
|
||||
|
||||
|
||||
@ -201,6 +246,12 @@ inline Poco::UInt16 TCPServer::port() const
|
||||
}
|
||||
|
||||
|
||||
inline TCPServerConnectionFilter::Ptr TCPServer::getConnectionFilter() const
|
||||
{
|
||||
return _pConnectionFilter;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
||||
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "Poco/Net/Net.h"
|
||||
#include "Poco/Net/StreamSocket.h"
|
||||
#include "Poco/Net/HTTPCredentials.h"
|
||||
#include "Poco/Buffer.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
@ -219,6 +220,21 @@ public:
|
||||
/// The frame flags and opcode (FrameFlags and FrameOpcodes)
|
||||
/// is stored in flags.
|
||||
|
||||
int receiveFrame(Poco::Buffer<char>& buffer, int& flags);
|
||||
/// Receives a frame from the socket and stores it
|
||||
/// after any previous content in buffer.
|
||||
///
|
||||
/// Returns the number of bytes received.
|
||||
/// A return value of 0 means that the peer has
|
||||
/// shut down or closed the connection.
|
||||
///
|
||||
/// Throws a TimeoutException if a receive timeout has
|
||||
/// been set and nothing is received within that interval.
|
||||
/// Throws a NetException (or a subclass) in case of other errors.
|
||||
///
|
||||
/// The frame flags and opcode (FrameFlags and FrameOpcodes)
|
||||
/// is stored in flags.
|
||||
|
||||
Mode mode() const;
|
||||
/// Returns WS_SERVER if the WebSocket is a server-side
|
||||
/// WebSocket, or WS_CLIENT otherwise.
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
|
||||
#include "Poco/Net/StreamSocketImpl.h"
|
||||
#include "Poco/Buffer.h"
|
||||
#include "Poco/Random.h"
|
||||
#include "Poco/Buffer.h"
|
||||
|
||||
@ -45,12 +46,17 @@ public:
|
||||
virtual int receiveBytes(void* buffer, int length, int flags);
|
||||
/// Receives a WebSocket protocol frame.
|
||||
|
||||
virtual int receiveBytes(Poco::Buffer<char>& buffer, int flags);
|
||||
/// Receives a WebSocket protocol frame.
|
||||
|
||||
virtual SocketImpl* acceptConnection(SocketAddress& clientAddr);
|
||||
virtual void connect(const SocketAddress& address);
|
||||
virtual void connect(const SocketAddress& address, const Poco::Timespan& timeout);
|
||||
virtual void connectNB(const SocketAddress& address);
|
||||
virtual void bind(const SocketAddress& address, bool reuseAddress = false);
|
||||
virtual void bind(const SocketAddress& address, bool reuseAddress, bool reusePort);
|
||||
virtual void bind6(const SocketAddress& address, bool reuseAddress = false, bool ipV6Only = false);
|
||||
virtual void bind6(const SocketAddress& address, bool reuseAddress, bool reusePort, bool ipV6Only);
|
||||
virtual void listen(int backlog = 64);
|
||||
virtual void close();
|
||||
virtual void shutdownReceive();
|
||||
@ -80,6 +86,8 @@ protected:
|
||||
MAX_HEADER_LENGTH = 14
|
||||
};
|
||||
|
||||
int receiveHeader(char mask[4], bool& useMask);
|
||||
int receivePayload(char *buffer, int payloadLength, char mask[4], bool useMask);
|
||||
int receiveNBytes(void* buffer, int bytes);
|
||||
int receiveSomeBytes(char* buffer, int bytes);
|
||||
virtual ~WebSocketImpl();
|
||||
|
@ -29,7 +29,7 @@ DatagramSocket::DatagramSocket(): Socket(new DatagramSocketImpl)
|
||||
}
|
||||
|
||||
|
||||
DatagramSocket::DatagramSocket(IPAddress::Family family): Socket(new DatagramSocketImpl(family))
|
||||
DatagramSocket::DatagramSocket(SocketAddress::Family family): Socket(new DatagramSocketImpl(family))
|
||||
{
|
||||
}
|
||||
|
||||
@ -81,6 +81,12 @@ void DatagramSocket::bind(const SocketAddress& address, bool reuseAddress)
|
||||
}
|
||||
|
||||
|
||||
void DatagramSocket::bind(const SocketAddress& address, bool reuseAddress, bool reusePort)
|
||||
{
|
||||
impl()->bind(address, reuseAddress, reusePort);
|
||||
}
|
||||
|
||||
|
||||
int DatagramSocket::sendBytes(const void* buffer, int length, int flags)
|
||||
{
|
||||
return impl()->sendBytes(buffer, length, flags);
|
||||
|
@ -25,17 +25,20 @@ namespace Net {
|
||||
|
||||
DatagramSocketImpl::DatagramSocketImpl()
|
||||
{
|
||||
init(AF_INET);
|
||||
}
|
||||
|
||||
|
||||
DatagramSocketImpl::DatagramSocketImpl(IPAddress::Family family)
|
||||
DatagramSocketImpl::DatagramSocketImpl(SocketAddress::Family family)
|
||||
{
|
||||
if (family == IPAddress::IPv4)
|
||||
if (family == SocketAddress::IPv4)
|
||||
init(AF_INET);
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
else if (family == IPAddress::IPv6)
|
||||
else if (family == SocketAddress::IPv6)
|
||||
init(AF_INET6);
|
||||
#endif
|
||||
#if defined(POCO_OS_FAMILY_UNIX)
|
||||
else if (family == SocketAddress::UNIX_LOCAL)
|
||||
init(AF_UNIX);
|
||||
#endif
|
||||
else throw InvalidArgumentException("Invalid or unsupported address family passed to DatagramSocketImpl");
|
||||
}
|
||||
|
@ -44,7 +44,8 @@ HTTPClientSession::HTTPClientSession():
|
||||
_keepAliveTimeout(DEFAULT_KEEP_ALIVE_TIMEOUT, 0),
|
||||
_reconnect(false),
|
||||
_mustReconnect(false),
|
||||
_expectResponseBody(false)
|
||||
_expectResponseBody(false),
|
||||
_responseReceived(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -56,7 +57,8 @@ HTTPClientSession::HTTPClientSession(const StreamSocket& socket):
|
||||
_keepAliveTimeout(DEFAULT_KEEP_ALIVE_TIMEOUT, 0),
|
||||
_reconnect(false),
|
||||
_mustReconnect(false),
|
||||
_expectResponseBody(false)
|
||||
_expectResponseBody(false),
|
||||
_responseReceived(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -68,7 +70,8 @@ HTTPClientSession::HTTPClientSession(const SocketAddress& address):
|
||||
_keepAliveTimeout(DEFAULT_KEEP_ALIVE_TIMEOUT, 0),
|
||||
_reconnect(false),
|
||||
_mustReconnect(false),
|
||||
_expectResponseBody(false)
|
||||
_expectResponseBody(false),
|
||||
_responseReceived(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -80,7 +83,8 @@ HTTPClientSession::HTTPClientSession(const std::string& host, Poco::UInt16 port)
|
||||
_keepAliveTimeout(DEFAULT_KEEP_ALIVE_TIMEOUT, 0),
|
||||
_reconnect(false),
|
||||
_mustReconnect(false),
|
||||
_expectResponseBody(false)
|
||||
_expectResponseBody(false),
|
||||
_responseReceived(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -92,7 +96,8 @@ HTTPClientSession::HTTPClientSession(const std::string& host, Poco::UInt16 port,
|
||||
_keepAliveTimeout(DEFAULT_KEEP_ALIVE_TIMEOUT, 0),
|
||||
_reconnect(false),
|
||||
_mustReconnect(false),
|
||||
_expectResponseBody(false)
|
||||
_expectResponseBody(false),
|
||||
_responseReceived(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -190,9 +195,10 @@ std::ostream& HTTPClientSession::sendRequest(HTTPRequest& request)
|
||||
{
|
||||
clearException();
|
||||
_pResponseStream = 0;
|
||||
_responseReceived = false;
|
||||
|
||||
bool keepAlive = getKeepAlive();
|
||||
if ((connected() && !keepAlive) || mustReconnect())
|
||||
if (((connected() && !keepAlive) || mustReconnect()) && !_host.empty())
|
||||
{
|
||||
close();
|
||||
_mustReconnect = false;
|
||||
@ -203,7 +209,7 @@ std::ostream& HTTPClientSession::sendRequest(HTTPRequest& request)
|
||||
reconnect();
|
||||
if (!keepAlive)
|
||||
request.setKeepAlive(false);
|
||||
if (!request.has(HTTPRequest::HOST))
|
||||
if (!request.has(HTTPRequest::HOST) && !_host.empty())
|
||||
request.setHost(_host, _port);
|
||||
if (!_proxyConfig.host.empty() && !bypassProxy())
|
||||
{
|
||||
@ -258,25 +264,28 @@ std::istream& HTTPClientSession::receiveResponse(HTTPResponse& response)
|
||||
_pRequestStream = 0;
|
||||
if (networkException()) networkException()->rethrow();
|
||||
|
||||
do
|
||||
if (!_responseReceived)
|
||||
{
|
||||
response.clear();
|
||||
HTTPHeaderInputStream his(*this);
|
||||
try
|
||||
do
|
||||
{
|
||||
response.read(his);
|
||||
}
|
||||
catch (Exception&)
|
||||
{
|
||||
close();
|
||||
if (networkException())
|
||||
networkException()->rethrow();
|
||||
else
|
||||
response.clear();
|
||||
HTTPHeaderInputStream his(*this);
|
||||
try
|
||||
{
|
||||
response.read(his);
|
||||
}
|
||||
catch (Exception&)
|
||||
{
|
||||
close();
|
||||
if (networkException())
|
||||
networkException()->rethrow();
|
||||
else
|
||||
throw;
|
||||
throw;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
while (response.getStatus() == HTTPResponse::HTTP_CONTINUE);
|
||||
}
|
||||
while (response.getStatus() == HTTPResponse::HTTP_CONTINUE);
|
||||
|
||||
_mustReconnect = getKeepAlive() && !response.getKeepAlive();
|
||||
|
||||
@ -297,6 +306,34 @@ std::istream& HTTPClientSession::receiveResponse(HTTPResponse& response)
|
||||
}
|
||||
|
||||
|
||||
bool HTTPClientSession::peekResponse(HTTPResponse& response)
|
||||
{
|
||||
poco_assert (!_responseReceived);
|
||||
|
||||
_pRequestStream->flush();
|
||||
|
||||
if (networkException()) networkException()->rethrow();
|
||||
|
||||
response.clear();
|
||||
HTTPHeaderInputStream his(*this);
|
||||
try
|
||||
{
|
||||
response.read(his);
|
||||
}
|
||||
catch (Exception&)
|
||||
{
|
||||
close();
|
||||
if (networkException())
|
||||
networkException()->rethrow();
|
||||
else
|
||||
throw;
|
||||
throw;
|
||||
}
|
||||
_responseReceived = response.getStatus() != HTTPResponse::HTTP_CONTINUE;
|
||||
return !_responseReceived;
|
||||
}
|
||||
|
||||
|
||||
void HTTPClientSession::reset()
|
||||
{
|
||||
close();
|
||||
|
@ -41,6 +41,7 @@ const std::string HTTPRequest::COOKIE = "Cookie";
|
||||
const std::string HTTPRequest::AUTHORIZATION = "Authorization";
|
||||
const std::string HTTPRequest::PROXY_AUTHORIZATION = "Proxy-Authorization";
|
||||
const std::string HTTPRequest::UPGRADE = "Upgrade";
|
||||
const std::string HTTPRequest::EXPECT = "Expect";
|
||||
|
||||
|
||||
HTTPRequest::HTTPRequest():
|
||||
@ -257,4 +258,20 @@ void HTTPRequest::setCredentials(const std::string& header, const std::string& s
|
||||
}
|
||||
|
||||
|
||||
bool HTTPRequest::getExpectContinue() const
|
||||
{
|
||||
const std::string& expect = get(EXPECT, EMPTY);
|
||||
return !expect.empty() && icompare(expect, "100-continue") == 0;
|
||||
}
|
||||
|
||||
|
||||
void HTTPRequest::setExpectContinue(bool expectContinue)
|
||||
{
|
||||
if (expectContinue)
|
||||
set(EXPECT, "100-continue");
|
||||
else
|
||||
erase(EXPECT);
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
||||
|
@ -38,6 +38,7 @@ namespace Net {
|
||||
|
||||
const std::string HTTPResponse::HTTP_REASON_CONTINUE = "Continue";
|
||||
const std::string HTTPResponse::HTTP_REASON_SWITCHING_PROTOCOLS = "Switching Protocols";
|
||||
const std::string HTTPResponse::HTTP_REASON_PROCESSING = "Processing";
|
||||
const std::string HTTPResponse::HTTP_REASON_OK = "OK";
|
||||
const std::string HTTPResponse::HTTP_REASON_CREATED = "Created";
|
||||
const std::string HTTPResponse::HTTP_REASON_ACCEPTED = "Accepted";
|
||||
@ -45,13 +46,17 @@ const std::string HTTPResponse::HTTP_REASON_NONAUTHORITATIVE = "N
|
||||
const std::string HTTPResponse::HTTP_REASON_NO_CONTENT = "No Content";
|
||||
const std::string HTTPResponse::HTTP_REASON_RESET_CONTENT = "Reset Content";
|
||||
const std::string HTTPResponse::HTTP_REASON_PARTIAL_CONTENT = "Partial Content";
|
||||
const std::string HTTPResponse::HTTP_REASON_MULTI_STATUS = "Multi Status";
|
||||
const std::string HTTPResponse::HTTP_REASON_ALREADY_REPORTED = "Already Reported";
|
||||
const std::string HTTPResponse::HTTP_REASON_IM_USED = "IM Used";
|
||||
const std::string HTTPResponse::HTTP_REASON_MULTIPLE_CHOICES = "Multiple Choices";
|
||||
const std::string HTTPResponse::HTTP_REASON_MOVED_PERMANENTLY = "Moved Permanently";
|
||||
const std::string HTTPResponse::HTTP_REASON_FOUND = "Found";
|
||||
const std::string HTTPResponse::HTTP_REASON_SEE_OTHER = "See Other";
|
||||
const std::string HTTPResponse::HTTP_REASON_NOT_MODIFIED = "Not Modified";
|
||||
const std::string HTTPResponse::HTTP_REASON_USEPROXY = "Use Proxy";
|
||||
const std::string HTTPResponse::HTTP_REASON_USE_PROXY = "Use Proxy";
|
||||
const std::string HTTPResponse::HTTP_REASON_TEMPORARY_REDIRECT = "Temporary Redirect";
|
||||
const std::string HTTPResponse::HTTP_REASON_PERMANENT_REDIRECT = "Permanent Redirect";
|
||||
const std::string HTTPResponse::HTTP_REASON_BAD_REQUEST = "Bad Request";
|
||||
const std::string HTTPResponse::HTTP_REASON_UNAUTHORIZED = "Unauthorized";
|
||||
const std::string HTTPResponse::HTTP_REASON_PAYMENT_REQUIRED = "Payment Required";
|
||||
@ -65,17 +70,33 @@ const std::string HTTPResponse::HTTP_REASON_CONFLICT = "C
|
||||
const std::string HTTPResponse::HTTP_REASON_GONE = "Gone";
|
||||
const std::string HTTPResponse::HTTP_REASON_LENGTH_REQUIRED = "Length Required";
|
||||
const std::string HTTPResponse::HTTP_REASON_PRECONDITION_FAILED = "Precondition Failed";
|
||||
const std::string HTTPResponse::HTTP_REASON_REQUESTENTITYTOOLARGE = "Request Entity Too Large";
|
||||
const std::string HTTPResponse::HTTP_REASON_REQUESTURITOOLONG = "Request-URI Too Large";
|
||||
const std::string HTTPResponse::HTTP_REASON_UNSUPPORTEDMEDIATYPE = "Unsupported Media Type";
|
||||
const std::string HTTPResponse::HTTP_REASON_REQUEST_ENTITY_TOO_LARGE = "Request Entity Too Large";
|
||||
const std::string HTTPResponse::HTTP_REASON_REQUEST_URI_TOO_LONG = "Request-URI Too Large";
|
||||
const std::string HTTPResponse::HTTP_REASON_UNSUPPORTED_MEDIA_TYPE = "Unsupported Media Type";
|
||||
const std::string HTTPResponse::HTTP_REASON_REQUESTED_RANGE_NOT_SATISFIABLE = "Requested Range Not Satisfiable";
|
||||
const std::string HTTPResponse::HTTP_REASON_EXPECTATION_FAILED = "Expectation Failed";
|
||||
const std::string HTTPResponse::HTTP_REASON_IM_A_TEAPOT = "I'm a Teapot";
|
||||
const std::string HTTPResponse::HTTP_REASON_ENCHANCE_YOUR_CALM = "Enchance Your Calm";
|
||||
const std::string HTTPResponse::HTTP_REASON_MISDIRECTED_REQUEST = "Misdirected Request";
|
||||
const std::string HTTPResponse::HTTP_REASON_UNPROCESSABLE_ENTITY = "Unprocessable Entity";
|
||||
const std::string HTTPResponse::HTTP_REASON_LOCKED = "Locked";
|
||||
const std::string HTTPResponse::HTTP_REASON_FAILED_DEPENDENCY = "Failed Dependency";
|
||||
const std::string HTTPResponse::HTTP_REASON_UPGRADE_REQUIRED = "Upgrade Required";
|
||||
const std::string HTTPResponse::HTTP_REASON_PRECONDITION_REQUIRED = "Precondition Required";
|
||||
const std::string HTTPResponse::HTTP_REASON_TOO_MANY_REQUESTS = "Too Many Requests";
|
||||
const std::string HTTPResponse::HTTP_REASON_REQUEST_HEADER_FIELDS_TOO_LARGE = "Request Header Fields Too Large";
|
||||
const std::string HTTPResponse::HTTP_REASON_UNAVAILABLE_FOR_LEGAL_REASONS = "Unavailable For Legal Reasons";
|
||||
const std::string HTTPResponse::HTTP_REASON_INTERNAL_SERVER_ERROR = "Internal Server Error";
|
||||
const std::string HTTPResponse::HTTP_REASON_NOT_IMPLEMENTED = "Not Implemented";
|
||||
const std::string HTTPResponse::HTTP_REASON_BAD_GATEWAY = "Bad Gateway";
|
||||
const std::string HTTPResponse::HTTP_REASON_SERVICE_UNAVAILABLE = "Service Unavailable";
|
||||
const std::string HTTPResponse::HTTP_REASON_GATEWAY_TIMEOUT = "Gateway Time-out";
|
||||
const std::string HTTPResponse::HTTP_REASON_VERSION_NOT_SUPPORTED = "HTTP Version not supported";
|
||||
const std::string HTTPResponse::HTTP_REASON_GATEWAY_TIMEOUT = "Gateway Time-Out";
|
||||
const std::string HTTPResponse::HTTP_REASON_VERSION_NOT_SUPPORTED = "HTTP Version Not Supported";
|
||||
const std::string HTTPResponse::HTTP_REASON_VARIANT_ALSO_NEGOTIATES = "Variant Also Negotiates";
|
||||
const std::string HTTPResponse::HTTP_REASON_INSUFFICIENT_STORAGE = "Insufficient Storage";
|
||||
const std::string HTTPResponse::HTTP_REASON_LOOP_DETECTED = "Loop Detected";
|
||||
const std::string HTTPResponse::HTTP_REASON_NOT_EXTENDED = "Not Extended";
|
||||
const std::string HTTPResponse::HTTP_REASON_NETWORK_AUTHENTICATION_REQUIRED = "Network Authentication Required";
|
||||
const std::string HTTPResponse::HTTP_REASON_UNKNOWN = "???";
|
||||
const std::string HTTPResponse::DATE = "Date";
|
||||
const std::string HTTPResponse::SET_COOKIE = "Set-Cookie";
|
||||
@ -238,6 +259,8 @@ const std::string& HTTPResponse::getReasonForStatus(HTTPStatus status)
|
||||
return HTTP_REASON_CONTINUE;
|
||||
case HTTP_SWITCHING_PROTOCOLS:
|
||||
return HTTP_REASON_SWITCHING_PROTOCOLS;
|
||||
case HTTP_PROCESSING:
|
||||
return HTTP_REASON_PROCESSING;
|
||||
case HTTP_OK:
|
||||
return HTTP_REASON_OK;
|
||||
case HTTP_CREATED:
|
||||
@ -252,6 +275,12 @@ const std::string& HTTPResponse::getReasonForStatus(HTTPStatus status)
|
||||
return HTTP_REASON_RESET_CONTENT;
|
||||
case HTTP_PARTIAL_CONTENT:
|
||||
return HTTP_REASON_PARTIAL_CONTENT;
|
||||
case HTTP_MULTI_STATUS:
|
||||
return HTTP_REASON_MULTI_STATUS;
|
||||
case HTTP_ALREADY_REPORTED:
|
||||
return HTTP_REASON_ALREADY_REPORTED;
|
||||
case HTTP_IM_USED:
|
||||
return HTTP_REASON_IM_USED;
|
||||
case HTTP_MULTIPLE_CHOICES:
|
||||
return HTTP_REASON_MULTIPLE_CHOICES;
|
||||
case HTTP_MOVED_PERMANENTLY:
|
||||
@ -262,8 +291,8 @@ const std::string& HTTPResponse::getReasonForStatus(HTTPStatus status)
|
||||
return HTTP_REASON_SEE_OTHER;
|
||||
case HTTP_NOT_MODIFIED:
|
||||
return HTTP_REASON_NOT_MODIFIED;
|
||||
case HTTP_USEPROXY:
|
||||
return HTTP_REASON_USEPROXY;
|
||||
case HTTP_USE_PROXY:
|
||||
return HTTP_REASON_USE_PROXY;
|
||||
case HTTP_TEMPORARY_REDIRECT:
|
||||
return HTTP_REASON_TEMPORARY_REDIRECT;
|
||||
case HTTP_BAD_REQUEST:
|
||||
@ -292,16 +321,38 @@ const std::string& HTTPResponse::getReasonForStatus(HTTPStatus status)
|
||||
return HTTP_REASON_LENGTH_REQUIRED;
|
||||
case HTTP_PRECONDITION_FAILED:
|
||||
return HTTP_REASON_PRECONDITION_FAILED;
|
||||
case HTTP_REQUESTENTITYTOOLARGE:
|
||||
return HTTP_REASON_REQUESTENTITYTOOLARGE;
|
||||
case HTTP_REQUESTURITOOLONG:
|
||||
return HTTP_REASON_REQUESTURITOOLONG;
|
||||
case HTTP_UNSUPPORTEDMEDIATYPE:
|
||||
return HTTP_REASON_UNSUPPORTEDMEDIATYPE;
|
||||
case HTTP_REQUEST_ENTITY_TOO_LARGE:
|
||||
return HTTP_REASON_REQUEST_ENTITY_TOO_LARGE;
|
||||
case HTTP_REQUEST_URI_TOO_LONG:
|
||||
return HTTP_REASON_REQUEST_URI_TOO_LONG;
|
||||
case HTTP_UNSUPPORTED_MEDIA_TYPE:
|
||||
return HTTP_REASON_UNSUPPORTED_MEDIA_TYPE;
|
||||
case HTTP_REQUESTED_RANGE_NOT_SATISFIABLE:
|
||||
return HTTP_REASON_REQUESTED_RANGE_NOT_SATISFIABLE;
|
||||
case HTTP_EXPECTATION_FAILED:
|
||||
return HTTP_REASON_EXPECTATION_FAILED;
|
||||
case HTTP_IM_A_TEAPOT:
|
||||
return HTTP_REASON_IM_A_TEAPOT;
|
||||
case HTTP_ENCHANCE_YOUR_CALM:
|
||||
return HTTP_REASON_ENCHANCE_YOUR_CALM;
|
||||
case HTTP_MISDIRECTED_REQUEST:
|
||||
return HTTP_REASON_MISDIRECTED_REQUEST;
|
||||
case HTTP_UNPROCESSABLE_ENTITY:
|
||||
return HTTP_REASON_UNPROCESSABLE_ENTITY;
|
||||
case HTTP_LOCKED:
|
||||
return HTTP_REASON_LOCKED;
|
||||
case HTTP_FAILED_DEPENDENCY:
|
||||
return HTTP_REASON_FAILED_DEPENDENCY;
|
||||
case HTTP_UPGRADE_REQUIRED:
|
||||
return HTTP_REASON_UPGRADE_REQUIRED;
|
||||
case HTTP_PRECONDITION_REQUIRED:
|
||||
return HTTP_REASON_PRECONDITION_REQUIRED;
|
||||
case HTTP_TOO_MANY_REQUESTS:
|
||||
return HTTP_REASON_TOO_MANY_REQUESTS;
|
||||
case HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE:
|
||||
return HTTP_REASON_REQUEST_HEADER_FIELDS_TOO_LARGE;
|
||||
case HTTP_UNAVAILABLE_FOR_LEGAL_REASONS:
|
||||
return HTTP_REASON_UNAVAILABLE_FOR_LEGAL_REASONS;
|
||||
case HTTP_INTERNAL_SERVER_ERROR:
|
||||
return HTTP_REASON_INTERNAL_SERVER_ERROR;
|
||||
case HTTP_NOT_IMPLEMENTED:
|
||||
@ -314,6 +365,16 @@ const std::string& HTTPResponse::getReasonForStatus(HTTPStatus status)
|
||||
return HTTP_REASON_GATEWAY_TIMEOUT;
|
||||
case HTTP_VERSION_NOT_SUPPORTED:
|
||||
return HTTP_REASON_VERSION_NOT_SUPPORTED;
|
||||
case HTTP_VARIANT_ALSO_NEGOTIATES:
|
||||
return HTTP_REASON_VARIANT_ALSO_NEGOTIATES;
|
||||
case HTTP_INSUFFICIENT_STORAGE:
|
||||
return HTTP_REASON_INSUFFICIENT_STORAGE;
|
||||
case HTTP_LOOP_DETECTED:
|
||||
return HTTP_REASON_LOOP_DETECTED;
|
||||
case HTTP_NOT_EXTENDED:
|
||||
return HTTP_REASON_NOT_EXTENDED;
|
||||
case HTTP_NETWORK_AUTHENTICATION_REQUIRED:
|
||||
return HTTP_REASON_NETWORK_AUTHENTICATION_REQUIRED;
|
||||
default:
|
||||
return HTTP_REASON_UNKNOWN;
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ void HTTPServerConnection::run()
|
||||
#endif
|
||||
if (pHandler.get())
|
||||
{
|
||||
if (request.expectContinue())
|
||||
if (request.getExpectContinue() && response.getStatus() == HTTPResponse::HTTP_OK)
|
||||
response.sendContinue();
|
||||
|
||||
pHandler->handleRequest(request, response);
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "Poco/Net/HTTPFixedLengthStream.h"
|
||||
#include "Poco/Net/HTTPChunkedStream.h"
|
||||
#include "Poco/Net/HTTPServerParams.h"
|
||||
#include "Poco/Net/StreamSocket.h"
|
||||
#include "Poco/String.h"
|
||||
|
||||
|
||||
@ -30,9 +31,6 @@ namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
const std::string HTTPServerRequestImpl::EXPECT("Expect");
|
||||
|
||||
|
||||
HTTPServerRequestImpl::HTTPServerRequestImpl(HTTPServerResponseImpl& response, HTTPServerSession& session, HTTPServerParams* pParams):
|
||||
_response(response),
|
||||
_session(session),
|
||||
@ -69,6 +67,12 @@ HTTPServerRequestImpl::~HTTPServerRequestImpl()
|
||||
}
|
||||
|
||||
|
||||
bool HTTPServerRequestImpl::secure() const
|
||||
{
|
||||
return _session.socket().secure();
|
||||
}
|
||||
|
||||
|
||||
StreamSocket& HTTPServerRequestImpl::socket()
|
||||
{
|
||||
return _session.socket();
|
||||
@ -81,11 +85,4 @@ StreamSocket HTTPServerRequestImpl::detachSocket()
|
||||
}
|
||||
|
||||
|
||||
bool HTTPServerRequestImpl::expectContinue() const
|
||||
{
|
||||
const std::string& expect = get(EXPECT, EMPTY);
|
||||
return !expect.empty() && icompare(expect, "100-continue") == 0;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
||||
|
@ -30,7 +30,9 @@ HTTPSession::HTTPSession():
|
||||
_pCurrent(0),
|
||||
_pEnd(0),
|
||||
_keepAlive(false),
|
||||
_timeout(HTTP_DEFAULT_TIMEOUT),
|
||||
_connectionTimeout(HTTP_DEFAULT_CONNECTION_TIMEOUT),
|
||||
_receiveTimeout(HTTP_DEFAULT_TIMEOUT),
|
||||
_sendTimeout(HTTP_DEFAULT_TIMEOUT),
|
||||
_pException(0)
|
||||
{
|
||||
}
|
||||
@ -42,7 +44,9 @@ HTTPSession::HTTPSession(const StreamSocket& socket):
|
||||
_pCurrent(0),
|
||||
_pEnd(0),
|
||||
_keepAlive(false),
|
||||
_timeout(HTTP_DEFAULT_TIMEOUT),
|
||||
_connectionTimeout(HTTP_DEFAULT_CONNECTION_TIMEOUT),
|
||||
_receiveTimeout(HTTP_DEFAULT_TIMEOUT),
|
||||
_sendTimeout(HTTP_DEFAULT_TIMEOUT),
|
||||
_pException(0)
|
||||
{
|
||||
}
|
||||
@ -54,7 +58,9 @@ HTTPSession::HTTPSession(const StreamSocket& socket, bool keepAlive):
|
||||
_pCurrent(0),
|
||||
_pEnd(0),
|
||||
_keepAlive(keepAlive),
|
||||
_timeout(HTTP_DEFAULT_TIMEOUT),
|
||||
_connectionTimeout(HTTP_DEFAULT_CONNECTION_TIMEOUT),
|
||||
_receiveTimeout(HTTP_DEFAULT_TIMEOUT),
|
||||
_sendTimeout(HTTP_DEFAULT_TIMEOUT),
|
||||
_pException(0)
|
||||
{
|
||||
}
|
||||
@ -89,7 +95,15 @@ void HTTPSession::setKeepAlive(bool keepAlive)
|
||||
|
||||
void HTTPSession::setTimeout(const Poco::Timespan& timeout)
|
||||
{
|
||||
_timeout = timeout;
|
||||
setTimeout(timeout, timeout, timeout);
|
||||
}
|
||||
|
||||
|
||||
void HTTPSession::setTimeout(const Poco::Timespan& connectionTimeout, const Poco::Timespan& sendTimeout, const Poco::Timespan& receiveTimeout)
|
||||
{
|
||||
_connectionTimeout = connectionTimeout;
|
||||
_sendTimeout = sendTimeout;
|
||||
_receiveTimeout = receiveTimeout;
|
||||
}
|
||||
|
||||
|
||||
@ -179,8 +193,9 @@ bool HTTPSession::connected() const
|
||||
|
||||
void HTTPSession::connect(const SocketAddress& address)
|
||||
{
|
||||
_socket.connect(address, _timeout);
|
||||
_socket.setReceiveTimeout(_timeout);
|
||||
_socket.connect(address, _connectionTimeout);
|
||||
_socket.setReceiveTimeout(_receiveTimeout);
|
||||
_socket.setSendTimeout(_sendTimeout);
|
||||
_socket.setNoDelay(true);
|
||||
// There may be leftover data from a previous (failed) request in the buffer,
|
||||
// so we clear it.
|
||||
|
@ -140,7 +140,7 @@ std::istream* HTTPStreamFactory::open(const URI& uri)
|
||||
{
|
||||
return new HTTPResponseStream(rs, pSession);
|
||||
}
|
||||
else if (res.getStatus() == HTTPResponse::HTTP_USEPROXY && !retry)
|
||||
else if (res.getStatus() == HTTPResponse::HTTP_USE_PROXY && !retry)
|
||||
{
|
||||
// The requested resource MUST be accessed through the proxy
|
||||
// given by the Location field. The Location field gives the
|
||||
|
@ -34,7 +34,7 @@ namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
ICMPClient::ICMPClient(IPAddress::Family family):
|
||||
ICMPClient::ICMPClient(SocketAddress::Family family):
|
||||
_family(family)
|
||||
{
|
||||
}
|
||||
|
@ -33,13 +33,25 @@ using Poco::UInt16;
|
||||
using Poco::UInt32;
|
||||
using Poco::Net::Impl::IPAddressImpl;
|
||||
using Poco::Net::Impl::IPv4AddressImpl;
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
using Poco::Net::Impl::IPv6AddressImpl;
|
||||
#endif
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
#if !defined(_MSC_VER) || defined(__STDC__)
|
||||
// Go home MSVC, you're drunk...
|
||||
// See http://stackoverflow.com/questions/5899857/multiple-definition-error-for-static-const-class-members
|
||||
const IPAddress::Family IPAddress::IPv4;
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
const IPAddress::Family IPAddress::IPv6;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
IPAddress::IPAddress()
|
||||
{
|
||||
newIPv4();
|
||||
@ -50,8 +62,10 @@ IPAddress::IPAddress(const IPAddress& addr)
|
||||
{
|
||||
if (addr.family() == IPv4)
|
||||
newIPv4(addr.addr());
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
else
|
||||
newIPv6(addr.addr(), addr.scope());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -63,8 +77,7 @@ IPAddress::IPAddress(Family family)
|
||||
else if (family == IPv6)
|
||||
newIPv6();
|
||||
#endif
|
||||
else
|
||||
throw Poco::InvalidArgumentException("Invalid or unsupported address family passed to IPAddress()");
|
||||
else throw Poco::InvalidArgumentException("Invalid or unsupported address family passed to IPAddress()");
|
||||
}
|
||||
|
||||
|
||||
@ -219,8 +232,12 @@ IPAddress& IPAddress::operator = (const IPAddress& addr)
|
||||
destruct();
|
||||
if (addr.family() == IPAddress::IPv4)
|
||||
newIPv4(addr.addr());
|
||||
else
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
else if (addr.family() == IPAddress::IPv6)
|
||||
newIPv6(addr.addr(), addr.scope());
|
||||
#endif
|
||||
else
|
||||
throw Poco::InvalidArgumentException("Invalid or unsupported address family");
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@ -228,7 +245,7 @@ IPAddress& IPAddress::operator = (const IPAddress& addr)
|
||||
|
||||
IPAddress::Family IPAddress::family() const
|
||||
{
|
||||
return static_cast<IPAddress::Family>(pImpl()->family());
|
||||
return pImpl()->family();
|
||||
}
|
||||
|
||||
|
||||
@ -561,19 +578,30 @@ IPAddress IPAddress::broadcast()
|
||||
}
|
||||
|
||||
|
||||
BinaryWriter& operator << (BinaryWriter& writer, const IPAddress& value)
|
||||
} } // namespace Poco::Net
|
||||
|
||||
|
||||
Poco::BinaryWriter& operator << (Poco::BinaryWriter& writer, const Poco::Net::IPAddress& value)
|
||||
{
|
||||
writer.stream().write((const char*) value.addr(), value.length());
|
||||
writer << static_cast<Poco::UInt8>(value.length());
|
||||
writer.writeRaw(reinterpret_cast<const char*>(value.addr()), value.length());
|
||||
return writer;
|
||||
}
|
||||
|
||||
BinaryReader& operator >> (BinaryReader& reader, IPAddress& value)
|
||||
|
||||
Poco::BinaryReader& operator >> (Poco::BinaryReader& reader, Poco::Net::IPAddress& value)
|
||||
{
|
||||
char buf[sizeof(struct in6_addr)];
|
||||
reader.stream().read(buf, value.length());
|
||||
value = IPAddress(buf, value.length());
|
||||
Poco::UInt8 length;
|
||||
reader >> length;
|
||||
reader.readRaw(buf, length);
|
||||
value = Poco::Net::IPAddress(buf, length);
|
||||
return reader;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
||||
std::ostream& operator << (std::ostream& ostr, const Poco::Net::IPAddress& addr)
|
||||
{
|
||||
ostr << addr.toString();
|
||||
return ostr;
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ const void* IPv4AddressImpl::addr() const
|
||||
|
||||
IPAddressImpl::Family IPv4AddressImpl::family() const
|
||||
{
|
||||
return IPAddressImpl::IPv4;
|
||||
return AddressFamily::IPv4;
|
||||
}
|
||||
|
||||
|
||||
@ -500,7 +500,7 @@ const void* IPv6AddressImpl::addr() const
|
||||
|
||||
IPAddressImpl::Family IPv6AddressImpl::family() const
|
||||
{
|
||||
return IPAddressImpl::IPv6;
|
||||
return AddressFamily::IPv6;
|
||||
}
|
||||
|
||||
|
||||
@ -535,6 +535,8 @@ unsigned IPv6AddressImpl::prefixLength() const
|
||||
throw NotImplementedException("prefixLength() not implemented");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
Poco::UInt32 IPv6AddressImpl::scope() const
|
||||
{
|
||||
return _scope;
|
||||
|
@ -16,6 +16,11 @@
|
||||
#include "Poco/Net/NetException.h"
|
||||
#include "Poco/String.h"
|
||||
#include "Poco/Ascii.h"
|
||||
#include "Poco/TextConverter.h"
|
||||
#include "Poco/StringTokenizer.h"
|
||||
#include "Poco/Base64Decoder.h"
|
||||
#include "Poco/UTF8Encoding.h"
|
||||
#include <sstream>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
@ -96,7 +101,7 @@ void MessageHeader::read(std::istream& istr)
|
||||
throw MessageException("Folded field value too long/no CRLF found");
|
||||
}
|
||||
Poco::trimRightInPlace(value);
|
||||
add(name, value);
|
||||
add(name, decodeWord(value));
|
||||
++fields;
|
||||
}
|
||||
istr.putback(ch);
|
||||
@ -252,4 +257,138 @@ void MessageHeader::quote(const std::string& value, std::string& result, bool al
|
||||
}
|
||||
|
||||
|
||||
void MessageHeader::decodeRFC2047(const std::string& ins, std::string& outs, const std::string& charset_to)
|
||||
{
|
||||
std::string tempout;
|
||||
StringTokenizer tokens(ins, "?");
|
||||
|
||||
std::string charset = toUpper(tokens[0]);
|
||||
std::string encoding = toUpper(tokens[1]);
|
||||
std::string text = tokens[2];
|
||||
|
||||
std::istringstream istr(text);
|
||||
|
||||
if (encoding == "B")
|
||||
{
|
||||
// Base64 encoding.
|
||||
Base64Decoder decoder(istr);
|
||||
for (char c; decoder.get(c); tempout += c) {}
|
||||
}
|
||||
else if (encoding == "Q")
|
||||
{
|
||||
// Quoted encoding.
|
||||
for (char c; istr.get(c);)
|
||||
{
|
||||
if (c == '_')
|
||||
{
|
||||
//RFC 2047 _ is a space.
|
||||
tempout += " ";
|
||||
continue;
|
||||
}
|
||||
|
||||
// FIXME: check that we have enought chars-
|
||||
if (c == '=')
|
||||
{
|
||||
// The next two chars are hex representation of the complete byte.
|
||||
std::string hex;
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
istr.get(c);
|
||||
hex += c;
|
||||
}
|
||||
hex = toUpper(hex);
|
||||
tempout += (char)(int)strtol(hex.c_str(), 0, 16);
|
||||
continue;
|
||||
}
|
||||
tempout += c;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Wrong encoding
|
||||
outs = ins;
|
||||
return;
|
||||
}
|
||||
|
||||
// convert to the right charset.
|
||||
if (charset != charset_to)
|
||||
{
|
||||
try
|
||||
{
|
||||
TextEncoding& enc = TextEncoding::byName(charset);
|
||||
TextEncoding& dec = TextEncoding::byName(charset_to);
|
||||
TextConverter converter(enc, dec);
|
||||
converter.convert(tempout, outs);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// FIXME: Unsuported encoding...
|
||||
outs = tempout;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not conversion necesary.
|
||||
outs = tempout;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string MessageHeader::decodeWord(const std::string& text, const std::string& charset)
|
||||
{
|
||||
std::string outs, tmp = text;
|
||||
do {
|
||||
std::string tmp2;
|
||||
// find the begining of the next rfc2047 chunk
|
||||
size_t pos = tmp.find("=?");
|
||||
if (pos == std::string::npos) {
|
||||
// No more found, return
|
||||
outs += tmp;
|
||||
break;
|
||||
}
|
||||
|
||||
// check if there are standar text before the rfc2047 chunk, and if so, copy it.
|
||||
if (pos > 0) {
|
||||
outs += tmp.substr(0, pos);
|
||||
}
|
||||
|
||||
// remove text already copied.
|
||||
tmp = tmp.substr(pos + 2);
|
||||
|
||||
// find the first separator
|
||||
size_t pos1 = tmp.find("?");
|
||||
if (pos1 == std::string::npos) {
|
||||
// not found.
|
||||
outs += tmp;
|
||||
break;
|
||||
}
|
||||
|
||||
// find the second separator
|
||||
size_t pos2 = tmp.find("?", pos1 + 1);
|
||||
if (pos2 == std::string::npos) {
|
||||
// not found
|
||||
outs += tmp;
|
||||
break;
|
||||
}
|
||||
|
||||
// find the end of the actual rfc2047 chunk
|
||||
size_t pos3 = tmp.find("?=", pos2 + 1);
|
||||
if (pos3 == std::string::npos) {
|
||||
// not found.
|
||||
outs += tmp;
|
||||
break;
|
||||
|
||||
}
|
||||
// At this place, there are a valid rfc2047 chunk, so decode and copy the result.
|
||||
decodeRFC2047(tmp.substr(0, pos3), tmp2, charset);
|
||||
outs += tmp2;
|
||||
|
||||
// Jump at the rest of the string and repeat the whole process.
|
||||
tmp = tmp.substr(pos3 + 2);
|
||||
} while (true);
|
||||
|
||||
return outs;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
||||
|
@ -51,8 +51,12 @@ MulticastSocket::MulticastSocket()
|
||||
}
|
||||
|
||||
|
||||
MulticastSocket::MulticastSocket(IPAddress::Family family): DatagramSocket(family)
|
||||
MulticastSocket::MulticastSocket(SocketAddress::Family family): DatagramSocket(family)
|
||||
{
|
||||
#if defined(POCO_OS_FAMILY_UNIX)
|
||||
if (family == SocketAddress::UNIX_LOCAL)
|
||||
throw Poco::InvalidArgumentException("Cannot create a MulticastSocket with UNIX_LOCAL socket");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -80,18 +84,17 @@ MulticastSocket& MulticastSocket::operator = (const Socket& socket)
|
||||
|
||||
void MulticastSocket::setInterface(const NetworkInterface& interfc)
|
||||
{
|
||||
if (address().family() == IPAddress::IPv4)
|
||||
if (address().family() == SocketAddress::IPv4)
|
||||
{
|
||||
impl()->setOption(IPPROTO_IP, IP_MULTICAST_IF, interfc.firstAddress(IPAddress::IPv4));
|
||||
}
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
else if (address().family() == IPAddress::IPv6)
|
||||
else if (address().family() == SocketAddress::IPv6)
|
||||
{
|
||||
impl()->setOption(IPPROTO_IPV6, IPV6_MULTICAST_IF, interfc.index());
|
||||
}
|
||||
#endif
|
||||
else
|
||||
throw UnsupportedFamilyException("Unknown or unsupported socket family.");
|
||||
else throw UnsupportedFamilyException("Unknown or unsupported socket family.");
|
||||
}
|
||||
|
||||
|
||||
|
@ -47,7 +47,8 @@ POCO_IMPLEMENT_EXCEPTION(ICMPException, NetException, "ICMP Exception")
|
||||
POCO_IMPLEMENT_EXCEPTION(NTPException, NetException, "NTP Exception")
|
||||
POCO_IMPLEMENT_EXCEPTION(HTMLFormException, NetException, "HTML Form Exception")
|
||||
POCO_IMPLEMENT_EXCEPTION(WebSocketException, NetException, "WebSocket Exception")
|
||||
POCO_IMPLEMENT_EXCEPTION(UnsupportedFamilyException, NetException, "Unknown or unsupported socket family.")
|
||||
POCO_IMPLEMENT_EXCEPTION(UnsupportedFamilyException, NetException, "Unknown or unsupported socket family")
|
||||
POCO_IMPLEMENT_EXCEPTION(AddressFamilyMismatchException, NetException, "Address family mismatch")
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
||||
|
@ -242,7 +242,7 @@ void NetworkInterfaceImpl::setPhyParams()
|
||||
#if !defined(POCO_OS_FAMILY_WINDOWS) && !defined(POCO_VXWORKS)
|
||||
struct ifreq ifr;
|
||||
std::strncpy(ifr.ifr_name, _name.c_str(), IFNAMSIZ);
|
||||
DatagramSocket ds;
|
||||
DatagramSocket ds(SocketAddress::IPv4);
|
||||
|
||||
ds.impl()->ioctl(SIOCGIFFLAGS, &ifr);
|
||||
setFlags(ifr.ifr_flags);
|
||||
@ -796,16 +796,10 @@ bool NetworkInterface::isUp() const
|
||||
|
||||
NetworkInterface NetworkInterface::forName(const std::string& name, bool requireIPv6)
|
||||
{
|
||||
Map map = NetworkInterface::map(false, false);
|
||||
Map::const_iterator it = map.begin();
|
||||
Map::const_iterator end = map.end();
|
||||
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
if (it->second.name() == name && ((requireIPv6 && it->second.supportsIPv6()) || !requireIPv6))
|
||||
return it->second;
|
||||
}
|
||||
throw InterfaceNotFoundException(name);
|
||||
if (requireIPv6)
|
||||
return forName(name, IPv6_ONLY);
|
||||
else
|
||||
return forName(name, IPv4_OR_IPv6);
|
||||
}
|
||||
|
||||
|
||||
|
@ -30,7 +30,7 @@ RawSocket::RawSocket():
|
||||
}
|
||||
|
||||
|
||||
RawSocket::RawSocket(IPAddress::Family family, int proto):
|
||||
RawSocket::RawSocket(SocketAddress::Family family, int proto):
|
||||
Socket(new RawSocketImpl(family, proto))
|
||||
{
|
||||
}
|
||||
@ -84,6 +84,12 @@ void RawSocket::bind(const SocketAddress& address, bool reuseAddress)
|
||||
}
|
||||
|
||||
|
||||
void RawSocket::bind(const SocketAddress& address, bool reuseAddress, bool reusePort)
|
||||
{
|
||||
impl()->bind(address, reuseAddress, reusePort);
|
||||
}
|
||||
|
||||
|
||||
int RawSocket::sendBytes(const void* buffer, int length, int flags)
|
||||
{
|
||||
return impl()->sendBytes(buffer, length, flags);
|
||||
|
@ -29,12 +29,12 @@ RawSocketImpl::RawSocketImpl()
|
||||
}
|
||||
|
||||
|
||||
RawSocketImpl::RawSocketImpl(IPAddress::Family family, int proto)
|
||||
RawSocketImpl::RawSocketImpl(SocketAddress::Family family, int proto)
|
||||
{
|
||||
if (family == IPAddress::IPv4)
|
||||
if (family == SocketAddress::IPv4)
|
||||
init2(AF_INET, proto);
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
else if (family == IPAddress::IPv6)
|
||||
else if (family == SocketAddress::IPv6)
|
||||
init2(AF_INET6, proto);
|
||||
#endif
|
||||
else throw InvalidArgumentException("Invalid or unsupported address family passed to RawSocketImpl");
|
||||
|
@ -78,6 +78,12 @@ void ServerSocket::bind(const SocketAddress& address, bool reuseAddress)
|
||||
}
|
||||
|
||||
|
||||
void ServerSocket::bind(const SocketAddress& address, bool reuseAddress, bool reusePort)
|
||||
{
|
||||
impl()->bind(address, reuseAddress, reusePort);
|
||||
}
|
||||
|
||||
|
||||
void ServerSocket::bind(Poco::UInt16 port, bool reuseAddress)
|
||||
{
|
||||
IPAddress wildcardAddr;
|
||||
@ -86,17 +92,47 @@ void ServerSocket::bind(Poco::UInt16 port, bool reuseAddress)
|
||||
}
|
||||
|
||||
|
||||
void ServerSocket::bind(Poco::UInt16 port, bool reuseAddress, bool reusePort)
|
||||
{
|
||||
IPAddress wildcardAddr;
|
||||
SocketAddress address(wildcardAddr, port);
|
||||
impl()->bind(address, reuseAddress, reusePort);
|
||||
}
|
||||
|
||||
|
||||
void ServerSocket::bind6(const SocketAddress& address, bool reuseAddress, bool ipV6Only)
|
||||
{
|
||||
impl()->bind6(address, reuseAddress, ipV6Only);
|
||||
}
|
||||
|
||||
|
||||
void ServerSocket::bind6(const SocketAddress& address, bool reuseAddress, bool reusePort, bool ipV6Only)
|
||||
{
|
||||
impl()->bind6(address, reuseAddress, reusePort, ipV6Only);
|
||||
}
|
||||
|
||||
|
||||
void ServerSocket::bind6(Poco::UInt16 port, bool reuseAddress, bool ipV6Only)
|
||||
{
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
IPAddress wildcardAddr(IPAddress::IPv6);
|
||||
SocketAddress address(wildcardAddr, port);
|
||||
impl()->bind6(address, reuseAddress, ipV6Only);
|
||||
#else
|
||||
throw Poco::NotImplementedException("No IPv6 support available");
|
||||
#endif // POCO_HAVE_IPv6
|
||||
}
|
||||
|
||||
|
||||
void ServerSocket::bind6(Poco::UInt16 port, bool reuseAddress, bool reusePort, bool ipV6Only)
|
||||
{
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
IPAddress wildcardAddr(IPAddress::IPv6);
|
||||
SocketAddress address(wildcardAddr, port);
|
||||
impl()->bind6(address, reuseAddress, reusePort, ipV6Only);
|
||||
#else
|
||||
throw Poco::NotImplementedException("No IPv6 support available");
|
||||
#endif // POCO_HAVE_IPv6
|
||||
}
|
||||
|
||||
|
||||
|
@ -22,9 +22,6 @@
|
||||
#elif defined(POCO_HAVE_FD_POLL)
|
||||
#include "Poco/SharedPtr.h"
|
||||
#include <poll.h>
|
||||
typedef Poco::SharedPtr<pollfd,
|
||||
Poco::ReferenceCounter,
|
||||
Poco::ReleaseArrayPolicy<pollfd> > SharedPollArray;
|
||||
#endif
|
||||
|
||||
|
||||
@ -209,6 +206,7 @@ int Socket::select(SocketList& readList, SocketList& writeList, SocketList& exce
|
||||
return readList.size() + writeList.size() + exceptList.size();
|
||||
|
||||
#elif defined(POCO_HAVE_FD_POLL)
|
||||
typedef Poco::SharedPtr<pollfd, Poco::ReferenceCounter, Poco::ReleaseArrayPolicy<pollfd> > SharedPollArray;
|
||||
|
||||
nfds_t nfd = readList.size() + writeList.size() + exceptList.size();
|
||||
if (0 == nfd) return 0;
|
||||
|
@ -18,19 +18,24 @@
|
||||
#include "Poco/Net/DNS.h"
|
||||
#include "Poco/RefCountedObject.h"
|
||||
#include "Poco/NumberParser.h"
|
||||
#include "Poco/NumberFormatter.h"
|
||||
#include "Poco/BinaryReader.h"
|
||||
#include "Poco/BinaryWriter.h"
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
using Poco::RefCountedObject;
|
||||
using Poco::NumberParser;
|
||||
using Poco::NumberFormatter;
|
||||
using Poco::UInt16;
|
||||
using Poco::InvalidArgumentException;
|
||||
using Poco::Net::Impl::SocketAddressImpl;
|
||||
using Poco::Net::Impl::IPv4SocketAddressImpl;
|
||||
#ifdef POCO_HAVE_IPv6
|
||||
using Poco::Net::Impl::IPv6SocketAddressImpl;
|
||||
#endif
|
||||
#ifdef POCO_OS_FAMILY_UNIX
|
||||
using Poco::Net::Impl::LocalSocketAddressImpl;
|
||||
#endif
|
||||
|
||||
|
||||
namespace Poco {
|
||||
@ -51,12 +56,31 @@ struct AFLT
|
||||
//
|
||||
|
||||
|
||||
#if !defined(_MSC_VER) || defined(__STDC__)
|
||||
// Go home MSVC, you're drunk...
|
||||
// See http://stackoverflow.com/questions/5899857/multiple-definition-error-for-static-const-class-members
|
||||
const SocketAddress::Family SocketAddress::IPv4;
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
const SocketAddress::Family SocketAddress::IPv6;
|
||||
#endif
|
||||
#if defined(POCO_OS_FAMILY_UNIX)
|
||||
const SocketAddress::Family SocketAddress::UNIX_LOCAL;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
SocketAddress::SocketAddress()
|
||||
{
|
||||
newIPv4();
|
||||
}
|
||||
|
||||
|
||||
SocketAddress::SocketAddress(Family fam)
|
||||
{
|
||||
init(IPAddress(fam), 0);
|
||||
}
|
||||
|
||||
|
||||
SocketAddress::SocketAddress(const IPAddress& hostAddress, Poco::UInt16 portNumber)
|
||||
{
|
||||
init(hostAddress, portNumber);
|
||||
@ -69,65 +93,76 @@ SocketAddress::SocketAddress(Poco::UInt16 portNumber)
|
||||
}
|
||||
|
||||
|
||||
SocketAddress::SocketAddress(Family fam, Poco::UInt16 portNumber)
|
||||
{
|
||||
init(IPAddress(fam), portNumber);
|
||||
}
|
||||
|
||||
|
||||
SocketAddress::SocketAddress(const std::string& hostAddress, Poco::UInt16 portNumber)
|
||||
{
|
||||
init(hostAddress, portNumber);
|
||||
}
|
||||
|
||||
|
||||
SocketAddress::SocketAddress(Family fam, const std::string& hostAddress, Poco::UInt16 portNumber)
|
||||
{
|
||||
init(fam, hostAddress, portNumber);
|
||||
}
|
||||
|
||||
|
||||
SocketAddress::SocketAddress(const std::string& hostAddress, const std::string& portNumber)
|
||||
{
|
||||
init(hostAddress, resolveService(portNumber));
|
||||
}
|
||||
|
||||
|
||||
SocketAddress::SocketAddress(Family fam, const std::string& hostAddress, const std::string& portNumber)
|
||||
{
|
||||
init(fam, hostAddress, resolveService(portNumber));
|
||||
}
|
||||
|
||||
|
||||
SocketAddress::SocketAddress(Family fam, const std::string& addr)
|
||||
{
|
||||
init(fam, addr);
|
||||
}
|
||||
|
||||
|
||||
SocketAddress::SocketAddress(const std::string& hostAndPort)
|
||||
{
|
||||
poco_assert (!hostAndPort.empty());
|
||||
|
||||
std::string host;
|
||||
std::string port;
|
||||
std::string::const_iterator it = hostAndPort.begin();
|
||||
std::string::const_iterator end = hostAndPort.end();
|
||||
if (*it == '[')
|
||||
{
|
||||
++it;
|
||||
while (it != end && *it != ']') host += *it++;
|
||||
if (it == end) throw InvalidArgumentException("Malformed IPv6 address");
|
||||
++it;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (it != end && *it != ':') host += *it++;
|
||||
}
|
||||
if (it != end && *it == ':')
|
||||
{
|
||||
++it;
|
||||
while (it != end) port += *it++;
|
||||
}
|
||||
else throw InvalidArgumentException("Missing port number");
|
||||
init(host, resolveService(port));
|
||||
init(hostAndPort);
|
||||
}
|
||||
|
||||
|
||||
SocketAddress::SocketAddress(const SocketAddress& socketAddress)
|
||||
{
|
||||
if (socketAddress.family() == IPAddress::IPv4)
|
||||
if (socketAddress.family() == IPv4)
|
||||
newIPv4(reinterpret_cast<const sockaddr_in*>(socketAddress.addr()));
|
||||
else
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
else if (socketAddress.family() == IPv6)
|
||||
newIPv6(reinterpret_cast<const sockaddr_in6*>(socketAddress.addr()));
|
||||
#endif
|
||||
#if defined(POCO_OS_FAMILY_UNIX)
|
||||
else if (socketAddress.family() == UNIX_LOCAL)
|
||||
newLocal(reinterpret_cast<const sockaddr_un*>(socketAddress.addr()));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
SocketAddress::SocketAddress(const struct sockaddr* sockAddr, poco_socklen_t length)
|
||||
{
|
||||
if (length == sizeof(struct sockaddr_in))
|
||||
if (length == sizeof(struct sockaddr_in) && sockAddr->sa_family == AF_INET)
|
||||
newIPv4(reinterpret_cast<const struct sockaddr_in*>(sockAddr));
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
else if (length == sizeof(struct sockaddr_in6))
|
||||
else if (length == sizeof(struct sockaddr_in6) && sockAddr->sa_family == AF_INET6)
|
||||
newIPv6(reinterpret_cast<const struct sockaddr_in6*>(sockAddr));
|
||||
#endif
|
||||
else throw Poco::InvalidArgumentException("Invalid address length passed to SocketAddress()");
|
||||
#if defined(POCO_OS_FAMILY_UNIX)
|
||||
else if (length > 0 && length <= sizeof(struct sockaddr_un) && sockAddr->sa_family == AF_UNIX)
|
||||
newLocal(reinterpret_cast<const sockaddr_un*>(sockAddr));
|
||||
#endif
|
||||
else throw Poco::InvalidArgumentException("Invalid address length or family passed to SocketAddress()");
|
||||
}
|
||||
|
||||
|
||||
@ -141,6 +176,9 @@ bool SocketAddress::operator < (const SocketAddress& socketAddress) const
|
||||
{
|
||||
if (family() < socketAddress.family()) return true;
|
||||
if (family() > socketAddress.family()) return false;
|
||||
#if defined(POCO_OS_FAMILY_UNIX)
|
||||
if (family() == UNIX_LOCAL) return toString() < socketAddress.toString();
|
||||
#endif
|
||||
if (host() < socketAddress.host()) return true;
|
||||
if (host() > socketAddress.host()) return false;
|
||||
return (port() < socketAddress.port());
|
||||
@ -152,10 +190,16 @@ SocketAddress& SocketAddress::operator = (const SocketAddress& socketAddress)
|
||||
if (&socketAddress != this)
|
||||
{
|
||||
destruct();
|
||||
if (socketAddress.family() == IPAddress::IPv4)
|
||||
if (socketAddress.family() == IPv4)
|
||||
newIPv4(reinterpret_cast<const sockaddr_in*>(socketAddress.addr()));
|
||||
else
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
else if (socketAddress.family() == IPv6)
|
||||
newIPv6(reinterpret_cast<const sockaddr_in6*>(socketAddress.addr()));
|
||||
#endif
|
||||
#if defined(POCO_OS_FAMILY_UNIX)
|
||||
else if (socketAddress.family() == UNIX_LOCAL)
|
||||
newLocal(reinterpret_cast<const sockaddr_un*>(socketAddress.addr()));
|
||||
#endif
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@ -191,19 +235,15 @@ int SocketAddress::af() const
|
||||
}
|
||||
|
||||
|
||||
SocketAddress::Family SocketAddress::family() const
|
||||
{
|
||||
return static_cast<Family>(pImpl()->family());
|
||||
}
|
||||
|
||||
|
||||
std::string SocketAddress::toString() const
|
||||
{
|
||||
std::string result;
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
if (host().family() == IPAddress::IPv6)
|
||||
result.append("[");
|
||||
result.append(host().toString());
|
||||
if (host().family() == IPAddress::IPv6)
|
||||
result.append("]");
|
||||
#endif
|
||||
result.append(":");
|
||||
NumberFormatter::append(result, port());
|
||||
return result;
|
||||
return pImpl()->toString();
|
||||
}
|
||||
|
||||
|
||||
@ -232,7 +272,7 @@ void SocketAddress::init(const std::string& hostAddress, Poco::UInt16 portNumber
|
||||
HostEntry::AddressList addresses = he.addresses();
|
||||
if (addresses.size() > 0)
|
||||
{
|
||||
#if defined(POCO_HAVE_IPv6) && !defined(POCO_SOCKETADDRESS_DONT_PREFER_IPV4)
|
||||
#if defined(POCO_HAVE_IPv6) && defined(POCO_SOCKETADDRESS_PREFER_IPv4)
|
||||
// if we get both IPv4 and IPv6 addresses, prefer IPv4
|
||||
std::stable_sort(addresses.begin(), addresses.end(), AFLT());
|
||||
#endif
|
||||
@ -243,6 +283,109 @@ void SocketAddress::init(const std::string& hostAddress, Poco::UInt16 portNumber
|
||||
}
|
||||
|
||||
|
||||
void SocketAddress::init(Family fam, const std::string& hostAddress, Poco::UInt16 portNumber)
|
||||
{
|
||||
IPAddress ip;
|
||||
if (IPAddress::tryParse(hostAddress, ip))
|
||||
{
|
||||
if (ip.family() != fam) throw AddressFamilyMismatchException(hostAddress);
|
||||
init(ip, portNumber);
|
||||
}
|
||||
else
|
||||
{
|
||||
HostEntry he = DNS::hostByName(hostAddress);
|
||||
HostEntry::AddressList addresses = he.addresses();
|
||||
if (addresses.size() > 0)
|
||||
{
|
||||
for (HostEntry::AddressList::const_iterator it = addresses.begin(); it != addresses.end(); ++it)
|
||||
{
|
||||
if (it->family() == fam)
|
||||
{
|
||||
init(*it, portNumber);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw AddressFamilyMismatchException(hostAddress);
|
||||
}
|
||||
else throw HostNotFoundException("No address found for host", hostAddress);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SocketAddress::init(Family fam, const std::string& address)
|
||||
{
|
||||
#if defined(POCO_OS_FAMILY_UNIX)
|
||||
if (fam == UNIX_LOCAL)
|
||||
{
|
||||
newLocal(address);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
std::string host;
|
||||
std::string port;
|
||||
std::string::const_iterator it = address.begin();
|
||||
std::string::const_iterator end = address.end();
|
||||
|
||||
if (*it == '[')
|
||||
{
|
||||
++it;
|
||||
while (it != end && *it != ']') host += *it++;
|
||||
if (it == end) throw InvalidArgumentException("Malformed IPv6 address");
|
||||
++it;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (it != end && *it != ':') host += *it++;
|
||||
}
|
||||
if (it != end && *it == ':')
|
||||
{
|
||||
++it;
|
||||
while (it != end) port += *it++;
|
||||
}
|
||||
else throw InvalidArgumentException("Missing port number");
|
||||
init(fam, host, resolveService(port));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SocketAddress::init(const std::string& hostAndPort)
|
||||
{
|
||||
poco_assert (!hostAndPort.empty());
|
||||
|
||||
std::string host;
|
||||
std::string port;
|
||||
std::string::const_iterator it = hostAndPort.begin();
|
||||
std::string::const_iterator end = hostAndPort.end();
|
||||
|
||||
#if defined(POCO_OS_FAMILY_UNIX)
|
||||
if (*it == '/')
|
||||
{
|
||||
newLocal(hostAndPort);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (*it == '[')
|
||||
{
|
||||
++it;
|
||||
while (it != end && *it != ']') host += *it++;
|
||||
if (it == end) throw InvalidArgumentException("Malformed IPv6 address");
|
||||
++it;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (it != end && *it != ':') host += *it++;
|
||||
}
|
||||
if (it != end && *it == ':')
|
||||
{
|
||||
++it;
|
||||
while (it != end) port += *it++;
|
||||
}
|
||||
else throw InvalidArgumentException("Missing port number");
|
||||
init(host, resolveService(port));
|
||||
}
|
||||
|
||||
|
||||
Poco::UInt16 SocketAddress::resolveService(const std::string& service)
|
||||
{
|
||||
unsigned port;
|
||||
@ -266,3 +409,29 @@ Poco::UInt16 SocketAddress::resolveService(const std::string& service)
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
||||
|
||||
|
||||
Poco::BinaryWriter& operator << (Poco::BinaryWriter& writer, const Poco::Net::SocketAddress& value)
|
||||
{
|
||||
writer << value.host();
|
||||
writer << value.port();
|
||||
return writer;
|
||||
}
|
||||
|
||||
|
||||
Poco::BinaryReader& operator >> (Poco::BinaryReader& reader, Poco::Net::SocketAddress& value)
|
||||
{
|
||||
Poco::Net::IPAddress host;
|
||||
reader >> host;
|
||||
Poco::UInt16 port;
|
||||
reader >> port;
|
||||
value = Poco::Net::SocketAddress(host, port);
|
||||
return reader;
|
||||
}
|
||||
|
||||
|
||||
std::ostream& operator << (std::ostream& ostr, const Poco::Net::SocketAddress& address)
|
||||
{
|
||||
ostr << address.toString();
|
||||
return ostr;
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include "Poco/Net/SocketAddressImpl.h"
|
||||
#include "Poco/Net/SocketDefs.h"
|
||||
#include "Poco/NumberFormatter.h"
|
||||
#include <cstring>
|
||||
|
||||
|
||||
@ -60,11 +61,22 @@ IPv4SocketAddressImpl::IPv4SocketAddressImpl(const void* addr, UInt16 port)
|
||||
{
|
||||
std::memset(&_addr, 0, sizeof(_addr));
|
||||
_addr.sin_family = AF_INET;
|
||||
poco_set_sin_len(&_addr);
|
||||
std::memcpy(&_addr.sin_addr, addr, sizeof(_addr.sin_addr));
|
||||
_addr.sin_port = port;
|
||||
}
|
||||
|
||||
|
||||
std::string IPv4SocketAddressImpl::toString() const
|
||||
{
|
||||
std::string result;
|
||||
result.append(host().toString());
|
||||
result.append(":");
|
||||
NumberFormatter::append(result, ntohs(port()));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
|
||||
|
||||
@ -100,7 +112,59 @@ IPv6SocketAddressImpl::IPv6SocketAddressImpl(const void* addr, UInt16 port, UInt
|
||||
}
|
||||
|
||||
|
||||
std::string IPv6SocketAddressImpl::toString() const
|
||||
{
|
||||
std::string result;
|
||||
result.append("[");
|
||||
result.append(host().toString());
|
||||
result.append("]");
|
||||
result.append(":");
|
||||
NumberFormatter::append(result, ntohs(port()));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#endif // POCO_HAVE_IPv6
|
||||
|
||||
|
||||
#if defined(POCO_OS_FAMILY_UNIX)
|
||||
|
||||
|
||||
//
|
||||
// LocalSocketAddressImpl
|
||||
//
|
||||
|
||||
|
||||
LocalSocketAddressImpl::LocalSocketAddressImpl(const struct sockaddr_un* addr)
|
||||
{
|
||||
_pAddr = new sockaddr_un;
|
||||
std::memcpy(_pAddr, addr, sizeof(struct sockaddr_un));
|
||||
}
|
||||
|
||||
|
||||
LocalSocketAddressImpl::LocalSocketAddressImpl(const char* path)
|
||||
{
|
||||
_pAddr = new sockaddr_un;
|
||||
poco_set_sun_len(_pAddr, std::strlen(path) + sizeof(struct sockaddr_un) - sizeof(_pAddr->sun_path) + 1);
|
||||
_pAddr->sun_family = AF_UNIX;
|
||||
std::strcpy(_pAddr->sun_path, path);
|
||||
}
|
||||
|
||||
|
||||
LocalSocketAddressImpl::~LocalSocketAddressImpl()
|
||||
{
|
||||
delete _pAddr;
|
||||
}
|
||||
|
||||
|
||||
std::string LocalSocketAddressImpl::toString() const
|
||||
{
|
||||
std::string result(path());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#endif // POCO_OS_FAMILY_UNIX
|
||||
|
||||
|
||||
} } } // namespace Poco::Net::Impl
|
||||
|
@ -31,6 +31,11 @@
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef POCO_OS_FAMILY_WINDOWS
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
|
||||
using Poco::IOException;
|
||||
using Poco::TimeoutException;
|
||||
using Poco::InvalidArgumentException;
|
||||
@ -42,16 +47,34 @@ namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
bool checkIsBrokenTimeout()
|
||||
{
|
||||
#if defined(POCO_BROKEN_TIMEOUTS)
|
||||
return true;
|
||||
#elif defined(POCO_OS_FAMILY_WINDOWS)
|
||||
// on Windows 7 and lower, socket timeouts have a minimum of 500ms, use poll for timeouts on this case
|
||||
// https://social.msdn.microsoft.com/Forums/en-US/76620f6d-22b1-4872-aaf0-833204f3f867/minimum-timeout-value-for-sorcvtimeo
|
||||
OSVERSIONINFO vi;
|
||||
vi.dwOSVersionInfoSize = sizeof(vi);
|
||||
if (GetVersionEx(&vi) == 0) return true; //throw SystemException("Cannot get OS version information");
|
||||
return vi.dwMajorVersion < 6 || (vi.dwMajorVersion == 6 && vi.dwMinorVersion < 2);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
SocketImpl::SocketImpl():
|
||||
_sockfd(POCO_INVALID_SOCKET),
|
||||
_blocking(true)
|
||||
_blocking(true),
|
||||
_isBrokenTimeout(checkIsBrokenTimeout())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SocketImpl::SocketImpl(poco_socket_t sockfd):
|
||||
_sockfd(sockfd),
|
||||
_blocking(true)
|
||||
_blocking(true),
|
||||
_isBrokenTimeout(checkIsBrokenTimeout())
|
||||
{
|
||||
}
|
||||
|
||||
@ -165,16 +188,21 @@ void SocketImpl::connectNB(const SocketAddress& address)
|
||||
|
||||
|
||||
void SocketImpl::bind(const SocketAddress& address, bool reuseAddress)
|
||||
{
|
||||
bind(address, reuseAddress, true);
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::bind(const SocketAddress& address, bool reuseAddress, bool reusePort)
|
||||
{
|
||||
if (_sockfd == POCO_INVALID_SOCKET)
|
||||
{
|
||||
init(address.af());
|
||||
}
|
||||
if (reuseAddress)
|
||||
{
|
||||
setReuseAddress(true);
|
||||
if (reusePort)
|
||||
setReusePort(true);
|
||||
}
|
||||
#if defined(POCO_VXWORKS)
|
||||
int rc = ::bind(_sockfd, (sockaddr*) address.addr(), address.length());
|
||||
#else
|
||||
@ -185,9 +213,15 @@ void SocketImpl::bind(const SocketAddress& address, bool reuseAddress)
|
||||
|
||||
|
||||
void SocketImpl::bind6(const SocketAddress& address, bool reuseAddress, bool ipV6Only)
|
||||
{
|
||||
bind6(address, reuseAddress, true, ipV6Only);
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::bind6(const SocketAddress& address, bool reuseAddress, bool reusePort, bool ipV6Only)
|
||||
{
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
if (address.family() != IPAddress::IPv6)
|
||||
if (address.family() != SocketAddress::IPv6)
|
||||
throw Poco::InvalidArgumentException("SocketAddress must be an IPv6 address");
|
||||
|
||||
if (_sockfd == POCO_INVALID_SOCKET)
|
||||
@ -200,10 +234,9 @@ void SocketImpl::bind6(const SocketAddress& address, bool reuseAddress, bool ipV
|
||||
if (ipV6Only) throw Poco::NotImplementedException("IPV6_V6ONLY not defined.");
|
||||
#endif
|
||||
if (reuseAddress)
|
||||
{
|
||||
setReuseAddress(true);
|
||||
if (reusePort)
|
||||
setReusePort(true);
|
||||
}
|
||||
int rc = ::bind(_sockfd, address.addr(), address.length());
|
||||
if (rc != 0) error(address.toString());
|
||||
#else
|
||||
@ -260,13 +293,14 @@ void SocketImpl::shutdown()
|
||||
|
||||
int SocketImpl::sendBytes(const void* buffer, int length, int flags)
|
||||
{
|
||||
#if defined(POCO_BROKEN_TIMEOUTS)
|
||||
if (_sndTimeout.totalMicroseconds() != 0)
|
||||
if (_isBrokenTimeout)
|
||||
{
|
||||
if (!poll(_sndTimeout, SELECT_WRITE))
|
||||
throw TimeoutException();
|
||||
if (_sndTimeout.totalMicroseconds() != 0)
|
||||
{
|
||||
if (!poll(_sndTimeout, SELECT_WRITE))
|
||||
throw TimeoutException();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int rc;
|
||||
do
|
||||
@ -282,13 +316,14 @@ int SocketImpl::sendBytes(const void* buffer, int length, int flags)
|
||||
|
||||
int SocketImpl::receiveBytes(void* buffer, int length, int flags)
|
||||
{
|
||||
#if defined(POCO_BROKEN_TIMEOUTS)
|
||||
if (_recvTimeout.totalMicroseconds() != 0)
|
||||
if (_isBrokenTimeout)
|
||||
{
|
||||
if (!poll(_recvTimeout, SELECT_READ))
|
||||
throw TimeoutException();
|
||||
if (_recvTimeout.totalMicroseconds() != 0)
|
||||
{
|
||||
if (!poll(_recvTimeout, SELECT_READ))
|
||||
throw TimeoutException();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int rc;
|
||||
do
|
||||
@ -331,13 +366,14 @@ int SocketImpl::sendTo(const void* buffer, int length, const SocketAddress& addr
|
||||
|
||||
int SocketImpl::receiveFrom(void* buffer, int length, SocketAddress& address, int flags)
|
||||
{
|
||||
#if defined(POCO_BROKEN_TIMEOUTS)
|
||||
if (_recvTimeout.totalMicroseconds() != 0)
|
||||
if (_isBrokenTimeout)
|
||||
{
|
||||
if (!poll(_recvTimeout, SELECT_READ))
|
||||
throw TimeoutException();
|
||||
if (_recvTimeout.totalMicroseconds() != 0)
|
||||
{
|
||||
if (!poll(_recvTimeout, SELECT_READ))
|
||||
throw TimeoutException();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
char abuffer[SocketAddress::MAX_ADDRESS_LENGTH];
|
||||
struct sockaddr* pSA = reinterpret_cast<struct sockaddr*>(abuffer);
|
||||
@ -555,11 +591,11 @@ void SocketImpl::setSendTimeout(const Poco::Timespan& timeout)
|
||||
#if defined(_WIN32) && !defined(POCO_BROKEN_TIMEOUTS)
|
||||
int value = (int) timeout.totalMilliseconds();
|
||||
setOption(SOL_SOCKET, SO_SNDTIMEO, value);
|
||||
#elif defined(POCO_BROKEN_TIMEOUTS)
|
||||
_sndTimeout = timeout;
|
||||
#else
|
||||
#elif !defined(POCO_BROKEN_TIMEOUTS)
|
||||
setOption(SOL_SOCKET, SO_SNDTIMEO, timeout);
|
||||
#endif
|
||||
if (_isBrokenTimeout)
|
||||
_sndTimeout = timeout;
|
||||
}
|
||||
|
||||
|
||||
@ -570,11 +606,11 @@ Poco::Timespan SocketImpl::getSendTimeout()
|
||||
int value;
|
||||
getOption(SOL_SOCKET, SO_SNDTIMEO, value);
|
||||
result = Timespan::TimeDiff(value)*1000;
|
||||
#elif defined(POCO_BROKEN_TIMEOUTS)
|
||||
result = _sndTimeout;
|
||||
#else
|
||||
#elif !defined(POCO_BROKEN_TIMEOUTS)
|
||||
getOption(SOL_SOCKET, SO_SNDTIMEO, result);
|
||||
#endif
|
||||
if (_isBrokenTimeout)
|
||||
result = _sndTimeout;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -588,9 +624,9 @@ void SocketImpl::setReceiveTimeout(const Poco::Timespan& timeout)
|
||||
#else
|
||||
setOption(SOL_SOCKET, SO_RCVTIMEO, timeout);
|
||||
#endif
|
||||
#else
|
||||
_recvTimeout = timeout;
|
||||
#endif
|
||||
if (_isBrokenTimeout)
|
||||
_recvTimeout = timeout;
|
||||
}
|
||||
|
||||
|
||||
@ -601,11 +637,11 @@ Poco::Timespan SocketImpl::getReceiveTimeout()
|
||||
int value;
|
||||
getOption(SOL_SOCKET, SO_RCVTIMEO, value);
|
||||
result = Timespan::TimeDiff(value)*1000;
|
||||
#elif defined(POCO_BROKEN_TIMEOUTS)
|
||||
result = _recvTimeout;
|
||||
#else
|
||||
#elif !defined(POCO_BROKEN_TIMEOUTS)
|
||||
getOption(SOL_SOCKET, SO_RCVTIMEO, result);
|
||||
#endif
|
||||
if (_isBrokenTimeout)
|
||||
result = _recvTimeout;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1060,6 +1096,8 @@ void SocketImpl::error(int code, const std::string& arg)
|
||||
throw IOException("Broken pipe", code);
|
||||
case EBADF:
|
||||
throw IOException("Bad socket descriptor", code);
|
||||
case ENOENT:
|
||||
throw IOException("Not found", arg, code);
|
||||
#endif
|
||||
default:
|
||||
throw IOException(NumberFormatter::format(code), arg, code);
|
||||
|
@ -39,7 +39,7 @@ StreamSocket::StreamSocket(const SocketAddress& address): Socket(new StreamSocke
|
||||
}
|
||||
|
||||
|
||||
StreamSocket::StreamSocket(IPAddress::Family family): Socket(new StreamSocketImpl(family))
|
||||
StreamSocket::StreamSocket(SocketAddress::Family family): Socket(new StreamSocketImpl(family))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -26,13 +26,17 @@ StreamSocketImpl::StreamSocketImpl()
|
||||
}
|
||||
|
||||
|
||||
StreamSocketImpl::StreamSocketImpl(IPAddress::Family family)
|
||||
StreamSocketImpl::StreamSocketImpl(SocketAddress::Family family)
|
||||
{
|
||||
if (family == IPAddress::IPv4)
|
||||
if (family == SocketAddress::IPv4)
|
||||
init(AF_INET);
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
else if (family == IPAddress::IPv6)
|
||||
else if (family == SocketAddress::IPv6)
|
||||
init(AF_INET6);
|
||||
#endif
|
||||
#if defined(POCO_OS_FAMILY_UNIX)
|
||||
else if (family == SocketAddress::UNIX_LOCAL)
|
||||
init(AF_UNIX);
|
||||
#endif
|
||||
else throw Poco::InvalidArgumentException("Invalid or unsupported address family passed to StreamSocketImpl");
|
||||
}
|
||||
|
@ -28,6 +28,21 @@ namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
//
|
||||
// TCPServerConnectionFilter
|
||||
//
|
||||
|
||||
|
||||
TCPServerConnectionFilter::~TCPServerConnectionFilter()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// TCPServer
|
||||
//
|
||||
|
||||
|
||||
TCPServer::TCPServer(TCPServerConnectionFactory::Ptr pFactory, Poco::UInt16 portNumber, TCPServerParams::Ptr pParams):
|
||||
_socket(ServerSocket(portNumber)),
|
||||
_thread(threadName(_socket)),
|
||||
@ -120,9 +135,18 @@ void TCPServer::run()
|
||||
try
|
||||
{
|
||||
StreamSocket ss = _socket.acceptConnection();
|
||||
// enabe nodelay per default: OSX really needs that
|
||||
ss.setNoDelay(true);
|
||||
_pDispatcher->enqueue(ss);
|
||||
|
||||
if (!_pConnectionFilter || _pConnectionFilter->accept(ss))
|
||||
{
|
||||
// enable nodelay per default: OSX really needs that
|
||||
#if defined(POCO_OS_FAMILY_UNIX)
|
||||
if (ss.address().family() != AddressFamily::UNIX_LOCAL)
|
||||
#endif
|
||||
{
|
||||
ss.setNoDelay(true);
|
||||
}
|
||||
_pDispatcher->enqueue(ss);
|
||||
}
|
||||
}
|
||||
catch (Poco::Exception& exc)
|
||||
{
|
||||
@ -191,6 +215,14 @@ int TCPServer::refusedConnections() const
|
||||
}
|
||||
|
||||
|
||||
void TCPServer::setConnectionFilter(const TCPServerConnectionFilter::Ptr& pConnectionFilter)
|
||||
{
|
||||
poco_assert (_stopped);
|
||||
|
||||
_pConnectionFilter = pConnectionFilter;
|
||||
}
|
||||
|
||||
|
||||
std::string TCPServer::threadName(const ServerSocket& socket)
|
||||
{
|
||||
#if _WIN32_WCE == 0x0800
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "Poco/Net/HTTPClientSession.h"
|
||||
#include "Poco/Net/HTTPServerSession.h"
|
||||
#include "Poco/Net/NetException.h"
|
||||
#include "Poco/Buffer.h"
|
||||
#include "Poco/MemoryStream.h"
|
||||
#include "Poco/NullStream.h"
|
||||
#include "Poco/BinaryWriter.h"
|
||||
@ -113,6 +112,14 @@ int WebSocket::receiveFrame(void* buffer, int length, int& flags)
|
||||
}
|
||||
|
||||
|
||||
int WebSocket::receiveFrame(Poco::Buffer<char>& buffer, int& flags)
|
||||
{
|
||||
int n = static_cast<WebSocketImpl*>(impl())->receiveBytes(buffer, 0);
|
||||
flags = static_cast<WebSocketImpl*>(impl())->frameFlags();
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
WebSocket::Mode WebSocket::mode() const
|
||||
{
|
||||
return static_cast<WebSocketImpl*>(impl())->mustMaskPayload() ? WS_CLIENT : WS_SERVER;
|
||||
|
@ -106,7 +106,7 @@ int WebSocketImpl::sendBytes(const void* buffer, int length, int flags)
|
||||
}
|
||||
|
||||
|
||||
int WebSocketImpl::receiveBytes(void* buffer, int length, int)
|
||||
int WebSocketImpl::receiveHeader(char mask[4], bool& useMask)
|
||||
{
|
||||
char header[MAX_HEADER_LENGTH];
|
||||
int n = receiveNBytes(header, 2);
|
||||
@ -116,82 +116,101 @@ int WebSocketImpl::receiveBytes(void* buffer, int length, int)
|
||||
return n;
|
||||
}
|
||||
poco_assert (n == 2);
|
||||
Poco::UInt8 lengthByte = static_cast<Poco::UInt8>(header[1]);
|
||||
int maskOffset = 0;
|
||||
if (lengthByte & FRAME_FLAG_MASK) maskOffset += 4;
|
||||
lengthByte &= 0x7f;
|
||||
if (lengthByte > 0 || maskOffset > 0)
|
||||
{
|
||||
if (lengthByte + 2 + maskOffset < MAX_HEADER_LENGTH)
|
||||
{
|
||||
n = receiveNBytes(header + 2, lengthByte + maskOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
n = receiveNBytes(header + 2, MAX_HEADER_LENGTH - 2);
|
||||
}
|
||||
if (n <= 0) throw WebSocketException("Incomplete header received", WebSocket::WS_ERR_INCOMPLETE_FRAME);
|
||||
n += 2;
|
||||
}
|
||||
Poco::MemoryInputStream istr(header, n);
|
||||
Poco::BinaryReader reader(istr, Poco::BinaryReader::NETWORK_BYTE_ORDER);
|
||||
Poco::UInt8 flags;
|
||||
char mask[4];
|
||||
reader >> flags >> lengthByte;
|
||||
Poco::UInt8 flags = static_cast<Poco::UInt8>(header[0]);
|
||||
_frameFlags = flags;
|
||||
int payloadLength = 0;
|
||||
int payloadOffset = 2;
|
||||
if ((lengthByte & 0x7f) == 127)
|
||||
Poco::UInt8 lengthByte = static_cast<Poco::UInt8>(header[1]);
|
||||
useMask = ((lengthByte & FRAME_FLAG_MASK) != 0);
|
||||
int payloadLength;
|
||||
lengthByte &= 0x7f;
|
||||
if (lengthByte == 127)
|
||||
{
|
||||
n = receiveNBytes(header + 2, 8);
|
||||
if (n <= 0)
|
||||
{
|
||||
_frameFlags = 0;
|
||||
return n;
|
||||
}
|
||||
Poco::MemoryInputStream istr(header + 2, 8);
|
||||
Poco::BinaryReader reader(istr, Poco::BinaryReader::NETWORK_BYTE_ORDER);
|
||||
Poco::UInt64 l;
|
||||
reader >> l;
|
||||
if (l > length) throw WebSocketException(Poco::format("Insufficient buffer for payload size %Lu", l), WebSocket::WS_ERR_PAYLOAD_TOO_BIG);
|
||||
payloadLength = static_cast<int>(l);
|
||||
payloadOffset += 8;
|
||||
}
|
||||
else if ((lengthByte & 0x7f) == 126)
|
||||
else if (lengthByte == 126)
|
||||
{
|
||||
n = receiveNBytes(header + 2, 2);
|
||||
if (n <= 0)
|
||||
{
|
||||
_frameFlags = 0;
|
||||
return n;
|
||||
}
|
||||
Poco::MemoryInputStream istr(header + 2, 2);
|
||||
Poco::BinaryReader reader(istr, Poco::BinaryReader::NETWORK_BYTE_ORDER);
|
||||
Poco::UInt16 l;
|
||||
reader >> l;
|
||||
if (l > length) throw WebSocketException(Poco::format("Insufficient buffer for payload size %hu", l), WebSocket::WS_ERR_PAYLOAD_TOO_BIG);
|
||||
payloadLength = static_cast<int>(l);
|
||||
payloadOffset += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
Poco::UInt8 l = lengthByte & 0x7f;
|
||||
if (l > length) throw WebSocketException(Poco::format("Insufficient buffer for payload size %u", unsigned(l)), WebSocket::WS_ERR_PAYLOAD_TOO_BIG);
|
||||
payloadLength = static_cast<int>(l);
|
||||
payloadLength = lengthByte;
|
||||
}
|
||||
if (lengthByte & FRAME_FLAG_MASK)
|
||||
|
||||
if (useMask)
|
||||
{
|
||||
reader.readRaw(mask, 4);
|
||||
payloadOffset += 4;
|
||||
n = receiveNBytes(mask, 4);
|
||||
if (n <= 0)
|
||||
{
|
||||
_frameFlags = 0;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
int received = 0;
|
||||
if (payloadOffset < n)
|
||||
|
||||
return payloadLength;
|
||||
}
|
||||
|
||||
|
||||
int WebSocketImpl::receivePayload(char *buffer, int payloadLength, char mask[4], bool useMask)
|
||||
{
|
||||
int received = receiveNBytes(reinterpret_cast<char*>(buffer), payloadLength);
|
||||
if (received <= 0) throw WebSocketException("Incomplete frame received", WebSocket::WS_ERR_INCOMPLETE_FRAME);
|
||||
|
||||
if (useMask)
|
||||
{
|
||||
std::memcpy(buffer, header + payloadOffset, n - payloadOffset);
|
||||
received = n - payloadOffset;
|
||||
}
|
||||
if (received < payloadLength)
|
||||
{
|
||||
n = receiveNBytes(reinterpret_cast<char*>(buffer) + received, payloadLength - received);
|
||||
if (n <= 0) throw WebSocketException("Incomplete frame received", WebSocket::WS_ERR_INCOMPLETE_FRAME);
|
||||
received += n;
|
||||
}
|
||||
if (lengthByte & FRAME_FLAG_MASK)
|
||||
{
|
||||
char* p = reinterpret_cast<char*>(buffer);
|
||||
for (int i = 0; i < received; i++)
|
||||
{
|
||||
p[i] ^= mask[i % 4];
|
||||
buffer[i] ^= mask[i % 4];
|
||||
}
|
||||
}
|
||||
return received;
|
||||
}
|
||||
|
||||
|
||||
int WebSocketImpl::receiveBytes(void* buffer, int length, int)
|
||||
{
|
||||
char mask[4];
|
||||
bool useMask;
|
||||
int payloadLength = receiveHeader(mask, useMask);
|
||||
if (payloadLength <= 0)
|
||||
return payloadLength;
|
||||
if (payloadLength > length)
|
||||
throw WebSocketException(Poco::format("Insufficient buffer for payload size %hu", payloadLength), WebSocket::WS_ERR_PAYLOAD_TOO_BIG);
|
||||
return receivePayload(reinterpret_cast<char*>(buffer), payloadLength, mask, useMask);
|
||||
}
|
||||
|
||||
|
||||
int WebSocketImpl::receiveBytes(Poco::Buffer<char>& buffer, int)
|
||||
{
|
||||
char mask[4];
|
||||
bool useMask;
|
||||
int payloadLength = receiveHeader(mask, useMask);
|
||||
if (payloadLength <= 0)
|
||||
return payloadLength;
|
||||
int oldSize = buffer.size();
|
||||
buffer.resize(oldSize + payloadLength);
|
||||
return receivePayload(buffer.begin() + oldSize, payloadLength, mask, useMask);
|
||||
}
|
||||
|
||||
|
||||
int WebSocketImpl::receiveNBytes(void* buffer, int bytes)
|
||||
{
|
||||
int received = receiveSomeBytes(reinterpret_cast<char*>(buffer), bytes);
|
||||
@ -212,7 +231,7 @@ int WebSocketImpl::receiveNBytes(void* buffer, int bytes)
|
||||
|
||||
int WebSocketImpl::receiveSomeBytes(char* buffer, int bytes)
|
||||
{
|
||||
int n = static_cast<int>(_buffer.size() - _bufferOffset);
|
||||
int n = _buffer.size() - _bufferOffset;
|
||||
if (n > 0)
|
||||
{
|
||||
if (bytes < n) n = bytes;
|
||||
@ -257,12 +276,24 @@ void WebSocketImpl::bind(const SocketAddress& address, bool reuseAddress)
|
||||
}
|
||||
|
||||
|
||||
void WebSocketImpl::bind(const SocketAddress& address, bool reuseAddress, bool reusePort)
|
||||
{
|
||||
throw Poco::InvalidAccessException("Cannot bind() a WebSocketImpl");
|
||||
}
|
||||
|
||||
|
||||
void WebSocketImpl::bind6(const SocketAddress& address, bool reuseAddress, bool ipV6Only)
|
||||
{
|
||||
throw Poco::InvalidAccessException("Cannot bind6() a WebSocketImpl");
|
||||
}
|
||||
|
||||
|
||||
void WebSocketImpl::bind6(const SocketAddress& address, bool reuseAddress, bool reusePort, bool ipV6Only)
|
||||
{
|
||||
throw Poco::InvalidAccessException("Cannot bind6() a WebSocketImpl");
|
||||
}
|
||||
|
||||
|
||||
void WebSocketImpl::listen(int backlog)
|
||||
{
|
||||
throw Poco::InvalidAccessException("Cannot listen() on a WebSocketImpl");
|
||||
|
@ -37,20 +37,20 @@ DNSTest::~DNSTest()
|
||||
|
||||
void DNSTest::testHostByName()
|
||||
{
|
||||
HostEntry he1 = DNS::hostByName("aliastest.appinf.com");
|
||||
HostEntry he1 = DNS::hostByName("aliastest.pocoproject.org");
|
||||
// different systems report different canonical names, unfortunately.
|
||||
assert (he1.name() == "dnstest.appinf.com" || he1.name() == "aliastest.appinf.com");
|
||||
assert (he1.name() == "dnstest.pocoproject.org" || he1.name() == "aliastest.pocoproject.org");
|
||||
#if !defined(POCO_HAVE_ADDRINFO)
|
||||
// getaddrinfo() does not report any aliases
|
||||
assert (!he1.aliases().empty());
|
||||
assert (he1.aliases()[0] == "aliastest.appinf.com");
|
||||
assert (he1.aliases()[0] == "aliastest.pocoproject.org");
|
||||
#endif
|
||||
assert (he1.addresses().size() >= 1);
|
||||
assert (he1.addresses()[0].toString() == "1.2.3.4");
|
||||
|
||||
try
|
||||
{
|
||||
HostEntry he1 = DNS::hostByName("nohost.appinf.com");
|
||||
HostEntry he1 = DNS::hostByName("nohost.pocoproject.org");
|
||||
fail("host not found - must throw");
|
||||
}
|
||||
catch (HostNotFoundException&)
|
||||
|
@ -49,7 +49,7 @@ void DatagramSocketTest::testEcho()
|
||||
UDPEchoServer echoServer;
|
||||
DatagramSocket ss;
|
||||
char buffer[256];
|
||||
ss.connect(SocketAddress("localhost", echoServer.port()));
|
||||
ss.connect(SocketAddress("127.0.0.1", echoServer.port()));
|
||||
int n = ss.sendBytes("hello", 5);
|
||||
assert (n == 5);
|
||||
n = ss.receiveBytes(buffer, sizeof(buffer));
|
||||
@ -61,9 +61,9 @@ void DatagramSocketTest::testEcho()
|
||||
|
||||
void DatagramSocketTest::testSendToReceiveFrom()
|
||||
{
|
||||
UDPEchoServer echoServer(SocketAddress("localhost", 0));
|
||||
DatagramSocket ss;
|
||||
int n = ss.sendTo("hello", 5, SocketAddress("localhost", echoServer.port()));
|
||||
UDPEchoServer echoServer(SocketAddress("127.0.0.1", 0));
|
||||
DatagramSocket ss(SocketAddress::IPv4);
|
||||
int n = ss.sendTo("hello", 5, SocketAddress("127.0.0.1", echoServer.port()));
|
||||
assert (n == 5);
|
||||
char buffer[256];
|
||||
SocketAddress sa;
|
||||
@ -76,6 +76,21 @@ void DatagramSocketTest::testSendToReceiveFrom()
|
||||
}
|
||||
|
||||
|
||||
void DatagramSocketTest::testUnbound()
|
||||
{
|
||||
UDPEchoServer echoServer;
|
||||
DatagramSocket ss;
|
||||
char buffer[256];
|
||||
ss.connect(SocketAddress("127.0.0.1", echoServer.port()));
|
||||
int n = ss.sendBytes("hello", 5);
|
||||
assert (n == 5);
|
||||
n = ss.receiveBytes(buffer, sizeof(buffer));
|
||||
assert (n == 5);
|
||||
assert (std::string(buffer, n) == "hello");
|
||||
ss.close();
|
||||
}
|
||||
|
||||
|
||||
void DatagramSocketTest::testBroadcast()
|
||||
{
|
||||
UDPEchoServer echoServer;
|
||||
@ -134,6 +149,7 @@ CppUnit::Test* DatagramSocketTest::suite()
|
||||
|
||||
CppUnit_addTest(pSuite, DatagramSocketTest, testEcho);
|
||||
CppUnit_addTest(pSuite, DatagramSocketTest, testSendToReceiveFrom);
|
||||
CppUnit_addTest(pSuite, DatagramSocketTest, testUnbound);
|
||||
#if (POCO_OS != POCO_OS_FREE_BSD) // works only with local net bcast and very randomly
|
||||
CppUnit_addTest(pSuite, DatagramSocketTest, testBroadcast);
|
||||
#endif
|
||||
|
@ -26,6 +26,7 @@ public:
|
||||
|
||||
void testEcho();
|
||||
void testSendToReceiveFrom();
|
||||
void testUnbound();
|
||||
void testBroadcast();
|
||||
|
||||
void setUp();
|
||||
|
@ -35,7 +35,7 @@ void DialogSocketTest::testDialogSocket()
|
||||
{
|
||||
EchoServer echoServer;
|
||||
DialogSocket ds;
|
||||
ds.connect(SocketAddress("localhost", echoServer.port()));
|
||||
ds.connect(SocketAddress("127.0.0.1", echoServer.port()));
|
||||
|
||||
ds.sendMessage("Hello, world!");
|
||||
std::string str;
|
||||
|
@ -30,6 +30,16 @@ EchoServer::EchoServer():
|
||||
}
|
||||
|
||||
|
||||
EchoServer::EchoServer(const Poco::Net::SocketAddress& address):
|
||||
_socket(address),
|
||||
_thread("EchoServer"),
|
||||
_stop(false)
|
||||
{
|
||||
_thread.start(*this);
|
||||
_ready.wait();
|
||||
}
|
||||
|
||||
|
||||
EchoServer::~EchoServer()
|
||||
{
|
||||
_stop = true;
|
||||
|
@ -27,6 +27,9 @@ public:
|
||||
EchoServer();
|
||||
/// Creates the EchoServer.
|
||||
|
||||
EchoServer(const Poco::Net::SocketAddress& address);
|
||||
/// Creates the EchoServer using the given address.
|
||||
|
||||
~EchoServer();
|
||||
/// Destroys the EchoServer.
|
||||
|
||||
|
@ -92,7 +92,7 @@ void FTPClientSessionTest::testLogin1()
|
||||
{
|
||||
DialogServer server;
|
||||
server.addResponse("220 localhost FTP ready");
|
||||
FTPClientSession session("localhost", server.port());
|
||||
FTPClientSession session("127.0.0.1", server.port());
|
||||
assert (session.isOpen());
|
||||
assert (!session.isLoggedIn());
|
||||
login(server, session);
|
||||
@ -123,7 +123,7 @@ void FTPClientSessionTest::testLogin2()
|
||||
server.addResponse("230 Welcome");
|
||||
server.addResponse("200 Type set to I");
|
||||
Poco::UInt16 serverPort = server.port();
|
||||
FTPClientSession session("localhost", serverPort, "user", "password");
|
||||
FTPClientSession session("127.0.0.1", serverPort, "user", "password");
|
||||
assert (session.isOpen());
|
||||
assert (session.isLoggedIn());
|
||||
server.addResponse("221 Good Bye");
|
||||
@ -137,7 +137,7 @@ void FTPClientSessionTest::testLogin2()
|
||||
server.addResponse("331 Password required");
|
||||
server.addResponse("230 Welcome");
|
||||
server.addResponse("200 Type set to I");
|
||||
session.open("localhost", serverPort, "user", "password");
|
||||
session.open("127.0.0.1", serverPort, "user", "password");
|
||||
assert (session.isOpen());
|
||||
assert (session.isLoggedIn());
|
||||
server.addResponse("221 Good Bye");
|
||||
@ -157,7 +157,7 @@ void FTPClientSessionTest::testLogin3()
|
||||
FTPClientSession session;
|
||||
assert (!session.isOpen());
|
||||
assert (!session.isLoggedIn());
|
||||
session.open("localhost", server.port(), "user", "password");
|
||||
session.open("127.0.0.1", server.port(), "user", "password");
|
||||
server.addResponse("221 Good Bye");
|
||||
session.close();
|
||||
assert (!session.isOpen());
|
||||
@ -170,7 +170,7 @@ void FTPClientSessionTest::testLoginFailed1()
|
||||
{
|
||||
DialogServer server;
|
||||
server.addResponse("421 localhost FTP not ready");
|
||||
FTPClientSession session("localhost", server.port());
|
||||
FTPClientSession session("127.0.0.1", server.port());
|
||||
try
|
||||
{
|
||||
session.login("user", "password");
|
||||
@ -190,7 +190,7 @@ void FTPClientSessionTest::testLoginFailed2()
|
||||
server.addResponse("220 localhost FTP ready");
|
||||
server.addResponse("331 Password required");
|
||||
server.addResponse("530 Login incorrect");
|
||||
FTPClientSession session("localhost", server.port());
|
||||
FTPClientSession session("127.0.0.1", server.port());
|
||||
try
|
||||
{
|
||||
session.login("user", "password");
|
||||
@ -211,7 +211,7 @@ void FTPClientSessionTest::testCommands()
|
||||
server.addResponse("331 Password required");
|
||||
server.addResponse("230 Welcome");
|
||||
server.addResponse("200 Type set to I");
|
||||
FTPClientSession session("localhost", server.port());
|
||||
FTPClientSession session("127.0.0.1", server.port());
|
||||
session.login("user", "password");
|
||||
std::string cmd = server.popCommand();
|
||||
assert (cmd == "USER user");
|
||||
@ -340,7 +340,7 @@ void FTPClientSessionTest::testDownloadPORT()
|
||||
server.addResponse("331 Password required");
|
||||
server.addResponse("230 Welcome");
|
||||
server.addResponse("200 Type set to I");
|
||||
FTPClientSession session("localhost", server.port());
|
||||
FTPClientSession session("127.0.0.1", server.port());
|
||||
session.setPassive(false);
|
||||
session.login("user", "password");
|
||||
server.clearCommands();
|
||||
@ -371,7 +371,7 @@ void FTPClientSessionTest::testDownloadPORT()
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd == "RETR test.txt");
|
||||
|
||||
SocketAddress sa("localhost", (Poco::UInt16) port);
|
||||
SocketAddress sa("127.0.0.1", (Poco::UInt16) port);
|
||||
DialogSocket dataSock;
|
||||
dataSock.connect(sa);
|
||||
|
||||
@ -395,7 +395,7 @@ void FTPClientSessionTest::testDownloadEPRT()
|
||||
server.addResponse("331 Password required");
|
||||
server.addResponse("230 Welcome");
|
||||
server.addResponse("200 Type set to I");
|
||||
FTPClientSession session("localhost", server.port());
|
||||
FTPClientSession session("127.0.0.1", server.port());
|
||||
session.setPassive(false);
|
||||
session.login("user", "password");
|
||||
server.clearCommands();
|
||||
@ -419,7 +419,7 @@ void FTPClientSessionTest::testDownloadEPRT()
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd == "RETR test.txt");
|
||||
|
||||
SocketAddress sa("localhost", (Poco::UInt16) port);
|
||||
SocketAddress sa("127.0.0.1", (Poco::UInt16) port);
|
||||
DialogSocket dataSock;
|
||||
dataSock.connect(sa);
|
||||
|
||||
@ -443,7 +443,7 @@ void FTPClientSessionTest::testDownloadPASV()
|
||||
server.addResponse("331 Password required");
|
||||
server.addResponse("230 Welcome");
|
||||
server.addResponse("200 Type set to I");
|
||||
FTPClientSession session("localhost", server.port());
|
||||
FTPClientSession session("127.0.0.1", server.port());
|
||||
session.login("user", "password");
|
||||
server.clearCommands();
|
||||
|
||||
@ -476,7 +476,7 @@ void FTPClientSessionTest::testDownloadEPSV()
|
||||
server.addResponse("331 Password required");
|
||||
server.addResponse("230 Welcome");
|
||||
server.addResponse("200 Type set to I");
|
||||
FTPClientSession session("localhost", server.port());
|
||||
FTPClientSession session("127.0.0.1", server.port());
|
||||
session.login("user", "password");
|
||||
server.clearCommands();
|
||||
|
||||
@ -511,7 +511,7 @@ void FTPClientSessionTest::testUpload()
|
||||
server.addResponse("331 Password required");
|
||||
server.addResponse("230 Welcome");
|
||||
server.addResponse("200 Type set to I");
|
||||
FTPClientSession session("localhost", server.port());
|
||||
FTPClientSession session("127.0.0.1", server.port());
|
||||
session.login("user", "password");
|
||||
server.clearCommands();
|
||||
|
||||
@ -544,7 +544,7 @@ void FTPClientSessionTest::testList()
|
||||
server.addResponse("331 Password required");
|
||||
server.addResponse("230 Welcome");
|
||||
server.addResponse("200 Type set to I");
|
||||
FTPClientSession session("localhost", server.port());
|
||||
FTPClientSession session("127.0.0.1", server.port());
|
||||
session.login("user", "password");
|
||||
server.clearCommands();
|
||||
|
||||
|
@ -75,7 +75,7 @@ void FTPStreamFactoryTest::testDownload()
|
||||
|
||||
URI uri;
|
||||
uri.setScheme("ftp");
|
||||
uri.setHost("localhost");
|
||||
uri.setHost("127.0.0.1");
|
||||
uri.setPort(server.port());
|
||||
uri.setPath("/test.txt;type=a");
|
||||
FTPStreamFactory sf;
|
||||
@ -116,7 +116,7 @@ void FTPStreamFactoryTest::testList()
|
||||
|
||||
URI uri;
|
||||
uri.setScheme("ftp");
|
||||
uri.setHost("localhost");
|
||||
uri.setHost("127.0.0.1");
|
||||
uri.setPort(server.port());
|
||||
uri.setPath("/usr/guest/data;type=d");
|
||||
FTPStreamFactory sf;
|
||||
@ -157,7 +157,7 @@ void FTPStreamFactoryTest::testUserInfo()
|
||||
|
||||
URI uri;
|
||||
uri.setScheme("ftp");
|
||||
uri.setHost("localhost");
|
||||
uri.setHost("127.0.0.1");
|
||||
uri.setPort(server.port());
|
||||
uri.setPath("/test.txt;type=a");
|
||||
uri.setUserInfo("user:secret");
|
||||
@ -200,7 +200,7 @@ void FTPStreamFactoryTest::testPasswordProvider()
|
||||
|
||||
URI uri;
|
||||
uri.setScheme("ftp");
|
||||
uri.setHost("localhost");
|
||||
uri.setHost("127.0.0.1");
|
||||
uri.setPort(server.port());
|
||||
uri.setPath("/test.txt;type=a");
|
||||
uri.setUserInfo("user");
|
||||
@ -231,7 +231,7 @@ void FTPStreamFactoryTest::testMissingPasswordProvider()
|
||||
|
||||
URI uri;
|
||||
uri.setScheme("ftp");
|
||||
uri.setHost("localhost");
|
||||
uri.setHost("127.0.0.1");
|
||||
uri.setPort(server.port());
|
||||
uri.setPath("/test.txt;type=a");
|
||||
uri.setUserInfo("user");
|
||||
|
@ -161,6 +161,29 @@ void HTMLFormTest::testReadUrlGET()
|
||||
}
|
||||
|
||||
|
||||
void HTMLFormTest::testReadUrlGETMultiple()
|
||||
{
|
||||
HTTPRequest req("GET", "/form.cgi?field1=value1&field1=value%202&field1=value%3D3&field1=value%264");
|
||||
HTMLForm form(req);
|
||||
assert (form.size() == 4);
|
||||
|
||||
HTMLForm::ConstIterator it = form.find("field1");
|
||||
assert (it != form.end());
|
||||
assert (it->first == "field1" && it->second == "value1");
|
||||
++it;
|
||||
assert (it != form.end());
|
||||
assert (it->first == "field1" && it->second == "value 2");
|
||||
++it;
|
||||
assert (it != form.end());
|
||||
assert (it->first == "field1" && it->second == "value=3");
|
||||
++it;
|
||||
assert (it != form.end());
|
||||
assert (it->first == "field1" && it->second == "value&4");
|
||||
++it;
|
||||
assert (it == form.end());
|
||||
}
|
||||
|
||||
|
||||
void HTMLFormTest::testReadUrlPOST()
|
||||
{
|
||||
HTTPRequest req("POST", "/form.cgi?field0=value0");
|
||||
@ -293,6 +316,21 @@ void HTMLFormTest::testSubmit3()
|
||||
}
|
||||
|
||||
|
||||
void HTMLFormTest::testSubmit4()
|
||||
{
|
||||
HTMLForm form;
|
||||
form.add("field1", "value1");
|
||||
form.add("field1", "value 2");
|
||||
form.add("field1", "value=3");
|
||||
form.add("field1", "value&4");
|
||||
|
||||
HTTPRequest req("GET", "/form.cgi");
|
||||
form.prepareSubmit(req);
|
||||
|
||||
assert (req.getURI() == "/form.cgi?field1=value1&field1=value%202&field1=value%3D3&field1=value%264");
|
||||
}
|
||||
|
||||
|
||||
void HTMLFormTest::testFieldLimitUrl()
|
||||
{
|
||||
HTTPRequest req("GET", "/form.cgi?field1=value1&field2=value%202&field3=value%3D3&field4=value%264");
|
||||
@ -369,6 +407,7 @@ CppUnit::Test* HTMLFormTest::suite()
|
||||
CppUnit_addTest(pSuite, HTMLFormTest, testWriteUrl);
|
||||
CppUnit_addTest(pSuite, HTMLFormTest, testWriteMultipart);
|
||||
CppUnit_addTest(pSuite, HTMLFormTest, testReadUrlGET);
|
||||
CppUnit_addTest(pSuite, HTMLFormTest, testReadUrlGETMultiple);
|
||||
CppUnit_addTest(pSuite, HTMLFormTest, testReadUrlPOST);
|
||||
CppUnit_addTest(pSuite, HTMLFormTest, testReadUrlPUT);
|
||||
CppUnit_addTest(pSuite, HTMLFormTest, testReadUrlBOM);
|
||||
@ -376,6 +415,7 @@ CppUnit::Test* HTMLFormTest::suite()
|
||||
CppUnit_addTest(pSuite, HTMLFormTest, testSubmit1);
|
||||
CppUnit_addTest(pSuite, HTMLFormTest, testSubmit2);
|
||||
CppUnit_addTest(pSuite, HTMLFormTest, testSubmit3);
|
||||
CppUnit_addTest(pSuite, HTMLFormTest, testSubmit4);
|
||||
CppUnit_addTest(pSuite, HTMLFormTest, testFieldLimitUrl);
|
||||
CppUnit_addTest(pSuite, HTMLFormTest, testFieldLimitMultipart);
|
||||
|
||||
|
@ -27,6 +27,7 @@ public:
|
||||
void testWriteUrl();
|
||||
void testWriteMultipart();
|
||||
void testReadUrlGET();
|
||||
void testReadUrlGETMultiple();
|
||||
void testReadUrlPOST();
|
||||
void testReadUrlPUT();
|
||||
void testReadUrlBOM();
|
||||
@ -34,6 +35,7 @@ public:
|
||||
void testSubmit1();
|
||||
void testSubmit2();
|
||||
void testSubmit3();
|
||||
void testSubmit4();
|
||||
void testFieldLimitUrl();
|
||||
void testFieldLimitMultipart();
|
||||
|
||||
|
@ -41,7 +41,7 @@ HTTPClientSessionTest::~HTTPClientSessionTest()
|
||||
void HTTPClientSessionTest::testGetSmall()
|
||||
{
|
||||
HTTPTestServer srv;
|
||||
HTTPClientSession s("localhost", srv.port());
|
||||
HTTPClientSession s("127.0.0.1", srv.port());
|
||||
HTTPRequest request(HTTPRequest::HTTP_GET, "/small");
|
||||
s.sendRequest(request);
|
||||
HTTPResponse response;
|
||||
@ -57,7 +57,7 @@ void HTTPClientSessionTest::testGetSmall()
|
||||
void HTTPClientSessionTest::testGetLarge()
|
||||
{
|
||||
HTTPTestServer srv;
|
||||
HTTPClientSession s("localhost", srv.port());
|
||||
HTTPClientSession s("127.0.0.1", srv.port());
|
||||
HTTPRequest request(HTTPRequest::HTTP_GET, "/large");
|
||||
s.sendRequest(request);
|
||||
HTTPResponse response;
|
||||
@ -73,7 +73,7 @@ void HTTPClientSessionTest::testGetLarge()
|
||||
void HTTPClientSessionTest::testHead()
|
||||
{
|
||||
HTTPTestServer srv;
|
||||
HTTPClientSession s("localhost", srv.port());
|
||||
HTTPClientSession s("127.0.0.1", srv.port());
|
||||
HTTPRequest request(HTTPRequest::HTTP_HEAD, "/large");
|
||||
s.sendRequest(request);
|
||||
HTTPResponse response;
|
||||
@ -88,7 +88,7 @@ void HTTPClientSessionTest::testHead()
|
||||
void HTTPClientSessionTest::testPostSmallIdentity()
|
||||
{
|
||||
HTTPTestServer srv;
|
||||
HTTPClientSession s("localhost", srv.port());
|
||||
HTTPClientSession s("127.0.0.1", srv.port());
|
||||
HTTPRequest request(HTTPRequest::HTTP_POST, "/echo");
|
||||
std::string body("this is a random request body\r\n0\r\n");
|
||||
request.setContentLength((int) body.length());
|
||||
@ -105,7 +105,7 @@ void HTTPClientSessionTest::testPostSmallIdentity()
|
||||
void HTTPClientSessionTest::testPostLargeIdentity()
|
||||
{
|
||||
HTTPTestServer srv;
|
||||
HTTPClientSession s("localhost", srv.port());
|
||||
HTTPClientSession s("127.0.0.1", srv.port());
|
||||
HTTPRequest request(HTTPRequest::HTTP_POST, "/echo");
|
||||
std::string body(8000, 'x');
|
||||
body.append("\r\n0\r\n");
|
||||
@ -123,7 +123,7 @@ void HTTPClientSessionTest::testPostLargeIdentity()
|
||||
void HTTPClientSessionTest::testPostSmallChunked()
|
||||
{
|
||||
HTTPTestServer srv;
|
||||
HTTPClientSession s("localhost", srv.port());
|
||||
HTTPClientSession s("127.0.0.1", srv.port());
|
||||
HTTPRequest request(HTTPRequest::HTTP_POST, "/echo");
|
||||
std::string body("this is a random request body");
|
||||
request.setChunkedTransferEncoding(true);
|
||||
@ -141,7 +141,7 @@ void HTTPClientSessionTest::testPostSmallChunked()
|
||||
void HTTPClientSessionTest::testPostLargeChunked()
|
||||
{
|
||||
HTTPTestServer srv;
|
||||
HTTPClientSession s("localhost", srv.port());
|
||||
HTTPClientSession s("127.0.0.1", srv.port());
|
||||
HTTPRequest request(HTTPRequest::HTTP_POST, "/echo");
|
||||
std::string body(16000, 'x');
|
||||
request.setChunkedTransferEncoding(true);
|
||||
@ -161,7 +161,7 @@ void HTTPClientSessionTest::testPostLargeChunked()
|
||||
void HTTPClientSessionTest::testPostSmallClose()
|
||||
{
|
||||
HTTPTestServer srv;
|
||||
HTTPClientSession s("localhost", srv.port());
|
||||
HTTPClientSession s("127.0.0.1", srv.port());
|
||||
HTTPRequest request(HTTPRequest::HTTP_POST, "/echo");
|
||||
std::string body("this is a random request body");
|
||||
s.sendRequest(request) << body;
|
||||
@ -178,7 +178,7 @@ void HTTPClientSessionTest::testPostSmallClose()
|
||||
void HTTPClientSessionTest::testPostLargeClose()
|
||||
{
|
||||
HTTPTestServer srv;
|
||||
HTTPClientSession s("localhost", srv.port());
|
||||
HTTPClientSession s("127.0.0.1", srv.port());
|
||||
HTTPRequest request(HTTPRequest::HTTP_POST, "/echo");
|
||||
std::string body(8000, 'x');
|
||||
s.sendRequest(request) << body;
|
||||
@ -195,7 +195,7 @@ void HTTPClientSessionTest::testPostLargeClose()
|
||||
void HTTPClientSessionTest::testKeepAlive()
|
||||
{
|
||||
HTTPTestServer srv;
|
||||
HTTPClientSession s("localhost", srv.port());
|
||||
HTTPClientSession s("127.0.0.1", srv.port());
|
||||
s.setKeepAlive(true);
|
||||
HTTPRequest request(HTTPRequest::HTTP_HEAD, "/keepAlive", HTTPMessage::HTTP_1_1);
|
||||
s.sendRequest(request);
|
||||
@ -244,7 +244,7 @@ void HTTPClientSessionTest::testProxy()
|
||||
{
|
||||
HTTPTestServer srv;
|
||||
HTTPClientSession s("www.somehost.com");
|
||||
s.setProxy("localhost", srv.port());
|
||||
s.setProxy("127.0.0.1", srv.port());
|
||||
HTTPRequest request(HTTPRequest::HTTP_GET, "/large");
|
||||
s.sendRequest(request);
|
||||
HTTPResponse response;
|
||||
@ -261,7 +261,7 @@ void HTTPClientSessionTest::testProxyAuth()
|
||||
{
|
||||
HTTPTestServer srv;
|
||||
HTTPClientSession s("www.somehost.com");
|
||||
s.setProxy("localhost", srv.port());
|
||||
s.setProxy("127.0.0.1", srv.port());
|
||||
s.setProxyCredentials("user", "pass");
|
||||
HTTPRequest request(HTTPRequest::HTTP_GET, "/large");
|
||||
s.sendRequest(request);
|
||||
@ -284,7 +284,7 @@ void HTTPClientSessionTest::testBypassProxy()
|
||||
proxyConfig.port = 80;
|
||||
proxyConfig.nonProxyHosts = "localhost|127\\.0\\.0\\.1";
|
||||
|
||||
HTTPClientSession s1("localhost", 80);
|
||||
HTTPClientSession s1("127.0.0.1", 80);
|
||||
s1.setProxyConfig(proxyConfig);
|
||||
assert (s1.bypassProxy());
|
||||
|
||||
@ -298,6 +298,47 @@ void HTTPClientSessionTest::testBypassProxy()
|
||||
}
|
||||
|
||||
|
||||
void HTTPClientSessionTest::testExpectContinue()
|
||||
{
|
||||
HTTPTestServer srv;
|
||||
HTTPClientSession s("127.0.0.1", srv.port());
|
||||
HTTPRequest request(HTTPRequest::HTTP_POST, "/expect");
|
||||
std::string body("this is a random request body\r\n0\r\n");
|
||||
request.setContentLength((int) body.length());
|
||||
request.setExpectContinue(true);
|
||||
s.sendRequest(request) << body;
|
||||
HTTPResponse response;
|
||||
assert (s.peekResponse(response));
|
||||
assert (response.getStatus() == HTTPResponse::HTTP_CONTINUE);
|
||||
std::istream& rs = s.receiveResponse(response);
|
||||
assert (response.getStatus() == HTTPResponse::HTTP_OK);
|
||||
assert (response.getContentLength() == body.length());
|
||||
std::ostringstream ostr;
|
||||
StreamCopier::copyStream(rs, ostr);
|
||||
assert (ostr.str() == body);
|
||||
}
|
||||
|
||||
|
||||
void HTTPClientSessionTest::testExpectContinueFail()
|
||||
{
|
||||
HTTPTestServer srv;
|
||||
HTTPClientSession s("127.0.0.1", srv.port());
|
||||
HTTPRequest request(HTTPRequest::HTTP_POST, "/fail");
|
||||
std::string body("this is a random request body\r\n0\r\n");
|
||||
request.setContentLength((int) body.length());
|
||||
request.setExpectContinue(true);
|
||||
s.sendRequest(request) << body;
|
||||
HTTPResponse response;
|
||||
assert (!s.peekResponse(response));
|
||||
assert (response.getStatus() == HTTPResponse::HTTP_BAD_REQUEST);
|
||||
std::istream& rs = s.receiveResponse(response);
|
||||
assert (response.getStatus() == HTTPResponse::HTTP_BAD_REQUEST);
|
||||
std::ostringstream ostr;
|
||||
StreamCopier::copyStream(rs, ostr);
|
||||
assert (ostr.str().empty());
|
||||
}
|
||||
|
||||
|
||||
void HTTPClientSessionTest::setUp()
|
||||
{
|
||||
}
|
||||
@ -325,6 +366,8 @@ CppUnit::Test* HTTPClientSessionTest::suite()
|
||||
CppUnit_addTest(pSuite, HTTPClientSessionTest, testProxy);
|
||||
CppUnit_addTest(pSuite, HTTPClientSessionTest, testProxyAuth);
|
||||
CppUnit_addTest(pSuite, HTTPClientSessionTest, testBypassProxy);
|
||||
CppUnit_addTest(pSuite, HTTPClientSessionTest, testExpectContinue);
|
||||
CppUnit_addTest(pSuite, HTTPClientSessionTest, testExpectContinueFail);
|
||||
|
||||
return pSuite;
|
||||
}
|
||||
|
@ -37,6 +37,8 @@ public:
|
||||
void testProxy();
|
||||
void testProxyAuth();
|
||||
void testBypassProxy();
|
||||
void testExpectContinue();
|
||||
void testExpectContinueFail();
|
||||
|
||||
void setUp();
|
||||
void tearDown();
|
||||
|
@ -196,8 +196,8 @@ void HTTPResponseTest::testCookies()
|
||||
cookies.clear();
|
||||
response2.getCookies(cookies);
|
||||
assert (cookies.size() == 2);
|
||||
assert (((cookies[0].getName() == "name1") && (cookies[1].getName() == "name2")) ||
|
||||
((cookies[0].getName() == "name2") && (cookies[1].getName() == "name1")));
|
||||
assert (cookies[0].getName() == "name1" && cookies[1].getName() == "name2"
|
||||
|| cookies[0].getName() == "name2" && cookies[1].getName() == "name1");
|
||||
}
|
||||
|
||||
|
||||
|
@ -144,7 +144,7 @@ void HTTPServerTest::testIdentityRequest()
|
||||
HTTPServer srv(new RequestHandlerFactory, svs, pParams);
|
||||
srv.start();
|
||||
|
||||
HTTPClientSession cs("localhost", svs.address().port());
|
||||
HTTPClientSession cs("127.0.0.1", svs.address().port());
|
||||
std::string body(5000, 'x');
|
||||
HTTPRequest request("POST", "/echoBody");
|
||||
request.setContentLength((int) body.length());
|
||||
@ -167,7 +167,7 @@ void HTTPServerTest::testPutIdentityRequest()
|
||||
HTTPServer srv(new RequestHandlerFactory, svs, pParams);
|
||||
srv.start();
|
||||
|
||||
HTTPClientSession cs("localhost", svs.address().port());
|
||||
HTTPClientSession cs("127.0.0.1", svs.address().port());
|
||||
std::string body(5000, 'x');
|
||||
HTTPRequest request("PUT", "/echoBody");
|
||||
request.setContentLength((int) body.length());
|
||||
@ -190,7 +190,7 @@ void HTTPServerTest::testChunkedRequest()
|
||||
HTTPServer srv(new RequestHandlerFactory, svs, pParams);
|
||||
srv.start();
|
||||
|
||||
HTTPClientSession cs("localhost", svs.address().port());
|
||||
HTTPClientSession cs("127.0.0.1", svs.address().port());
|
||||
std::string body(5000, 'x');
|
||||
HTTPRequest request("POST", "/echoBody");
|
||||
request.setContentType("text/plain");
|
||||
@ -214,7 +214,7 @@ void HTTPServerTest::testClosedRequest()
|
||||
HTTPServer srv(new RequestHandlerFactory, svs, pParams);
|
||||
srv.start();
|
||||
|
||||
HTTPClientSession cs("localhost", svs.address().port());
|
||||
HTTPClientSession cs("127.0.0.1", svs.address().port());
|
||||
std::string body(5000, 'x');
|
||||
HTTPRequest request("POST", "/echoBody");
|
||||
request.setContentType("text/plain");
|
||||
@ -234,7 +234,7 @@ void HTTPServerTest::testIdentityRequestKeepAlive()
|
||||
HTTPServer srv(new RequestHandlerFactory, 8008);
|
||||
srv.start();
|
||||
|
||||
HTTPClientSession cs("localhost", srv.socket().address().port());
|
||||
HTTPClientSession cs("127.0.0.1", srv.socket().address().port());
|
||||
cs.setKeepAlive(true);
|
||||
std::string body(5000, 'x');
|
||||
HTTPRequest request("POST", "/echoBody", HTTPMessage::HTTP_1_1);
|
||||
@ -265,7 +265,7 @@ void HTTPServerTest::testChunkedRequestKeepAlive()
|
||||
HTTPServer srv(new RequestHandlerFactory, 8009);
|
||||
srv.start();
|
||||
|
||||
HTTPClientSession cs("localhost", srv.socket().address().port());
|
||||
HTTPClientSession cs("127.0.0.1", srv.socket().address().port());
|
||||
cs.setKeepAlive(true);
|
||||
std::string body(5000, 'x');
|
||||
HTTPRequest request("POST", "/echoBody", HTTPMessage::HTTP_1_1);
|
||||
@ -297,7 +297,7 @@ void HTTPServerTest::testClosedRequestKeepAlive()
|
||||
HTTPServer srv(new RequestHandlerFactory, 8010);
|
||||
srv.start();
|
||||
|
||||
HTTPClientSession cs("localhost", srv.socket().address().port());
|
||||
HTTPClientSession cs("127.0.0.1", srv.socket().address().port());
|
||||
std::string body(5000, 'x');
|
||||
HTTPRequest request("POST", "/echoBody");
|
||||
request.setContentType("text/plain");
|
||||
@ -322,7 +322,7 @@ void HTTPServerTest::testMaxKeepAlive()
|
||||
HTTPServer srv(new RequestHandlerFactory, svs, pParams);
|
||||
srv.start();
|
||||
|
||||
HTTPClientSession cs("localhost", svs.address().port());
|
||||
HTTPClientSession cs("127.0.0.1", svs.address().port());
|
||||
cs.setKeepAlive(true);
|
||||
HTTPRequest request("POST", "/echoBody", HTTPMessage::HTTP_1_1);
|
||||
request.setContentType("text/plain");
|
||||
@ -378,7 +378,7 @@ void HTTPServerTest::testKeepAliveTimeout()
|
||||
HTTPServer srv(new RequestHandlerFactory, svs, pParams);
|
||||
srv.start();
|
||||
|
||||
HTTPClientSession cs("localhost", svs.address().port());
|
||||
HTTPClientSession cs("127.0.0.1", svs.address().port());
|
||||
cs.setKeepAlive(true);
|
||||
cs.setKeepAliveTimeout(Poco::Timespan(2, 0));
|
||||
HTTPRequest request("POST", "/echoBody", HTTPMessage::HTTP_1_1);
|
||||
@ -422,7 +422,7 @@ void HTTPServerTest::test100Continue()
|
||||
HTTPServer srv(new RequestHandlerFactory, svs, pParams);
|
||||
srv.start();
|
||||
|
||||
HTTPClientSession cs("localhost", svs.address().port());
|
||||
HTTPClientSession cs("127.0.0.1", svs.address().port());
|
||||
std::string body(5000, 'x');
|
||||
HTTPRequest request("POST", "/echoBody");
|
||||
request.setContentLength((int) body.length());
|
||||
@ -446,7 +446,7 @@ void HTTPServerTest::testRedirect()
|
||||
HTTPServer srv(new RequestHandlerFactory, svs, pParams);
|
||||
srv.start();
|
||||
|
||||
HTTPClientSession cs("localhost", svs.address().port());
|
||||
HTTPClientSession cs("127.0.0.1", svs.address().port());
|
||||
HTTPRequest request("GET", "/redirect");
|
||||
cs.sendRequest(request);
|
||||
HTTPResponse response;
|
||||
@ -466,7 +466,7 @@ void HTTPServerTest::testAuth()
|
||||
HTTPServer srv(new RequestHandlerFactory, svs, pParams);
|
||||
srv.start();
|
||||
|
||||
HTTPClientSession cs("localhost", svs.address().port());
|
||||
HTTPClientSession cs("127.0.0.1", svs.address().port());
|
||||
HTTPRequest request("GET", "/auth");
|
||||
cs.sendRequest(request);
|
||||
HTTPResponse response;
|
||||
@ -486,7 +486,7 @@ void HTTPServerTest::testNotImpl()
|
||||
HTTPServer srv(new RequestHandlerFactory, svs, pParams);
|
||||
srv.start();
|
||||
|
||||
HTTPClientSession cs("localhost", svs.address().port());
|
||||
HTTPClientSession cs("127.0.0.1", svs.address().port());
|
||||
HTTPRequest request("GET", "/notImpl");
|
||||
cs.sendRequest(request);
|
||||
HTTPResponse response;
|
||||
@ -505,7 +505,7 @@ void HTTPServerTest::testBuffer()
|
||||
HTTPServer srv(new RequestHandlerFactory, svs, pParams);
|
||||
srv.start();
|
||||
|
||||
HTTPClientSession cs("localhost", svs.address().port());
|
||||
HTTPClientSession cs("127.0.0.1", svs.address().port());
|
||||
HTTPRequest request("GET", "/buffer");
|
||||
cs.sendRequest(request);
|
||||
HTTPResponse response;
|
||||
|
@ -42,7 +42,7 @@ void HTTPStreamFactoryTest::testNoRedirect()
|
||||
{
|
||||
HTTPTestServer server;
|
||||
HTTPStreamFactory factory;
|
||||
URI uri("http://localhost/large");
|
||||
URI uri("http://127.0.0.1/large");
|
||||
uri.setPort(server.port());
|
||||
#ifndef POCO_ENABLE_CPP11
|
||||
std::auto_ptr<std::istream> pStr(factory.open(uri));
|
||||
@ -59,7 +59,7 @@ void HTTPStreamFactoryTest::testEmptyPath()
|
||||
{
|
||||
HTTPTestServer server;
|
||||
HTTPStreamFactory factory;
|
||||
URI uri("http://localhost");
|
||||
URI uri("http://127.0.0.1");
|
||||
uri.setPort(server.port());
|
||||
#ifndef POCO_ENABLE_CPP11
|
||||
std::auto_ptr<std::istream> pStr(factory.open(uri));
|
||||
@ -77,7 +77,7 @@ void HTTPStreamFactoryTest::testRedirect()
|
||||
HTTPTestServer server;
|
||||
Poco::URIStreamOpener opener;
|
||||
opener.registerStreamFactory("http", new HTTPStreamFactory);
|
||||
URI uri("http://localhost/redirect");
|
||||
URI uri("http://127.0.0.1/redirect");
|
||||
uri.setPort(server.port());
|
||||
#ifndef POCO_ENABLE_CPP11
|
||||
std::auto_ptr<std::istream> pStr(opener.open(uri));
|
||||
@ -93,7 +93,7 @@ void HTTPStreamFactoryTest::testRedirect()
|
||||
void HTTPStreamFactoryTest::testProxy()
|
||||
{
|
||||
HTTPTestServer server;
|
||||
HTTPStreamFactory factory("localhost", server.port());
|
||||
HTTPStreamFactory factory("127.0.0.1", server.port());
|
||||
URI uri("http://www.somehost.com/large");
|
||||
#ifndef POCO_ENABLE_CPP11
|
||||
std::auto_ptr<std::istream> pStr(factory.open(uri));
|
||||
@ -110,7 +110,7 @@ void HTTPStreamFactoryTest::testError()
|
||||
{
|
||||
HTTPTestServer server;
|
||||
HTTPStreamFactory factory;
|
||||
URI uri("http://localhost/notfound");
|
||||
URI uri("http://127.0.0.1/notfound");
|
||||
uri.setPort(server.port());
|
||||
try
|
||||
{
|
||||
|
@ -140,6 +140,37 @@ std::string HTTPTestServer::handleRequest() const
|
||||
if (_lastRequest.substr(0, 3) == "GET")
|
||||
response.append(body);
|
||||
}
|
||||
else if (_lastRequest.substr(0, 12) == "POST /expect")
|
||||
{
|
||||
std::string::size_type pos = _lastRequest.find("\r\n\r\n");
|
||||
pos += 4;
|
||||
std::string body = _lastRequest.substr(pos);
|
||||
response.append("HTTP/1.1 100 Continue\r\n\r\n");
|
||||
response.append("HTTP/1.1 200 OK\r\n");
|
||||
response.append("Content-Type: text/plain\r\n");
|
||||
if (_lastRequest.find("Content-Length") != std::string::npos)
|
||||
{
|
||||
response.append("Content-Length: ");
|
||||
response.append(NumberFormatter::format((int) body.size()));
|
||||
response.append("\r\n");
|
||||
}
|
||||
else if (_lastRequest.find("chunked") != std::string::npos)
|
||||
{
|
||||
response.append("Transfer-Encoding: chunked\r\n");
|
||||
}
|
||||
response.append("Connection: Close\r\n");
|
||||
response.append("\r\n");
|
||||
response.append(body);
|
||||
}
|
||||
else if (_lastRequest.substr(0, 10) == "POST /fail")
|
||||
{
|
||||
std::string::size_type pos = _lastRequest.find("\r\n\r\n");
|
||||
pos += 4;
|
||||
std::string body = _lastRequest.substr(pos);
|
||||
response.append("HTTP/1.1 400 Bad Request\r\n");
|
||||
response.append("Connection: Close\r\n");
|
||||
response.append("\r\n");
|
||||
}
|
||||
else if (_lastRequest.substr(0, 4) == "POST")
|
||||
{
|
||||
std::string::size_type pos = _lastRequest.find("\r\n\r\n");
|
||||
|
@ -46,9 +46,9 @@ ICMPClientTest::~ICMPClientTest()
|
||||
|
||||
void ICMPClientTest::testPing()
|
||||
{
|
||||
assert(ICMPClient::pingIPv4("localhost") > 0);
|
||||
assert(ICMPClient::pingIPv4("127.0.0.1") > 0);
|
||||
|
||||
assert(_icmpClient.ping("localhost") > 0);
|
||||
assert(_icmpClient.ping("127.0.0.1") > 0);
|
||||
assert(_icmpClient.ping("www.appinf.com", 4) > 0);
|
||||
|
||||
// warning: may fail depending on the existence of the addresses at test site
|
||||
|
@ -429,6 +429,42 @@ void MailMessageTest::testReadMultiPart()
|
||||
}
|
||||
|
||||
|
||||
void MailMessageTest::testReadMultiPartWithAttachmentNames()
|
||||
{
|
||||
std::istringstream istr(
|
||||
"Content-Type: multipart/mixed; boundary=MIME_boundary_01234567\r\n"
|
||||
"Date: Thu, 1 Jan 1970 00:00:00 GMT\r\n"
|
||||
"From: poco@appinf.com\r\n"
|
||||
"Mime-Version: 1.0\r\n"
|
||||
"Subject: Test Message\r\n"
|
||||
"To: John Doe <john.doe@no.where>\r\n"
|
||||
"\r\n"
|
||||
"\r\n"
|
||||
"--MIME_boundary_01234567\r\n"
|
||||
"Content-Disposition: inline\r\n"
|
||||
"Content-Transfer-Encoding: 8bit\r\n"
|
||||
"Content-Type: text/plain\r\n"
|
||||
"\r\n"
|
||||
"Hello World!\r\n"
|
||||
"\r\n"
|
||||
"--MIME_boundary_01234567\r\n"
|
||||
"Content-Disposition: attachment; filename=sample.dat\r\n"
|
||||
"Content-Transfer-Encoding: base64\r\n"
|
||||
"Content-Type: application/octet-stream; name=sample\r\n"
|
||||
"\r\n"
|
||||
"VGhpcyBpcyBzb21lIGJpbmFyeSBkYXRhLiBSZWFsbHku\r\n"
|
||||
"--MIME_boundary_01234567--\r\n"
|
||||
);
|
||||
|
||||
MailMessage message;
|
||||
message.read(istr);
|
||||
|
||||
assert (message.parts().size() == 2);
|
||||
assert (message.parts()[1].name == "sample");
|
||||
assert (message.parts()[1].pSource->filename() == "sample.dat");
|
||||
}
|
||||
|
||||
|
||||
void MailMessageTest::testReadMultiPartDefaultTransferEncoding()
|
||||
{
|
||||
std::istringstream istr(
|
||||
|
@ -35,6 +35,7 @@ public:
|
||||
void testReadQP();
|
||||
void testRead8Bit();
|
||||
void testReadMultiPart();
|
||||
void testReadMultiPartWithAttachmentNames();
|
||||
void testReadMultiPartDefaultTransferEncoding();
|
||||
void testEncodeWord();
|
||||
|
||||
|
@ -360,6 +360,23 @@ void MessageHeaderTest::testFieldLimit()
|
||||
}
|
||||
|
||||
|
||||
void MessageHeaderTest::testDecodeWord()
|
||||
{
|
||||
std::string coded("this is pure ASCII");
|
||||
std::string decoded = MessageHeader::decodeWord(coded, "ISO-8859-1");
|
||||
assert(decoded == coded);
|
||||
|
||||
coded = "(=?ISO-8859-1?Q?a?= =?ISO-8859-1?Q?b?=)";
|
||||
decoded = MessageHeader::decodeWord(coded, "ISO-8859-1");
|
||||
assert(decoded == "(a b)");
|
||||
|
||||
coded = "Hello =?UTF-8?B?RnJhbmNpcw==?=, good bye";
|
||||
decoded = MessageHeader::decodeWord(coded, "ISO-8859-1");
|
||||
assert(decoded == "Hello Francis, good bye");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MessageHeaderTest::setUp()
|
||||
{
|
||||
}
|
||||
@ -390,6 +407,7 @@ CppUnit::Test* MessageHeaderTest::suite()
|
||||
CppUnit_addTest(pSuite, MessageHeaderTest, testSplitElements);
|
||||
CppUnit_addTest(pSuite, MessageHeaderTest, testSplitParameters);
|
||||
CppUnit_addTest(pSuite, MessageHeaderTest, testFieldLimit);
|
||||
CppUnit_addTest(pSuite, MessageHeaderTest, testDecodeWord);
|
||||
|
||||
return pSuite;
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ public:
|
||||
void testSplitElements();
|
||||
void testSplitParameters();
|
||||
void testFieldLimit();
|
||||
void testDecodeWord();
|
||||
|
||||
void setUp();
|
||||
void tearDown();
|
||||
|
@ -48,7 +48,7 @@ MulticastSocketTest::~MulticastSocketTest()
|
||||
void MulticastSocketTest::testMulticast()
|
||||
{
|
||||
MulticastEchoServer echoServer;
|
||||
MulticastSocket ms;
|
||||
MulticastSocket ms(SocketAddress::IPv4);
|
||||
int n = ms.sendTo("hello", 5, echoServer.group());
|
||||
assert (n == 5);
|
||||
char buffer[256];
|
||||
|
@ -63,11 +63,11 @@ void NetworkInterfaceTest::testMap()
|
||||
std::cout << std::endl << "----------" << std::endl;
|
||||
std::cout << "Address " << counter << std::endl;
|
||||
std::cout << "----------" << std::endl;
|
||||
std::cout << "Address: " << ipIt->get<NetworkInterface::IP_ADDRESS>().toString() << std::endl;
|
||||
std::cout << "Address: " << ipIt->get<NetworkInterface::IP_ADDRESS>() << std::endl;
|
||||
IPAddress addr = ipIt->get<NetworkInterface::SUBNET_MASK>();
|
||||
if (!addr.isWildcard()) std::cout << "Subnet: " << addr.toString() << " (/" << addr.prefixLength() << ")" << std::endl;
|
||||
if (!addr.isWildcard()) std::cout << "Subnet: " << addr << " (/" << addr.prefixLength() << ")" << std::endl;
|
||||
addr = ipIt->get<NetworkInterface::BROADCAST_ADDRESS>();
|
||||
if (!addr.isWildcard()) std::cout << "Broadcast: " << addr.toString() << std::endl;
|
||||
if (!addr.isWildcard()) std::cout << "Broadcast: " << addr << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "=============" << std::endl << std::endl;
|
||||
@ -98,11 +98,11 @@ void NetworkInterfaceTest::testList()
|
||||
List::const_iterator ipEnd = ipList.end();
|
||||
for (int counter = 0; ipIt != ipEnd; ++ipIt, ++counter)
|
||||
{
|
||||
std::cout << "IP Address: " << ipIt->get<NetworkInterface::IP_ADDRESS>().toString() << std::endl;
|
||||
std::cout << "IP Address: " << ipIt->get<NetworkInterface::IP_ADDRESS>() << std::endl;
|
||||
IPAddress addr = ipIt->get<NetworkInterface::SUBNET_MASK>();
|
||||
if (!addr.isWildcard()) std::cout << "Subnet: " << ipIt->get<NetworkInterface::SUBNET_MASK>().toString() << " (/" << ipIt->get<NetworkInterface::SUBNET_MASK>().prefixLength() << ")" << std::endl;
|
||||
if (!addr.isWildcard()) std::cout << "Subnet: " << ipIt->get<NetworkInterface::SUBNET_MASK>() << " (/" << ipIt->get<NetworkInterface::SUBNET_MASK>().prefixLength() << ")" << std::endl;
|
||||
addr = ipIt->get<NetworkInterface::BROADCAST_ADDRESS>();
|
||||
if (!addr.isWildcard()) std::cout << "Broadcast: " << ipIt->get<NetworkInterface::BROADCAST_ADDRESS>().toString() << std::endl;
|
||||
if (!addr.isWildcard()) std::cout << "Broadcast: " << ipIt->get<NetworkInterface::BROADCAST_ADDRESS>() << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "==============" << std::endl << std::endl;
|
||||
@ -178,7 +178,7 @@ void NetworkInterfaceTest::testMapIpOnly()
|
||||
{
|
||||
assert(it->second.supportsIPv4() || it->second.supportsIPv6());
|
||||
std::cout << "Interface: (" << it->second.index() << ")" << std::endl;
|
||||
std::cout << "Address: " << it->second.address().toString() << std::endl;
|
||||
std::cout << "Address: " << it->second.address() << std::endl;
|
||||
NetworkInterface::MACAddress mac(it->second.macAddress());
|
||||
if (!mac.empty() && (it->second.type() != NetworkInterface::NI_TYPE_SOFTWARE_LOOPBACK))
|
||||
std::cout << "MAC Address:" << mac << std::endl;
|
||||
|
@ -40,7 +40,7 @@ void POP3ClientSessionTest::testLogin()
|
||||
server.addResponse("+OK USER");
|
||||
server.addResponse("+OK PASS");
|
||||
server.addResponse("+OK QUIT");
|
||||
POP3ClientSession session("localhost", server.port());
|
||||
POP3ClientSession session("127.0.0.1", server.port());
|
||||
session.login("user", "secret");
|
||||
std::string cmd = server.popCommand();
|
||||
assert (cmd == "USER user");
|
||||
@ -59,7 +59,7 @@ void POP3ClientSessionTest::testLoginFail()
|
||||
server.addResponse("+OK USER");
|
||||
server.addResponse("-ERR PASS");
|
||||
server.addResponse("+OK QUIT");
|
||||
POP3ClientSession session("localhost", server.port());
|
||||
POP3ClientSession session("127.0.0.1", server.port());
|
||||
try
|
||||
{
|
||||
session.login("user", "secret");
|
||||
@ -80,7 +80,7 @@ void POP3ClientSessionTest::testMessageCount()
|
||||
server.addResponse("+OK PASS");
|
||||
server.addResponse("+OK 42 12345");
|
||||
server.addResponse("+OK QUIT");
|
||||
POP3ClientSession session("localhost", server.port());
|
||||
POP3ClientSession session("127.0.0.1", server.port());
|
||||
session.login("user", "secret");
|
||||
server.clearCommands();
|
||||
int n = session.messageCount();
|
||||
@ -105,7 +105,7 @@ void POP3ClientSessionTest::testList()
|
||||
".\r\n"
|
||||
);
|
||||
server.addResponse("+OK QUIT");
|
||||
POP3ClientSession session("localhost", server.port());
|
||||
POP3ClientSession session("127.0.0.1", server.port());
|
||||
session.login("user", "secret");
|
||||
server.clearCommands();
|
||||
std::vector<POP3ClientSession::MessageInfo> infos;
|
||||
@ -144,7 +144,7 @@ void POP3ClientSessionTest::testRetrieveMessage()
|
||||
".\r\n"
|
||||
);
|
||||
server.addResponse("+OK QUIT");
|
||||
POP3ClientSession session("localhost", server.port());
|
||||
POP3ClientSession session("127.0.0.1", server.port());
|
||||
session.login("user", "secret");
|
||||
server.clearCommands();
|
||||
MailMessage message;
|
||||
@ -180,7 +180,7 @@ void POP3ClientSessionTest::testRetrieveHeader()
|
||||
"."
|
||||
);
|
||||
server.addResponse("+OK QUIT");
|
||||
POP3ClientSession session("localhost", server.port());
|
||||
POP3ClientSession session("127.0.0.1", server.port());
|
||||
session.login("user", "secret");
|
||||
server.clearCommands();
|
||||
MessageHeader header;
|
||||
@ -223,7 +223,7 @@ void POP3ClientSessionTest::testRetrieveMessages()
|
||||
"."
|
||||
);
|
||||
server.addResponse("+OK QUIT");
|
||||
POP3ClientSession session("localhost", server.port());
|
||||
POP3ClientSession session("127.0.0.1", server.port());
|
||||
session.login("user", "secret");
|
||||
server.clearCommands();
|
||||
MessageHeader header;
|
||||
@ -259,7 +259,7 @@ void POP3ClientSessionTest::testDeleteMessage()
|
||||
server.addResponse("+OK PASS");
|
||||
server.addResponse("+OK DELETED");
|
||||
server.addResponse("+OK QUIT");
|
||||
POP3ClientSession session("localhost", server.port());
|
||||
POP3ClientSession session("127.0.0.1", server.port());
|
||||
session.login("user", "secret");
|
||||
server.clearCommands();
|
||||
session.deleteMessage(42);
|
||||
|
@ -43,7 +43,7 @@ RawSocketTest::~RawSocketTest()
|
||||
|
||||
void RawSocketTest::testEchoIPv4()
|
||||
{
|
||||
SocketAddress sa("localhost", 0);
|
||||
SocketAddress sa("127.0.0.1", 0);
|
||||
RawSocket rs(IPAddress::IPv4);
|
||||
rs.connect(sa);
|
||||
|
||||
@ -68,7 +68,7 @@ void RawSocketTest::testSendToReceiveFromIPv4()
|
||||
{
|
||||
RawSocket rs(IPAddress::IPv4);
|
||||
|
||||
int n = rs.sendTo("hello", 5, SocketAddress("localhost", 0));
|
||||
int n = rs.sendTo("hello", 5, SocketAddress("127.0.0.1", 0));
|
||||
assert (n == 5);
|
||||
|
||||
char buffer[256] = "";
|
||||
|
@ -40,7 +40,7 @@ void SMTPClientSessionTest::testLoginEHLO()
|
||||
server.addResponse("220 localhost SMTP ready");
|
||||
server.addResponse("250 Hello localhost");
|
||||
server.addResponse("221 Bye");
|
||||
SMTPClientSession session("localhost", server.port());
|
||||
SMTPClientSession session("127.0.0.1", server.port());
|
||||
session.login("localhost");
|
||||
std::string cmd = server.popCommand();
|
||||
assert (cmd == "EHLO localhost");
|
||||
@ -57,7 +57,7 @@ void SMTPClientSessionTest::testLoginHELO()
|
||||
server.addResponse("500 EHLO not understood");
|
||||
server.addResponse("250 Hello localhost");
|
||||
server.addResponse("221 Bye");
|
||||
SMTPClientSession session("localhost", server.port());
|
||||
SMTPClientSession session("127.0.0.1", server.port());
|
||||
session.login("localhost");
|
||||
std::string cmd = server.popCommand();
|
||||
assert (cmd == "EHLO localhost");
|
||||
@ -74,7 +74,7 @@ void SMTPClientSessionTest::testLoginFailed()
|
||||
DialogServer server;
|
||||
server.addResponse("500 No SMTP service here");
|
||||
server.addResponse("221 Bye");
|
||||
SMTPClientSession session("localhost", server.port());
|
||||
SMTPClientSession session("127.0.0.1", server.port());
|
||||
try
|
||||
{
|
||||
session.login("localhost");
|
||||
@ -97,7 +97,7 @@ void SMTPClientSessionTest::testSend()
|
||||
server.addResponse("354 Send data");
|
||||
server.addResponse("250 OK");
|
||||
server.addResponse("221 Bye");
|
||||
SMTPClientSession session("localhost", server.port());
|
||||
SMTPClientSession session("127.0.0.1", server.port());
|
||||
session.login("localhost");
|
||||
|
||||
MailMessage message;
|
||||
@ -151,7 +151,7 @@ void SMTPClientSessionTest::testSendMultiRecipient()
|
||||
server.addResponse("250 OK");
|
||||
server.addResponse("250 OK");
|
||||
server.addResponse("221 Bye");
|
||||
SMTPClientSession session("localhost", server.port());
|
||||
SMTPClientSession session("127.0.0.1", server.port());
|
||||
session.login("localhost");
|
||||
|
||||
MailMessage message;
|
||||
@ -216,7 +216,7 @@ void SMTPClientSessionTest::testMultiSeparateRecipient()
|
||||
server.addResponse("250 OK");
|
||||
server.addResponse("250 OK");
|
||||
server.addResponse("221 Bye");
|
||||
SMTPClientSession session("localhost", server.port());
|
||||
SMTPClientSession session("127.0.0.1", server.port());
|
||||
session.login("localhost");
|
||||
|
||||
MailMessage message;
|
||||
@ -283,7 +283,7 @@ void SMTPClientSessionTest::testSendFailed()
|
||||
server.addResponse("354 Send data");
|
||||
server.addResponse("500 Error");
|
||||
server.addResponse("221 Bye");
|
||||
SMTPClientSession session("localhost", server.port());
|
||||
SMTPClientSession session("127.0.0.1", server.port());
|
||||
session.login("localhost");
|
||||
|
||||
MailMessage message;
|
||||
|
@ -21,6 +21,7 @@ using Poco::Net::InvalidAddressException;
|
||||
using Poco::Net::HostNotFoundException;
|
||||
using Poco::Net::ServiceNotFoundException;
|
||||
using Poco::Net::NoAddressFoundException;
|
||||
using Poco::Net::AddressFamilyMismatchException;
|
||||
using Poco::InvalidArgumentException;
|
||||
|
||||
|
||||
@ -41,8 +42,11 @@ void SocketAddressTest::testSocketAddress()
|
||||
assert (wild.port() == 0);
|
||||
|
||||
SocketAddress sa1("192.168.1.100", 100);
|
||||
assert (sa1.af() == AF_INET);
|
||||
assert (sa1.family() == SocketAddress::IPv4);
|
||||
assert (sa1.host().toString() == "192.168.1.100");
|
||||
assert (sa1.port() == 100);
|
||||
assert (sa1.toString() == "192.168.1.100:100");
|
||||
|
||||
SocketAddress sa2("192.168.1.100", "100");
|
||||
assert (sa2.host().toString() == "192.168.1.100");
|
||||
@ -63,7 +67,7 @@ void SocketAddressTest::testSocketAddress()
|
||||
{
|
||||
}
|
||||
|
||||
SocketAddress sa4("www.appinf.com", 80);
|
||||
SocketAddress sa4("pocoproject.org", 80);
|
||||
assert (sa4.host().toString() == "162.209.7.4");
|
||||
assert (sa4.port() == 80);
|
||||
|
||||
@ -113,6 +117,24 @@ void SocketAddressTest::testSocketAddress()
|
||||
catch (InvalidArgumentException&)
|
||||
{
|
||||
}
|
||||
|
||||
SocketAddress sa10("www6.pocoproject.org", 80);
|
||||
assert (sa10.host().toString() == "162.209.7.4" || sa10.host().toString() == "[2001:4801:7819:74:be76:4eff:fe10:6b73]");
|
||||
|
||||
SocketAddress sa11(SocketAddress::IPv4, "www6.pocoproject.org", 80);
|
||||
assert (sa11.host().toString() == "162.209.7.4");
|
||||
|
||||
#ifdef POCO_HAVE_IPv6
|
||||
try
|
||||
{
|
||||
SocketAddress sa12(SocketAddress::IPv6, "www6.pocoproject.org", 80);
|
||||
assert (sa12.host().toString() == "2001:4801:7819:74:be76:4eff:fe10:6b73");
|
||||
}
|
||||
catch (AddressFamilyMismatchException&)
|
||||
{
|
||||
// may happen if no IPv6 address is configured on the system
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -133,6 +155,42 @@ void SocketAddressTest::testSocketRelationals()
|
||||
void SocketAddressTest::testSocketAddress6()
|
||||
{
|
||||
#ifdef POCO_HAVE_IPv6
|
||||
SocketAddress sa1("FE80::E6CE:8FFF:FE4A:EDD0", 100);
|
||||
assert (sa1.af() == AF_INET6);
|
||||
assert (sa1.family() == SocketAddress::IPv6);
|
||||
assert (sa1.host().toString() == "fe80::e6ce:8fff:fe4a:edd0");
|
||||
assert (sa1.port() == 100);
|
||||
assert (sa1.toString() == "[fe80::e6ce:8fff:fe4a:edd0]:100");
|
||||
|
||||
SocketAddress sa2("[FE80::E6CE:8FFF:FE4A:EDD0]:100");
|
||||
assert (sa2.af() == AF_INET6);
|
||||
assert (sa2.family() == SocketAddress::IPv6);
|
||||
assert (sa2.host().toString() == "fe80::e6ce:8fff:fe4a:edd0");
|
||||
assert (sa2.port() == 100);
|
||||
assert (sa2.toString() == "[fe80::e6ce:8fff:fe4a:edd0]:100");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void SocketAddressTest::testSocketAddressUnixLocal()
|
||||
{
|
||||
#ifdef POCO_OS_FAMILY_UNIX
|
||||
SocketAddress sa1(SocketAddress::UNIX_LOCAL, "/tmp/sock1");
|
||||
assert (sa1.af() == AF_UNIX);
|
||||
assert (sa1.family() == SocketAddress::UNIX_LOCAL);
|
||||
assert (sa1.toString() == "/tmp/sock1");
|
||||
|
||||
SocketAddress sa2(SocketAddress::UNIX_LOCAL, "/tmp/sock2");
|
||||
assert (sa1 != sa2);
|
||||
assert (sa1 < sa2);
|
||||
|
||||
SocketAddress sa3(SocketAddress::UNIX_LOCAL, "/tmp/sock1");
|
||||
assert (sa1 == sa3);
|
||||
assert (!(sa1 < sa3));
|
||||
|
||||
SocketAddress sa4("/tmp/sock1");
|
||||
assert (sa1 == sa4);
|
||||
assert (sa4.toString() == "/tmp/sock1");
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -154,6 +212,7 @@ CppUnit::Test* SocketAddressTest::suite()
|
||||
CppUnit_addTest(pSuite, SocketAddressTest, testSocketAddress);
|
||||
CppUnit_addTest(pSuite, SocketAddressTest, testSocketRelationals);
|
||||
CppUnit_addTest(pSuite, SocketAddressTest, testSocketAddress6);
|
||||
CppUnit_addTest(pSuite, SocketAddressTest, testSocketAddressUnixLocal);
|
||||
|
||||
return pSuite;
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ public:
|
||||
void testSocketAddress();
|
||||
void testSocketRelationals();
|
||||
void testSocketAddress6();
|
||||
void testSocketAddressUnixLocal();
|
||||
|
||||
void setUp();
|
||||
void tearDown();
|
||||
|
@ -312,7 +312,7 @@ void SocketReactorTest::testSocketReactor()
|
||||
ServerSocket ss(ssa);
|
||||
SocketReactor reactor;
|
||||
SocketAcceptor<EchoServiceHandler> acceptor(ss, reactor);
|
||||
SocketAddress sa("localhost", ss.address().port());
|
||||
SocketAddress sa("127.0.0.1", ss.address().port());
|
||||
SocketConnector<ClientServiceHandler> connector(sa, reactor);
|
||||
ClientServiceHandler::setOnce(true);
|
||||
ClientServiceHandler::resetData();
|
||||
@ -332,7 +332,7 @@ void SocketReactorTest::testSetSocketReactor()
|
||||
SocketReactor reactor;
|
||||
SocketAcceptor<EchoServiceHandler> acceptor(ss);
|
||||
acceptor.setReactor(reactor);
|
||||
SocketAddress sa("localhost", ss.address().port());
|
||||
SocketAddress sa("127.0.0.1", ss.address().port());
|
||||
SocketConnector<ClientServiceHandler> connector(sa, reactor);
|
||||
ClientServiceHandler::setOnce(true);
|
||||
ClientServiceHandler::resetData();
|
||||
@ -351,7 +351,7 @@ void SocketReactorTest::testParallelSocketReactor()
|
||||
ServerSocket ss(ssa);
|
||||
SocketReactor reactor;
|
||||
ParallelSocketAcceptor<EchoServiceHandler, SocketReactor> acceptor(ss, reactor);
|
||||
SocketAddress sa("localhost", ss.address().port());
|
||||
SocketAddress sa("127.0.0.1", ss.address().port());
|
||||
SocketConnector<ClientServiceHandler> connector1(sa, reactor);
|
||||
SocketConnector<ClientServiceHandler> connector2(sa, reactor);
|
||||
SocketConnector<ClientServiceHandler> connector3(sa, reactor);
|
||||
@ -388,7 +388,7 @@ void SocketReactorTest::testSocketConnectorTimeout()
|
||||
SocketAddress ssa;
|
||||
ServerSocket ss(ssa);
|
||||
SocketReactor reactor;
|
||||
SocketAddress sa("localhost", ss.address().port());
|
||||
SocketAddress sa("127.0.0.1", ss.address().port());
|
||||
SocketConnector<ClientServiceHandler> connector(sa, reactor);
|
||||
reactor.run();
|
||||
assert (ClientServiceHandler::timeout());
|
||||
|
@ -47,7 +47,7 @@ void SocketStreamTest::testStreamEcho()
|
||||
{
|
||||
EchoServer echoServer;
|
||||
StreamSocket ss;
|
||||
ss.connect(SocketAddress("localhost", echoServer.port()));
|
||||
ss.connect(SocketAddress("127.0.0.1", echoServer.port()));
|
||||
SocketStream str(ss);
|
||||
str << "hello";
|
||||
assert (str.good());
|
||||
@ -70,7 +70,7 @@ void SocketStreamTest::testLargeStreamEcho()
|
||||
const int msgSize = 64000;
|
||||
EchoServer echoServer;
|
||||
StreamSocket ss;
|
||||
ss.connect(SocketAddress("localhost", echoServer.port()));
|
||||
ss.connect(SocketAddress("127.0.0.1", echoServer.port()));
|
||||
SocketStream str(ss);
|
||||
ss.setSendBufferSize(msgSize);
|
||||
ss.setReceiveBufferSize(msgSize);
|
||||
@ -98,7 +98,7 @@ void SocketStreamTest::testEOF()
|
||||
{
|
||||
EchoServer echoServer;
|
||||
|
||||
ss.connect(SocketAddress("localhost", echoServer.port()));
|
||||
ss.connect(SocketAddress("127.0.0.1", echoServer.port()));
|
||||
str << "hello";
|
||||
assert (str.good());
|
||||
str.flush();
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "Poco/Buffer.h"
|
||||
#include "Poco/FIFOBuffer.h"
|
||||
#include "Poco/Delegate.h"
|
||||
#include "Poco/File.h"
|
||||
#include <iostream>
|
||||
|
||||
|
||||
@ -52,7 +53,7 @@ void SocketTest::testEcho()
|
||||
{
|
||||
EchoServer echoServer;
|
||||
StreamSocket ss;
|
||||
ss.connect(SocketAddress("localhost", echoServer.port()));
|
||||
ss.connect(SocketAddress("127.0.0.1", echoServer.port()));
|
||||
int n = ss.sendBytes("hello", 5);
|
||||
assert (n == 5);
|
||||
char buffer[256];
|
||||
@ -67,7 +68,7 @@ void SocketTest::testPoll()
|
||||
{
|
||||
EchoServer echoServer;
|
||||
StreamSocket ss;
|
||||
ss.connect(SocketAddress("localhost", echoServer.port()));
|
||||
ss.connect(SocketAddress("127.0.0.1", echoServer.port()));
|
||||
Stopwatch sw;
|
||||
sw.start();
|
||||
Timespan timeout(1000000);
|
||||
@ -92,7 +93,7 @@ void SocketTest::testAvailable()
|
||||
{
|
||||
EchoServer echoServer;
|
||||
StreamSocket ss;
|
||||
ss.connect(SocketAddress("localhost", echoServer.port()));
|
||||
ss.connect(SocketAddress("127.0.0.1", echoServer.port()));
|
||||
Timespan timeout(1000000);
|
||||
ss.sendBytes("hello", 5);
|
||||
char buffer[256];
|
||||
@ -132,7 +133,7 @@ void SocketTest::testFIFOBuffer()
|
||||
|
||||
EchoServer echoServer;
|
||||
StreamSocket ss;
|
||||
ss.connect(SocketAddress("localhost", echoServer.port()));
|
||||
ss.connect(SocketAddress("127.0.0.1", echoServer.port()));
|
||||
int n = ss.sendBytes(f);
|
||||
assert (n == 5);
|
||||
assert(1 == _notToReadable);
|
||||
@ -169,7 +170,7 @@ void SocketTest::testConnect()
|
||||
serv.listen();
|
||||
StreamSocket ss;
|
||||
Timespan timeout(250000);
|
||||
ss.connect(SocketAddress("localhost", serv.address().port()), timeout);
|
||||
ss.connect(SocketAddress("127.0.0.1", serv.address().port()), timeout);
|
||||
}
|
||||
|
||||
|
||||
@ -184,7 +185,7 @@ void SocketTest::testConnectRefused()
|
||||
Timespan timeout(250000);
|
||||
try
|
||||
{
|
||||
ss.connect(SocketAddress("localhost", port));
|
||||
ss.connect(SocketAddress("127.0.0.1", port));
|
||||
fail("connection refused - must throw");
|
||||
}
|
||||
catch (ConnectionRefusedException&)
|
||||
@ -204,7 +205,7 @@ void SocketTest::testConnectRefusedNB()
|
||||
Timespan timeout(2, 0);
|
||||
try
|
||||
{
|
||||
ss.connect(SocketAddress("localhost", port), timeout);
|
||||
ss.connect(SocketAddress("127.0.0.1", port), timeout);
|
||||
fail("connection refused - must throw");
|
||||
}
|
||||
catch (TimeoutException&)
|
||||
@ -220,7 +221,7 @@ void SocketTest::testNonBlocking()
|
||||
{
|
||||
EchoServer echoServer;
|
||||
StreamSocket ss;
|
||||
ss.connect(SocketAddress("localhost", echoServer.port()));
|
||||
ss.connect(SocketAddress("127.0.0.1", echoServer.port()));
|
||||
ss.setBlocking(false);
|
||||
|
||||
Timespan timeout(1000000);
|
||||
@ -244,7 +245,7 @@ void SocketTest::testAddress()
|
||||
serv.bind(SocketAddress());
|
||||
serv.listen();
|
||||
StreamSocket ss;
|
||||
ss.connect(SocketAddress("localhost", serv.address().port()));
|
||||
ss.connect(SocketAddress("127.0.0.1", serv.address().port()));
|
||||
StreamSocket css = serv.acceptConnection();
|
||||
assert (css.peerAddress().host() == ss.address().host());
|
||||
assert (css.peerAddress().port() == ss.address().port());
|
||||
@ -306,7 +307,7 @@ void SocketTest::testTimeout()
|
||||
{
|
||||
EchoServer echoServer;
|
||||
StreamSocket ss;
|
||||
ss.connect(SocketAddress("localhost", echoServer.port()));
|
||||
ss.connect(SocketAddress("127.0.0.1", echoServer.port()));
|
||||
|
||||
Timespan timeout0 = ss.getReceiveTimeout();
|
||||
Timespan timeout(250000);
|
||||
@ -344,7 +345,7 @@ void SocketTest::testTimeout()
|
||||
void SocketTest::testBufferSize()
|
||||
{
|
||||
EchoServer echoServer;
|
||||
SocketAddress sa("localhost", 1234);
|
||||
SocketAddress sa("127.0.0.1", 1234);
|
||||
StreamSocket ss(sa.family());
|
||||
|
||||
int osz = ss.getSendBufferSize();
|
||||
@ -368,7 +369,7 @@ void SocketTest::testOptions()
|
||||
{
|
||||
EchoServer echoServer;
|
||||
StreamSocket ss;
|
||||
ss.connect(SocketAddress("localhost", echoServer.port()));
|
||||
ss.connect(SocketAddress("127.0.0.1", echoServer.port()));
|
||||
|
||||
ss.setLinger(true, 20);
|
||||
bool f;
|
||||
@ -402,7 +403,7 @@ void SocketTest::testSelect()
|
||||
|
||||
EchoServer echoServer;
|
||||
StreamSocket ss;
|
||||
ss.connect(SocketAddress("localhost", echoServer.port()));
|
||||
ss.connect(SocketAddress("127.0.0.1", echoServer.port()));
|
||||
|
||||
Socket::SocketList readList;
|
||||
Socket::SocketList writeList;
|
||||
@ -439,8 +440,8 @@ void SocketTest::testSelect2()
|
||||
|
||||
EchoServer echoServer1;
|
||||
EchoServer echoServer2;
|
||||
StreamSocket ss1(SocketAddress("localhost", echoServer1.port()));
|
||||
StreamSocket ss2(SocketAddress("localhost", echoServer2.port()));
|
||||
StreamSocket ss1(SocketAddress("127.0.0.1", echoServer1.port()));
|
||||
StreamSocket ss2(SocketAddress("127.0.0.1", echoServer2.port()));
|
||||
|
||||
Socket::SocketList readList;
|
||||
Socket::SocketList writeList;
|
||||
@ -499,6 +500,28 @@ void SocketTest::testSelect3()
|
||||
}
|
||||
|
||||
|
||||
void SocketTest::testEchoUnixLocal()
|
||||
{
|
||||
#if defined(POCO_OS_FAMILY_UNIX)
|
||||
Poco::File socketFile("/tmp/SocketTest.sock");
|
||||
if (socketFile.exists()) socketFile.remove();
|
||||
SocketAddress localAddr(SocketAddress::UNIX_LOCAL, socketFile.path());
|
||||
EchoServer echoServer(localAddr);
|
||||
StreamSocket ss(SocketAddress::UNIX_LOCAL);
|
||||
ss.connect(localAddr);
|
||||
int n = ss.sendBytes("hello", 5);
|
||||
assert (n == 5);
|
||||
char buffer[256];
|
||||
n = ss.receiveBytes(buffer, sizeof(buffer));
|
||||
assert (n == 5);
|
||||
assert (std::string(buffer, n) == "hello");
|
||||
ss.close();
|
||||
socketFile.remove();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SocketTest::onReadable(bool& b)
|
||||
{
|
||||
if (b) ++_notToReadable;
|
||||
@ -547,6 +570,7 @@ CppUnit::Test* SocketTest::suite()
|
||||
CppUnit_addTest(pSuite, SocketTest, testSelect);
|
||||
CppUnit_addTest(pSuite, SocketTest, testSelect2);
|
||||
CppUnit_addTest(pSuite, SocketTest, testSelect3);
|
||||
CppUnit_addTest(pSuite, SocketTest, testEchoUnixLocal);
|
||||
|
||||
return pSuite;
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ public:
|
||||
void testSelect();
|
||||
void testSelect2();
|
||||
void testSelect3();
|
||||
void testEchoUnixLocal();
|
||||
|
||||
void setUp();
|
||||
void tearDown();
|
||||
|
@ -123,7 +123,7 @@ SyslogTest::~SyslogTest()
|
||||
void SyslogTest::testListener()
|
||||
{
|
||||
Poco::AutoPtr<RemoteSyslogChannel> channel = new RemoteSyslogChannel();
|
||||
channel->setProperty("loghost", "localhost:51400");
|
||||
channel->setProperty("loghost", "127.0.0.1:51400");
|
||||
channel->open();
|
||||
Poco::AutoPtr<RemoteSyslogListener> listener = new RemoteSyslogListener(51400);
|
||||
listener->open();
|
||||
@ -148,7 +148,7 @@ void SyslogTest::testListener()
|
||||
void SyslogTest::testChannelOpenClose()
|
||||
{
|
||||
Poco::AutoPtr<RemoteSyslogChannel> channel = new RemoteSyslogChannel();
|
||||
channel->setProperty("loghost", "localhost:51400");
|
||||
channel->setProperty("loghost", "127.0.0.1:51400");
|
||||
channel->open();
|
||||
Poco::AutoPtr<RemoteSyslogListener> listener = new RemoteSyslogListener(51400);
|
||||
listener->open();
|
||||
@ -187,7 +187,7 @@ void SyslogTest::testChannelOpenClose()
|
||||
void SyslogTest::testOldBSD()
|
||||
{
|
||||
Poco::AutoPtr<RemoteSyslogChannel> channel = new RemoteSyslogChannel();
|
||||
channel->setProperty("loghost", "localhost:51400");
|
||||
channel->setProperty("loghost", "127.0.0.1:51400");
|
||||
channel->setProperty("format", "bsd");
|
||||
channel->open();
|
||||
Poco::AutoPtr<RemoteSyslogListener> listener = new RemoteSyslogListener(51400);
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
|
||||
using Poco::Net::TCPServer;
|
||||
using Poco::Net::TCPServerConnectionFilter;
|
||||
using Poco::Net::TCPServerConnection;
|
||||
using Poco::Net::TCPServerConnectionFactory;
|
||||
using Poco::Net::TCPServerConnectionFactoryImpl;
|
||||
@ -60,6 +61,15 @@ namespace
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class RejectFilter: public TCPServerConnectionFilter
|
||||
{
|
||||
public:
|
||||
bool accept(const StreamSocket&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -82,7 +92,7 @@ void TCPServerTest::testOneConnection()
|
||||
assert (srv.queuedConnections() == 0);
|
||||
assert (srv.totalConnections() == 0);
|
||||
|
||||
SocketAddress sa("localhost", srv.socket().address().port());
|
||||
SocketAddress sa("127.0.0.1", srv.socket().address().port());
|
||||
StreamSocket ss1(sa);
|
||||
std::string data("hello, world");
|
||||
ss1.sendBytes(data.data(), (int) data.size());
|
||||
@ -109,7 +119,7 @@ void TCPServerTest::testTwoConnections()
|
||||
assert (srv.queuedConnections() == 0);
|
||||
assert (srv.totalConnections() == 0);
|
||||
|
||||
SocketAddress sa("localhost", srv.socket().address().port());
|
||||
SocketAddress sa("127.0.0.1", srv.socket().address().port());
|
||||
StreamSocket ss1(sa);
|
||||
StreamSocket ss2(sa);
|
||||
std::string data("hello, world");
|
||||
@ -157,7 +167,7 @@ void TCPServerTest::testMultiConnections()
|
||||
assert (srv.queuedConnections() == 0);
|
||||
assert (srv.totalConnections() == 0);
|
||||
|
||||
SocketAddress sa("localhost", svs.address().port());
|
||||
SocketAddress sa("127.0.0.1", svs.address().port());
|
||||
StreamSocket ss1(sa);
|
||||
StreamSocket ss2(sa);
|
||||
StreamSocket ss3(sa);
|
||||
@ -231,7 +241,9 @@ void TCPServerTest::testMultiConnections()
|
||||
assert (srv.currentConnections() == 0);
|
||||
}
|
||||
|
||||
void TCPServerTest::testThreadCapacity(){
|
||||
|
||||
void TCPServerTest::testThreadCapacity()
|
||||
{
|
||||
ServerSocket svs(0);
|
||||
TCPServerParams* pParams = new TCPServerParams;
|
||||
pParams->setMaxThreads(64);
|
||||
@ -241,6 +253,29 @@ void TCPServerTest::testThreadCapacity(){
|
||||
}
|
||||
|
||||
|
||||
void TCPServerTest::testFilter()
|
||||
{
|
||||
TCPServer srv(new TCPServerConnectionFactoryImpl<EchoConnection>());
|
||||
srv.setConnectionFilter(new RejectFilter);
|
||||
srv.start();
|
||||
assert (srv.currentConnections() == 0);
|
||||
assert (srv.currentThreads() == 0);
|
||||
assert (srv.queuedConnections() == 0);
|
||||
assert (srv.totalConnections() == 0);
|
||||
|
||||
SocketAddress sa("127.0.0.1", srv.socket().address().port());
|
||||
StreamSocket ss(sa);
|
||||
|
||||
char buffer[256];
|
||||
int n = ss.receiveBytes(buffer, sizeof(buffer));
|
||||
|
||||
assert (n == 0);
|
||||
assert (srv.currentConnections() == 0);
|
||||
assert (srv.currentThreads() == 0);
|
||||
assert (srv.queuedConnections() == 0);
|
||||
assert (srv.totalConnections() == 0);
|
||||
}
|
||||
|
||||
|
||||
void TCPServerTest::setUp()
|
||||
{
|
||||
@ -260,6 +295,7 @@ CppUnit::Test* TCPServerTest::suite()
|
||||
CppUnit_addTest(pSuite, TCPServerTest, testTwoConnections);
|
||||
CppUnit_addTest(pSuite, TCPServerTest, testMultiConnections);
|
||||
CppUnit_addTest(pSuite, TCPServerTest, testThreadCapacity);
|
||||
CppUnit_addTest(pSuite, TCPServerTest, testFilter);
|
||||
|
||||
return pSuite;
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ public:
|
||||
void testTwoConnections();
|
||||
void testMultiConnections();
|
||||
void testThreadCapacity();
|
||||
void testFilter();
|
||||
|
||||
void setUp();
|
||||
void tearDown();
|
||||
|
@ -118,7 +118,7 @@ void WebSocketTest::testWebSocket()
|
||||
|
||||
Poco::Thread::sleep(200);
|
||||
|
||||
HTTPClientSession cs("localhost", ss.address().port());
|
||||
HTTPClientSession cs("127.0.0.1", ss.address().port());
|
||||
HTTPRequest request(HTTPRequest::HTTP_GET, "/ws", HTTPRequest::HTTP_1_1);
|
||||
HTTPResponse response;
|
||||
WebSocket ws(cs, request, response);
|
||||
@ -140,6 +140,13 @@ void WebSocketTest::testWebSocket()
|
||||
assert (n == payload.size());
|
||||
assert (payload.compare(0, payload.size(), buffer, 0, n) == 0);
|
||||
assert (flags == WebSocket::FRAME_TEXT);
|
||||
|
||||
ws.sendFrame(payload.data(), (int) payload.size());
|
||||
Poco::Buffer<char> pocobuffer(0);
|
||||
n = ws.receiveFrame(pocobuffer, flags);
|
||||
assert (n == payload.size());
|
||||
assert (payload.compare(0, payload.size(), pocobuffer.begin(), 0, n) == 0);
|
||||
assert (flags == WebSocket::FRAME_TEXT);
|
||||
}
|
||||
|
||||
for (int i = 125; i < 129; i++)
|
||||
@ -150,6 +157,13 @@ void WebSocketTest::testWebSocket()
|
||||
assert (n == payload.size());
|
||||
assert (payload.compare(0, payload.size(), buffer, 0, n) == 0);
|
||||
assert (flags == WebSocket::FRAME_TEXT);
|
||||
|
||||
ws.sendFrame(payload.data(), (int) payload.size());
|
||||
Poco::Buffer<char> pocobuffer(0);
|
||||
n = ws.receiveFrame(pocobuffer, flags);
|
||||
assert (n == payload.size());
|
||||
assert (payload.compare(0, payload.size(), pocobuffer.begin(), 0, n) == 0);
|
||||
assert (flags == WebSocket::FRAME_TEXT);
|
||||
}
|
||||
|
||||
payload = "Hello, world!";
|
||||
@ -185,7 +199,7 @@ void WebSocketTest::testWebSocketLarge()
|
||||
|
||||
Poco::Thread::sleep(200);
|
||||
|
||||
HTTPClientSession cs("localhost", ss.address().port());
|
||||
HTTPClientSession cs("127.0.0.1", ss.address().port());
|
||||
HTTPRequest request(HTTPRequest::HTTP_GET, "/ws", HTTPRequest::HTTP_1_1);
|
||||
HTTPResponse response;
|
||||
WebSocket ws(cs, request, response);
|
||||
@ -209,6 +223,49 @@ void WebSocketTest::testWebSocketLarge()
|
||||
}
|
||||
|
||||
|
||||
void WebSocketTest::testOneLargeFrame(int msgSize)
|
||||
{
|
||||
Poco::Net::ServerSocket ss(0);
|
||||
Poco::Net::HTTPServer server(new WebSocketRequestHandlerFactory(msgSize), ss, new Poco::Net::HTTPServerParams);
|
||||
server.start();
|
||||
|
||||
Poco::Thread::sleep(200);
|
||||
|
||||
HTTPClientSession cs("127.0.0.1", ss.address().port());
|
||||
HTTPRequest request(HTTPRequest::HTTP_GET, "/ws", HTTPRequest::HTTP_1_1);
|
||||
HTTPResponse response;
|
||||
WebSocket ws(cs, request, response);
|
||||
ws.setSendBufferSize(msgSize);
|
||||
ws.setReceiveBufferSize(msgSize);
|
||||
std::string payload(msgSize, 'x');
|
||||
|
||||
ws.sendFrame(payload.data(), msgSize);
|
||||
|
||||
Poco::Buffer<char> buffer(msgSize);
|
||||
int flags;
|
||||
int n;
|
||||
|
||||
n = ws.receiveFrame(buffer.begin(), buffer.size(), flags);
|
||||
assert (n == payload.size());
|
||||
assert (payload.compare(0, payload.size(), buffer.begin(), 0, n) == 0);
|
||||
|
||||
ws.sendFrame(payload.data(), msgSize);
|
||||
|
||||
Poco::Buffer<char> pocobuffer(0);
|
||||
|
||||
n = ws.receiveFrame(pocobuffer, flags);
|
||||
assert (n == payload.size());
|
||||
assert (payload.compare(0, payload.size(), pocobuffer.begin(), 0, n) == 0);
|
||||
}
|
||||
|
||||
|
||||
void WebSocketTest::testWebSocketLargeInOneFrame()
|
||||
{
|
||||
testOneLargeFrame(64000);
|
||||
testOneLargeFrame(70000);
|
||||
}
|
||||
|
||||
|
||||
void WebSocketTest::setUp()
|
||||
{
|
||||
}
|
||||
@ -225,6 +282,7 @@ CppUnit::Test* WebSocketTest::suite()
|
||||
|
||||
CppUnit_addTest(pSuite, WebSocketTest, testWebSocket);
|
||||
CppUnit_addTest(pSuite, WebSocketTest, testWebSocketLarge);
|
||||
CppUnit_addTest(pSuite, WebSocketTest, testWebSocketLargeInOneFrame);
|
||||
|
||||
return pSuite;
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ public:
|
||||
|
||||
void testWebSocket();
|
||||
void testWebSocketLarge();
|
||||
void testWebSocketLargeInOneFrame();
|
||||
|
||||
void setUp();
|
||||
void tearDown();
|
||||
@ -33,6 +34,7 @@ public:
|
||||
static CppUnit::Test* suite();
|
||||
|
||||
private:
|
||||
void testOneLargeFrame(int msgSize);
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user