diff --git a/Net/Makefile b/Net/Makefile index 2d3291750..a58d22dd9 100644 --- a/Net/Makefile +++ b/Net/Makefile @@ -22,6 +22,8 @@ objects = \ HTTPRequest HTTPSession HTTPSessionInstantiator HTTPSessionFactory NetworkInterface \ HTTPRequestHandler HTTPStream HTTPIOStream ServerSocket TCPServerDispatcher TCPServerConnectionFactory \ HTTPRequestHandlerFactory HTTPStreamFactory ServerSocketImpl TCPServerParams \ + HTTPReactorServer HTTPReactorServerSession \ + TCPReactorAcceptor TCPReactorServer TCPReactorServerConnection \ QuotedPrintableEncoder QuotedPrintableDecoder StringPartSource \ FTPClientSession FTPStreamFactory PartHandler PartSource PartStore NullPartHandler \ SocketReactor SocketProactor SocketNotifier SocketNotification AbstractHTTPRequestHandler \ diff --git a/Net/Net_vs170.vcxproj b/Net/Net_vs170.vcxproj index 2cd0ad320..5d9193681 100644 --- a/Net/Net_vs170.vcxproj +++ b/Net/Net_vs170.vcxproj @@ -900,6 +900,9 @@ + + + @@ -986,6 +989,9 @@ + + + @@ -1111,6 +1117,16 @@ stdcpp17 stdc11 + + true + stdcpp17 + stdc11 + + + true + stdcpp17 + stdc11 + true stdcpp17 @@ -1506,6 +1522,21 @@ stdcpp17 stdc11 + + true + stdcpp17 + stdc11 + + + true + stdcpp17 + stdc11 + + + true + stdcpp17 + stdc11 + true stdcpp17 diff --git a/Net/include/Poco/Net/HTTPClientSession.h b/Net/include/Poco/Net/HTTPClientSession.h index d7eabb298..066c16422 100644 --- a/Net/include/Poco/Net/HTTPClientSession.h +++ b/Net/include/Poco/Net/HTTPClientSession.h @@ -18,6 +18,7 @@ #define Net_HTTPClientSession_INCLUDED +#include "Poco/Net/IPAddress.h" #include "Poco/Net/Net.h" #include "Poco/Net/HTTPSession.h" #include "Poco/Net/HTTPBasicCredentials.h" @@ -315,6 +316,8 @@ public: /// Returns true if the proxy should be bypassed /// for the current host. + SocketAddress clientAddress() {return _sourceAddress;} + SocketAddress serverAddress() {return SocketAddress(IPAddress(_host), _port);} protected: enum { diff --git a/Net/include/Poco/Net/HTTPObserver.h b/Net/include/Poco/Net/HTTPObserver.h new file mode 100644 index 000000000..73a1893b4 --- /dev/null +++ b/Net/include/Poco/Net/HTTPObserver.h @@ -0,0 +1,158 @@ +// +// HTTPObserver.h +// +// Library: Foundation +// Package: Net +// Module: HTTPObserver +// +// Definition of the HTTPObserver class template. +// +// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// +#ifndef Net_HTTPObserver_INCLUDED +#define Net_HTTPObserver_INCLUDED + + +#include "Poco/AbstractObserver.h" +#include "Poco/Mutex.h" +#include + + +namespace Poco { +namespace Net { + + +template +class HTTPObserver: public AbstractObserver + /// This template class implements an adapter that sits between + /// a NotificationCenter and an object receiving notifications + /// from it. It is quite similar in concept to the + /// RunnableAdapter, but provides some NotificationCenter + /// specific additional methods. + /// See the NotificationCenter class for information on how + /// to use this template class. + /// + /// This class template is quite similar to the Observer class + /// template. The differences are: + /// + /// - HTTPObserver expects the callback function to accept a const AutoPtr& + /// instead of a plain pointer as argument, thus simplifying memory + /// management. + /// + /// - HTTPObserver expects the object to accept a shared pointer. + /// + /// - In addition to dispatching notifications based on the Notification runtime + /// type, HTTPObserver can also notify subscribers based on the Notification name. + /// To enable this functionality, a matcher function must be provided. + /// Null matcher means no matching is performed and all notificiations + /// of the type subscribed to are dispatched. +{ +public: + using Type = HTTPObserver; + using SharedPtrC = std::shared_ptr; + using NotificationPtr = AutoPtr; + using Callback = void (C::*)(const NotificationPtr&); + using Handler = Callback; + using Matcher = bool (C::*)(const std::string&) const; + + HTTPObserver() = delete; + + HTTPObserver(SharedPtrC object, Handler method, Matcher matcher = nullptr): + _pObject(object), + _handler(method), + _matcher(matcher) + { + } + + HTTPObserver(const HTTPObserver& observer): + AbstractObserver(observer), + _pObject(observer._pObject), + _handler(observer._handler), + _matcher(observer._matcher) + { + } + + ~HTTPObserver() + { + } + + HTTPObserver& operator = (const HTTPObserver& observer) + { + if (&observer != this) + { + _pObject = observer._pObject; + _handler = observer._handler; + _matcher = observer._matcher; + } + return *this; + } + + virtual void notify(Notification* pNf) const + { + handle(NotificationPtr(static_cast(pNf), true)); + } + + virtual bool equals(const AbstractObserver& abstractObserver) const + { + const HTTPObserver* pObs = dynamic_cast(&abstractObserver); + return pObs && pObs->_pObject == _pObject && pObs->_handler == _handler && pObs->_matcher == _matcher; + } + + POCO_DEPRECATED("use `bool accepts(const Notification::Ptr&)` instead") + virtual bool accepts(Notification* pNf, const char* pName) const + { + return (!pName || pNf->name() == pName) && dynamic_cast(pNf) != nullptr; + } + + virtual bool accepts(const Notification::Ptr& pNf) const + { + return (match(pNf) && (pNf.template cast() != nullptr)); + } + + virtual AbstractObserver* clone() const + { + return new HTTPObserver(*this); + } + + virtual void disable() + { + // do nothing + } + +protected: + + void handle(const NotificationPtr& ptr) const + { + Mutex::ScopedLock lock(_mutex); + + if (_pObject) + (_pObject.get()->*_handler)(ptr); + } + + bool match(const Notification::Ptr& ptr) const + { + Mutex::ScopedLock l(_mutex); + + return _pObject && (!_matcher || (_pObject.get()->*_matcher)(ptr->name())); + } + + Mutex& mutex() const + { + return _mutex; + } + +private: + SharedPtrC _pObject; + Callback _handler; + Matcher _matcher; + mutable Poco::Mutex _mutex; +}; + +}} // namespace Poco:Net + + +#endif // Net_HTTPObserver_INCLUDED + diff --git a/Net/include/Poco/Net/HTTPReactorServer.h b/Net/include/Poco/Net/HTTPReactorServer.h new file mode 100644 index 000000000..952451c67 --- /dev/null +++ b/Net/include/Poco/Net/HTTPReactorServer.h @@ -0,0 +1,33 @@ +#include "Poco/Logger.h" +#include "Poco/Net/HTTPRequestHandlerFactory.h" +#include "Poco/Net/HTTPServerParams.h" +#include "Poco/Net/HTTPServerRequest.h" +#include "Poco/Net/HTTPServerRequestImpl.h" +#include "Poco/Net/HTTPSession.h" +#include "Poco/Net/TCPReactorServer.h" +#include "Poco/ThreadPool.h" +namespace Poco { +namespace Net { + + +class Net_API HTTPReactorServer +{ +public: + HTTPReactorServer(int port, HTTPServerParams::Ptr pParams, HTTPRequestHandlerFactory::Ptr pFactory); + ~HTTPReactorServer(); + void start(); + void stop(); + void onMessage(const TcpReactorConnectionPtr& conn); + void onError(const Poco::Exception& ex); + void sendErrorResponse(HTTPSession& session, HTTPResponse::HTTPStatus status); + +private: + TCPReactorServer _tcpReactorServer; + HTTPServerParams::Ptr _pParams; + HTTPRequestHandlerFactory::Ptr _pFactory; + + ThreadPool _threadPool; +}; + +}} // namespace Poco::Net + diff --git a/Net/include/Poco/Net/HTTPReactorServerSession.h b/Net/include/Poco/Net/HTTPReactorServerSession.h new file mode 100644 index 000000000..22e897f16 --- /dev/null +++ b/Net/include/Poco/Net/HTTPReactorServerSession.h @@ -0,0 +1,64 @@ +#ifndef Net_HTTPReactorServerSession_INCLUDED +#define Net_HTTPReactorServerSession_INCLUDED +#include "Poco/Net/HTTPServerParams.h" +#include "Poco/Net/HTTPSession.h" +#include "Poco/Net/SocketAddress.h" +#include "Poco/Net/StreamSocket.h" +#include +#include +namespace Poco { +namespace Net { + + +class Net_API HTTPReactorServerSession : public HTTPSession +/// This class handles the server side of a +/// HTTP session. It is used internally by +/// HTTPReactorServer. +{ +public: + HTTPReactorServerSession(const StreamSocket& socket, std::string& buf, HTTPServerParams::Ptr pParams); + /// Creates the HTTPReactorServerSession. + + virtual ~HTTPReactorServerSession(); + /// Destroys the HTTPReactorServerSession. + + SocketAddress clientAddress() override + { + return _realsocket.peerAddress(); + } + /// Returns the client's address. + + SocketAddress serverAddress() override + { + return _realsocket.address(); + } + /// Returns the server's address. + + bool checkRequestComplete(); + + void popCompletedRequest(); + +private: + int get() override; + + int peek() override; + + int write(const char* buffer, std::streamsize length) override; + + bool parseHeaders(std::size_t pos, std::size_t& bodyStart, std::size_t& contentLength, bool& isChunked); + + bool parseChunkSize(std::size_t& pos, std::size_t& chunkSize, int&); + +private: + std::string& _buf; + char* _pcur; + char* _pend; + int _idx; + int _complete; + StreamSocket _realsocket; +}; + +}} // namespace Poco::Net + +#endif // Net_HTTPReactorServerSession_INCLUDED + diff --git a/Net/include/Poco/Net/HTTPServerRequestImpl.h b/Net/include/Poco/Net/HTTPServerRequestImpl.h index fc406c836..7007a0193 100644 --- a/Net/include/Poco/Net/HTTPServerRequestImpl.h +++ b/Net/include/Poco/Net/HTTPServerRequestImpl.h @@ -18,6 +18,7 @@ #define Net_HTTPServerRequestImpl_INCLUDED +#include "Poco/Net/HTTPSession.h" #include "Poco/Net/Net.h" #include "Poco/Net/HTTPServerRequest.h" #include "Poco/Net/HTTPServerResponseImpl.h" @@ -43,7 +44,7 @@ class Net_API HTTPServerRequestImpl: public HTTPServerRequest /// handleRequest() method of HTTPRequestHandler. { public: - HTTPServerRequestImpl(HTTPServerResponseImpl& response, HTTPServerSession& session, HTTPServerParams* pParams); + HTTPServerRequestImpl(HTTPServerResponseImpl& response, HTTPSession& session, HTTPServerParams* pParams); /// Creates the HTTPServerRequestImpl, using the /// given HTTPServerSession. @@ -82,12 +83,12 @@ public: /// Returns the underlying socket after detaching /// it from the server session. - HTTPServerSession& session(); + HTTPSession& session(); /// Returns the underlying HTTPServerSession. private: HTTPServerResponseImpl& _response; - HTTPServerSession& _session; + HTTPSession& _session; std::istream* _pStream; Poco::AutoPtr _pParams; SocketAddress _clientAddress; @@ -130,7 +131,7 @@ inline HTTPServerResponse& HTTPServerRequestImpl::response() const } -inline HTTPServerSession& HTTPServerRequestImpl::session() +inline HTTPSession& HTTPServerRequestImpl::session() { return _session; } diff --git a/Net/include/Poco/Net/HTTPServerResponseImpl.h b/Net/include/Poco/Net/HTTPServerResponseImpl.h index 39081182b..bc2c06674 100644 --- a/Net/include/Poco/Net/HTTPServerResponseImpl.h +++ b/Net/include/Poco/Net/HTTPServerResponseImpl.h @@ -18,6 +18,7 @@ #define Net_HTTPServerResponseImpl_INCLUDED +#include "Poco/Net/HTTPSession.h" #include "Poco/Net/Net.h" #include "Poco/Net/HTTPServerResponse.h" @@ -42,7 +43,7 @@ class Net_API HTTPServerResponseImpl: public HTTPServerResponse /// as necessary, and provide a message body. { public: - HTTPServerResponseImpl(HTTPServerSession& session); + HTTPServerResponseImpl(HTTPSession& session); /// Creates the HTTPServerResponseImpl. ~HTTPServerResponseImpl(); @@ -110,7 +111,7 @@ protected: void attachRequest(HTTPServerRequestImpl* pRequest); private: - HTTPServerSession& _session; + HTTPSession& _session; HTTPServerRequestImpl* _pRequest; std::ostream* _pStream; diff --git a/Net/include/Poco/Net/HTTPSession.h b/Net/include/Poco/Net/HTTPSession.h index c0db0f299..ff8de905b 100644 --- a/Net/include/Poco/Net/HTTPSession.h +++ b/Net/include/Poco/Net/HTTPSession.h @@ -20,6 +20,7 @@ #include "Poco/Net/Net.h" #include "Poco/Net/MessageHeader.h" +#include "Poco/Net/SocketAddress.h" #include "Poco/Net/StreamSocket.h" #include "Poco/Timespan.h" #include "Poco/Exception.h" @@ -149,7 +150,8 @@ public: /// Returns the trailer for a response sent using chunked /// transfer encoding. The trailer fields to be sent must be set /// before the response body has been fully written. - + virtual SocketAddress clientAddress() = 0; + virtual SocketAddress serverAddress() = 0; protected: HTTPSession(); /// Creates a HTTP session using an @@ -171,12 +173,12 @@ protected: /// Destroys the HTTPSession and closes the /// underlying socket. - int get(); + virtual int get(); /// Returns the next byte in the buffer. /// Reads more data from the socket if there are /// no bytes left in the buffer. - int peek(); + virtual int peek(); /// Peeks at the next character in the buffer. /// Reads more data from the socket if there are /// no bytes left in the buffer. diff --git a/Net/include/Poco/Net/TCPReactorAcceptor.h b/Net/include/Poco/Net/TCPReactorAcceptor.h new file mode 100644 index 000000000..5bbe93e47 --- /dev/null +++ b/Net/include/Poco/Net/TCPReactorAcceptor.h @@ -0,0 +1,48 @@ +#ifndef Net_TCPReactorAcceptor_INCLUDED +#define Net_TCPReactorAcceptor_INCLUDED + +#include "Poco/Net/Net.h" +#include "Poco/Net/SocketAcceptor.h" +#include "Poco/Net/SocketReactor.h" +#include "Poco/Net/TCPReactorServerConnection.h" +#include "Poco/Net/TCPServerParams.h" +#include "Poco/ThreadPool.h" +#include +#include + +namespace Poco { +namespace Net { + + +class Net_API TCPReactorAcceptor : public Poco::Net::SocketAcceptor +{ +public: + TCPReactorAcceptor( + Poco::Net::ServerSocket& socket, Poco::Net::SocketReactor& reactor, TCPServerParams::Ptr pParams); + + ~TCPReactorAcceptor(); + SocketReactor& reactor(); + + void setRecvMessageCallback(const RecvMessageCallback& cb) + { + _recvMessageCallback = cb; + } + +private: + TCPReactorServerConnection* createServiceHandler(Poco::Net::StreamSocket& socket) override; + +private: + TCPReactorAcceptor(const TCPReactorAcceptor&) = delete; + TCPReactorAcceptor& operator=(const TCPReactorAcceptor&) = delete; + std::vector> _wokerReactors; + SocketReactor& _selfReactor; + bool _useSelfReactor; + std::shared_ptr _threadPool; + RecvMessageCallback _recvMessageCallback; + TCPServerParams::Ptr _pParams; +}; + +}} // namespace Poco::Net + +#endif // Net_TCPReactorAcceptor_INCLUDED + diff --git a/Net/include/Poco/Net/TCPReactorServer.h b/Net/include/Poco/Net/TCPReactorServer.h new file mode 100644 index 000000000..ef162865e --- /dev/null +++ b/Net/include/Poco/Net/TCPReactorServer.h @@ -0,0 +1,49 @@ +#ifndef Net_TCPReactorServer_INCLUDED +#define Net_TCPReactorServer_INCLUDED + +#include "Poco/Net/Net.h" +#include "Poco/Net/ServerSocket.h" +#include "Poco/Net/TCPReactorAcceptor.h" +#include "Poco/Net/TCPServerParams.h" +#include "Poco/ThreadPool.h" +#include + +namespace Poco { namespace Net { + +class Net_API TCPReactorServer + /// This class implements a TCP server using the Reactor pattern. + /// It uses a SocketReactor to handle incoming connections and + /// dispatches them to TCPReactorServerConnection objects. + /// + /// The TCPReactorServer is designed to be used with a SocketReactor + /// and a TCPReactorAcceptor. The SocketReactor handles the event + /// loop, while the TCPReactorAcceptor accepts incoming connections + /// and creates TCPReactorServerConnection objects to handle them. +{ +public: + TCPReactorServer(int port, TCPServerParams::Ptr pParams); + + ~TCPReactorServer(); + + void start(); + /// Starts the TCPReactorServer. + /// The server will listen for incoming connections + /// on the given port. + + void stop(); + + void setRecvMessageCallback(const RecvMessageCallback& cb); + +private: + ThreadPool _threadPool; + std::vector _reactors; + std::vector> _acceptors; + std::vector _sockets; + TCPServerParams::Ptr _pParams; + int _port; +}; + +}} // namespace Poco::Net + +#endif // Net_TCPReactorServer_INCLUDED + diff --git a/Net/include/Poco/Net/TCPReactorServerConnection.h b/Net/include/Poco/Net/TCPReactorServerConnection.h new file mode 100644 index 000000000..8644ae39f --- /dev/null +++ b/Net/include/Poco/Net/TCPReactorServerConnection.h @@ -0,0 +1,47 @@ +#ifndef Net_TCPReactorServerConnection_INCLUDED +#define Net_TCPReactorServerConnection_INCLUDED + +#include "Poco/Net/Net.h" +#include "Poco/Net/SocketReactor.h" +#include "Poco/Net/StreamSocket.h" +#include +#include + +namespace Poco { +namespace Net { + + +class TCPReactorServerConnection; +using TcpReactorConnectionPtr = std::shared_ptr; +using RecvMessageCallback = std::function; + +class Net_API TCPReactorServerConnection : public std::enable_shared_from_this +{ +public: + TCPReactorServerConnection(StreamSocket socket, SocketReactor& reactor); + + ~TCPReactorServerConnection(); + + void initialize(); + + void onRead(const AutoPtr& pNf); + void onError(const AutoPtr& pNf); + void onShutdown(const AutoPtr& pNf); + + void handleClose(); + const StreamSocket& socket(); + std::string& buffer(); + + void setRecvMessageCallback(const RecvMessageCallback& cb); + +private: + Poco::Net::SocketReactor& _reactor; + Poco::Net::StreamSocket _socket; + RecvMessageCallback _rcvCallback; + std::string _buf; +}; + +}} // namespace Poco::Net + +#endif // Net_TCPReactorServerConnection_INCLUDED + diff --git a/Net/include/Poco/Net/TCPServerParams.h b/Net/include/Poco/Net/TCPServerParams.h index 362b9c6ee..8d935c038 100644 --- a/Net/include/Poco/Net/TCPServerParams.h +++ b/Net/include/Poco/Net/TCPServerParams.h @@ -91,6 +91,31 @@ public: Poco::Thread::Priority getThreadPriority() const; /// Returns the priority of TCP server threads /// created by TCPServer. + //reactor + bool getReactorMode() const; + /// Returns the reactor mode. + /// + /// If true, use reactor mode, else use thread pool mode. + void setReactorMode(bool reactorMode); + /// Sets the reactor mode. + /// + /// If true, use reactor mode, else use thread pool mode. + int getAcceptorNum() const; + /// Returns the number of acceptors. + + void setAcceptorNum(int acceptorNum); + /// Sets the number of acceptors. + /// + /// The number of acceptors must be greater than 0. + /// The default is 1. + + bool getUseSelfReactor() const; + /// Returns true if acceptor's self reactor is used. + + void setUseSelfReactor(bool useSelfReactor); + /// Sets the acceptor's self reactor. + /// + /// If true, use acceptor's self reactor, else create {_maxThreads} threads to use protected: virtual ~TCPServerParams(); @@ -101,6 +126,10 @@ private: int _maxThreads; int _maxQueued; Poco::Thread::Priority _threadPriority; + + bool _reactorMode; + int _acceptorNum; + bool _useSelfReactor; }; diff --git a/Net/samples/CMakeLists.txt b/Net/samples/CMakeLists.txt index 33c8e6c91..830968e44 100644 --- a/Net/samples/CMakeLists.txt +++ b/Net/samples/CMakeLists.txt @@ -2,6 +2,7 @@ add_subdirectory(EchoServer) add_subdirectory(HTTPFormServer) add_subdirectory(HTTPLoadTest) add_subdirectory(HTTPTimeServer) +add_subdirectory(HTTPReactorTimeServer) add_subdirectory(Mail) add_subdirectory(Ping) add_subdirectory(SMTPLogger) diff --git a/Net/samples/HTTPReactorTimeServer/CMakeLists.txt b/Net/samples/HTTPReactorTimeServer/CMakeLists.txt new file mode 100644 index 000000000..880417488 --- /dev/null +++ b/Net/samples/HTTPReactorTimeServer/CMakeLists.txt @@ -0,0 +1,2 @@ +add_executable(HTTPReactorTimeServer src/HTTPReactorTimeServer.cpp) +target_link_libraries(HTTPReactorTimeServer PUBLIC Poco::Net Poco::Util Poco::JSON) diff --git a/Net/samples/HTTPReactorTimeServer/HTTPReactorTimeServer.progen b/Net/samples/HTTPReactorTimeServer/HTTPReactorTimeServer.progen new file mode 100644 index 000000000..c610dc055 --- /dev/null +++ b/Net/samples/HTTPReactorTimeServer/HTTPReactorTimeServer.progen @@ -0,0 +1,11 @@ +vc.project.guid = ${vc.project.guidFromName} +vc.project.name = ${vc.project.baseName} +vc.project.target = ${vc.project.name} +vc.project.type = executable +vc.project.pocobase = ..\\..\\.. +vc.project.platforms = Win32 +vc.project.configurations = debug_shared, release_shared, debug_static_mt, release_static_mt, debug_static_md, release_static_md +vc.project.prototype = ${vc.project.name}_vs90.vcproj +vc.project.compiler.include = ..\\..\\..\\Foundation\\include;..\\..\\..\\XML\\include;..\\..\\..\\Util\\include;..\\..\\..\\Net\\include +vc.project.compiler.additionalOptions = /Zc:__cplusplus +vc.project.linker.dependencies.Win32 = ws2_32.lib iphlpapi.lib diff --git a/Net/samples/HTTPReactorTimeServer/HTTPReactorTimeServer.properties b/Net/samples/HTTPReactorTimeServer/HTTPReactorTimeServer.properties new file mode 100644 index 000000000..1d6d2e704 --- /dev/null +++ b/Net/samples/HTTPReactorTimeServer/HTTPReactorTimeServer.properties @@ -0,0 +1,16 @@ +# This is a sample configuration file for HTTPTimeServer + +logging.loggers.root.channel.class = ConsoleChannel +logging.loggers.root.channel.formatter = f1 +logging.loggers.app.name = Application +logging.loggers.app.channel = c1 +logging.formatters.f1.class = PatternFormatter +logging.formatters.f1.pattern = %L%Y-%m-%dT%H:%M:%S.%i%z|%E|%p|%J|%t +logging.channels.c1.class = ConsoleChannel +logging.channels.c1.formatter = f1 +HTTPTimeServer.format = %W, %e %b %y %H:%M:%S %Z +HTTPTimeServer.port = 9980 +#HTTPTimeServer.maxQueued = 200 +#HTTPTimeServer.maxThreads = 64 + +HTTPReactorTimeServer.delay = 10 diff --git a/Net/samples/HTTPReactorTimeServer/HTTPReactorTimeServer_vs160.vcxproj b/Net/samples/HTTPReactorTimeServer/HTTPReactorTimeServer_vs160.vcxproj new file mode 100644 index 000000000..4f102e147 --- /dev/null +++ b/Net/samples/HTTPReactorTimeServer/HTTPReactorTimeServer_vs160.vcxproj @@ -0,0 +1,661 @@ + + + + + debug_shared + Win32 + + + debug_shared + x64 + + + debug_static_md + Win32 + + + debug_static_md + x64 + + + debug_static_mt + Win32 + + + debug_static_mt + x64 + + + release_shared + Win32 + + + release_shared + x64 + + + release_static_md + Win32 + + + release_static_md + x64 + + + release_static_mt + Win32 + + + release_static_mt + x64 + + + + 17.0 + HTTPReactorTimeServer + {18A0143A-444A-38E3-838C-1ACFBE4EE18C} + HTTPReactorTimeServer + Win32Proj + + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>17.0.34714.143 + HTTPReactorTimeServerd + HTTPReactorTimeServerd + HTTPReactorTimeServerd + HTTPReactorTimeServer + HTTPReactorTimeServer + HTTPReactorTimeServer + HTTPReactorTimeServerd + HTTPReactorTimeServerd + HTTPReactorTimeServerd + HTTPReactorTimeServer + HTTPReactorTimeServer + HTTPReactorTimeServer + + + bin\ + obj\HTTPReactorTimeServer\$(Configuration)\ + true + + + bin\ + obj\HTTPReactorTimeServer\$(Configuration)\ + false + + + bin\static_mt\ + obj\HTTPReactorTimeServer\$(Configuration)\ + true + + + bin\static_mt\ + obj\HTTPReactorTimeServer\$(Configuration)\ + false + + + bin\static_md\ + obj\HTTPReactorTimeServer\$(Configuration)\ + true + + + bin\static_md\ + obj\HTTPReactorTimeServer\$(Configuration)\ + false + + + bin64\ + obj64\HTTPReactorTimeServer\$(Configuration)\ + true + + + bin64\ + obj64\HTTPReactorTimeServer\$(Configuration)\ + false + + + bin64\static_mt\ + obj64\HTTPReactorTimeServer\$(Configuration)\ + true + + + bin64\static_mt\ + obj64\HTTPReactorTimeServer\$(Configuration)\ + false + + + bin64\static_md\ + obj64\HTTPReactorTimeServer\$(Configuration)\ + true + + + bin64\static_md\ + obj64\HTTPReactorTimeServer\$(Configuration)\ + false + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + /Zc:__cplusplus %(AdditionalOptions) + true + stdcpp17 + stdc11 + + + ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\HTTPReactorTimeServerd.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + /Zc:__cplusplus %(AdditionalOptions) + true + stdcpp17 + stdc11 + + + ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\HTTPReactorTimeServer.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX86 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + /Zc:__cplusplus %(AdditionalOptions) + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\static_mt\HTTPReactorTimeServerd.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + /Zc:__cplusplus %(AdditionalOptions) + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\static_mt\HTTPReactorTimeServer.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX86 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + /Zc:__cplusplus %(AdditionalOptions) + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\static_md\HTTPReactorTimeServerd.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + /Zc:__cplusplus %(AdditionalOptions) + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\static_md\HTTPReactorTimeServer.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX86 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + /Zc:__cplusplus %(AdditionalOptions) + true + stdcpp17 + stdc11 + + + ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\HTTPReactorTimeServerd.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + /Zc:__cplusplus %(AdditionalOptions) + true + stdcpp17 + stdc11 + + + ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\HTTPReactorTimeServer.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX64 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + /Zc:__cplusplus %(AdditionalOptions) + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\static_mt\HTTPReactorTimeServerd.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + /Zc:__cplusplus %(AdditionalOptions) + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\static_mt\HTTPReactorTimeServer.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX64 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + /Zc:__cplusplus %(AdditionalOptions) + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\static_md\HTTPReactorTimeServerd.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + /Zc:__cplusplus %(AdditionalOptions) + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\static_md\HTTPReactorTimeServer.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX64 + + + + + + + + true + stdcpp17 + stdc11 + + + + + diff --git a/Net/samples/HTTPReactorTimeServer/HTTPReactorTimeServer_vs160.vcxproj.filters b/Net/samples/HTTPReactorTimeServer/HTTPReactorTimeServer_vs160.vcxproj.filters new file mode 100644 index 000000000..0e4a49b71 --- /dev/null +++ b/Net/samples/HTTPReactorTimeServer/HTTPReactorTimeServer_vs160.vcxproj.filters @@ -0,0 +1,21 @@ + + + + + {f2077d28-2de7-4969-9c63-998bbd4d49d1} + + + {30ba8631-c476-486c-9a3f-5ec26cff94ff} + + + + + Configuration Files + + + + + Source Files + + + \ No newline at end of file diff --git a/Net/samples/HTTPReactorTimeServer/HTTPReactorTimeServer_vs170.vcxproj b/Net/samples/HTTPReactorTimeServer/HTTPReactorTimeServer_vs170.vcxproj new file mode 100644 index 000000000..dc4ec032e --- /dev/null +++ b/Net/samples/HTTPReactorTimeServer/HTTPReactorTimeServer_vs170.vcxproj @@ -0,0 +1,976 @@ + + + + + debug_shared + ARM64 + + + debug_shared + Win32 + + + debug_shared + x64 + + + debug_static_md + ARM64 + + + debug_static_md + Win32 + + + debug_static_md + x64 + + + debug_static_mt + ARM64 + + + debug_static_mt + Win32 + + + debug_static_mt + x64 + + + release_shared + ARM64 + + + release_shared + Win32 + + + release_shared + x64 + + + release_static_md + ARM64 + + + release_static_md + Win32 + + + release_static_md + x64 + + + release_static_mt + ARM64 + + + release_static_mt + Win32 + + + release_static_mt + x64 + + + + 17.0 + HTTPReactorTimeServer + {18A0143A-444A-38E3-838C-1ACFBE4EE18C} + HTTPReactorTimeServer + Win32Proj + + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>17.0.34714.143 + HTTPReactorTimeServerd + HTTPReactorTimeServerd + HTTPReactorTimeServerd + HTTPReactorTimeServer + HTTPReactorTimeServer + HTTPReactorTimeServer + HTTPReactorTimeServerd + HTTPReactorTimeServerd + HTTPReactorTimeServerd + HTTPReactorTimeServer + HTTPReactorTimeServer + HTTPReactorTimeServer + HTTPReactorTimeServerd + HTTPReactorTimeServerd + HTTPReactorTimeServerd + HTTPReactorTimeServer + HTTPReactorTimeServer + HTTPReactorTimeServer + + + binA64\ + objA64\HTTPReactorTimeServer\$(Configuration)\ + true + + + binA64\ + objA64\HTTPReactorTimeServer\$(Configuration)\ + false + + + binA64\static_mt\ + objA64\HTTPReactorTimeServer\$(Configuration)\ + true + + + binA64\static_mt\ + objA64\HTTPReactorTimeServer\$(Configuration)\ + false + + + binA64\static_md\ + objA64\HTTPReactorTimeServer\$(Configuration)\ + true + + + binA64\static_md\ + objA64\HTTPReactorTimeServer\$(Configuration)\ + false + + + bin\ + obj\HTTPReactorTimeServer\$(Configuration)\ + true + + + bin\ + obj\HTTPReactorTimeServer\$(Configuration)\ + false + + + bin\static_mt\ + obj\HTTPReactorTimeServer\$(Configuration)\ + true + + + bin\static_mt\ + obj\HTTPReactorTimeServer\$(Configuration)\ + false + + + bin\static_md\ + obj\HTTPReactorTimeServer\$(Configuration)\ + true + + + bin\static_md\ + obj\HTTPReactorTimeServer\$(Configuration)\ + false + + + bin64\ + obj64\HTTPReactorTimeServer\$(Configuration)\ + true + + + bin64\ + obj64\HTTPReactorTimeServer\$(Configuration)\ + false + + + bin64\static_mt\ + obj64\HTTPReactorTimeServer\$(Configuration)\ + true + + + bin64\static_mt\ + obj64\HTTPReactorTimeServer\$(Configuration)\ + false + + + bin64\static_md\ + obj64\HTTPReactorTimeServer\$(Configuration)\ + true + + + bin64\static_md\ + obj64\HTTPReactorTimeServer\$(Configuration)\ + false + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + /Zc:__cplusplus %(AdditionalOptions) + true + stdcpp17 + stdc11 + + + ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName).exe + ..\..\..\libA64;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineARM64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + /Zc:__cplusplus %(AdditionalOptions) + true + stdcpp17 + stdc11 + + + ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + binA64\HTTPReactorTimeServer.exe + ..\..\..\libA64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineARM64 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + /Zc:__cplusplus %(AdditionalOptions) + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + binA64\static_mt\HTTPReactorTimeServerd.exe + ..\..\..\libA64;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineARM64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + /Zc:__cplusplus %(AdditionalOptions) + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + binA64\static_mt\HTTPReactorTimeServer.exe + ..\..\..\libA64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineARM64 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + /Zc:__cplusplus %(AdditionalOptions) + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + binA64\static_md\HTTPReactorTimeServerd.exe + ..\..\..\libA64;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineARM64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + /Zc:__cplusplus %(AdditionalOptions) + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName).exe + ..\..\..\libA64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineARM64 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + /Zc:__cplusplus %(AdditionalOptions) + true + stdcpp17 + stdc11 + + + ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\HTTPReactorTimeServerd.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + /Zc:__cplusplus %(AdditionalOptions) + true + stdcpp17 + stdc11 + + + ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\HTTPReactorTimeServer.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX86 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + /Zc:__cplusplus %(AdditionalOptions) + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\static_mt\HTTPReactorTimeServerd.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + /Zc:__cplusplus %(AdditionalOptions) + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\static_mt\HTTPReactorTimeServer.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX86 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + /Zc:__cplusplus %(AdditionalOptions) + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\static_md\HTTPReactorTimeServerd.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + /Zc:__cplusplus %(AdditionalOptions) + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\static_md\HTTPReactorTimeServer.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX86 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + /Zc:__cplusplus %(AdditionalOptions) + true + stdcpp17 + stdc11 + + + ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\HTTPReactorTimeServerd.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + /Zc:__cplusplus %(AdditionalOptions) + true + stdcpp17 + stdc11 + + + ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\HTTPReactorTimeServer.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX64 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + /Zc:__cplusplus %(AdditionalOptions) + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\static_mt\HTTPReactorTimeServerd.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + /Zc:__cplusplus %(AdditionalOptions) + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\static_mt\HTTPReactorTimeServer.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX64 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + /Zc:__cplusplus %(AdditionalOptions) + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\static_md\HTTPReactorTimeServerd.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + /Zc:__cplusplus %(AdditionalOptions) + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\static_md\HTTPReactorTimeServer.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX64 + + + + + + + + true + stdcpp17 + stdc11 + + + + + diff --git a/Net/samples/HTTPReactorTimeServer/HTTPReactorTimeServer_vs170.vcxproj.filters b/Net/samples/HTTPReactorTimeServer/HTTPReactorTimeServer_vs170.vcxproj.filters new file mode 100644 index 000000000..a4313c6f1 --- /dev/null +++ b/Net/samples/HTTPReactorTimeServer/HTTPReactorTimeServer_vs170.vcxproj.filters @@ -0,0 +1,21 @@ + + + + + {35ea3e5f-3889-4ae1-9624-639f81d11698} + + + {2e3d1abc-e17d-4db0-94e8-9d4e575759b4} + + + + + Configuration Files + + + + + Source Files + + + \ No newline at end of file diff --git a/Net/samples/HTTPReactorTimeServer/HTTPReactorTimeServer_vs90.vcproj b/Net/samples/HTTPReactorTimeServer/HTTPReactorTimeServer_vs90.vcproj new file mode 100644 index 000000000..657aaa916 --- /dev/null +++ b/Net/samples/HTTPReactorTimeServer/HTTPReactorTimeServer_vs90.vcproj @@ -0,0 +1,450 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Net/samples/HTTPReactorTimeServer/Makefile b/Net/samples/HTTPReactorTimeServer/Makefile new file mode 100644 index 000000000..4a804bb24 --- /dev/null +++ b/Net/samples/HTTPReactorTimeServer/Makefile @@ -0,0 +1,19 @@ +# +# Makefile +# +# Makefile for Poco HTTPReactorTimeServer +# + +include $(POCO_BASE)/build/rules/global + +objects = HTTPReactorTimeServer + +target = HTTPReactorTimeServer +target_version = 1 +target_libs = PocoUtil PocoJSON PocoNet PocoXML PocoFoundation + +include $(POCO_BASE)/build/rules/exec + +ifdef POCO_UNBUNDLED + SYSLIBS += -lz -lpcre -lexpat +endif diff --git a/Net/samples/HTTPReactorTimeServer/src/HTTPReactorTimeServer.cpp b/Net/samples/HTTPReactorTimeServer/src/HTTPReactorTimeServer.cpp new file mode 100644 index 000000000..1d22fc9a4 --- /dev/null +++ b/Net/samples/HTTPReactorTimeServer/src/HTTPReactorTimeServer.cpp @@ -0,0 +1,225 @@ +// +// HTTPReactorTimeServer.cpp +// +// This sample demonstrates the HTTPServer and related classes. +// +// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/Net/HTTPServer.h" +#include "Poco/Net/HTTPRequestHandler.h" +#include "Poco/Net/HTTPRequestHandlerFactory.h" +#include "Poco/Net/HTTPServerParams.h" +#include "Poco/Net/HTTPServerRequest.h" +#include "Poco/Net/HTTPServerResponse.h" +#include "Poco/Net/HTTPServerParams.h" +#include "Poco/Net/ServerSocket.h" +#include "Poco/Thread.h" +#include "Poco/Timestamp.h" +#include "Poco/DateTimeFormatter.h" +#include "Poco/DateTimeFormat.h" +#include "Poco/Exception.h" +#include "Poco/ThreadPool.h" +#include "Poco/Util/ServerApplication.h" +#include "Poco/Util/Option.h" +#include "Poco/Util/OptionSet.h" +#include "Poco/Util/HelpFormatter.h" +#include +#include + +#include "Poco/Net/HTTPReactorServer.h" + + +using Poco::Net::ServerSocket; +using Poco::Net::HTTPRequestHandler; +using Poco::Net::HTTPRequestHandlerFactory; +using Poco::Net::HTTPServer; +using Poco::Net::HTTPServerRequest; +using Poco::Net::HTTPServerResponse; +using Poco::Net::HTTPServerParams; +using Poco::Timestamp; +using Poco::DateTimeFormatter; +using Poco::DateTimeFormat; +using Poco::ThreadPool; +using Poco::Util::ServerApplication; +using Poco::Util::Application; +using Poco::Util::Option; +using Poco::Util::OptionSet; +using Poco::Util::HelpFormatter; + + +class TimeRequestHandler: public HTTPRequestHandler + /// Return a HTML document with the current date and time. +{ +public: + TimeRequestHandler(const std::string& format, long delay) : _format(format), _delay(delay) + { + } + + void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response) + { + Application& app = Application::instance(); + app.logger().information("Request from " + request.clientAddress().toString()); + + Timestamp now; + std::string dt(DateTimeFormatter::format(now, _format)); + + response.setChunkedTransferEncoding(true); + response.setContentType("text/html"); + response.set("Clear-Site-Data", "\"cookies\""); + + Poco::Thread::sleep(_delay); + + std::ostream& ostr = response.send(); + ostr << "HTTPReactorTimeServer powered by POCO C++ Libraries"; + ostr << ""; + ostr << "

"; + ostr << dt; + ostr << "

"; + } + +private: + std::string _format; + long _delay; + HTTPServerParams::Ptr _params; +}; + + +class TimeRequestHandlerFactory: public HTTPRequestHandlerFactory +{ +public: + TimeRequestHandlerFactory(const std::string& format, long delay) : _format(format), _delay(delay) + { + } + + HTTPRequestHandler* createRequestHandler(const HTTPServerRequest& request) + { + if (request.getURI() == "/") + return new TimeRequestHandler(_format, _delay); + else + return 0; + } + +private: + std::string _format; + long _delay; +}; + + +class HTTPReactorTimeServer: public Poco::Util::ServerApplication + /// The main application class. + /// + /// This class handles command-line arguments and + /// configuration files. + /// Start the HTTPReactorTimeServer executable with the help + /// option (/help on Windows, --help on Unix) for + /// the available command line options. + /// + /// To use the sample configuration file (HTTPReactorTimeServer.properties), + /// copy the file to the directory where the HTTPReactorTimeServer executable + /// resides. If you start the debug version of the HTTPReactorTimeServer + /// (HTTPReactorTimeServerd[.exe]), you must also create a copy of the configuration + /// file named HTTPReactorTimeServerd.properties. In the configuration file, you + /// can specify the port on which the server is listening (default + /// 9980) and the format of the date/time string sent back to the client. + /// + /// To test the TimeServer you can use any web browser (http://localhost:9980/). +{ +public: + HTTPReactorTimeServer(): _helpRequested(false) + { + } + + ~HTTPReactorTimeServer() + { + } + +protected: + void initialize(Application& self) + { + loadConfiguration(); // load default configuration files, if present + ServerApplication::initialize(self); + } + + void uninitialize() + { + ServerApplication::uninitialize(); + } + + void defineOptions(OptionSet& options) + { + ServerApplication::defineOptions(options); + + options.addOption( + Option("help", "h", "display help information on command line arguments") + .required(false) + .repeatable(false)); + } + + void handleOption(const std::string& name, const std::string& value) + { + ServerApplication::handleOption(name, value); + + if (name == "help") + _helpRequested = true; + } + + void displayHelp() + { + HelpFormatter helpFormatter(options()); + helpFormatter.setCommand(commandName()); + helpFormatter.setUsage("OPTIONS"); + helpFormatter.setHeader("A web server that serves the current date and time."); + helpFormatter.format(std::cout); + } + + int main(const std::vector& args) + { + if (_helpRequested) + { + displayHelp(); + } + else + { + // get parameters from configuration file + unsigned short port = (unsigned short) config().getInt("HTTPReactorTimeServer.port", 9980); + std::string format(config().getString("HTTPReactorTimeServer.format", DateTimeFormat::SORTABLE_FORMAT)); + int delay = config().getInt("HTTPReactorTimeServer.delay", 0); + int maxQueued = config().getInt("HTTPReactorTimeServer.maxQueued", 100); + int maxThreads = config().getInt("HTTPReactorTimeServer.maxThreads", 4); + ThreadPool::defaultPool().addCapacity(maxThreads); + + HTTPServerParams* pParams = new HTTPServerParams; + pParams->setMaxQueued(maxQueued); + pParams->setMaxThreads(maxThreads); + pParams->setReactorMode(true); + pParams->setAcceptorNum(1); + pParams->setUseSelfReactor(false); + + // set-up a reactor HTTPServer instance + Poco::Net::HTTPReactorServer server(port, pParams, new TimeRequestHandlerFactory(format, delay)); + // start the HTTPServer + server.start(); + + // wait for CTRL-C or kill + waitForTerminationRequest(); + // Stop the HTTPServer + server.stop(); + } + return Application::EXIT_OK; + } + +private: + bool _helpRequested; +}; + + +int main(int argc, char** argv) +{ + HTTPReactorTimeServer app; + return app.run(argc, argv); +} diff --git a/Net/samples/Makefile b/Net/samples/Makefile index 4285e4cb3..5798eeeb4 100644 --- a/Net/samples/Makefile +++ b/Net/samples/Makefile @@ -11,6 +11,7 @@ projects: $(MAKE) -C TimeServer $(MAKECMDGOALS) $(MAKE) -C httpget $(MAKECMDGOALS) $(MAKE) -C HTTPTimeServer $(MAKECMDGOALS) + $(MAKE) -C HTTPReactorTimeServer $(MAKECMDGOALS) $(MAKE) -C HTTPFormServer $(MAKECMDGOALS) $(MAKE) -C HTTPLoadTest $(MAKECMDGOALS) $(MAKE) -C download $(MAKECMDGOALS) diff --git a/Net/src/HTTPReactorServer.cpp b/Net/src/HTTPReactorServer.cpp new file mode 100644 index 000000000..14a9d80e5 --- /dev/null +++ b/Net/src/HTTPReactorServer.cpp @@ -0,0 +1,113 @@ +#include "Poco/Net/HTTPReactorServer.h" +#include "Poco/Net/HTTPReactorServerSession.h" +#include "Poco/Net/HTTPRequestHandler.h" +#include "Poco/Net/HTTPSession.h" +#include + +namespace Poco { namespace Net { + +HTTPReactorServer::HTTPReactorServer(int port, HTTPServerParams::Ptr pParams, HTTPRequestHandlerFactory::Ptr pFactory) + : _tcpReactorServer(port, pParams) +{ + _pParams = pParams; + _pFactory = pFactory; + _tcpReactorServer.setRecvMessageCallback([this](const TcpReactorConnectionPtr& conn) { + // Handle incoming message + this->onMessage(conn); + }); +} + +HTTPReactorServer::~HTTPReactorServer() +{ +} + +void HTTPReactorServer::start() +{ + _tcpReactorServer.start(); +} + +void HTTPReactorServer::stop() +{ + _tcpReactorServer.stop(); +} + +void HTTPReactorServer::onMessage(const TcpReactorConnectionPtr& conn) +{ + try + { + // Handle read event + HTTPReactorServerSession session(conn->socket(), conn->buffer(), _pParams); + if (!session.checkRequestComplete()) + { + return; + } + // Create request and response objects + HTTPServerResponseImpl response(session); + HTTPServerRequestImpl request(response, session, _pParams); + // Process request and generate response + Poco::Timestamp now; + response.setDate(now); + response.setVersion(request.getVersion()); + response.setKeepAlive(request.getKeepAlive()); + std::string server = _pParams->getSoftwareVersion(); + if (!server.empty()) + { + response.set("Server", server); + } + try + { + session.requestTrailer().clear(); + session.responseTrailer().clear(); + std::unique_ptr pHandler(_pFactory->createRequestHandler(request)); + if (pHandler.get()) + { + if (request.getExpectContinue() && response.getStatus() == HTTPResponse::HTTP_OK) + response.sendContinue(); + + pHandler->handleRequest(request, response); + session.setKeepAlive(_pParams->getKeepAlive() && response.getKeepAlive()); + } + else + sendErrorResponse(session, HTTPResponse::HTTP_NOT_IMPLEMENTED); + } + catch (Poco::Exception& e) + { + if (!response.sent()) + { + try + { + sendErrorResponse( + session, + e.code() == 0 ? HTTPResponse::HTTP_INTERNAL_SERVER_ERROR : HTTPResponse::HTTPStatus(e.code())); + } + catch (...) + { + } + } + throw; + } + } + catch (const Poco::Exception& ex) + { + onError(ex); + } +} + +void HTTPReactorServer::sendErrorResponse(HTTPSession& session, HTTPResponse::HTTPStatus status) +{ + HTTPServerResponseImpl response(session); + response.setVersion(HTTPMessage::HTTP_1_1); + response.setStatusAndReason(status); + response.setKeepAlive(false); + + session.setKeepAlive(false); +} + +void HTTPReactorServer::onError(const Poco::Exception& ex) +{ + // Handle error + throw ex; +} + +}} // namespace Poco::Net + diff --git a/Net/src/HTTPReactorServerSession.cpp b/Net/src/HTTPReactorServerSession.cpp new file mode 100644 index 000000000..0692c62ae --- /dev/null +++ b/Net/src/HTTPReactorServerSession.cpp @@ -0,0 +1,226 @@ +#include "Poco/Net/HTTPReactorServerSession.h" +#include "Poco/Net/HTTPMessage.h" +#include "Poco/String.h" +#include + +namespace Poco { +namespace Net { + + +HTTPReactorServerSession::HTTPReactorServerSession( + const StreamSocket& socket, std::string& buf, HTTPServerParams::Ptr pParams) + : // do not deliver socket to HTTPSession + HTTPSession(), _buf(buf), _realsocket(socket), _complete(0), _idx(0) +{ + _pcur = const_cast(_buf.c_str()); + _idx = 0; +} +/// Creates the HTTPReactorServerSession. + +HTTPReactorServerSession::~HTTPReactorServerSession() +{ + if (_complete > 0) + { + popCompletedRequest(); + } +}; +/// Destroys the HTTPReactorServerSession. + +bool HTTPReactorServerSession::checkRequestComplete() +{ + enum State { PARSING_HEADERS, PARSING_CHUNK_SIZE, PARSING_CHUNK_DATA, PARSING_BODY, COMPLETE }; + + State state = PARSING_HEADERS; + std::size_t pos = 0; + std::size_t bodyStart = 0; + std::size_t contentLength = 0; + std::size_t chunkSize = 0; + + while (pos < _buf.size()) + { + switch (state) + { + case PARSING_HEADERS: + { + bool isChunked = false; + if (!parseHeaders(pos, bodyStart, contentLength, isChunked)) + return false; + if (isChunked) + { + state = PARSING_CHUNK_SIZE; + pos = bodyStart; + } else if (contentLength > 0) + { + state = PARSING_BODY; + pos = bodyStart; + } else + { + _complete = bodyStart; + return true; + } + break; + } + case PARSING_CHUNK_SIZE: + { + if (!parseChunkSize(pos, chunkSize, _complete)) + return false; + if (chunkSize == 0) + return true; + state = PARSING_CHUNK_DATA; + break; + } + case PARSING_CHUNK_DATA: + { + if (pos + chunkSize + 2 <= _buf.size()) + { + pos += chunkSize + 2; // Skip chunk data and trailing "\r\n" + state = PARSING_CHUNK_SIZE; + } else + { + return false; // Incomplete chunk data + } + break; + } + case PARSING_BODY: + { + if (_buf.size() >= bodyStart + contentLength) + { + _complete = bodyStart + contentLength; + return true; + } + return false; // Incomplete body + } + case COMPLETE: + return true; + } + } + return false; // Request is not complete +} + +bool HTTPReactorServerSession::parseHeaders( + std::size_t pos, std::size_t& bodyStart, std::size_t& contentLength, bool& isChunked) +{ + std::size_t headerEnd = _buf.find("\r\n\r\n", pos); + if (headerEnd == std::string::npos) + { + return false; // Incomplete headers + } + + bodyStart = headerEnd + 4; // "\r\n\r\n" is 4 characters + std::size_t chunkedPos = _buf.find(HTTPMessage::TRANSFER_ENCODING, pos); + if (chunkedPos == std::string::npos) + { + chunkedPos = _buf.find(toLower(HTTPMessage::TRANSFER_ENCODING), pos); + } + std::size_t chunkedVal = _buf.find(HTTPMessage::CHUNKED_TRANSFER_ENCODING, chunkedPos); + std::size_t chunkedLineEnd = _buf.find("\r\n", chunkedPos); + if (chunkedPos != std::string::npos && chunkedVal != std::string::npos && + chunkedLineEnd != std::string::npos && chunkedVal < chunkedLineEnd) + { + isChunked = true; + return true; + } + std::size_t contentLengthPos = _buf.find(HTTPMessage::CONTENT_LENGTH, pos); + if(contentLengthPos == std::string::npos) + { + contentLengthPos = _buf.find(toLower(HTTPMessage::CONTENT_LENGTH), pos); + } + if (contentLengthPos != std::string::npos) + { + std::size_t valueStart = contentLengthPos + 15; // "Content-Length:" is 15 characters + std::size_t valueEnd = _buf.find("\r\n", valueStart); + if (valueEnd != std::string::npos) + { + contentLength = std::stoi(_buf.substr(valueStart, valueEnd - valueStart)); + isChunked = false; + return true; + } else + { + return false; // Incomplete Content-Length header + } + } + contentLength = 0; + isChunked = false; + return true; +} + +bool HTTPReactorServerSession::parseChunkSize(std::size_t& pos, std::size_t& chunkSize, int& complete) +{ + + std::size_t chunkSizeEnd = _buf.find("\r\n", pos); + if (chunkSizeEnd == std::string::npos) + return false; // Incomplete chunk size + + std::string chunkSizeStr = _buf.substr(pos, chunkSizeEnd - pos); + chunkSize = std::stoi(chunkSizeStr, nullptr, 16); // Parse hex chunk size + if (chunkSize == 0) + { + std::size_t finalChunkEnd = _buf.find("\r\n\r\n", chunkSizeEnd); + if (finalChunkEnd != std::string::npos) + { + complete = finalChunkEnd + 4; // End of "\r\n\r\n" + return true; + } else + { + return false; // Incomplete final "\r\n\r\n" + } + } + pos = chunkSizeEnd + 2; // Move to the chunk data + + return true; +} + +void HTTPReactorServerSession::popCompletedRequest() +{ + if (_complete >= _buf.length()) + { + // All data has been processed + _buf.clear(); + } else + { + _buf = _buf.substr(_complete); + } + _complete = 0; + _idx = 0; + _pcur = const_cast(_buf.c_str()); + _pend = _pcur + _buf.length(); +} + +int HTTPReactorServerSession::get() +{ + if (_idx < _complete) + { + return _buf[_idx++]; + } else + { + return std::char_traits::eof(); + } +} + +int HTTPReactorServerSession::peek() +{ + if (_idx < _complete) + { + + return _buf[_idx]; + } else + { + + return std::char_traits::eof(); + } +} + +int HTTPReactorServerSession::write(const char* buffer, std::streamsize length) +{ + try + { + return _realsocket.sendBytes(buffer, (int)length); + } catch (Poco::Exception& exc) + { + setException(exc); + throw; + } +} + +}} // namespace Poco::Net + diff --git a/Net/src/HTTPServerRequestImpl.cpp b/Net/src/HTTPServerRequestImpl.cpp index 9651a5dd5..4a686c29d 100644 --- a/Net/src/HTTPServerRequestImpl.cpp +++ b/Net/src/HTTPServerRequestImpl.cpp @@ -16,6 +16,7 @@ #include "Poco/Net/HTTPServerResponseImpl.h" #include "Poco/Net/HTTPServerSession.h" #include "Poco/Net/HTTPHeaderStream.h" +#include "Poco/Net/HTTPSession.h" #include "Poco/Net/HTTPStream.h" #include "Poco/Net/HTTPFixedLengthStream.h" #include "Poco/Net/HTTPChunkedStream.h" @@ -31,7 +32,7 @@ namespace Poco { namespace Net { -HTTPServerRequestImpl::HTTPServerRequestImpl(HTTPServerResponseImpl& response, HTTPServerSession& session, HTTPServerParams* pParams): +HTTPServerRequestImpl::HTTPServerRequestImpl(HTTPServerResponseImpl& response, HTTPSession& session, HTTPServerParams* pParams): _response(response), _session(session), _pStream(0), diff --git a/Net/src/HTTPServerResponseImpl.cpp b/Net/src/HTTPServerResponseImpl.cpp index 7195dd7b0..ff033a565 100644 --- a/Net/src/HTTPServerResponseImpl.cpp +++ b/Net/src/HTTPServerResponseImpl.cpp @@ -16,6 +16,7 @@ #include "Poco/Net/HTTPServerRequestImpl.h" #include "Poco/Net/HTTPServerSession.h" #include "Poco/Net/HTTPHeaderStream.h" +#include "Poco/Net/HTTPSession.h" #include "Poco/Net/HTTPStream.h" #include "Poco/Net/HTTPFixedLengthStream.h" #include "Poco/Net/HTTPChunkedStream.h" @@ -47,7 +48,7 @@ namespace Poco { namespace Net { -HTTPServerResponseImpl::HTTPServerResponseImpl(HTTPServerSession& session): +HTTPServerResponseImpl::HTTPServerResponseImpl(HTTPSession& session): _session(session), _pRequest(0), _pStream(0) diff --git a/Net/src/TCPReactorAcceptor.cpp b/Net/src/TCPReactorAcceptor.cpp new file mode 100644 index 000000000..71b8c86e6 --- /dev/null +++ b/Net/src/TCPReactorAcceptor.cpp @@ -0,0 +1,57 @@ +#include "Poco/Net/TCPReactorAcceptor.h" +#include + + +namespace Poco { +namespace Net { + + +TCPReactorAcceptor::TCPReactorAcceptor( + Poco::Net::ServerSocket& socket, Poco::Net::SocketReactor& reactor, TCPServerParams::Ptr pParams) + : Poco::Net::SocketAcceptor(socket, reactor), _pParams(pParams), _selfReactor(reactor), + _useSelfReactor(pParams->getUseSelfReactor()) +{ + int workerThreads = _useSelfReactor ? 0 : _pParams->getMaxThreads(); + if (workerThreads > 0) + { + _threadPool = std::make_shared("TCPRA", workerThreads, workerThreads); + } + for (int i = 0; i < workerThreads; i++) + { + std::shared_ptr workerReactor(std::make_shared()); + _wokerReactors.push_back(workerReactor); + _threadPool->start(*workerReactor); + } +} + +TCPReactorAcceptor::~TCPReactorAcceptor() +{ +} + +SocketReactor& TCPReactorAcceptor::reactor() +{ + if (_useSelfReactor) + { + return _selfReactor; + } + static std::atomic_uint index(0); + return *_wokerReactors[index++ % _wokerReactors.size()]; +} + +TCPReactorServerConnection* TCPReactorAcceptor::createServiceHandler(Poco::Net::StreamSocket& socket) +{ + // enable nodelay per default: OSX really needs that +#if defined(POCO_HAS_UNIX_SOCKET) + if (socket.address().family() != AddressFamily::UNIX_LOCAL) +#endif + { + socket.setNoDelay(true); + } + auto tmpConnPtr = std::make_shared(socket, reactor()); + tmpConnPtr->setRecvMessageCallback(_recvMessageCallback); + tmpConnPtr->initialize(); + return tmpConnPtr.get(); +} + +}} // namespace Poco::Net + diff --git a/Net/src/TCPReactorServer.cpp b/Net/src/TCPReactorServer.cpp new file mode 100644 index 000000000..e463680da --- /dev/null +++ b/Net/src/TCPReactorServer.cpp @@ -0,0 +1,55 @@ +#include "Poco/Net/TCPReactorServer.h" +#include "Poco/Net/ServerSocket.h" +#include "Poco/Net/TCPServerParams.h" +#include "Poco/ThreadPool.h" + +namespace Poco { +namespace Net { + + + +TCPReactorServer::TCPReactorServer(int port, TCPServerParams::Ptr pParams) + : _threadPool("TCPR", pParams->getAcceptorNum()), _reactors(pParams->getAcceptorNum()), _port(port), + _pParams(pParams) +{ + for (auto& reactor : _reactors) + { + ServerSocket socket(_port); + _sockets.push_back(socket); + auto acceptor = std::make_shared(socket, reactor, _pParams); + _acceptors.push_back(acceptor); + } +} + +TCPReactorServer::~TCPReactorServer() +{ + stop(); +} + +void TCPReactorServer::start() +{ + for (auto& reactor : _reactors) + { + _threadPool.start(reactor); + } +} + +void TCPReactorServer::setRecvMessageCallback(const RecvMessageCallback& cb) +{ + for (auto& acceptor : _acceptors) + { + acceptor->setRecvMessageCallback(cb); + } +} + +void TCPReactorServer::stop() +{ + for (auto& reactor : _reactors) + { + reactor.stop(); + } + _threadPool.joinAll(); +} + +}} // namespace Poco::Net + diff --git a/Net/src/TCPReactorServerConnection.cpp b/Net/src/TCPReactorServerConnection.cpp new file mode 100644 index 000000000..30228e1d7 --- /dev/null +++ b/Net/src/TCPReactorServerConnection.cpp @@ -0,0 +1,84 @@ +#include "Poco/Net/TCPReactorServerConnection.h" +#include "Poco/Net/HTTPObserver.h" + +namespace Poco { +namespace Net { + + +const int BUFFER_SIZE = 4096; + + +TCPReactorServerConnection::TCPReactorServerConnection(StreamSocket socket, SocketReactor& reactor) + : _reactor(reactor), _socket(socket) +{ + _buf.reserve(BUFFER_SIZE); +} + +TCPReactorServerConnection::~TCPReactorServerConnection() +{ +} + +void TCPReactorServerConnection::initialize() +{ + _reactor.addEventHandler( + _socket, + HTTPObserver( + shared_from_this(), &TCPReactorServerConnection::onRead)); +} + +void TCPReactorServerConnection::onRead(const AutoPtr& pNf) +{ + char tmp[BUFFER_SIZE] = {0}; + int n = _socket.receiveBytes(tmp, sizeof(tmp)); + if (n == 0) + { + handleClose(); + } else if (n < 0) + { + // TODO + handleClose(); + } else + { + _buf.append(tmp, n); + _rcvCallback(shared_from_this()); + } +} + +void TCPReactorServerConnection::onError(const AutoPtr& pNf) +{ + handleClose(); +} + +void TCPReactorServerConnection::onShutdown(const AutoPtr& pNf) +{ + handleClose(); +} + +void TCPReactorServerConnection::handleClose() +{ + // here must keep _socket to delay the _socket destrcutor + StreamSocket keepSocket = _socket; + // here will delete this, so memberships' destructor will be invoked + _reactor.removeEventHandler( + _socket, + HTTPObserver( + shared_from_this(), &TCPReactorServerConnection::onRead)); +} + +const StreamSocket& TCPReactorServerConnection::socket() +{ + return _socket; +} + +std::string& TCPReactorServerConnection::buffer() +{ + return _buf; +} + +void TCPReactorServerConnection::setRecvMessageCallback(const RecvMessageCallback& cb) +{ + _rcvCallback = cb; +} + +}} // namespace Poco::Net + diff --git a/Net/src/TCPServerParams.cpp b/Net/src/TCPServerParams.cpp index 6a90374ab..c50d1c0b1 100644 --- a/Net/src/TCPServerParams.cpp +++ b/Net/src/TCPServerParams.cpp @@ -13,6 +13,7 @@ #include "Poco/Net/TCPServerParams.h" +#include "Poco/Bugcheck.h" namespace Poco { @@ -23,7 +24,10 @@ TCPServerParams::TCPServerParams(): _threadIdleTime(10000000), _maxThreads(0), _maxQueued(64), - _threadPriority(Poco::Thread::PRIO_NORMAL) + _threadPriority(Poco::Thread::PRIO_NORMAL), + _reactorMode(false), + _acceptorNum(1), + _useSelfReactor(false) { } @@ -60,5 +64,35 @@ void TCPServerParams::setThreadPriority(Poco::Thread::Priority prio) _threadPriority = prio; } +bool TCPServerParams::getReactorMode() const +{ + return _reactorMode; +} +void TCPServerParams::setReactorMode(bool reactorMode) +{ + _reactorMode = reactorMode; +} +int TCPServerParams::getAcceptorNum() const +{ + poco_assert(_reactorMode); + return _acceptorNum; +} +void TCPServerParams::setAcceptorNum(int acceptorNum) +{ + poco_assert(_reactorMode); + poco_assert(acceptorNum > 0); + _acceptorNum = acceptorNum; +} +bool TCPServerParams::getUseSelfReactor() const +{ + poco_assert(_reactorMode); + return _useSelfReactor; +} +void TCPServerParams::setUseSelfReactor(bool useSelfReactor) +{ + poco_assert(_reactorMode); + _useSelfReactor = useSelfReactor; +} + } } // namespace Poco::Net diff --git a/Net/testsuite/Makefile b/Net/testsuite/Makefile index 0070233e9..845a128e0 100644 --- a/Net/testsuite/Makefile +++ b/Net/testsuite/Makefile @@ -15,6 +15,7 @@ objects = \ HTTPRequestTest MessageHeaderTest NetTestSuite UDPEchoServer \ HTTPResponseTest MessagesTestSuite NetworkInterfaceTest \ HTTPServerTest MulticastEchoServer SocketAddressTest \ + HTTPReactorServerSessionTest HTTPReactorServerTestSuite \ HTTPCookieTest HTTPCredentialsTest HTMLFormTest HTMLTestSuite \ MediaTypeTest QuotedPrintableTest DialogSocketTest \ HTTPClientTestSuite FTPClientTestSuite FTPClientSessionTest \ diff --git a/Net/testsuite/TestSuite_vs170.vcxproj b/Net/testsuite/TestSuite_vs170.vcxproj index 03051fa8a..a00cad876 100644 --- a/Net/testsuite/TestSuite_vs170.vcxproj +++ b/Net/testsuite/TestSuite_vs170.vcxproj @@ -978,6 +978,8 @@ + + @@ -1110,6 +1112,16 @@ stdcpp17 stdc11
+ + true + stdcpp17 + stdc11 + + + true + stdcpp17 + stdc11 + true stdcpp17 diff --git a/Net/testsuite/src/HTTPReactorServerSessionTest.cpp b/Net/testsuite/src/HTTPReactorServerSessionTest.cpp new file mode 100644 index 000000000..b0fda3929 --- /dev/null +++ b/Net/testsuite/src/HTTPReactorServerSessionTest.cpp @@ -0,0 +1,172 @@ +#include "HTTPReactorServerSessionTest.h" +#include "Poco/Net/HTTPReactorServerSession.h" +#include "CppUnit/TestSuite.h" +#include "CppUnit/TestCaller.h" + + +HTTPReactorServerSessionTest::HTTPReactorServerSessionTest(const std::string& name) : CppUnit::TestCase(name) +{ +} + +HTTPReactorServerSessionTest::~HTTPReactorServerSessionTest() +{ +} + +void HTTPReactorServerSessionTest::setUp() +{ +} + +void HTTPReactorServerSessionTest::tearDown() +{ +} + +void HTTPReactorServerSessionTest::testCheckRequestComplete() +{ + std::string buf("GET / HTTP/1.1\r\nHost: localhost\r\nContent-Length: 0\r\n\r\n"); + Poco::Net::HTTPReactorServerSession session(Poco::Net::StreamSocket(), buf, nullptr); + assertTrue(session.checkRequestComplete()); + session.popCompletedRequest(); + assertTrue(buf.empty()); +} + +void HTTPReactorServerSessionTest::testCheckRequestCompleteChunked() +{ + std::string buf("GET / HTTP/1.1\r\nHost: localhost\r\nTransfer-Encoding: chunked\r\n\r\n"); + Poco::Net::HTTPReactorServerSession session(Poco::Net::StreamSocket(), buf, nullptr); + assertTrue(!session.checkRequestComplete()); + session.popCompletedRequest(); + assertTrue(!buf.empty()); + + buf.assign("GET / HTTP/1.1\r\nhost: localhost\r\ntransfer-encoding: chunked\r\n\r\n"); + Poco::Net::HTTPReactorServerSession session1(Poco::Net::StreamSocket(), buf, nullptr); + assertTrue(!session1.checkRequestComplete()); + session1.popCompletedRequest(); + assertTrue(!buf.empty()); +} + +void HTTPReactorServerSessionTest::testCheckRequestCompleteChunkedWithTrailer() +{ + std::string buf("GET / HTTP/1.1\r\nHost: localhost\r\nTransfer-Encoding: chunked\r\nTrailer: Content-MD5\r\n\r\n"); + Poco::Net::HTTPReactorServerSession session(Poco::Net::StreamSocket(), buf, nullptr); + assertTrue(!session.checkRequestComplete()); + session.popCompletedRequest(); + assertTrue(!buf.empty()); + + buf.assign("GET / HTTP/1.1\r\nhost: localhost\r\ntransfer-encoding: chunked\r\ntrailer: content-md5\r\n\r\n"); + Poco::Net::HTTPReactorServerSession session1(Poco::Net::StreamSocket(), buf, nullptr); + assertTrue(!session1.checkRequestComplete()); + session1.popCompletedRequest(); + assertTrue(!buf.empty()); +} + +void HTTPReactorServerSessionTest::testCheckRequestCompleteChunkedWithTrailerAndBody() +{ + std::string buf( + "GET / HTTP/1.1\r\nHost: localhost\r\nTransfer-Encoding: chunked\r\nTrailer: Content-MD5\r\n\r\n0\r\nContent-MD5:xxxxx\r\n\r\n"); + Poco::Net::HTTPReactorServerSession session(Poco::Net::StreamSocket(), buf, nullptr); + assertTrue(session.checkRequestComplete()); + session.popCompletedRequest(); + assertTrue(buf.empty()); + + buf.assign( + "GET / HTTP/1.1\r\nhost: localhost\r\ntransfer-encoding: chunked\r\ntrailer: content-md5\r\n\r\n0\r\ncontent-md5:xxxxx\r\n\r\n"); + Poco::Net::HTTPReactorServerSession session1(Poco::Net::StreamSocket(), buf, nullptr); + assertTrue(session1.checkRequestComplete()); + session1.popCompletedRequest(); + assertTrue(buf.empty()); +} + +void HTTPReactorServerSessionTest::testCheckRequestCompleteChunkedWithBody() +{ + std::string buf("GET / HTTP/1.1\r\nHost: localhost\r\nTransfer-Encoding: chunked\r\n\r\n0\r\n\r\n"); + Poco::Net::HTTPReactorServerSession session(Poco::Net::StreamSocket(), buf, nullptr); + assertTrue(session.checkRequestComplete()); + session.popCompletedRequest(); + assertTrue(buf.empty()); + + buf.assign("GET / HTTP/1.1\r\nhost: localhost\r\ntransfer-encoding: chunked\r\n\r\n0\r\n\r\n"); + Poco::Net::HTTPReactorServerSession session1(Poco::Net::StreamSocket(), buf, nullptr); + assertTrue(session1.checkRequestComplete()); + session1.popCompletedRequest(); + assertTrue(buf.empty()); +} + +void HTTPReactorServerSessionTest::testCheckRequestCompleteChunkedWithStickyBody() +{ + std::string buf("GET / HTTP/1.1\r\nHost: localhost\r\nTransfer-Encoding: chunked\r\n\r\n5\r\nHello\r\n5\r\nWorld\r\n0\r\n\r\n"); + int len = buf.length(); + buf.append(buf); + Poco::Net::HTTPReactorServerSession session(Poco::Net::StreamSocket(), buf, nullptr); + assertTrue(session.checkRequestComplete()); + session.popCompletedRequest(); + assertTrue(buf.length() == len); +} + +void HTTPReactorServerSessionTest::testCheckRequestCompleteContentLength() +{ + std::string buf("GET / HTTP/1.1\r\nHost: localhost\r\nContent-Length: 5\r\n\r\nHello"); + Poco::Net::HTTPReactorServerSession session(Poco::Net::StreamSocket(), buf, nullptr); + assertTrue(session.checkRequestComplete()); + session.popCompletedRequest(); + assertTrue(buf.empty()); + + buf.assign("GET / HTTP/1.1\r\nhost: localhost\r\ncontent-length: 5\r\n\r\nHello"); + Poco::Net::HTTPReactorServerSession session1(Poco::Net::StreamSocket(), buf, nullptr); + assertTrue(session1.checkRequestComplete()); + session1.popCompletedRequest(); + assertTrue(buf.empty()); +} + +void HTTPReactorServerSessionTest::testCheckRequestCompleteContentLengthIncomplete() +{ + std::string buf("GET / HTTP/1.1\r\nHost: localhost\r\nContent-Length: 5\r\n\r\nHel"); + int len = buf.length(); + Poco::Net::HTTPReactorServerSession session(Poco::Net::StreamSocket(), buf, nullptr); + assertTrue(!session.checkRequestComplete()); + session.popCompletedRequest(); + assertTrue(buf.size() == len); + + buf.assign("GET / HTTP/1.1\r\nhost: localhost\r\ncontent-length: 5\r\n\r\nHel"); + len = buf.length(); + Poco::Net::HTTPReactorServerSession session1(Poco::Net::StreamSocket(), buf, nullptr); + assertTrue(!session1.checkRequestComplete()); + session1.popCompletedRequest(); + assertTrue(buf.size() == len); +} + +void HTTPReactorServerSessionTest::testCheckRequestCompleteContentLengthWithStickyBody() +{ + std::string buf("GET / HTTP/1.1\r\nHost: localhost\r\nContent-Length: 5\r\n\r\nHello"); + int len = buf.length(); + buf.append(buf); + Poco::Net::HTTPReactorServerSession session(Poco::Net::StreamSocket(), buf, nullptr); + assertTrue(session.checkRequestComplete()); + session.popCompletedRequest(); + assertTrue(buf.length() == len); + + buf.assign("GET / HTTP/1.1\r\nhost: localhost\r\ncontent-length: 5\r\n\r\nHello"); + len = buf.length(); + buf.append(buf); + Poco::Net::HTTPReactorServerSession session1(Poco::Net::StreamSocket(), buf, nullptr); + assertTrue(session1.checkRequestComplete()); + session1.popCompletedRequest(); + assertTrue(buf.length() == len); +} + +CppUnit::Test* HTTPReactorServerSessionTest::suite() +{ + CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("HTTPReactorServerSessionTest"); + + CppUnit_addTest(pSuite, HTTPReactorServerSessionTest, testCheckRequestComplete); + CppUnit_addTest(pSuite, HTTPReactorServerSessionTest, testCheckRequestCompleteChunked); + CppUnit_addTest(pSuite, HTTPReactorServerSessionTest, testCheckRequestCompleteChunkedWithTrailer); + CppUnit_addTest(pSuite, HTTPReactorServerSessionTest, testCheckRequestCompleteChunkedWithTrailerAndBody); + CppUnit_addTest(pSuite, HTTPReactorServerSessionTest, testCheckRequestCompleteChunkedWithBody); + CppUnit_addTest(pSuite, HTTPReactorServerSessionTest, testCheckRequestCompleteChunkedWithStickyBody); + CppUnit_addTest(pSuite, HTTPReactorServerSessionTest, testCheckRequestCompleteContentLength); + CppUnit_addTest(pSuite, HTTPReactorServerSessionTest, testCheckRequestCompleteContentLengthIncomplete); + CppUnit_addTest(pSuite, HTTPReactorServerSessionTest, testCheckRequestCompleteContentLengthWithStickyBody); + + return pSuite; +} + diff --git a/Net/testsuite/src/HTTPReactorServerSessionTest.h b/Net/testsuite/src/HTTPReactorServerSessionTest.h new file mode 100644 index 000000000..a7dd60019 --- /dev/null +++ b/Net/testsuite/src/HTTPReactorServerSessionTest.h @@ -0,0 +1,33 @@ +#ifndef HTTPReactorServerSessionTest_INCLUDED +#define HTTPReactorServerSessionTest_INCLUDED + +#include "CppUnit/TestCase.h" + + +class HTTPReactorServerSessionTest: public CppUnit::TestCase +{ +public: + HTTPReactorServerSessionTest(const std::string& name); + ~HTTPReactorServerSessionTest(); + + void testCheckRequestComplete(); + void testCheckRequestCompleteChunked(); + void testCheckRequestCompleteChunkedWithTrailer(); + void testCheckRequestCompleteChunkedWithTrailerAndBody(); + void testCheckRequestCompleteChunkedWithBody(); + void testCheckRequestCompleteChunkedWithStickyBody(); + void testCheckRequestCompleteContentLength(); + void testCheckRequestCompleteContentLengthIncomplete(); + void testCheckRequestCompleteContentLengthWithStickyBody(); + + + void setUp(); + void tearDown(); + + static CppUnit::Test* suite(); + +private: +}; + +#endif // HTTPReactorServerSessionTest_INCLUDED + diff --git a/Net/testsuite/src/HTTPReactorServerTestSuite.cpp b/Net/testsuite/src/HTTPReactorServerTestSuite.cpp new file mode 100644 index 000000000..f0edd4d5f --- /dev/null +++ b/Net/testsuite/src/HTTPReactorServerTestSuite.cpp @@ -0,0 +1,14 @@ +#include "HTTPReactorServerTestSuite.h" +#include "CppUnit/TestSuite.h" +#include "HTTPReactorServerSessionTest.h" + + +CppUnit::Test* HTTPReactorServerTestSuite::suite() +{ + CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("HTTPReactorServerTestSuite"); + + pSuite->addTest(HTTPReactorServerSessionTest::suite()); + + return pSuite; +} + diff --git a/Net/testsuite/src/HTTPReactorServerTestSuite.h b/Net/testsuite/src/HTTPReactorServerTestSuite.h new file mode 100644 index 000000000..bcc8c2b85 --- /dev/null +++ b/Net/testsuite/src/HTTPReactorServerTestSuite.h @@ -0,0 +1,13 @@ +#ifndef HTTPReactorServerTestSuite_INCLUDED +#define HTTPReactorServerTestSuite_INCLUDED + +#include "CppUnit/Test.h" + +class HTTPReactorServerTestSuite +{ +public: + static CppUnit::Test* suite(); +}; + +#endif // HTTPReactorServerTestSuite_INCLUDED + diff --git a/Net/testsuite/src/NetTestSuite.cpp b/Net/testsuite/src/NetTestSuite.cpp index 29419ab57..8a7bbb76c 100644 --- a/Net/testsuite/src/NetTestSuite.cpp +++ b/Net/testsuite/src/NetTestSuite.cpp @@ -17,6 +17,7 @@ #include "TCPServerTestSuite.h" #include "UDPServerTestSuite.h" #include "HTTPServerTestSuite.h" +#include "HTTPReactorServerTestSuite.h" #include "HTMLTestSuite.h" #include "ReactorTestSuite.h" #include "FTPClientTestSuite.h" @@ -40,6 +41,7 @@ CppUnit::Test* NetTestSuite::suite() pSuite->addTest(TCPServerTestSuite::suite()); pSuite->addTest(UDPServerTestSuite::suite()); pSuite->addTest(HTTPServerTestSuite::suite()); + pSuite->addTest(HTTPReactorServerTestSuite::suite()); pSuite->addTest(HTMLTestSuite::suite()); pSuite->addTest(ReactorTestSuite::suite()); pSuite->addTest(FTPClientTestSuite::suite());