aboutsummaryrefslogtreecommitdiff
path: root/web/apache/service.txx
diff options
context:
space:
mode:
Diffstat (limited to 'web/apache/service.txx')
-rw-r--r--web/apache/service.txx213
1 files changed, 0 insertions, 213 deletions
diff --git a/web/apache/service.txx b/web/apache/service.txx
deleted file mode 100644
index bda8e10..0000000
--- a/web/apache/service.txx
+++ /dev/null
@@ -1,213 +0,0 @@
-// file : web/apache/service.txx -*- C++ -*-
-// license : MIT; see accompanying LICENSE file
-
-#include <httpd.h> // APEXIT_CHILDSICK
-#include <http_log.h> // APLOG_*
-
-#include <cstdlib> // exit()
-#include <utility> // move()
-#include <exception>
-
-#include <libbutl/utility.mxx> // operator<<(ostream, exception)
-
-namespace web
-{
- namespace apache
- {
- template <typename H>
- void service::
- init_worker (log& l)
- {
- using namespace std;
-
- const string func_name (
- "web::apache::service<" + name_ + ">::init_worker");
-
- try
- {
- const H* exemplar (dynamic_cast<const H*> (&exemplar_));
- assert (exemplar != nullptr);
-
- // For each directory configuration context, for which the handler is
- // allowed to handle a request, create the handler exemplar as a deep
- // copy of the exemplar_ member, and initialize it with the
- // context-specific option list.
- //
- for (const auto& o: options_)
- {
- const context* c (o.first);
-
- if (c->server != nullptr && // Is a directory configuration context.
- c->handling == request_handling::allowed)
- {
- auto r (
- exemplars_.emplace (
- c,
- unique_ptr<handler> (new H (*exemplar))));
-
- r.first->second->init (o.second, l);
- }
- }
-
- // Options are not needed anymore. Free up the space.
- //
- options_.clear ();
- }
- catch (const exception& e)
- {
- l.write (nullptr, 0, func_name.c_str (), APLOG_EMERG, e.what ());
-
- // Terminate the worker apache process. APEXIT_CHILDSICK indicates to
- // the root process that the worker have exited due to a resource
- // shortage. In this case the root process limits the rate of forking
- // until situation is resolved.
- //
- // If the root process fails to create any worker process on startup,
- // the behaviour depends on the Multi-Processing Module enabled. For
- // mpm_worker_module and mpm_event_module the root process terminates.
- // For mpm_prefork_module it keeps trying to create the worker process
- // at one-second intervals.
- //
- // If the root process loses all it's workers while running (for
- // example due to the MaxRequestsPerChild directive), and fails to
- // create any new ones, it keeps trying to create the worker process
- // at one-second intervals.
- //
- exit (APEXIT_CHILDSICK);
- }
- catch (...)
- {
- l.write (nullptr,
- 0,
- func_name.c_str (),
- APLOG_EMERG,
- "unknown error");
-
- // Terminate the worker apache process.
- //
- exit (APEXIT_CHILDSICK);
- }
- }
-
- template <typename H>
- int service::
- request_handler (request_rec* r) noexcept
- {
- auto srv (instance<H> ());
- if (!r->handler || srv->name_ != r->handler) return DECLINED;
-
- assert (r->per_dir_config != nullptr);
-
- // Obtain the request-associated configuration context.
- //
- const context* cx (
- context_cast (ap_get_module_config (r->per_dir_config, srv)));
-
- assert (cx != nullptr);
-
- request rq (r);
- log lg (r->server, srv);
- return srv->template handle<H> (rq, cx, lg);
- }
-
- template <typename H>
- int service::
- handle (request& rq, const context* cx, log& lg) const
- {
- using namespace std;
-
- static const string func_name (
- "web::apache::service<" + name_ + ">::handle");
-
- try
- {
- auto i (exemplars_.find (cx));
- assert (i != exemplars_.end ());
-
- const H* e (dynamic_cast<const H*> (i->second.get ()));
- assert (e != nullptr);
-
- for (H h (*e);;)
- {
- try
- {
- if (static_cast<handler&> (h).handle (rq, rq, lg))
- return rq.flush ();
-
- if (rq.state () == request_state::initial)
- return DECLINED;
-
- lg.write (nullptr, 0, func_name.c_str (), APLOG_ERR,
- "handling declined being partially executed");
- break;
- }
- catch (const handler::retry&)
- {
- // Retry to handle the request.
- //
- rq.rewind ();
- }
- }
- }
- catch (const invalid_request& e)
- {
- if (!e.content.empty () && rq.state () < request_state::writing)
- {
- try
- {
- rq.content (e.status, e.type) << e.content << endl;
- return rq.flush ();
- }
- catch (const exception& e)
- {
- lg.write (nullptr, 0, func_name.c_str (), APLOG_ERR, e.what ());
- }
- }
-
- return e.status;
- }
- catch (const exception& e)
- {
- lg.write (nullptr, 0, func_name.c_str (), APLOG_ERR, e.what ());
-
- if (*e.what () && rq.state () < request_state::writing)
- {
- try
- {
- rq.content (
- HTTP_INTERNAL_SERVER_ERROR, "text/plain;charset=utf-8")
- << e << endl;
-
- return rq.flush ();
- }
- catch (const exception& e)
- {
- lg.write (nullptr, 0, func_name.c_str (), APLOG_ERR, e.what ());
- }
- }
- }
- catch (...)
- {
- lg.write (nullptr, 0, func_name.c_str (), APLOG_ERR, "unknown error");
-
- if (rq.state () < request_state::writing)
- {
- try
- {
- rq.content (
- HTTP_INTERNAL_SERVER_ERROR, "text/plain;charset=utf-8")
- << "unknown error" << endl;
-
- return rq.flush ();
- }
- catch (const exception& e)
- {
- lg.write (nullptr, 0, func_name.c_str (), APLOG_ERR, e.what ());
- }
- }
- }
-
- return HTTP_INTERNAL_SERVER_ERROR;
- }
- }
-}