diff options
Diffstat (limited to 'web/apache/service')
-rw-r--r-- | web/apache/service | 192 |
1 files changed, 18 insertions, 174 deletions
diff --git a/web/apache/service b/web/apache/service index cd405ee..8456f12 100644 --- a/web/apache/service +++ b/web/apache/service @@ -5,18 +5,11 @@ #ifndef WEB_APACHE_SERVICE #define WEB_APACHE_SERVICE -#include <string.h> // memset() -#include <unistd.h> // getppid() -#include <signal.h> // kill() - #include <httpd/httpd.h> -#include <httpd/http_config.h> #include <string> #include <vector> -#include <memory> // unique_ptr #include <cassert> -#include <exception> #include <algorithm> // move() #include <web/module> @@ -30,7 +23,6 @@ namespace web class service: ::module { public: - using option_names = std::vector<std::string>; // Note that the module exemplar is stored by-reference. @@ -52,48 +44,17 @@ namespace web name_ (name), exemplar_ (exemplar), option_names_ (std::move (opts)) -// Doesn't look like handle_ member is required at all. -// handle_ (&handle_impl<M>) { - // Fill apache module directive definitions. Directives share - // common name space in apache configuration file, so to prevent name - // clash have to form directive name as a combination of module and - // option names: <module name>-<option name>. This why for option - // bar of module foo the corresponding directive will appear in apache - // configuration file as foo-bar. - // - std::unique_ptr<command_rec[]> directives ( - new command_rec[option_names_.size () + 1]); - - command_rec* d = directives.get (); - - for (auto& o: option_names_) - { - o = name_ + "-" + o; - - *d++ = - { - o.c_str (), - reinterpret_cast<cmd_func> (add_option), - this, - RSRC_CONF, - TAKE1, - nullptr - }; - } - - *d = {}; + init_directives(); // instance<M> () 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<M> (); + service*& srv (instance<M> ()); assert (srv == nullptr); srv = this; - - cmds = directives.release (); } ~service () @@ -101,23 +62,6 @@ namespace web delete [] cmds; } - static const char* - add_option (cmd_parms *parms, void *mconfig, const char *value) - { - service& srv = *reinterpret_cast<service*> (parms->cmd->cmd_data); - std::string name (parms->cmd->name + srv.name_.length () + 1); - - for (auto& v: srv.options_) - if (v.name == name) - { - v.value = value; - return 0; - } - - srv.options_.emplace_back (name, value); - return 0; - } - template <typename M> static service*& instance () noexcept @@ -144,144 +88,44 @@ namespace web static void worker_initializer (apr_pool_t*, server_rec* server) noexcept { - auto srv = instance<M> (); log l (server); - - static const std::string func_name ( - "web::apache::service<" + srv->name_ + ">::worker_initializer"); - - try - { - srv->exemplar_.init (srv->options_, l); - } - catch (const std::exception& e) - { - l.write (nullptr, 0, func_name.c_str (), APLOG_EMERG, e.what ()); - - // Terminate the root apache process. - // - ::kill (::getppid (), SIGTERM); - } - catch (...) - { - l.write (nullptr, - 0, - func_name.c_str (), - APLOG_EMERG, - "unknown error"); - - // Terminate the root apache process. - // - ::kill (::getppid (), SIGTERM); - } + instance<M> ()->init_worker(l); } template <typename M> static int request_handler (request_rec* r) noexcept { - auto srv = instance<M> (); - - if (!r->handler || srv->name_ != r->handler) - return DECLINED; - - static const std::string func_name ( - "web::apache::service<" + srv->name_ + ">::request_handler"); + auto srv (instance<M> ()); + if (!r->handler || srv->name_ != r->handler) return DECLINED; request req (r); log l (r->server); + return srv->handle<M>(req, l); + } - try - { - M m (static_cast<const M&> (srv->exemplar_)); - static_cast<module&> (m).handle (req, req, l); - return req.flush (); - } - catch (const invalid_request& e) - { - if (!e.content.empty () && !req.get_write_state ()) - { - try - { - req.content (e.status, e.type) << e.content; - return req.flush (); - } - catch (const std::exception& e) - { - l.write (nullptr, 0, func_name.c_str (), APLOG_ERR, e.what ()); - } - } - - return e.status; - } - catch (const std::exception& e) - { - l.write (nullptr, 0, func_name.c_str (), APLOG_ERR, e.what ()); - - if (*e.what () && !req.get_write_state ()) - { - try - { - req.content (HTTP_INTERNAL_SERVER_ERROR, - "text/plain;charset=utf-8") - << e.what (); - - return req.flush (); - } - catch (const std::exception& e) - { - l.write (nullptr, 0, func_name.c_str (), APLOG_ERR, e.what ()); - } - } - } - catch (...) - { - l.write (nullptr, 0, func_name.c_str (), APLOG_ERR, "unknown error"); - - if (!req.get_write_state ()) - { - try - { - req.content (HTTP_INTERNAL_SERVER_ERROR, - "text/plain;charset=utf-8") - << "unknown error"; - - return req.flush (); - } - catch (const std::exception& e) - { - l.write (nullptr, 0, func_name.c_str (), APLOG_ERR, e.what ()); - } - } + private: + void + init_directives(); - } + void + init_worker(log& l) noexcept; - return HTTP_INTERNAL_SERVER_ERROR; - } + static const char* + add_option (cmd_parms *parms, void *mconfig, const char *value) noexcept; - //@@ Implementation calls handle_ function pointer below: - // - // handle_ (rq, rs, l, exemplar_); - // + template <typename M> + int handle(request& r, log& l) noexcept; private: -/* - template <typename M> - static void - handle_impl (request& rq, response& rs, log& l, const module& exemplar) - { - M m (static_cast<const M&> (exemplar)); - static_cast<module&> (m).handle (rq, rs, l); - } -*/ std::string name_; module& exemplar_; option_names option_names_; name_values options_; - -// void (*handle_) (request&, response&, log&, const module&); }; } } +#include <web/apache/service.txx> + #endif // WEB_APACHE_SERVICE |