1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #ifndef CEPH_RGW_REST_CONN_H
5 #define CEPH_RGW_REST_CONN_H
8 #include "rgw_rest_client.h"
9 #include "common/ceph_json.h"
10 #include "common/RefCountedObj.h"
18 static int parse_decode_json(CephContext *cct, T& t, bufferlist& bl)
21 int ret = p.parse(bl.c_str(), bl.length());
27 decode_json_obj(t, &p);
28 } catch (JSONDecoder::err& e) {
34 struct rgw_http_param_pair {
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)
43 while (pp && pp->key) {
45 string v = (pp->val ? pp->val : "");
46 params.emplace_back(make_pair(std::move(k), std::move(v)));
55 vector<string> endpoints;
57 string self_zone_group;
59 std::atomic<int64_t> counter = { 0 };
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);
68 int get_url(string& endpoint);
70 const string& get_self_zonegroup() {
71 return self_zone_group;
73 const string& get_remote_id() {
76 RGWAccessKey& get_key() {
80 CephContext *get_ctx() {
83 size_t get_endpoint_count() const { return endpoints.size(); }
86 int forward(const rgw_user& uid, req_info& info, obj_version *objv, size_t max_response, bufferlist *inbl, bufferlist *outbl);
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);
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);
100 int get_resource(const string& resource,
101 param_vec_t *extra_params,
102 map<string, string>* extra_headers,
104 bufferlist *send_data = nullptr,
105 RGWHTTPManager *mgr = nullptr);
108 int get_json_resource(const string& resource, param_vec_t *params, bufferlist *in_data, T& t);
110 int get_json_resource(const string& resource, param_vec_t *params, T& t);
112 int get_json_resource(const string& resource, const rgw_http_param_pair *pp, T& t);
117 int RGWRESTConn::get_json_resource(const string& resource, param_vec_t *params, bufferlist *in_data, T& t)
120 int ret = get_resource(resource, params, nullptr, bl, in_data);
125 ret = parse_decode_json(cct, t, bl);
134 int RGWRESTConn::get_json_resource(const string& resource, param_vec_t *params, T& t)
136 return get_json_resource(resource, params, nullptr, t);
140 int RGWRESTConn::get_json_resource(const string& resource, const rgw_http_param_pair *pp, T& t)
142 param_vec_t params = make_param_list(pp);
143 return get_json_resource(resource, ¶ms, t);
146 class RGWStreamIntoBufferlist : public RGWGetDataCB {
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);
156 class RGWRESTReadResource : public RefCountedObject {
161 map<string, string> headers;
163 RGWStreamIntoBufferlist cb;
166 RGWRESTStreamReadRequest req;
168 void init_common(param_vec_t *extra_headers);
171 RGWRESTReadResource(RGWRESTConn *_conn,
172 const string& _resource,
173 const rgw_http_param_pair *pp,
174 param_vec_t *extra_headers,
175 RGWHTTPManager *_mgr);
177 RGWRESTReadResource(RGWRESTConn *_conn,
178 const string& _resource,
179 param_vec_t& _params,
180 param_vec_t *extra_headers,
181 RGWHTTPManager *_mgr);
183 void set_user_info(void *user_info) {
184 req.set_user_info(user_info);
186 void *get_user_info() {
187 return req.get_user_info();
191 int decode_resource(T *dest);
201 int get_http_status() {
202 return req.get_http_status();
205 int wait_bl(bufferlist *pbl) {
206 int ret = req.wait();
211 if (req.get_status() < 0) {
212 return req.get_status();
227 int RGWRESTReadResource::decode_resource(T *dest)
229 int ret = req.get_status();
233 ret = parse_decode_json(cct, *dest, bl);
241 int RGWRESTReadResource::fetch(T *dest)
248 ret = decode_resource(dest);
256 int RGWRESTReadResource::wait(T *dest)
258 int ret = req.wait();
263 ret = decode_resource(dest);
270 class RGWRESTSendResource : public RefCountedObject {
276 map<string, string> headers;
278 RGWStreamIntoBufferlist cb;
281 RGWRESTStreamRWRequest req;
283 void init_common(param_vec_t *extra_headers);
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);
293 RGWRESTSendResource(RGWRESTConn *_conn,
294 const string& _method,
295 const string& _resource,
297 param_vec_t *extra_headers,
298 RGWHTTPManager *_mgr);
300 void set_user_info(void *user_info) {
301 req.set_user_info(user_info);
303 void *get_user_info() {
304 return req.get_user_info();
308 int decode_resource(T *dest);
310 int send(bufferlist& bl);
312 int aio_send(bufferlist& bl);
318 int get_http_status() {
319 return req.get_http_status();
322 int wait_bl(bufferlist *pbl) {
323 int ret = req.wait();
328 if (req.get_status() < 0) {
329 return req.get_status();
340 int RGWRESTSendResource::decode_resource(T *dest)
342 int ret = req.get_status();
346 ret = parse_decode_json(cct, *dest, bl);
354 int RGWRESTSendResource::wait(T *dest)
356 int ret = req.wait();
361 ret = decode_resource(dest);
368 class RGWRESTPostResource : public RGWRESTSendResource {
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) {}
377 RGWRESTPostResource(RGWRESTConn *_conn,
378 const string& _resource,
380 param_vec_t *extra_headers,
381 RGWHTTPManager *_mgr) : RGWRESTSendResource(_conn, "POST", _resource,
382 params, extra_headers, _mgr) {}
386 class RGWRESTPutResource : public RGWRESTSendResource {
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) {}
395 RGWRESTPutResource(RGWRESTConn *_conn,
396 const string& _resource,
398 param_vec_t *extra_headers,
399 RGWHTTPManager *_mgr) : RGWRESTSendResource(_conn, "PUT", _resource,
400 params, extra_headers, _mgr) {}
404 class RGWRESTDeleteResource : public RGWRESTSendResource {
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) {}
413 RGWRESTDeleteResource(RGWRESTConn *_conn,
414 const string& _resource,
416 param_vec_t *extra_headers,
417 RGWHTTPManager *_mgr) : RGWRESTSendResource(_conn, "DELETE", _resource,
418 params, extra_headers, _mgr) {}