diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2015-11-16 20:02:06 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2015-11-25 20:35:10 +0200 |
commit | 2700ed6a3e1092a064f28b07f8e2c4e5b9b830e7 (patch) | |
tree | a54ffc979dde42e609bc9877120fa010887c6b66 /brep/repository-root.cxx | |
parent | 48a3c47d34c2acc0a39e2db5acfd437dace499c1 (diff) |
Implement new URL path schema for the web interface
Diffstat (limited to 'brep/repository-root.cxx')
-rw-r--r-- | brep/repository-root.cxx | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/brep/repository-root.cxx b/brep/repository-root.cxx new file mode 100644 index 0000000..180d61f --- /dev/null +++ b/brep/repository-root.cxx @@ -0,0 +1,119 @@ +// file : brep/repository-root.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#include <brep/repository-root> + +#include <map> +#include <functional> + +#include <web/module> + +#include <brep/types> +#include <brep/utility> +#include <brep/package-search> +#include <brep/repository-details> + +using namespace std; + +namespace brep +{ + // request_proxy + // + class request_proxy: public request + { + public: + request_proxy (request& r, const name_values& p) + : request_ (r), parameters_ (p) {} + + virtual const path_type& + path () {return request_.path ();} + + virtual const name_values& + parameters () {return parameters_;} + + virtual const name_values& + cookies () {return request_.cookies ();} + + virtual istream& + content () {return request_.content ();} + + private: + request& request_; + const name_values& parameters_; + }; + + // repository_root + // + void repository_root:: + handle (request& rq, response& rs) + { + MODULE_DIAG; + + // Dispatch request handling to the appropriate module depending on the + // function name passed as a first HTTP request parameter. The parameter + // should have no value specified. If no function name is passed, + // the default handler is selected. Example: cppget.org/?about + // + + string func; + name_values params (rq.parameters ()); + + // Obtain the function name. + // + if (!params.empty () && !params.front ().value) + { + func = move (params.front ().name); + + // Cleanup not to confuse the selected handler with the unknown parameter. + // + params.erase (params.begin ()); + } + + // To handle the request a new module instance is created as a copy of + // the corresponsing exemplar. + // + using module_ptr = unique_ptr<module>; + + // Function name to module factory map. + // + const map<string, function<module_ptr()>> + handlers ({ + { + "about", + [this]() -> module_ptr + {return module_ptr (new repository_details (repository_details_));} + }, + { + string (), // The default handler. + [this]() -> module_ptr + {return module_ptr (new package_search (package_search_));} + }}); + + // Find proper handler. + // + auto i (handlers.find (func)); + if (i == handlers.end ()) + throw invalid_request (400, "unknown function"); + + module_ptr m (i->second ()); + if (m->loaded ()) + { + // Delegate request handling. + // + // @@ An exception thrown by the handler will be attributed to the + // repository-root service while being logged. Could intercept + // exception handling to fix that, but let's not complicate the + // code for the time being. + // + // + request_proxy rqp (rq, params); + m->handle (rqp, rs); + } + else + // The module is not loaded, presumably being disabled in the web server + // configuration file. + // + throw invalid_request (404, "handler not available"); + } +} |