POCO ApacheConnector User Guide
POCO ApacheConnector

!!!Introduction
ApacheConnector (<[mod_poco]>) is an Apache module that allows one to write Apache server extensions using
the POCO Net HTTPServer framework. Almost any subclass of Poco::Net::HTTPRequestHandler written
for Poco::Net::HTTPServer can be used with ApacheConnector. For this to work, the request handler
subclass, together with its factory (Poco::Net::HTTPRequestHandlerFactory) must be contained
in a shared library. The ApacheConnector uses the Poco::ClassLoader to load request handler
factories from shared libraries.

!!!Adding ApacheConnector to Apache
ApacheConnector is implemented as an ordinary Apache 2 module, named <[mod_poco]>.
To add <[mod_poco]> to Apache, add the following entry to the Apache configuration
file (usually <[httpd.conf]>):

    LoadModule poco_module modules/mod_pocod.so
----

!!!Configuring ApacheConnector
ApacheConnector must be able to find shared libraries containing request handler, as well
as optional configuration files. ApacheConnector provides an Poco::Util::Application class
to request handlers that can be used to access configuration data, loaded from configuration
files.

!!Request Handler Configuration

To have the ApacheConnector load a request handler class, the <[AddPocoRequestHandler]> directive
is used in the Apache configuration file:

    AddPocoRequestHandler <FactoryClass> <SharedLibrary> <Path>...
----

The first argument specifies the name of the request handler factory class. The second argument
contains the path of the shared library containing the request handler.
The third (and optionally following) argument(s) specify the URI paths handled by the
request handler. For example:

    AddPocoRequestHandler TimeRequestHandlerFactory p:/Poco/ApacheConnector/samples/TimeServer/bin/TimeServerd.dll /time
----

loads the TimeRequestHandlerFactory from TimeServerd.dll. Whenever a request for a URI starting with "/time"
is sent by a client, this request will be handled by the TimeRequestHandler.

!!Configuration Files
ApacheConnector can also load POCO configuration files (.ini, .properties or .xml) for later use by
request handlers. This is done using the <[AddPocoConfig]> directive:

    AddPocoConfig <Path>
----

where <Path> specifies the full path to the configuration file.

In a request handler, the configuration properties loaded this way can be accessed using:

    Poco::Util::Application& app = Poco::Util::Application::instance();
    std::string myProp = app.config().getString("MyProperty");
----

!!!Logging in Request Handlers
ApacheConnector provides a special logging channel that logs to Apache's error log file.
This channel is set as the root channel when the ApacheConnector is loaded, so every
logger will automatically inherit this channel.


!!!A Sample Request Handler
Following is a sample for a request handler implementation. The complete sample project can be found in the
<[samples]> subdirectory of the ApacheConnector directory.

    #include "Poco/Net/HTTPServer.h"
    #include "Poco/Net/HTTPRequestHandler.h"
    #include "Poco/Net/HTTPRequestHandlerFactory.h"
    #include "Poco/Net/HTTPServerRequest.h"
    #include "Poco/Net/HTTPServerResponse.h"
    #include "Poco/Timestamp.h"
    #include "Poco/DateTimeFormatter.h"
    #include "Poco/DateTimeFormat.h"
    #include "Poco/ClassLibrary.h"


    using Poco::Net::HTTPRequestHandler;
    using Poco::Net::HTTPRequestHandlerFactory;
    using Poco::Net::HTTPServerRequest;
    using Poco::Net::HTTPServerResponse;
    using Poco::Timestamp;
    using Poco::DateTimeFormatter;
    using Poco::DateTimeFormat;


    class TimeRequestHandler: public HTTPRequestHandler
        /// Return a HTML document with the current date and time.
    {
    public:
        TimeRequestHandler()
        {
        }

        void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response)
        {
            Timestamp now;
            std::string dt(DateTimeFormatter::format(now, DateTimeFormat::SORTABLE_FORMAT));

            response.setChunkedTransferEncoding(true);
            response.setContentType("text/html");

            std::ostream& ostr = response.send();
            ostr << "<html><head><title>TimeServer powered by POCO ApacheConnector</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>";
        }
    };


    class TimeRequestHandlerFactory: public HTTPRequestHandlerFactory
    {
    public:
        TimeRequestHandlerFactory()
        {
        }

        HTTPRequestHandler* createRequestHandler(const HTTPServerRequest& request)
        {
            return new TimeRequestHandler;
        }
    };


    POCO_BEGIN_MANIFEST(HTTPRequestHandlerFactory)
        POCO_EXPORT_CLASS(TimeRequestHandlerFactory)
    POCO_END_MANIFEST
----

Both the TimeRequestHandler class and the TimeRequestHandlerFactory class are the same as for
an ordinary Poco::Net::HTTPServer. The only addition in this sample is the definition
of the class loader manifest, which allows the ApacheConnector to load the TimeRequestHandlerFactory
class from the shared library.

To run this sample, the following directives must be added to the Apache configuration files:

    LoadModule poco_module p:/Poco/ApacheConnector/bin/mod_poco.so
    AddPocoRequestHandler TimeRequestHandlerFactory p:/Poco/ApacheConnector/samples/TimeServer/bin/TimeServer.dll /time
----

You'll have to change the paths to <[mod_poco.so]> and <[TimeServer.dll]> to match your
own environment.
To test the sample, simply direct your favorite web browser to <http://localhost/time>.
