POCO ApacheConnector

POCO ApacheConnector User Guide

Contents

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>.