]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_rest_conn.h
update sources to v12.2.1
[ceph.git] / ceph / src / rgw / rgw_rest_conn.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #ifndef CEPH_RGW_REST_CONN_H
5 #define CEPH_RGW_REST_CONN_H
6
7 #include "rgw_rados.h"
8 #include "rgw_rest_client.h"
9 #include "common/ceph_json.h"
10 #include "common/RefCountedObj.h"
11
12 #include <atomic>
13
14 class CephContext;
15 class RGWRados;
16
17 template <class T>
18 static int parse_decode_json(CephContext *cct, T& t, bufferlist& bl)
19 {
20 JSONParser p;
21 int ret = p.parse(bl.c_str(), bl.length());
22 if (ret < 0) {
23 return ret;
24 }
25
26 try {
27 decode_json_obj(t, &p);
28 } catch (JSONDecoder::err& e) {
29 return -EINVAL;
30 }
31 return 0;
32 }
33
34 struct rgw_http_param_pair {
35 const char *key;
36 const char *val;
37 };
38
39 // copy a null-terminated rgw_http_param_pair list into a list of string pairs
40 inline param_vec_t make_param_list(const rgw_http_param_pair* pp)
41 {
42 param_vec_t params;
43 while (pp && pp->key) {
44 string k = pp->key;
45 string v = (pp->val ? pp->val : "");
46 params.emplace_back(make_pair(std::move(k), std::move(v)));
47 ++pp;
48 }
49 return params;
50 }
51
52 class RGWRESTConn
53 {
54 CephContext *cct;
55 vector<string> endpoints;
56 RGWAccessKey key;
57 string self_zone_group;
58 string remote_id;
59 std::atomic<int64_t> counter = { 0 };
60
61 public:
62
63 RGWRESTConn(CephContext *_cct, RGWRados *store, const string& _remote_id, const list<string>& endpoints);
64 // custom move needed for atomic
65 RGWRESTConn(RGWRESTConn&& other);
66 RGWRESTConn& operator=(RGWRESTConn&& other);
67
68 int get_url(string& endpoint);
69 string get_url();
70 const string& get_self_zonegroup() {
71 return self_zone_group;
72 }
73 const string& get_remote_id() {
74 return remote_id;
75 }
76 RGWAccessKey& get_key() {
77 return key;
78 }
79
80 CephContext *get_ctx() {
81 return cct;
82 }
83 size_t get_endpoint_count() const { return endpoints.size(); }
84
85 /* sync request */
86 int forward(const rgw_user& uid, req_info& info, obj_version *objv, size_t max_response, bufferlist *inbl, bufferlist *outbl);
87
88 /* async request */
89 int put_obj_init(const rgw_user& uid, rgw_obj& obj, uint64_t obj_size,
90 map<string, bufferlist>& attrs, RGWRESTStreamWriteRequest **req);
91 int complete_request(RGWRESTStreamWriteRequest *req, string& etag, ceph::real_time *mtime);
92
93 int get_obj(const rgw_user& uid, req_info *info /* optional */, rgw_obj& obj,
94 const ceph::real_time *mod_ptr, const ceph::real_time *unmod_ptr,
95 uint32_t mod_zone_id, uint64_t mod_pg_ver,
96 bool prepend_metadata, bool get_op, bool rgwx_stat, bool sync_manifest,
97 bool skip_decrypt, RGWGetDataCB *cb, RGWRESTStreamRWRequest **req);
98 int complete_request(RGWRESTStreamRWRequest *req, string& etag, ceph::real_time *mtime, uint64_t *psize, map<string, string>& attrs);
99
100 int get_resource(const string& resource,
101 param_vec_t *extra_params,
102 map<string, string>* extra_headers,
103 bufferlist& bl,
104 bufferlist *send_data = nullptr,
105 RGWHTTPManager *mgr = nullptr);
106
107 template <class T>
108 int get_json_resource(const string& resource, param_vec_t *params, bufferlist *in_data, T& t);
109 template <class T>
110 int get_json_resource(const string& resource, param_vec_t *params, T& t);
111 template <class T>
112 int get_json_resource(const string& resource, const rgw_http_param_pair *pp, T& t);
113 };
114
115
116 template<class T>
117 int RGWRESTConn::get_json_resource(const string& resource, param_vec_t *params, bufferlist *in_data, T& t)
118 {
119 bufferlist bl;
120 int ret = get_resource(resource, params, nullptr, bl, in_data);
121 if (ret < 0) {
122 return ret;
123 }
124
125 ret = parse_decode_json(cct, t, bl);
126 if (ret < 0) {
127 return ret;
128 }
129
130 return 0;
131 }
132
133 template<class T>
134 int RGWRESTConn::get_json_resource(const string& resource, param_vec_t *params, T& t)
135 {
136 return get_json_resource(resource, params, nullptr, t);
137 }
138
139 template<class T>
140 int RGWRESTConn::get_json_resource(const string& resource, const rgw_http_param_pair *pp, T& t)
141 {
142 param_vec_t params = make_param_list(pp);
143 return get_json_resource(resource, &params, t);
144 }
145
146 class RGWStreamIntoBufferlist : public RGWGetDataCB {
147 bufferlist& bl;
148 public:
149 RGWStreamIntoBufferlist(bufferlist& _bl) : bl(_bl) {}
150 int handle_data(bufferlist& inbl, off_t bl_ofs, off_t bl_len) override {
151 bl.claim_append(inbl);
152 return bl_len;
153 }
154 };
155
156 class RGWRESTReadResource : public RefCountedObject {
157 CephContext *cct;
158 RGWRESTConn *conn;
159 string resource;
160 param_vec_t params;
161 map<string, string> headers;
162 bufferlist bl;
163 RGWStreamIntoBufferlist cb;
164
165 RGWHTTPManager *mgr;
166 RGWRESTStreamReadRequest req;
167
168 void init_common(param_vec_t *extra_headers);
169
170 public:
171 RGWRESTReadResource(RGWRESTConn *_conn,
172 const string& _resource,
173 const rgw_http_param_pair *pp,
174 param_vec_t *extra_headers,
175 RGWHTTPManager *_mgr);
176
177 RGWRESTReadResource(RGWRESTConn *_conn,
178 const string& _resource,
179 param_vec_t& _params,
180 param_vec_t *extra_headers,
181 RGWHTTPManager *_mgr);
182
183 void set_user_info(void *user_info) {
184 req.set_user_info(user_info);
185 }
186 void *get_user_info() {
187 return req.get_user_info();
188 }
189
190 template <class T>
191 int decode_resource(T *dest);
192
193 int read();
194
195 int aio_read();
196
197 string to_str() {
198 return req.to_str();
199 }
200
201 int get_http_status() {
202 return req.get_http_status();
203 }
204
205 int wait_bl(bufferlist *pbl) {
206 int ret = req.wait();
207 if (ret < 0) {
208 return ret;
209 }
210
211 if (req.get_status() < 0) {
212 return req.get_status();
213 }
214 *pbl = bl;
215 return 0;
216 }
217
218 template <class T>
219 int wait(T *dest);
220
221 template <class T>
222 int fetch(T *dest);
223 };
224
225
226 template <class T>
227 int RGWRESTReadResource::decode_resource(T *dest)
228 {
229 int ret = req.get_status();
230 if (ret < 0) {
231 return ret;
232 }
233 ret = parse_decode_json(cct, *dest, bl);
234 if (ret < 0) {
235 return ret;
236 }
237 return 0;
238 }
239
240 template <class T>
241 int RGWRESTReadResource::fetch(T *dest)
242 {
243 int ret = read();
244 if (ret < 0) {
245 return ret;
246 }
247
248 ret = decode_resource(dest);
249 if (ret < 0) {
250 return ret;
251 }
252 return 0;
253 }
254
255 template <class T>
256 int RGWRESTReadResource::wait(T *dest)
257 {
258 int ret = req.wait();
259 if (ret < 0) {
260 return ret;
261 }
262
263 ret = decode_resource(dest);
264 if (ret < 0) {
265 return ret;
266 }
267 return 0;
268 }
269
270 class RGWRESTSendResource : public RefCountedObject {
271 CephContext *cct;
272 RGWRESTConn *conn;
273 string method;
274 string resource;
275 param_vec_t params;
276 map<string, string> headers;
277 bufferlist bl;
278 RGWStreamIntoBufferlist cb;
279
280 RGWHTTPManager *mgr;
281 RGWRESTStreamRWRequest req;
282
283 void init_common(param_vec_t *extra_headers);
284
285 public:
286 RGWRESTSendResource(RGWRESTConn *_conn,
287 const string& _method,
288 const string& _resource,
289 const rgw_http_param_pair *pp,
290 param_vec_t *extra_headers,
291 RGWHTTPManager *_mgr);
292
293 RGWRESTSendResource(RGWRESTConn *_conn,
294 const string& _method,
295 const string& _resource,
296 param_vec_t& params,
297 param_vec_t *extra_headers,
298 RGWHTTPManager *_mgr);
299
300 void set_user_info(void *user_info) {
301 req.set_user_info(user_info);
302 }
303 void *get_user_info() {
304 return req.get_user_info();
305 }
306
307 template <class T>
308 int decode_resource(T *dest);
309
310 int send(bufferlist& bl);
311
312 int aio_send(bufferlist& bl);
313
314 string to_str() {
315 return req.to_str();
316 }
317
318 int get_http_status() {
319 return req.get_http_status();
320 }
321
322 int wait_bl(bufferlist *pbl) {
323 int ret = req.wait();
324 if (ret < 0) {
325 return ret;
326 }
327
328 if (req.get_status() < 0) {
329 return req.get_status();
330 }
331 *pbl = bl;
332 return 0;
333 }
334
335 template <class T>
336 int wait(T *dest);
337 };
338
339 template <class T>
340 int RGWRESTSendResource::decode_resource(T *dest)
341 {
342 int ret = req.get_status();
343 if (ret < 0) {
344 return ret;
345 }
346 ret = parse_decode_json(cct, *dest, bl);
347 if (ret < 0) {
348 return ret;
349 }
350 return 0;
351 }
352
353 template <class T>
354 int RGWRESTSendResource::wait(T *dest)
355 {
356 int ret = req.wait();
357 if (ret < 0) {
358 return ret;
359 }
360
361 ret = decode_resource(dest);
362 if (ret < 0) {
363 return ret;
364 }
365 return 0;
366 }
367
368 class RGWRESTPostResource : public RGWRESTSendResource {
369 public:
370 RGWRESTPostResource(RGWRESTConn *_conn,
371 const string& _resource,
372 const rgw_http_param_pair *pp,
373 param_vec_t *extra_headers,
374 RGWHTTPManager *_mgr) : RGWRESTSendResource(_conn, "POST", _resource,
375 pp, extra_headers, _mgr) {}
376
377 RGWRESTPostResource(RGWRESTConn *_conn,
378 const string& _resource,
379 param_vec_t& params,
380 param_vec_t *extra_headers,
381 RGWHTTPManager *_mgr) : RGWRESTSendResource(_conn, "POST", _resource,
382 params, extra_headers, _mgr) {}
383
384 };
385
386 class RGWRESTPutResource : public RGWRESTSendResource {
387 public:
388 RGWRESTPutResource(RGWRESTConn *_conn,
389 const string& _resource,
390 const rgw_http_param_pair *pp,
391 param_vec_t *extra_headers,
392 RGWHTTPManager *_mgr) : RGWRESTSendResource(_conn, "PUT", _resource,
393 pp, extra_headers, _mgr) {}
394
395 RGWRESTPutResource(RGWRESTConn *_conn,
396 const string& _resource,
397 param_vec_t& params,
398 param_vec_t *extra_headers,
399 RGWHTTPManager *_mgr) : RGWRESTSendResource(_conn, "PUT", _resource,
400 params, extra_headers, _mgr) {}
401
402 };
403
404 class RGWRESTDeleteResource : public RGWRESTSendResource {
405 public:
406 RGWRESTDeleteResource(RGWRESTConn *_conn,
407 const string& _resource,
408 const rgw_http_param_pair *pp,
409 param_vec_t *extra_headers,
410 RGWHTTPManager *_mgr) : RGWRESTSendResource(_conn, "DELETE", _resource,
411 pp, extra_headers, _mgr) {}
412
413 RGWRESTDeleteResource(RGWRESTConn *_conn,
414 const string& _resource,
415 param_vec_t& params,
416 param_vec_t *extra_headers,
417 RGWHTTPManager *_mgr) : RGWRESTSendResource(_conn, "DELETE", _resource,
418 params, extra_headers, _mgr) {}
419
420 };
421
422
423
424 #endif