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(T
& t
, bufferlist
& bl
)
21 if (!p
.parse(bl
.c_str(), bl
.length())) {
26 decode_json_obj(t
, &p
);
27 } catch (JSONDecoder::err
& e
) {
33 struct rgw_http_param_pair
{
38 // append a null-terminated rgw_http_param_pair list into a list of string pairs
39 inline void append_param_list(param_vec_t
& params
, const rgw_http_param_pair
* pp
)
41 while (pp
&& pp
->key
) {
43 string v
= (pp
->val
? pp
->val
: "");
44 params
.emplace_back(make_pair(std::move(k
), std::move(v
)));
49 // copy a null-terminated rgw_http_param_pair list into a list of string pairs
50 inline param_vec_t
make_param_list(const rgw_http_param_pair
* pp
)
53 append_param_list(params
, pp
);
57 inline param_vec_t
make_param_list(const map
<string
, string
> *pp
)
63 for (auto iter
: *pp
) {
64 params
.emplace_back(make_pair(iter
.first
, iter
.second
));
72 vector
<string
> endpoints
;
74 string self_zone_group
;
77 std::atomic
<int64_t> counter
= { 0 };
81 RGWRESTConn(CephContext
*_cct
, RGWSI_Zone
*zone_svc
, const string
& _remote_id
, const list
<string
>& endpoints
, HostStyle _host_style
= PathStyle
);
82 RGWRESTConn(CephContext
*_cct
, RGWSI_Zone
*zone_svc
, const string
& _remote_id
, const list
<string
>& endpoints
, RGWAccessKey _cred
, HostStyle _host_style
= PathStyle
);
84 // custom move needed for atomic
85 RGWRESTConn(RGWRESTConn
&& other
);
86 RGWRESTConn
& operator=(RGWRESTConn
&& other
);
87 virtual ~RGWRESTConn() = default;
89 int get_url(string
& endpoint
);
91 const string
& get_self_zonegroup() {
92 return self_zone_group
;
94 const string
& get_remote_id() {
97 RGWAccessKey
& get_key() {
101 HostStyle
get_host_style() {
105 CephContext
*get_ctx() {
108 size_t get_endpoint_count() const { return endpoints
.size(); }
110 virtual void populate_params(param_vec_t
& params
, const rgw_user
*uid
, const string
& zonegroup
);
113 int forward(const rgw_user
& uid
, req_info
& info
, obj_version
*objv
, size_t max_response
, bufferlist
*inbl
, bufferlist
*outbl
);
117 int put_obj_send_init(rgw_obj
& obj
, const rgw_http_param_pair
*extra_params
, RGWRESTStreamS3PutObj
**req
);
118 int put_obj_async(const rgw_user
& uid
, rgw_obj
& obj
, uint64_t obj_size
,
119 map
<string
, bufferlist
>& attrs
, bool send
, RGWRESTStreamS3PutObj
**req
);
120 int complete_request(RGWRESTStreamS3PutObj
*req
, string
& etag
, ceph::real_time
*mtime
);
122 struct get_obj_params
{
124 req_info
*info
{nullptr};
125 const ceph::real_time
*mod_ptr
{nullptr};
126 const ceph::real_time
*unmod_ptr
{nullptr};
127 bool high_precision_time
{true};
131 uint32_t mod_zone_id
{0};
132 uint64_t mod_pg_ver
{0};
134 bool prepend_metadata
{false};
136 bool rgwx_stat
{false};
137 bool sync_manifest
{false};
139 bool skip_decrypt
{true};
140 RGWHTTPStreamRWRequest::ReceiveCB
*cb
{nullptr};
142 bool range_is_set
{false};
143 uint64_t range_start
{0};
144 uint64_t range_end
{0};
147 int get_obj(const rgw_obj
& obj
, const get_obj_params
& params
, bool send
, RGWRESTStreamRWRequest
**req
);
149 int get_obj(const rgw_user
& uid
, req_info
*info
/* optional */, const rgw_obj
& obj
,
150 const ceph::real_time
*mod_ptr
, const ceph::real_time
*unmod_ptr
,
151 uint32_t mod_zone_id
, uint64_t mod_pg_ver
,
152 bool prepend_metadata
, bool get_op
, bool rgwx_stat
, bool sync_manifest
,
153 bool skip_decrypt
, bool send
, RGWHTTPStreamRWRequest::ReceiveCB
*cb
, RGWRESTStreamRWRequest
**req
);
154 int complete_request(RGWRESTStreamRWRequest
*req
,
156 ceph::real_time
*mtime
,
158 map
<string
, string
> *pattrs
,
159 map
<string
, string
> *pheaders
);
161 int get_resource(const string
& resource
,
162 param_vec_t
*extra_params
,
163 map
<string
, string
>* extra_headers
,
165 bufferlist
*send_data
= nullptr,
166 RGWHTTPManager
*mgr
= nullptr);
169 int get_json_resource(const string
& resource
, param_vec_t
*params
, bufferlist
*in_data
, T
& t
);
171 int get_json_resource(const string
& resource
, param_vec_t
*params
, T
& t
);
173 int get_json_resource(const string
& resource
, const rgw_http_param_pair
*pp
, T
& t
);
176 void populate_zonegroup(param_vec_t
& params
, const string
& zonegroup
) {
177 if (!zonegroup
.empty()) {
178 params
.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX
"zonegroup", zonegroup
));
181 void populate_uid(param_vec_t
& params
, const rgw_user
*uid
) {
183 string uid_str
= uid
->to_str();
185 params
.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX
"uid", uid_str
));
191 class S3RESTConn
: public RGWRESTConn
{
195 S3RESTConn(CephContext
*_cct
, RGWSI_Zone
*svc_zone
, const string
& _remote_id
, const list
<string
>& endpoints
, HostStyle _host_style
= PathStyle
) :
196 RGWRESTConn(_cct
, svc_zone
, _remote_id
, endpoints
, _host_style
) {}
198 S3RESTConn(CephContext
*_cct
, RGWSI_Zone
*svc_zone
, const string
& _remote_id
, const list
<string
>& endpoints
, RGWAccessKey _cred
, HostStyle _host_style
= PathStyle
):
199 RGWRESTConn(_cct
, svc_zone
, _remote_id
, endpoints
, _cred
, _host_style
) {}
200 ~S3RESTConn() override
= default;
202 void populate_params(param_vec_t
& params
, const rgw_user
*uid
, const string
& zonegroup
) override
{
203 // do not populate any params in S3 REST Connection.
210 int RGWRESTConn::get_json_resource(const string
& resource
, param_vec_t
*params
, bufferlist
*in_data
, T
& t
)
213 int ret
= get_resource(resource
, params
, nullptr, bl
, in_data
);
218 ret
= parse_decode_json(t
, bl
);
227 int RGWRESTConn::get_json_resource(const string
& resource
, param_vec_t
*params
, T
& t
)
229 return get_json_resource(resource
, params
, nullptr, t
);
233 int RGWRESTConn::get_json_resource(const string
& resource
, const rgw_http_param_pair
*pp
, T
& t
)
235 param_vec_t params
= make_param_list(pp
);
236 return get_json_resource(resource
, ¶ms
, t
);
239 class RGWStreamIntoBufferlist
: public RGWHTTPStreamRWRequest::ReceiveCB
{
242 explicit RGWStreamIntoBufferlist(bufferlist
& _bl
) : bl(_bl
) {}
243 int handle_data(bufferlist
& inbl
, bool *pause
) override
{
244 bl
.claim_append(inbl
);
245 return inbl
.length();
249 class RGWRESTReadResource
: public RefCountedObject
, public RGWIOProvider
{
254 map
<string
, string
> headers
;
256 RGWStreamIntoBufferlist cb
;
259 RGWRESTStreamReadRequest req
;
261 void init_common(param_vec_t
*extra_headers
);
264 RGWRESTReadResource(RGWRESTConn
*_conn
,
265 const string
& _resource
,
266 const rgw_http_param_pair
*pp
,
267 param_vec_t
*extra_headers
,
268 RGWHTTPManager
*_mgr
);
270 RGWRESTReadResource(RGWRESTConn
*_conn
,
271 const string
& _resource
,
272 param_vec_t
& _params
,
273 param_vec_t
*extra_headers
,
274 RGWHTTPManager
*_mgr
);
275 ~RGWRESTReadResource() = default;
277 rgw_io_id
get_io_id(int io_type
) {
278 return req
.get_io_id(io_type
);
281 void set_io_user_info(void *user_info
) override
{
282 req
.set_io_user_info(user_info
);
285 void *get_io_user_info() override
{
286 return req
.get_io_user_info();
290 int decode_resource(T
*dest
);
300 int get_http_status() {
301 return req
.get_http_status();
304 int wait(bufferlist
*pbl
) {
305 int ret
= req
.wait();
310 if (req
.get_status() < 0) {
311 return req
.get_status();
326 int RGWRESTReadResource::decode_resource(T
*dest
)
328 int ret
= req
.get_status();
332 ret
= parse_decode_json(*dest
, bl
);
340 int RGWRESTReadResource::fetch(T
*dest
)
347 ret
= decode_resource(dest
);
355 int RGWRESTReadResource::wait(T
*dest
)
357 int ret
= req
.wait();
362 ret
= decode_resource(dest
);
369 class RGWRESTSendResource
: public RefCountedObject
, public RGWIOProvider
{
375 map
<string
, string
> headers
;
377 RGWStreamIntoBufferlist cb
;
380 RGWRESTStreamRWRequest req
;
382 void init_common(param_vec_t
*extra_headers
);
385 RGWRESTSendResource(RGWRESTConn
*_conn
,
386 const string
& _method
,
387 const string
& _resource
,
388 const rgw_http_param_pair
*pp
,
389 param_vec_t
*extra_headers
,
390 RGWHTTPManager
*_mgr
);
392 RGWRESTSendResource(RGWRESTConn
*_conn
,
393 const string
& _method
,
394 const string
& _resource
,
396 param_vec_t
*extra_headers
,
397 RGWHTTPManager
*_mgr
);
399 ~RGWRESTSendResource() = default;
401 rgw_io_id
get_io_id(int io_type
) {
402 return req
.get_io_id(io_type
);
405 void set_io_user_info(void *user_info
) override
{
406 req
.set_io_user_info(user_info
);
409 void *get_io_user_info() override
{
410 return req
.get_io_user_info();
413 int send(bufferlist
& bl
);
415 int aio_send(bufferlist
& bl
);
421 int get_http_status() {
422 return req
.get_http_status();
425 template <class E
= int>
426 int wait(bufferlist
*pbl
, E
*err_result
= nullptr) {
427 int ret
= req
.wait();
430 if (ret
< 0 && err_result
) {
431 ret
= parse_decode_json(*err_result
, bl
);
434 return req
.get_status();
437 template <class T
, class E
= int>
438 int wait(T
*dest
, E
*err_result
= nullptr);
441 template <class T
, class E
=int>
442 int RGWRESTSendResource::wait(T
*dest
, E
*err_result
)
444 int ret
= req
.wait();
446 ret
= req
.get_status();
449 if (ret
< 0 && err_result
) {
450 ret
= parse_decode_json(*err_result
, bl
);
457 ret
= parse_decode_json(*dest
, bl
);
465 class RGWRESTPostResource
: public RGWRESTSendResource
{
467 RGWRESTPostResource(RGWRESTConn
*_conn
,
468 const string
& _resource
,
469 const rgw_http_param_pair
*pp
,
470 param_vec_t
*extra_headers
,
471 RGWHTTPManager
*_mgr
) : RGWRESTSendResource(_conn
, "POST", _resource
,
472 pp
, extra_headers
, _mgr
) {}
474 RGWRESTPostResource(RGWRESTConn
*_conn
,
475 const string
& _resource
,
477 param_vec_t
*extra_headers
,
478 RGWHTTPManager
*_mgr
) : RGWRESTSendResource(_conn
, "POST", _resource
,
479 params
, extra_headers
, _mgr
) {}
483 class RGWRESTPutResource
: public RGWRESTSendResource
{
485 RGWRESTPutResource(RGWRESTConn
*_conn
,
486 const string
& _resource
,
487 const rgw_http_param_pair
*pp
,
488 param_vec_t
*extra_headers
,
489 RGWHTTPManager
*_mgr
) : RGWRESTSendResource(_conn
, "PUT", _resource
,
490 pp
, extra_headers
, _mgr
) {}
492 RGWRESTPutResource(RGWRESTConn
*_conn
,
493 const string
& _resource
,
495 param_vec_t
*extra_headers
,
496 RGWHTTPManager
*_mgr
) : RGWRESTSendResource(_conn
, "PUT", _resource
,
497 params
, extra_headers
, _mgr
) {}
501 class RGWRESTDeleteResource
: public RGWRESTSendResource
{
503 RGWRESTDeleteResource(RGWRESTConn
*_conn
,
504 const string
& _resource
,
505 const rgw_http_param_pair
*pp
,
506 param_vec_t
*extra_headers
,
507 RGWHTTPManager
*_mgr
) : RGWRESTSendResource(_conn
, "DELETE", _resource
,
508 pp
, extra_headers
, _mgr
) {}
510 RGWRESTDeleteResource(RGWRESTConn
*_conn
,
511 const string
& _resource
,
513 param_vec_t
*extra_headers
,
514 RGWHTTPManager
*_mgr
) : RGWRESTSendResource(_conn
, "DELETE", _resource
,
515 params
, extra_headers
, _mgr
) {}