]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
4 | #include <set> | |
5 | #include <string> | |
6 | ||
7 | #include <boost/utility/string_ref.hpp> | |
8 | ||
9 | #include "rgw_frontend.h" | |
10 | #include "rgw_client_io_filters.h" | |
11 | ||
12 | #define dout_subsys ceph_subsys_rgw | |
13 | ||
14 | static int civetweb_callback(struct mg_connection* conn) | |
15 | { | |
16 | const struct mg_request_info* const req_info = mg_get_request_info(conn); | |
17 | return static_cast<RGWCivetWebFrontend *>(req_info->user_data)->process(conn); | |
18 | } | |
19 | ||
20 | int RGWCivetWebFrontend::process(struct mg_connection* const conn) | |
21 | { | |
22 | /* Hold a read lock over access to env.store for reconfiguration. */ | |
23 | RWLock::RLocker lock(env.mutex); | |
24 | ||
25 | RGWCivetWeb cw_client(conn); | |
26 | auto real_client_io = rgw::io::add_reordering( | |
181888fb | 27 | rgw::io::add_buffering(dout_context, |
7c673cae FG |
28 | rgw::io::add_chunking( |
29 | rgw::io::add_conlen_controlling( | |
30 | &cw_client)))); | |
181888fb | 31 | RGWRestfulIO client_io(dout_context, &real_client_io); |
7c673cae FG |
32 | |
33 | RGWRequest req(env.store->get_new_req_id()); | |
94b18763 | 34 | int http_ret = 0; |
7c673cae | 35 | int ret = process_request(env.store, env.rest, &req, env.uri_prefix, |
94b18763 | 36 | *env.auth_registry, &client_io, env.olog, &http_ret); |
7c673cae FG |
37 | if (ret < 0) { |
38 | /* We don't really care about return code. */ | |
39 | dout(20) << "process_request() returned " << ret << dendl; | |
40 | } | |
41 | ||
94b18763 FG |
42 | if (http_ret <= 0) { |
43 | /* Mark as processed. */ | |
44 | return 1; | |
45 | } | |
46 | ||
47 | return http_ret; | |
7c673cae FG |
48 | } |
49 | ||
50 | int RGWCivetWebFrontend::run() | |
51 | { | |
52 | auto& conf_map = conf->get_config_map(); | |
7c673cae FG |
53 | |
54 | set_conf_default(conf_map, "num_threads", | |
55 | std::to_string(g_conf->rgw_thread_pool_size)); | |
56 | set_conf_default(conf_map, "decode_url", "no"); | |
57 | set_conf_default(conf_map, "enable_keep_alive", "yes"); | |
58 | set_conf_default(conf_map, "validate_http_method", "no"); | |
59 | set_conf_default(conf_map, "canonicalize_url_path", "no"); | |
31f18b77 | 60 | set_conf_default(conf_map, "enable_auth_domain_check", "no"); |
28e407b8 AA |
61 | |
62 | std::string listening_ports; | |
63 | // support multiple port= entries | |
64 | auto range = conf_map.equal_range("port"); | |
65 | for (auto p = range.first; p != range.second; ++p) { | |
66 | std::string port_str = p->second; | |
67 | // support port= entries with multiple values | |
68 | std::replace(port_str.begin(), port_str.end(), '+', ','); | |
69 | if (!listening_ports.empty()) { | |
70 | listening_ports.append(1, ','); | |
71 | } | |
72 | listening_ports.append(port_str); | |
73 | } | |
74 | if (listening_ports.empty()) { | |
75 | listening_ports = "80"; | |
76 | } | |
77 | conf_map.emplace("listening_ports", std::move(listening_ports)); | |
7c673cae FG |
78 | |
79 | /* Set run_as_user. This will cause civetweb to invoke setuid() and setgid() | |
80 | * based on pw_uid and pw_gid obtained from pw_name. */ | |
81 | std::string uid_string = g_ceph_context->get_set_uid_string(); | |
82 | if (! uid_string.empty()) { | |
28e407b8 | 83 | conf_map.emplace("run_as_user", std::move(uid_string)); |
7c673cae FG |
84 | } |
85 | ||
86 | /* Prepare options for CivetWeb. */ | |
87 | const std::set<boost::string_ref> rgw_opts = { "port", "prefix" }; | |
88 | ||
89 | std::vector<const char*> options; | |
90 | ||
91 | for (const auto& pair : conf_map) { | |
92 | if (! rgw_opts.count(pair.first)) { | |
93 | /* CivetWeb doesn't understand configurables of the glue layer between | |
94 | * it and RadosGW. We need to strip them out. Otherwise CivetWeb would | |
95 | * signalise an error. */ | |
96 | options.push_back(pair.first.c_str()); | |
97 | options.push_back(pair.second.c_str()); | |
98 | ||
99 | dout(20) << "civetweb config: " << pair.first | |
100 | << ": " << pair.second << dendl; | |
101 | } | |
102 | } | |
103 | ||
104 | options.push_back(nullptr); | |
105 | /* Initialize the CivetWeb right now. */ | |
106 | struct mg_callbacks cb; | |
107 | memset((void *)&cb, 0, sizeof(cb)); | |
108 | cb.begin_request = civetweb_callback; | |
109 | cb.log_message = rgw_civetweb_log_callback; | |
110 | cb.log_access = rgw_civetweb_log_access_callback; | |
111 | ctx = mg_start(&cb, this, options.data()); | |
112 | ||
113 | return ! ctx ? -EIO : 0; | |
114 | } /* RGWCivetWebFrontend::run */ |