1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
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");
}
}
|