diff options
Diffstat (limited to 'web/apache/service.txx')
-rw-r--r-- | web/apache/service.txx | 44 |
1 files changed, 28 insertions, 16 deletions
diff --git a/web/apache/service.txx b/web/apache/service.txx index b57befc..961c19b 100644 --- a/web/apache/service.txx +++ b/web/apache/service.txx @@ -3,9 +3,9 @@ // license : MIT; see accompanying LICENSE file #include <unistd.h> // getppid() -#include <signal.h> // kill() +#include <signal.h> // kill(), SIGTERM -#include <http_log.h> +#include <http_log.h> // APLOG_* #include <utility> // move() #include <exception> @@ -132,21 +132,31 @@ namespace web const M* e (dynamic_cast<const M*> (exemplar)); assert (e != nullptr); - M m (*e); - - if (static_cast<module&> (m).handle (rq, rq, lg)) - return rq.flush (); + for (M m (*e);;) + { + try + { + if (static_cast<module&> (m).handle (rq, rq, lg)) + return rq.flush (); - if (!rq.get_write_state ()) - return DECLINED; + if (rq.state () == request_state::initial) + return DECLINED; - lg.write (nullptr, 0, func_name.c_str (), APLOG_ERR, - "handling declined while unbuffered content " - "has been written"); + lg.write (nullptr, 0, func_name.c_str (), APLOG_ERR, + "handling declined being partially executed"); + break; + } + catch (const module::retry&) + { + // Retry to handle the request. + // + rq.rewind (); + } + } } catch (const invalid_request& e) { - if (!e.content.empty () && !rq.get_write_state ()) + if (!e.content.empty () && rq.state () < request_state::writing) { try { @@ -165,11 +175,12 @@ namespace web { lg.write (nullptr, 0, func_name.c_str (), APLOG_ERR, e.what ()); - if (*e.what () && !rq.get_write_state ()) + if (*e.what () && rq.state () < request_state::writing) { try { - rq.content (HTTP_INTERNAL_SERVER_ERROR, "text/plain;charset=utf-8") + rq.content ( + HTTP_INTERNAL_SERVER_ERROR, "text/plain;charset=utf-8") << e.what (); return rq.flush (); @@ -184,11 +195,12 @@ namespace web { lg.write (nullptr, 0, func_name.c_str (), APLOG_ERR, "unknown error"); - if (!rq.get_write_state ()) + if (rq.state () < request_state::writing) { try { - rq.content (HTTP_INTERNAL_SERVER_ERROR, "text/plain;charset=utf-8") + rq.content ( + HTTP_INTERNAL_SERVER_ERROR, "text/plain;charset=utf-8") << "unknown error"; return rq.flush (); |