From a20443c285dabdec8d2ee740500c62e31ad90c7b Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 23 Apr 2015 12:43:52 +0200 Subject: Implement apache service --- web/apache/service | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 90 insertions(+), 4 deletions(-) (limited to 'web/apache/service') diff --git a/web/apache/service b/web/apache/service index 8dd21d8..688f8f1 100644 --- a/web/apache/service +++ b/web/apache/service @@ -5,22 +5,106 @@ #ifndef WEB_APACHE_SERVICE #define WEB_APACHE_SERVICE +#include #include +#include + +#include +#include #include +#include +#include + namespace web { namespace apache { - class service + class service : ::module { public: // Note that the module exemplar is stored by-reference. // template service (const std::string& name, const M& exemplar) - : exemplar_ (exemplar), handle_ (&handle_impl) {} + : ::module + { + STANDARD20_MODULE_STUFF, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + ®ister_hooks + }, + name_ (name), + exemplar_ (exemplar) + +// Doesn't look like handle_ member is required at all. +// handle_ (&handle_impl) + { + // instance () invented to delegate processing from apache request + // handler C function to service non static member function. + // This appoach resticts number of service objects per module + // implementation class with just one instance. + // + service*& srv = instance (); + assert (srv == nullptr); + srv = this; + } + + template + static service*& + instance () noexcept + { + static service* instance; + return instance; + } + + template + static void + register_hooks (apr_pool_t *pool) noexcept + { + ap_hook_handler (&request_handler, NULL, NULL, APR_HOOK_LAST); + } + + template + static int + request_handler (request_rec* r) noexcept + { + auto srv = instance (); + + if (!r->handler || srv->name_ != r->handler) + return DECLINED; + + request req (r); + log l(r); + + // As soons as M (), handle () and flush () can throw need to handle + // exceptions here. + // + try + { + M m (static_cast (srv->exemplar_)); + static_cast (m).handle (req, req, l); + return req.flush(); + } + catch (const std::exception& e) + { + l.write (nullptr, 0, __PRETTY_FUNCTION__, APLOG_ERR, e.what ()); + } + catch (...) + { + l.write (nullptr, + 0, + __PRETTY_FUNCTION__, + APLOG_ERR, + "unknown error"); + } + + return HTTP_INTERNAL_SERVER_ERROR; + } //@@ Implementation calls handle_ function pointer below: // @@ -28,6 +112,7 @@ namespace web // private: +/* template static void handle_impl (request& rq, response& rs, log& l, const module& exemplar) @@ -35,9 +120,10 @@ namespace web M m (static_cast (exemplar)); static_cast (m).handle (rq, rs, l); } - +*/ + std::string name_; const module& exemplar_; - void (*handle_) (request&, response&, log&, const module&); +// void (*handle_) (request&, response&, log&, const module&); }; } } -- cgit v1.1