poco/doc/00100-GuidedTour.page
Aleksandar Fabijanic d294391c94
Dev/devel 1.12.0 (#3585)
* fix(PollSet): #3248 #3249

* bump version to 1.11.0

* updated changelog|

* #3299: NetSSL: Allow per-Context InvalidCertificateHandler

* #3022: Process::isRunning(PID pid) causes handle leak on Windows

* #3022: fix for WinCE

* upgrade bundled pdjson to latest master

* update build configs - add support for Apple Silicon

* #2906, #2904: Support environments without hardware floating point

* #3130: fix error handling: report original error before close()

* #3107: remove unused variable

* #3219: SMTPClientSession: invalid SMTP command if empty recipients list in MailMessage

* Poco::trim*() code cleanup - use ptrdiff_t instead of int; additional test cases

* #3182 Poco::Process:launch on MacOS BigSur: limit maximum number of file descriptors to close before exec() to 100000

* #3278: Fixing no hardware floating point support - Part II

* #3090: Do not initialize value with undefined behavior

* #3163: Correct Var::parse null value

* #3196: std::forward for Poco::Optional ctor with rvalue

* #3068: Documented ENABLE_JWT option

* #3041: PostgreSQL and TEXT column type

* #3099: Fixed Postgres extraction into Dynamic::Var

* #3138: Add support of arch riscv32

* #2825: riscv: Enable double operations when using double float abi

* #3166: Fix PostgresSQL BLOB extractor

* #3237: An error in the documentation for Poco/JSON/Parser.h

* #3193: ServerApplication::registerService() unquoted path security vulnerability

* #3266: Order of Util::Application::uninitialize() is not in reverse as documented

* #3215: XML parser returns item from different element in a array

* #3282: Update constant in setContentType documentation

* #3089: HTTPSessionFactory does not support HTTPClientSession::ProxyConfig

* #2418: SecureServerSocket doesn't work with IpV6

* fix warnings

* #3019: ObjectPool wait on borrow condition fix

* #3224: Remove SSL23 support from Poco/Crypto

* #3191: Fixing a bug in the NetSSL_Win module (Host name verification failed error)

* disallow SSLv3

* #3269: Poco::Net::Context initialization with empty certificateFile

* #3307: Poco::Crypto::X509Certificate: obtain certificate fingerprint

* #3260: Memory leak in EVPPKey::loadKey used with files & wrong password

* #3157: fix(openssl): add missing dependency to OpenSSL components

* #3066: CMake warning about MYSQL casing

* #3135: Poco::Data::SQLite::Utility::fileToMemory unsuccessful if journal exists

* #3217: CMake: warning message with -DPOCO_STATIC confusing

* #3274: Fix localtime_r for VxWorks 6.9 and later

* #2746, #3169: Fix race condition on TCPServerDispatcher stop

* #3092: add more detailed error description when LoadLibrary fails|

* #3074: Fix sessions may not return back to the pool

* #3309: optimize parsing from stream (no copying of entire JSON to memory); limit maximum depth to avoid stack overflow with malicious documents (fuzzing - #3285); code cleanup

* JSON Parser performance improvements

* #3310: Upgrade bundled SQLite to 3.35.5

* fix UB/bad cast in TCPServerTest.cpp

* add comment regarding potential UB in AnyTest::testCastToReference()

* support sanitizers in build configs

* bump version

* fix 'catching polymorphic type by value' warnings

* fix 'catching polymorphic type by value' warnings

* fix 'catching polymorphic type by value' warnings

* remove failing Android build; add sanitizer builds

* update postgres version

* fix warning

* fix warning

* add GitHub workflow

* fix ci.yml

* fix ci.yml

* additional ci builds

* fix ci.yml for macos and windows

* fix(double-conversion): Upgrade bundled double-conversion #3313

* ci fixes

* #3314: NetSSL_OpenSSL: any.pem certificate error: ca md too weak

* testReuseSession: remove bad checks for session reuse

* investigate failing test

* investigate failing test

* investigate failing test

* investigate failing test

* ci

* remove travis and appveyor

* ci, readme

* ci fixes

* fix ci

* fix ci

* fix ci

* fix memory leak when ignoring test error/failure

* fix ci

* don't define UNREACHABLE as poco_bugcheck as it triggers 'control reaches end of non-void function' warning

* add Linux cross build, build Data libs on macos

* fix ci

* add MySQL include/lib search paths for Homebrew

* ci fixes

* ci fixes

* ci fixes

* ci fixes

* fix indluce paths for brew mysql

* #3317: Data::MySQL MySQL headers and library search paths

* fix ARM-Linux build config

* fix MySQL.make

* update FindMySQL.cmake

* fix(SocketReactor): fix dataCollection test

* chore: remove troubleshooting help leftovers

* #3302: MSVC: Poco hides warnings (C4996) for the C++14 attribute [[deprecated]]

* fix potential crash in testAsyncNotify: don't delete event object while async notification is still in progress

* fix(PollSetTest): change connect to blocking

* added ActiveRecord library and compiler

* added dependencies file

* update copyright dates

* ActiveRecord: project files and fixes for MSVC

* ci: enable ActiveRecord on Windows

* fix(PollSetTest): remove poll timing check (fails on msvc ci)

* fix ActiveRecord CMake build and configuration

* feat(build): add gen directory (for generated sources) and macchina lib link dirs (if needed)

* #3318: Data: Support Poco::UUID for data binding

* ODBC tests for UUID, updated ActiveRecord projects

* ActiveRecord user guide

* update ActiveRecord documentation

* documentation fixes

* #3321: manually merge ODBC text encoding support

* CppParser: merge changes from internal repository

* updated Makefile

* AbstractObserver::accepts() - add optional name parameter

* fix SharedPtr::makeSharedArray() [merge from devel]

* remove blank line

* #2895, #2935: support OCSP stapling

* style

* clang support (merge from devel)

* #3322: remove useless struct

* link libmariadb instead of libmysql if headers indicate MariaDB

* fix nullptr passed to memcmp/memcpy reported by ubsan

* fix nullptr passed to memcmp/memcpy reported by ubsan

* fix PageCompiler cross-compile; fix Content-Security-Policy header

* remove Data release notes page

* style, remove unused var

* update docs

* improve BLOB handling, clean-up code

* fix(ICMPv4Packet): [asan] Undefined behavior in ICMPv4PacketImpl.cpp #3326

* fix(NumericString): Bug in NumericString with decSep != '.' #3159

* fix(HostEntry): DNS HostEntry returns multiple entries #3303

* fix(PollSet): #3248 #3249

* fix(NetworkInterface): Unterminated string possible in NetworkInterfaceImpl::setPhyParams() #3301

* style/whitespace

* fix warnings

* add version resources to executables

* style

* whitespace

* update changelog

* cpproj: also copy testsuite/include if it's there

* branch off 1.11.1

* #3335: XML error when build 1.11.0

* #3353: add POCO_NO_FORK_EXEC CMake option

* #3381: DNS::hostByAddress not thread-safe

* #3400: fix std::localtime not thread safe

* #3221: Crash reported on Windows in X509Certificate verification

* #3344: [bug] MacOS bundle destination path is not set

* #3360: Add POCO_PGSQL_{INCLUDE,LIB} variables

* #3363: Fixed compilation error with MongoDB::Connection and Util::Application

* #3377: Correct Poco::Path::configHome() and dataHome() documentation for Windows

* #2823: error: implicit conversion from 'int' to 'float' changes value from 2147483647 to 2147483648

* #3425: Fixed suspend/resumeEvents pair in DirectoryWatcher

* #2966: SocketReactor loads one core of CPU up to 100%

* #3330: Poco::Data::ODBC::ODBCStatementImpl causes crash

* use OpenSSL 1.1.1 on macOS

* add missing include search path

* upgrade bundled PCRE to 8.45

* upgrade bundled SQLite to 3.36.0

* updated changelog

* fix brew OpenSSL version

* branch off poco-1.11.2

* #3506: Upgrade bundled expat to 2.4.4

* manually merge #3448, part 1 (Crypto)

* manually merge #3448, part 1 (NetSSL)

* #3515: NetSSL_OpenSSL Testsuite: testInterop() and testProxy() fail due to changed certificate

* #3448: fix version check

* #3465: NetSSL_Win: bad error handling when decodeMessage() fails

* #3458: encryptString() crash on redhat/centos 8 with FIPS enabled using md5 default digest

* #3505: JSON::PrintHandler.value(bool) prints incorrect value

* #3527: Upgrade bundled expat to 2.4.5

* #3470: bug in JSON ParseHandler.cpp (RFC 7159 should be valid)

* #3507: Reference counting for bound configuration in Util::Option is broken

* #3518: Expat version check in #defines incorrect

* #3338: NamedMutex does not work on Linux distributions where fs.protected_regular=1

* CI: don't build PageCompiler in ARM cross build

* detect ARM64 on Windows

* updated README.md

* ProGen: support generation of VS 2022 project files

* ci: add windows 2022

* fix library name

* remove unused CppUnit headers

* added VS2022 project files

* #3530: Upgrade bundled expat to 2.4.6

* #3538: Upgrade bundled expat to 2.4.7

* Add back NIOS2 double conversion detection to fix compile errors

The commit
558324f672

removed the nios2 support, which was originally added in
e7b91e8125

This commit add it back.

Signed-off-by: Julien Olivain <ju.o@free.fr>

* #3466: DefinePlatformSpecific.cmake: handle RelWithDebInfo and MinSizeRel configurations

* #3524: remove XML and Util dependencies in Zip/SevenZip

* #3483: Adds Windows 11 and Server 2022 to Environment::osDisplayName()

* #3495: Array::operator[] should not throw

* #3268: Poco redis command set have a bug when you want to set nx ex or expireTime

* #3509: fix dst and utcOffset handling for Dublin time zone

* #2882: another attempt at fixing it that should also work on other platforms

* remove unused method in Timezone_WIN32.cpp

* use tm_gmtoff on Linux

* Basic support for OpenSSL 3.0.0 (#3448)

* updated README.md

* Create close-inactive-issues.yml

* check return codes of EVP_CIPHER_CTX_new and EVP_CipherInit

Especially with OpenSSL 3, it is possible that EVP_CipherInit may fail even when
passed a non-null cipher[1]. Without the checking, it will finally get to a
segfault.

[1] https://github.com/openssl/openssl/issues/16864

* Automatically load default and legacy providers with OpenSSL 3

Without the legacy provider [1], some ciphers are not available. For example,
the 'des-ecb' one used by test sutie is missed and the test will fail.

[1] OSSL_PROVIDER-LEGACY(7ossl)

* Make p12 ca order the same as pem

OpenSSL < 3 returns p12 ca order in reversed order. This is fixed
in OpenSSL 3. We work around it with old OpenSSL.

See:
https://github.com/openssl/openssl/issues/16421
https://github.com/openssl/openssl/pull/12641
f5eb85eb0f

* Implement SSL abort handling on OpenSSL 3

On an unexpected EOF, versions before OpenSSL 3.0 returned SSL_ERROR_SYSCALL,
nothing was added to the error stack, and errno was 0. Since OpenSSL 3.0 the
returned error is SSL_ERROR_SSL with a meaningful error on the error stack.[1]

[1] SSL_GET_ERROR(3ossl)

Co-authored-by: Günter Obiltschnig <guenter.obiltschnig@appinf.com>
Co-authored-by: Robin Lee <cheeselee@fedoraproject.org>
Co-authored-by: Aleksandar Fabijanic <aleks-f@users.noreply.github.com>

* fix(Socket): shutdown fixes from pull #3448

* #3500: Sandbox all iFrames in PocoDoc

* #3549; replace assert with assertTrue

* #3553: Upgrade bundled zlib to 1.2.12

* #3525: Bad management of file in case of OpenSSLException in X509Certificate::readPEM and X509Certificate::writePEM

* disable OpenSSL deprecation warnings

* chore: cleanup

* fix(X509Certificate): add missing string format

* #3559: Poco::Data::PostgreSQL - DateTime extraction truncates fractional seconds

* feat(EVP): 3.0 support

- add EVPCipher
- additional EVPPKey constructors
- tests
- fix and improve openssl-related exceptions

Transition towards 3.0 support;
deprecating direct EC and RSA interface portions.

* fix(openssl): pre 3.0 compile

* feat(Envelope): Add envelope to crypto #3561

* fix(Envelope): mac/clang compile

* fix(Any): #3297 #3514

* #3562: fixed OpenSSL setup/shutdown

* fix exception text

* #3563: Remove support for OpenSSL < 1.0

* ci jobs for OpenSSL 1.1 and 3

* updated CHANGELOG

* updated .vscode

* Refactor/any soo (#3564)

* refactor(Any): SOO

- encapsulate data holders
- add missing gets and ops
- eliminate g++ warnings with enable_if's
- default enable SOO

* refactor(Placeholder): encapsulate SOO memory management and fix leaks; cf. #3297 #3514

* fix(Placeholder): asan errors and add tests

cf. #3297 #3514

* fix(SSLManager): Race condition in SSLManager #3558

* remove unused include

* updated copyright date

* PocoDoc: fix iframe sandboxing

* fix(SHA2Engine): cannot use HMACEngine with SHA2Engine #3421

* refactor(Placeholder): ifdef POCO_NO_SOO only in Placeholder and remove it anywhere else (#3566)

* refactor(Placeholder): more SOO consolidation and optimization

* fix(FPEnvironment): Visual Studio Warning C4244 #3543

* fix(Extractor): move extraction decoding to AbstractExtractor #3396

* Netssl/openssl3 (#3575)

* feat(Context): DH init openssl3 port (1/2 hardcoded params)

* create poco-1.11.3 branch, bump version

* update copyright date

* #3567: check legacy provider existence for legacy exception #3567

* fix(Placeholder): comparison for zero value

* feat(Context): DH init openssl3 port (2/2 params from file)

* test(HTTPSClientSession): try/catch to understand CI failure

* chore(cmake): copy the DH parameters file

* fix(OpenSSLInitializer): unload provider on uninitialize

* chore(HTTPSClientSessionTest): remove try/catch

* fix(OpenSSLInitializer): fix provider unloading

* feat(CppUnit): make tests exceptions more descriptive

* chore(CppUnit): a more descriptive name for callback

Co-authored-by: Günter Obiltschnig <guenter.obiltschnig@appinf.com>

* fix(Foundation): update VS 2019 platform version

* chore(Data): update VS project files (add Transcoder #3396)

* fix(Data): Poco::Data::ODBC-dbEncoding property not used for insert/update #3396

* fix(Data): add transcoder to Makefile #3396

* fix(JWT): remove duplicate test functions after merge

Co-authored-by: Günter Obiltschnig <guenter.obiltschnig@appinf.com>
Co-authored-by: Julien Olivain <ju.o@free.fr>
Co-authored-by: Robin Lee <robinlee.sysu@gmail.com>
Co-authored-by: Robin Lee <cheeselee@fedoraproject.org>
2022-05-04 13:57:08 -05:00

429 lines
17 KiB
Plaintext

A Guided Tour Of The POCO C++ Libraries
AAAIntroduction
!!! Introduction
The POCO C++ Libraries are a collection of open source C++
class libraries that simplify and accelerate the development of
network-centric, portable applications in C++. The libraries integrate
perfectly with the C++ Standard Library and fill many of the functional
gaps left open by it. Their modular and efficient design and
implementation makes the POCO C++ Libraries extremely well suited
for embedded development, an area where the C++ programming language is
becoming increasingly popular, due to its suitability for both low-level
(device I/O, interrupt handlers, etc.) and high-level object-oriented
development. Of course, POCO is also ready for enterprise-level
challenges.
<%
<img src="images/poco.png" width="320" height="255" alt="POCO Libraries" border="0">
%>
POCO consists of four core libraries, and a number of add-on libraries.
The core libraries are Foundation, XML, Util and Net. Two of the add-on
libraries are NetSSL, providing SSL support for the network classes in
the Net library, and Data, a library for uniformly accessing different
SQL databases. POCO aims to be for
network-centric, cross-platform C++ software development what Apple's
Cocoa is for Mac development, or Ruby on Rails is for Web development --
a powerful, yet easy and fun to use platform to build your applications
upon. POCO is built strictly using standard ANSI/ISO C++, including the
standard library. The contributors attempt to find a good balance
between using advanced C++ features and keeping the classes
comprehensible and the code clean, consistent and easy to maintain.
<%
<?-PocoDoc.adContent?>
%>
!!! The Foundation Library
The Foundation library makes up the heart of POCO. It contains the
underlying platform abstraction layer, as well as frequently used
utility classes and functions. The Foundation library contains types for
fixed-size integers, functions for converting integers between byte
orders, an Poco::Any class (based on <[boost::Any]>), utilities for error handling
and debugging, including various exception classes and support for
assertions. Also available are a number of classes for memory
management, including reference counting based smart pointers, as well
as classes for buffer management and memory pools. For string handling,
POCO contains a number of functions that among other things, trim
strings, perform case insensitive comparisons and case conversions.
Basic support for Unicode text is also available in the form of classes
that convert text between different character encodings, including UTF-8
and UTF-16. Support for formatting and parsing numbers is there,
including a typesafe variant of sprintf. Regular expressions based on
the well-known PCRE library (http://www.pcre.org) are provided as well.
POCO gives you classes for handling dates and times in various variants.
For accessing the file system, POCO has Poco::File and Poco::Path classes, as well as a
Poco::DirectoryIterator class. In many applications, some parts of the
application need to tell other parts that something has happened. In
POCO, Poco::NotificationCenter, Poco::NotificationQueue and events (similar to C#
events) make this easy. The following example shows how POCO events can be used. In
this example, class <[Source]> has a public event named <[theEvent]>, having an
argument of type int. Subscribers can subscribe by calling <[operator +=]>
and unsubscribe by calling <[operator -=]>, passing a pointer to an object
and a pointer to a member function. The event can be fired by calling
<[operator ()]>, as its done in <[Source::fireEvent()]>.
#include "Poco/BasicEvent.h"
#include "Poco/Delegate.h"
#include <iostream>
using Poco::BasicEvent;
using Poco::delegate;
class Source
{
public:
BasicEvent<int> theEvent;
void fireEvent(int n)
{
theEvent(this, n);
}
};
class Target
{
public:
void onEvent(const void* pSender, int& arg)
{
std::cout << "onEvent: " << arg << std::endl;
}
};
int main(int argc, char** argv)
{
Source source;
Target target;
source.theEvent += delegate(&target, &Target::onEvent);
source.fireEvent(42);
source.theEvent -= delegate(&target, &Target::onEvent);
return 0;
}
----
The stream classes available in POCO have already been mentioned. These are
augmented by Poco::BinaryReader and Poco::BinaryWriter for writing binary data to
streams, automatically and transparently handling byte order issues.
In complex multithreaded applications, the only way to find problems or
bugs is by writing extensive logging information. POCO provides a
powerful and extensible logging framework that supports filtering,
routing to different channels, and formatting of log messages. Log
messages can be written to the console, a file, the Windows Event Log,
the Unix syslog daemon, or to the network. If the channels provided by
POCO are not sufficient, it is easy to extend the logging framework with
new classes.
For loading (and unloading) shared libraries at runtime,
POCO has a low-level Poco::SharedLibrary class. Based on it is the Poco::ClassLoader
class template and supporting framework, allowing dynamic loading and
unloading of C++ classes at runtime, similar to what's available to Java
and .NET developers. The class loader framework also makes it a breeze
to implement plug-in support for applications in a platform-independent
way.
Finally, POCO Foundation contains multithreading abstractions at
different levels. Starting with a Poco::Thread class and the usual
synchronization primitives (Poco::Mutex, Poco::ScopedLock, Poco::Event,
Poco::Semaphore, Poco::RWLock), a Poco::ThreadPool class and support for
thread-local storage, also high level abstractions like active objects are
available. Simply speaking, an active object is an object that has methods executing in
their own thread. This makes asynchronous member function calls possible
-- call a member function, while the function executes, do a bunch of
other things, and, eventually, obtain the function's return value.
The following example shows how this is done in POCO. The <[ActiveAdder]> class in
defines an active method <[add()]>, implemented by the <[addImpl()]>
member function. Invoking the active method in <[main()]> yields an
Poco::ActiveResult (also known as a future), that eventually receives the
function's return value.
#include "Poco/ActiveMethod.h"
#include "Poco/ActiveResult.h"
#include <utility>
#include <iostream>
using Poco::ActiveMethod;
using Poco::ActiveResult;
class ActiveAdder
{
public:
ActiveAdder(): add(this, &ActiveAdder::addImpl)
{
}
ActiveMethod<int, std::pair<int, int>, ActiveAdder> add;
private:
int addImpl(const std::pair<int, int>& args)
{
return args.first + args.second;
}
};
int main(int argc, char** argv)
{
ActiveAdder adder;
ActiveResult<int> sum = adder.add(std::make_pair(1, 2));
// do other things
sum.wait();
std::cout << sum.data() << std::endl;
return 0;
}
----
!!! The XML Library
The POCO XML library provides support for reading, processing and
writing XML. Following one's of POCO's guiding principles -- don't try to
reinvent things that already work -- POCO's XML library supports the
industry-standard SAX (version 2) and DOM interfaces, familiar
to many developers with XML experience. SAX, the Simple API for XML
(http://www.saxproject.org),
defines an event-based interface for reading XML. A SAX-based XML parser
reads through the XML document and notifies the application whenever it
encounters an element, character data, or other XML artifact. A SAX
parser does not need to load the complete XML document into memory, so
it can be used to parse huge XML files efficiently. In contrast, DOM
(Document Object Model, http://www.w3.org/DOM/) gives the application
complete access to an XML
document, using a tree-style object hierarchy. For this to work, the DOM
parser provided by POCO has to load the entire document into memory. To
reduce the memory footprint of the DOM document, the POCO DOM
implementation uses string pooling, storing frequently occuring strings
such as element and attribute names only once. The XML library is based
on the Expat open source XML parser library (http://www.libexpat.org).
Built on top of Expat
are the SAX interfaces, and built on top of the SAX interfaces is the
DOM implementation. For strings, the XML library uses <[std::string]>, with
characters encoded in UTF-8. This makes interfacing the XML library to
other parts of the application easy. Support for XPath and XSLT will be
available in a future release.
!!! The Util Library
The Util library has a somewhat misleading name, as it basically
contains a framework for creating command-line and server applications.
Included is support for handling command line arguments (validation,
binding to configuration properties, etc.) and managing configuration
information. Different configuration file formats are supported --
Windows-style INI files, Java-style property files, XML files and the
Windows registry.
For server applications, the framework provides
transparent support for Windows services and Unix daemons. Every server
application can be registered and run as a Windows service, with no
extra code required. Of course, all server applications can still be
executed from the command line, which makes testing and debugging easier.
!!! The Net Library
POCO's Net library makes it easy to write network-based applications. No
matter whether your application simply needs to send data over a plain
TCP socket, or whether your application needs a full-fledged built-in
HTTP server, you will find something useful in the Net library.
At the lowest level, the Net library contains socket classes, supporting TCP
stream and server sockets, UDP sockets, multicast sockets, ICMP and raw
sockets. If your application needs secure sockets, these are available
in the NetSSL library, implemented using OpenSSL (http://www.openssl.org).
Based on the socket classes are two frameworks for building TCP servers -- one for
multithreaded servers (one thread per connection, taken from a thread
pool), one for servers based on the Acceptor-Reactor pattern. The
multithreaded Poco::Net::TCPServer class and its supporting framework are also the
foundation for POCO's HTTP server implementation (Poco::Net::HTTPServer).
On the client side, the Net library provides classes for talking to HTTP servers,
for sending and receiving files using the FTP protocol, for sending mail
messages (including attachments) using SMTP and for receiving mail from
a POP3 server.
!!! Putting It All Together
The following example shows the implementation of a simple HTTP server using the
POCO libraries. The server returns a HTML document showing the current
date and time. The application framework is used to build a server
application that can run as a Windows service, or Unix daemon process.
Of course, the same executable can also directly be started from the
shell. For use with the HTTP server framework, a <[TimeRequestHandler]>
class is defined that servers incoming requests by returning a HTML
document containing the current date and time. Also, for each incoming
request, a message is logged using the logging framework. Together with
the <[TimeRequestHandler]> class, a corresponding factory class,
<[TimeRequestHandlerFactory]> is needed; an instance of the factory is
passed to the HTTP server object. The <[HTTPTimeServer]> application class
defines a command line argument help by overriding the <[defineOptions()]>
member function of Poco::Util::ServerApplication. It also reads in the default
application configuration file (in <[initialize()]>) and obtains the value
of some configuration properties in <[main()]>, before starting the HTTP
server.
#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/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 <iostream>
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::OptionCallback;
using Poco::Util::HelpFormatter;
class TimeRequestHandler: public HTTPRequestHandler
{
public:
TimeRequestHandler(const std::string& format): _format(format)
{
}
void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response)
{
Application& app = Application::instance();
app.logger().information("Request from %s",
request.clientAddress().toString());
Timestamp now;
std::string dt(DateTimeFormatter::format(now, _format));
response.setChunkedTransferEncoding(true);
response.setContentType("text/html");
std::ostream& ostr = response.send();
ostr << "<html><head><title>HTTPTimeServer powered by "
"POCO C++ Libraries</title>";
ostr << "<meta http-equiv=\"refresh\" content=\"1\"></head>";
ostr << "<body><p style=\"text-align: center; "
"font-size: 48px;\">";
ostr << dt;
ostr << "</p></body></html>";
}
private:
std::string _format;
};
class TimeRequestHandlerFactory: public HTTPRequestHandlerFactory
{
public:
TimeRequestHandlerFactory(const std::string& format):
_format(format)
{
}
HTTPRequestHandler* createRequestHandler(const HTTPServerRequest& request)
{
if (request.getURI() == "/")
return new TimeRequestHandler(_format);
else
return 0;
}
private:
std::string _format;
};
class HTTPTimeServer: public Poco::Util::ServerApplication
{
protected:
void initialize(Application& self)
{
loadConfiguration();
ServerApplication::initialize(self);
}
void defineOptions(OptionSet& options)
{
ServerApplication::defineOptions(options);
options.addOption(
Option("help", "h", "display argument help information")
.required(false)
.repeatable(false)
.callback(OptionCallback<HTTPTimeServer>(
this, &HTTPTimeServer::handleHelp)));
}
void handleHelp(const std::string& name, const std::string& value)
{
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);
stopOptionsProcessing();
_helpRequested = true;
}
int main(const std::vector<std::string>& args)
{
if (!_helpRequested)
{
unsigned short port = static_cast<unsigned short>(
config().getInt("HTTPTimeServer.port", 9980));
std::string format(config().getString(
"HTTPTimeServer.format",
DateTimeFormat::SORTABLE_FORMAT));
ServerSocket svs(port);
HTTPServer srv(
new TimeRequestHandlerFactory(format),
svs, new HTTPServerParams);
srv.start();
waitForTerminationRequest();
srv.stop();
}
return Application::EXIT_OK;
}
private:
bool _helpRequested = false;
};
int main(int argc, char** argv)
{
HTTPTimeServer app;
return app.run(argc, argv);
}
----