aboutsummaryrefslogtreecommitdiff
path: root/web/apache/service.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'web/apache/service.cxx')
-rw-r--r--web/apache/service.cxx66
1 files changed, 42 insertions, 24 deletions
diff --git a/web/apache/service.cxx b/web/apache/service.cxx
index 3bd60f6..1741af3 100644
--- a/web/apache/service.cxx
+++ b/web/apache/service.cxx
@@ -10,12 +10,15 @@
#include <httpd.h>
#include <http_config.h>
-#include <memory> // unique_ptr
+#include <memory> // unique_ptr
#include <string>
#include <cassert>
-#include <cstring> // strlen()
+#include <utility> // move()
+#include <cstring> // strlen()
#include <exception>
+#include <web/module>
+
using namespace std;
namespace web
@@ -34,19 +37,19 @@ namespace web
// bar of module foo the corresponding directive will appear in apache
// configuration file as foo-bar.
//
- unique_ptr<command_rec[]> directives (
- new command_rec[option_names_.size () + 1]);
-
+ const option_descriptions& od (exemplar_.options ());
+ unique_ptr<command_rec[]> directives (new command_rec[od.size () + 1]);
command_rec* d (directives.get ());
- for (auto& o: option_names_)
+ for (const auto& o: od)
{
- o = name_ + "-" + o;
+ auto i (option_descriptions_.emplace (name_ + "-" + o.first, o.second));
+ assert (i.second);
*d++ =
{
- o.c_str (),
- reinterpret_cast<cmd_func> (add_option),
+ i.first->first.c_str (),
+ reinterpret_cast<cmd_func> (parse_option),
this,
RSRC_CONF,
// Move away from TAKE1 to be able to handle empty string and
@@ -58,36 +61,51 @@ namespace web
}
*d = {nullptr, nullptr, nullptr, 0, RAW_ARGS, nullptr};
-
cmds = directives.release ();
}
const char* service::
- add_option (cmd_parms* parms, void*, const char* args) noexcept
+ parse_option (cmd_parms* parms, void*, const char* args) noexcept
{
+ // @@ Current implementation does not consider configuration context
+ // (server config, virtual host, directory) for directive parsing, nor
+ // for request handling.
+ //
service& srv (*reinterpret_cast<service*> (parms->cmd->cmd_data));
- string name (parms->cmd->name + srv.name_.length () + 1);
- optional<string> value;
- // 'args' is an optionally double-quoted string. Use double quotes to
- // distinguish empty string from no-value case.
+ if (srv.options_parsed_)
+ // Apache is inside the second pass of its messy initialization cycle
+ // (more details at http://wiki.apache.org/httpd/ModuleLife). Just
+ // ignore it.
+ //
+ return 0;
+
+ // 'args' is an optionally double-quoted string. It uses double quotes
+ // to distinguish empty string from no-value case.
//
assert (args != nullptr);
+
+ optional<string> value;
if (auto l = strlen (args))
value = l >= 2 && args[0] == '"' && args[l - 1] == '"'
? string (args + 1, l - 2)
: args;
- for (auto& v: srv.options_)
- {
- if (v.name == name)
- {
- v.value = value;
- return 0;
- }
- }
+ return srv.add_option (parms->cmd->name, move (value));
+ }
+
+ const char* service::
+ add_option (const char* name, optional<string> value)
+ {
+ auto i (option_descriptions_.find (name));
+ assert (i != option_descriptions_.end ());
+
+ // Check that option value presense is expected.
+ //
+ if (i->second != static_cast<bool> (value))
+ return value ? "unexpected value" : "value expected";
- srv.options_.emplace_back (name, value);
+ options_.emplace_back (name + name_.length () + 1, move (value));
return 0;
}