From 2700ed6a3e1092a064f28b07f8e2c4e5b9b830e7 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 16 Nov 2015 20:02:06 +0200 Subject: Implement new URL path schema for the web interface --- brep/repository-root.cxx | 119 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 brep/repository-root.cxx (limited to 'brep/repository-root.cxx') 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 + +#include +#include + +#include + +#include +#include +#include +#include + +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; + + // Function name to module factory map. + // + const map> + 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"); + } +} -- cgit v1.1