]>
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()); | |
34 | int ret = process_request(env.store, env.rest, &req, env.uri_prefix, | |
35 | *env.auth_registry, &client_io, env.olog); | |
36 | if (ret < 0) { | |
37 | /* We don't really care about return code. */ | |
38 | dout(20) << "process_request() returned " << ret << dendl; | |
39 | } | |
40 | ||
41 | /* Mark as processed. */ | |
42 | return 1; | |
43 | } | |
44 | ||
45 | int RGWCivetWebFrontend::run() | |
46 | { | |
47 | auto& conf_map = conf->get_config_map(); | |
48 | string port_str; | |
49 | ||
50 | set_conf_default(conf_map, "num_threads", | |
51 | std::to_string(g_conf->rgw_thread_pool_size)); | |
52 | set_conf_default(conf_map, "decode_url", "no"); | |
53 | set_conf_default(conf_map, "enable_keep_alive", "yes"); | |
54 | set_conf_default(conf_map, "validate_http_method", "no"); | |
55 | set_conf_default(conf_map, "canonicalize_url_path", "no"); | |
31f18b77 | 56 | set_conf_default(conf_map, "enable_auth_domain_check", "no"); |
7c673cae FG |
57 | conf->get_val("port", "80", &port_str); |
58 | std::replace(port_str.begin(), port_str.end(), '+', ','); | |
59 | conf_map["listening_ports"] = port_str; | |
60 | ||
61 | /* Set run_as_user. This will cause civetweb to invoke setuid() and setgid() | |
62 | * based on pw_uid and pw_gid obtained from pw_name. */ | |
63 | std::string uid_string = g_ceph_context->get_set_uid_string(); | |
64 | if (! uid_string.empty()) { | |
65 | conf_map["run_as_user"] = std::move(uid_string); | |
66 | } | |
67 | ||
68 | /* Prepare options for CivetWeb. */ | |
69 | const std::set<boost::string_ref> rgw_opts = { "port", "prefix" }; | |
70 | ||
71 | std::vector<const char*> options; | |
72 | ||
73 | for (const auto& pair : conf_map) { | |
74 | if (! rgw_opts.count(pair.first)) { | |
75 | /* CivetWeb doesn't understand configurables of the glue layer between | |
76 | * it and RadosGW. We need to strip them out. Otherwise CivetWeb would | |
77 | * signalise an error. */ | |
78 | options.push_back(pair.first.c_str()); | |
79 | options.push_back(pair.second.c_str()); | |
80 | ||
81 | dout(20) << "civetweb config: " << pair.first | |
82 | << ": " << pair.second << dendl; | |
83 | } | |
84 | } | |
85 | ||
86 | options.push_back(nullptr); | |
87 | /* Initialize the CivetWeb right now. */ | |
88 | struct mg_callbacks cb; | |
89 | memset((void *)&cb, 0, sizeof(cb)); | |
90 | cb.begin_request = civetweb_callback; | |
91 | cb.log_message = rgw_civetweb_log_callback; | |
92 | cb.log_access = rgw_civetweb_log_access_callback; | |
93 | ctx = mg_start(&cb, this, options.data()); | |
94 | ||
95 | return ! ctx ? -EIO : 0; | |
96 | } /* RGWCivetWebFrontend::run */ |