// file : web/apache/service -*- C++ -*- // copyright : Copyright (c) 2014-2015 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file #ifndef WEB_APACHE_SERVICE #define WEB_APACHE_SERVICE #include #include #include #include #include // move() #include #include #include namespace web { namespace apache { class service: ::module { public: using option_names = std::vector; // Note that the module exemplar is stored by-reference. // template service (const std::string& name, M& exemplar, option_names opts = option_names ()) : ::module { STANDARD20_MODULE_STUFF, nullptr, nullptr, nullptr, nullptr, nullptr, ®ister_hooks }, name_ (name), exemplar_ (exemplar), option_names_ (std::move (opts)) { init_directives (); // instance () is invented to delegate processing from apache // request handler C function to the service non static member // function. This appoach resticts number of service objects per // specific module implementation class with just one instance. // service*& srv (instance ()); assert (srv == nullptr); srv = this; } ~service () { delete [] cmds; } template static service*& instance () noexcept { static service* instance; return instance; } template static void register_hooks (apr_pool_t*) noexcept { // The registered function is called right after apache worker // process is started. Called for every new process spawned. // ap_hook_child_init (&worker_initializer, NULL, NULL, APR_HOOK_LAST); // The registered function is called for each client request. // ap_hook_handler (&request_handler, NULL, NULL, APR_HOOK_LAST); } template static void worker_initializer (apr_pool_t*, server_rec* server) noexcept { log l (server); instance ()->init_worker (l); } 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->server); return srv->handle (req, l); } private: void init_directives (); void init_worker (log& l) noexcept; static const char* add_option (cmd_parms* parms, void* mconfig, const char* args) noexcept; template int handle (request& r, log& l) noexcept; private: std::string name_; module& exemplar_; option_names option_names_; name_values options_; }; } } #include #endif // WEB_APACHE_SERVICE