aboutsummaryrefslogtreecommitdiff
path: root/web/apache/service
diff options
context:
space:
mode:
Diffstat (limited to 'web/apache/service')
-rw-r--r--web/apache/service192
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