]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_process.cc
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / rgw / rgw_process.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #include "common/errno.h"
5 #include "common/Throttle.h"
6 #include "common/WorkQueue.h"
7
8 #include "rgw_rados.h"
9 #include "rgw_rest.h"
10 #include "rgw_frontend.h"
11 #include "rgw_request.h"
12 #include "rgw_process.h"
13 #include "rgw_loadgen.h"
14 #include "rgw_client_io.h"
15
16 #define dout_subsys ceph_subsys_rgw
17
18 void RGWProcess::RGWWQ::_dump_queue()
19 {
20 if (!g_conf->subsys.should_gather(ceph_subsys_rgw, 20)) {
21 return;
22 }
23 deque<RGWRequest *>::iterator iter;
24 if (process->m_req_queue.empty()) {
25 dout(20) << "RGWWQ: empty" << dendl;
26 return;
27 }
28 dout(20) << "RGWWQ:" << dendl;
29 for (iter = process->m_req_queue.begin();
30 iter != process->m_req_queue.end(); ++iter) {
31 dout(20) << "req: " << hex << *iter << dec << dendl;
32 }
33 } /* RGWProcess::RGWWQ::_dump_queue */
34
35
36 int rgw_process_authenticated(RGWHandler_REST * const handler,
37 RGWOp *& op,
38 RGWRequest * const req,
39 req_state * const s,
40 const bool skip_retarget)
41 {
42 req->log(s, "init permissions");
43 int ret = handler->init_permissions(op);
44 if (ret < 0) {
45 return ret;
46 }
47
48 /**
49 * Only some accesses support website mode, and website mode does NOT apply
50 * if you are using the REST endpoint either (ergo, no authenticated access)
51 */
52 if (! skip_retarget) {
53 req->log(s, "recalculating target");
54 ret = handler->retarget(op, &op);
55 if (ret < 0) {
56 return ret;
57 }
58 req->op = op;
59 } else {
60 req->log(s, "retargeting skipped because of SubOp mode");
61 }
62
63 /* If necessary extract object ACL and put them into req_state. */
64 req->log(s, "reading permissions");
65 ret = handler->read_permissions(op);
66 if (ret < 0) {
67 return ret;
68 }
69
70 req->log(s, "init op");
71 ret = op->init_processing();
72 if (ret < 0) {
73 return ret;
74 }
75
76 req->log(s, "verifying op mask");
77 ret = op->verify_op_mask();
78 if (ret < 0) {
79 return ret;
80 }
81
82 req->log(s, "verifying op permissions");
83 ret = op->verify_permission();
84 if (ret < 0) {
85 if (s->system_request) {
86 dout(2) << "overriding permissions due to system operation" << dendl;
87 } else if (s->auth.identity->is_admin_of(s->user->user_id)) {
88 dout(2) << "overriding permissions due to admin operation" << dendl;
89 } else {
90 return ret;
91 }
92 }
93
94 req->log(s, "verifying op params");
95 ret = op->verify_params();
96 if (ret < 0) {
97 return ret;
98 }
99
100 req->log(s, "pre-executing");
101 op->pre_exec();
102
103 req->log(s, "executing");
104 op->execute();
105
106 req->log(s, "completing");
107 op->complete();
108
109 return 0;
110 }
111
112 int process_request(RGWRados* const store,
113 RGWREST* const rest,
114 RGWRequest* const req,
115 const std::string& frontend_prefix,
116 const rgw_auth_registry_t& auth_registry,
117 RGWRestfulIO* const client_io,
118 OpsLogSocket* const olog)
119 {
120 int ret = 0;
121
122 client_io->init(g_ceph_context);
123
124 req->log_init();
125
126 dout(1) << "====== starting new request req=" << hex << req << dec
127 << " =====" << dendl;
128 perfcounter->inc(l_rgw_req);
129
130 RGWEnv& rgw_env = client_io->get_env();
131
132 RGWUserInfo userinfo;
133
134 struct req_state rstate(g_ceph_context, &rgw_env, &userinfo);
135 struct req_state *s = &rstate;
136
137 RGWObjectCtx rados_ctx(store, s);
138 s->obj_ctx = &rados_ctx;
139
140 s->req_id = store->unique_id(req->id);
141 s->trans_id = store->unique_trans_id(req->id);
142 s->host_id = store->host_id;
143
144 req->log_format(s, "initializing for trans_id = %s", s->trans_id.c_str());
145
146 RGWOp* op = NULL;
147 int init_error = 0;
148 bool should_log = false;
149 RGWRESTMgr *mgr;
150 RGWHandler_REST *handler = rest->get_handler(store, s,
151 auth_registry,
152 frontend_prefix,
153 client_io, &mgr, &init_error);
154 if (init_error != 0) {
155 abort_early(s, NULL, init_error, NULL);
156 goto done;
157 }
158 dout(10) << "handler=" << typeid(*handler).name() << dendl;
159
160 should_log = mgr->get_logging();
161
162 req->log_format(s, "getting op %d", s->op);
163 op = handler->get_op(store);
164 if (!op) {
165 abort_early(s, NULL, -ERR_METHOD_NOT_ALLOWED, handler);
166 goto done;
167 }
168
169 req->op = op;
170 dout(10) << "op=" << typeid(*op).name() << dendl;
171
172 s->op_type = op->get_type();
173
174 req->log(s, "verifying requester");
175 ret = op->verify_requester(auth_registry);
176 if (ret < 0) {
177 dout(10) << "failed to authorize request" << dendl;
178 abort_early(s, NULL, ret, handler);
179 goto done;
180 }
181
182 /* FIXME: remove this after switching all handlers to the new authentication
183 * infrastructure. */
184 if (nullptr == s->auth.identity) {
185 s->auth.identity = rgw::auth::transform_old_authinfo(s);
186 }
187
188 req->log(s, "normalizing buckets and tenants");
189 ret = handler->postauth_init();
190 if (ret < 0) {
191 dout(10) << "failed to run post-auth init" << dendl;
192 abort_early(s, op, ret, handler);
193 goto done;
194 }
195
196 if (s->user->suspended) {
197 dout(10) << "user is suspended, uid=" << s->user->user_id << dendl;
198 abort_early(s, op, -ERR_USER_SUSPENDED, handler);
199 goto done;
200 }
201
202 ret = rgw_process_authenticated(handler, op, req, s);
203 if (ret < 0) {
204 abort_early(s, op, ret, handler);
205 goto done;
206 }
207 done:
208 try {
209 client_io->complete_request();
210 } catch (rgw::io::Exception& e) {
211 dout(0) << "ERROR: client_io->complete_request() returned "
212 << e.what() << dendl;
213 }
214
215 if (should_log) {
216 rgw_log_op(store, rest, s, (op ? op->name() : "unknown"), olog);
217 }
218
219 int http_ret = s->err.http_ret;
220 int op_ret = 0;
221 if (op) {
222 op_ret = op->get_ret();
223 }
224
225 req->log_format(s, "op status=%d", op_ret);
226 req->log_format(s, "http status=%d", http_ret);
227
228 if (handler)
229 handler->put_op(op);
230 rest->put_handler(handler);
231
232 dout(1) << "====== req done req=" << hex << req << dec
233 << " op status=" << op_ret
234 << " http_status=" << http_ret
235 << " ======"
236 << dendl;
237
238 return (ret < 0 ? ret : s->err.ret);
239 } /* process_request */