diff options
Diffstat (limited to 'web/apache/service.txx')
-rw-r--r-- | web/apache/service.txx | 213 |
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; - } - } -} |