]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_rest_conn.h
add subtree-ish sources for 12.0.3
[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 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, RGWHTTPManager *mgr = NULL);
104
105 template <class T>
106 int get_json_resource(const string& resource, param_vec_t *params, T& t);
107 template <class T>
108 int get_json_resource(const string& resource, const rgw_http_param_pair *pp, T& t);
109 };
110
111
112 template<class T>
113 int RGWRESTConn::get_json_resource(const string& resource, param_vec_t *params, T& t)
114 {
115 bufferlist bl;
116 int ret = get_resource(resource, params, NULL, bl);
117 if (ret < 0) {
118 return ret;
119 }
120
121 ret = parse_decode_json(cct, t, bl);
122 if (ret < 0) {
123 return ret;
124 }
125
126 return 0;
127 }
128
129 template<class T>
130 int RGWRESTConn::get_json_resource(const string& resource, const rgw_http_param_pair *pp, T& t)
131 {
132 param_vec_t params = make_param_list(pp);
133 return get_json_resource(resource, &params, t);
134 }
135
136 class RGWStreamIntoBufferlist : public RGWGetDataCB {
137 bufferlist& bl;
138 public:
139 RGWStreamIntoBufferlist(bufferlist& _bl) : bl(_bl) {}
140 int handle_data(bufferlist& inbl, off_t bl_ofs, off_t bl_len) override {
141 bl.claim_append(inbl);
142 return bl_len;
143 }
144 };
145
146 class RGWRESTReadResource : public RefCountedObject {
147 CephContext *cct;
148 RGWRESTConn *conn;
149 string resource;
150 param_vec_t params;
151 map<string, string> headers;
152 bufferlist bl;
153 RGWStreamIntoBufferlist cb;
154
155 RGWHTTPManager *mgr;
156 RGWRESTStreamReadRequest req;
157
158 void init_common(param_vec_t *extra_headers);
159
160 public:
161 RGWRESTReadResource(RGWRESTConn *_conn,
162 const string& _resource,
163 const rgw_http_param_pair *pp,
164 param_vec_t *extra_headers,
165 RGWHTTPManager *_mgr);
166
167 RGWRESTReadResource(RGWRESTConn *_conn,
168 const string& _resource,
169 param_vec_t& _params,
170 param_vec_t *extra_headers,
171 RGWHTTPManager *_mgr);
172
173 void set_user_info(void *user_info) {
174 req.set_user_info(user_info);
175 }
176 void *get_user_info() {
177 return req.get_user_info();
178 }
179
180 template <class T>
181 int decode_resource(T *dest);
182
183 int read();
184
185 int aio_read();
186
187 string to_str() {
188 return req.to_str();
189 }
190
191 int get_http_status() {
192 return req.get_http_status();
193 }
194
195 int wait_bl(bufferlist *pbl) {
196 int ret = req.wait();
197 if (ret < 0) {
198 return ret;
199 }
200
201 if (req.get_status() < 0) {
202 return req.get_status();
203 }
204 *pbl = bl;
205 return 0;
206 }
207
208 template <class T>
209 int wait(T *dest);
210
211 template <class T>
212 int fetch(T *dest);
213 };
214
215
216 template <class T>
217 int RGWRESTReadResource::decode_resource(T *dest)
218 {
219 int ret = req.get_status();
220 if (ret < 0) {
221 return ret;
222 }
223 ret = parse_decode_json(cct, *dest, bl);
224 if (ret < 0) {
225 return ret;
226 }
227 return 0;
228 }
229
230 template <class T>
231 int RGWRESTReadResource::fetch(T *dest)
232 {
233 int ret = read();
234 if (ret < 0) {
235 return ret;
236 }
237
238 ret = decode_resource(dest);
239 if (ret < 0) {
240 return ret;
241 }
242 return 0;
243 }
244
245 template <class T>
246 int RGWRESTReadResource::wait(T *dest)
247 {
248 int ret = req.wait();
249 if (ret < 0) {
250 return ret;
251 }
252
253 ret = decode_resource(dest);
254 if (ret < 0) {
255 return ret;
256 }
257 return 0;
258 }
259
260 class RGWRESTSendResource : public RefCountedObject {
261 CephContext *cct;
262 RGWRESTConn *conn;
263 string method;
264 string resource;
265 param_vec_t params;
266 map<string, string> headers;
267 bufferlist bl;
268 RGWStreamIntoBufferlist cb;
269
270 RGWHTTPManager *mgr;
271 RGWRESTStreamRWRequest req;
272
273 void init_common(param_vec_t *extra_headers);
274
275 public:
276 RGWRESTSendResource(RGWRESTConn *_conn,
277 const string& _method,
278 const string& _resource,
279 const rgw_http_param_pair *pp,
280 param_vec_t *extra_headers,
281 RGWHTTPManager *_mgr);
282
283 RGWRESTSendResource(RGWRESTConn *_conn,
284 const string& _method,
285 const string& _resource,
286 param_vec_t& params,
287 param_vec_t *extra_headers,
288 RGWHTTPManager *_mgr);
289
290 void set_user_info(void *user_info) {
291 req.set_user_info(user_info);
292 }
293 void *get_user_info() {
294 return req.get_user_info();
295 }
296
297 template <class T>
298 int decode_resource(T *dest);
299
300 int send(bufferlist& bl);
301
302 int aio_send(bufferlist& bl);
303
304 string to_str() {
305 return req.to_str();
306 }
307
308 int get_http_status() {
309 return req.get_http_status();
310 }
311
312 int wait_bl(bufferlist *pbl) {
313 int ret = req.wait();
314 if (ret < 0) {
315 return ret;
316 }
317
318 if (req.get_status() < 0) {
319 return req.get_status();
320 }
321 *pbl = bl;
322 return 0;
323 }
324
325 template <class T>
326 int wait(T *dest);
327 };
328
329 template <class T>
330 int RGWRESTSendResource::decode_resource(T *dest)
331 {
332 int ret = req.get_status();
333 if (ret < 0) {
334 return ret;
335 }
336 ret = parse_decode_json(cct, *dest, bl);
337 if (ret < 0) {
338 return ret;
339 }
340 return 0;
341 }
342
343 template <class T>
344 int RGWRESTSendResource::wait(T *dest)
345 {
346 int ret = req.wait();
347 if (ret < 0) {
348 return ret;
349 }
350
351 ret = decode_resource(dest);
352 if (ret < 0) {
353 return ret;
354 }
355 return 0;
356 }
357
358 class RGWRESTPostResource : public RGWRESTSendResource {
359 public:
360 RGWRESTPostResource(RGWRESTConn *_conn,
361 const string& _resource,
362 const rgw_http_param_pair *pp,
363 param_vec_t *extra_headers,
364 RGWHTTPManager *_mgr) : RGWRESTSendResource(_conn, "POST", _resource,
365 pp, extra_headers, _mgr) {}
366
367 RGWRESTPostResource(RGWRESTConn *_conn,
368 const string& _resource,
369 param_vec_t& params,
370 param_vec_t *extra_headers,
371 RGWHTTPManager *_mgr) : RGWRESTSendResource(_conn, "POST", _resource,
372 params, extra_headers, _mgr) {}
373
374 };
375
376 class RGWRESTPutResource : public RGWRESTSendResource {
377 public:
378 RGWRESTPutResource(RGWRESTConn *_conn,
379 const string& _resource,
380 const rgw_http_param_pair *pp,
381 param_vec_t *extra_headers,
382 RGWHTTPManager *_mgr) : RGWRESTSendResource(_conn, "PUT", _resource,
383 pp, extra_headers, _mgr) {}
384
385 RGWRESTPutResource(RGWRESTConn *_conn,
386 const string& _resource,
387 param_vec_t& params,
388 param_vec_t *extra_headers,
389 RGWHTTPManager *_mgr) : RGWRESTSendResource(_conn, "PUT", _resource,
390 params, extra_headers, _mgr) {}
391
392 };
393
394 class RGWRESTDeleteResource : public RGWRESTSendResource {
395 public:
396 RGWRESTDeleteResource(RGWRESTConn *_conn,
397 const string& _resource,
398 const rgw_http_param_pair *pp,
399 param_vec_t *extra_headers,
400 RGWHTTPManager *_mgr) : RGWRESTSendResource(_conn, "DELETE", _resource,
401 pp, extra_headers, _mgr) {}
402
403 RGWRESTDeleteResource(RGWRESTConn *_conn,
404 const string& _resource,
405 param_vec_t& params,
406 param_vec_t *extra_headers,
407 RGWHTTPManager *_mgr) : RGWRESTSendResource(_conn, "DELETE", _resource,
408 params, extra_headers, _mgr) {}
409
410 };
411
412
413
414 #endif