]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_rest_conn.cc
afcc86db11cd8ca71d7cb5148e2104aacf2bcd8f
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
5 #include "rgw_rest_conn.h"
9 #include "services/svc_zone.h"
11 #define dout_subsys ceph_subsys_rgw
15 RGWRESTConn::RGWRESTConn(CephContext
*_cct
, RGWSI_Zone
*zone_svc
,
16 const string
& _remote_id
,
17 const list
<string
>& remote_endpoints
,
18 std::optional
<string
> _api_name
,
19 HostStyle _host_style
)
21 endpoints(remote_endpoints
.begin(), remote_endpoints
.end()),
22 remote_id(_remote_id
),
24 host_style(_host_style
)
27 key
= zone_svc
->get_zone_params().system_key
;
28 self_zone_group
= zone_svc
->get_zonegroup().get_id();
32 RGWRESTConn::RGWRESTConn(CephContext
*_cct
, rgw::sal::Store
* store
,
33 const string
& _remote_id
,
34 const list
<string
>& remote_endpoints
,
35 std::optional
<string
> _api_name
,
36 HostStyle _host_style
)
38 endpoints(remote_endpoints
.begin(), remote_endpoints
.end()),
39 remote_id(_remote_id
),
41 host_style(_host_style
)
44 key
= store
->get_zone()->get_params().system_key
;
45 self_zone_group
= store
->get_zone()->get_zonegroup().get_id();
49 RGWRESTConn::RGWRESTConn(CephContext
*_cct
, RGWSI_Zone
*zone_svc
,
50 const string
& _remote_id
,
51 const list
<string
>& remote_endpoints
,
53 std::optional
<string
> _api_name
,
54 HostStyle _host_style
)
56 endpoints(remote_endpoints
.begin(), remote_endpoints
.end()),
57 key(std::move(_cred
)),
58 remote_id(_remote_id
),
60 host_style(_host_style
)
63 self_zone_group
= zone_svc
->get_zonegroup().get_id();
67 RGWRESTConn::RGWRESTConn(CephContext
*_cct
, rgw::sal::Store
* store
,
68 const string
& _remote_id
,
69 const list
<string
>& remote_endpoints
,
71 std::optional
<string
> _api_name
,
72 HostStyle _host_style
)
74 endpoints(remote_endpoints
.begin(), remote_endpoints
.end()),
75 key(std::move(_cred
)),
76 remote_id(_remote_id
),
78 host_style(_host_style
)
81 self_zone_group
= store
->get_zone()->get_zonegroup().get_id();
85 RGWRESTConn::RGWRESTConn(RGWRESTConn
&& other
)
87 endpoints(std::move(other
.endpoints
)),
88 key(std::move(other
.key
)),
89 self_zone_group(std::move(other
.self_zone_group
)),
90 remote_id(std::move(other
.remote_id
)),
91 counter(other
.counter
.load())
95 RGWRESTConn
& RGWRESTConn::operator=(RGWRESTConn
&& other
)
98 endpoints
= std::move(other
.endpoints
);
99 key
= std::move(other
.key
);
100 self_zone_group
= std::move(other
.self_zone_group
);
101 remote_id
= std::move(other
.remote_id
);
102 counter
= other
.counter
.load();
106 int RGWRESTConn::get_url(string
& endpoint
)
108 if (endpoints
.empty()) {
109 ldout(cct
, 0) << "ERROR: endpoints not configured for upstream zone" << dendl
;
114 endpoint
= endpoints
[i
% endpoints
.size()];
119 string
RGWRESTConn::get_url()
126 void RGWRESTConn::populate_params(param_vec_t
& params
, const rgw_user
*uid
, const string
& zonegroup
)
128 populate_uid(params
, uid
);
129 populate_zonegroup(params
, zonegroup
);
132 int RGWRESTConn::forward(const DoutPrefixProvider
*dpp
, const rgw_user
& uid
, req_info
& info
, obj_version
*objv
, size_t max_response
, bufferlist
*inbl
, bufferlist
*outbl
, optional_yield y
)
135 int ret
= get_url(url
);
139 populate_params(params
, &uid
, self_zone_group
);
141 params
.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX
"tag", objv
->tag
));
143 snprintf(buf
, sizeof(buf
), "%lld", (long long)objv
->ver
);
144 params
.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX
"ver", buf
));
146 RGWRESTSimpleRequest
req(cct
, info
.method
, url
, NULL
, ¶ms
, api_name
);
147 return req
.forward_request(dpp
, key
, info
, max_response
, inbl
, outbl
, y
);
150 int RGWRESTConn::put_obj_send_init(rgw::sal::Object
* obj
, const rgw_http_param_pair
*extra_params
, RGWRESTStreamS3PutObj
**req
)
153 int ret
= get_url(url
);
159 populate_params(params
, &uid
, self_zone_group
);
162 append_param_list(params
, extra_params
);
165 RGWRESTStreamS3PutObj
*wr
= new RGWRESTStreamS3PutObj(cct
, "PUT", url
, NULL
, ¶ms
, api_name
, host_style
);
171 int RGWRESTConn::put_obj_async_init(const DoutPrefixProvider
*dpp
, const rgw_user
& uid
, rgw::sal::Object
* obj
,
172 map
<string
, bufferlist
>& attrs
,
173 RGWRESTStreamS3PutObj
**req
)
176 int ret
= get_url(url
);
181 populate_params(params
, &uid
, self_zone_group
);
182 RGWRESTStreamS3PutObj
*wr
= new RGWRESTStreamS3PutObj(cct
, "PUT", url
, NULL
, ¶ms
, api_name
, host_style
);
183 wr
->put_obj_init(dpp
, key
, obj
, attrs
);
188 int RGWRESTConn::complete_request(RGWRESTStreamS3PutObj
*req
, string
& etag
,
189 real_time
*mtime
, optional_yield y
)
191 int ret
= req
->complete_request(y
, &etag
, mtime
);
197 static void set_date_header(const real_time
*t
, map
<string
, string
>& headers
, bool high_precision_time
, const string
& header_name
)
203 utime_t tm
= utime_t(*t
);
204 if (high_precision_time
) {
209 headers
[header_name
] = s
.str();
213 static void set_header(T val
, map
<string
, string
>& headers
, const string
& header_name
)
217 headers
[header_name
] = s
.str();
221 int RGWRESTConn::get_obj(const DoutPrefixProvider
*dpp
, const rgw_user
& uid
, req_info
*info
/* optional */, const rgw::sal::Object
* obj
,
222 const real_time
*mod_ptr
, const real_time
*unmod_ptr
,
223 uint32_t mod_zone_id
, uint64_t mod_pg_ver
,
224 bool prepend_metadata
, bool get_op
, bool rgwx_stat
,
225 bool sync_manifest
, bool skip_decrypt
,
226 bool send
, RGWHTTPStreamRWRequest::ReceiveCB
*cb
, RGWRESTStreamRWRequest
**req
)
228 get_obj_params params
;
231 params
.mod_ptr
= mod_ptr
;
232 params
.mod_pg_ver
= mod_pg_ver
;
233 params
.prepend_metadata
= prepend_metadata
;
234 params
.get_op
= get_op
;
235 params
.rgwx_stat
= rgwx_stat
;
236 params
.sync_manifest
= sync_manifest
;
237 params
.skip_decrypt
= skip_decrypt
;
239 return get_obj(dpp
, obj
, params
, send
, req
);
242 int RGWRESTConn::get_obj(const DoutPrefixProvider
*dpp
, const rgw::sal::Object
* obj
, const get_obj_params
& in_params
, bool send
, RGWRESTStreamRWRequest
**req
)
245 int ret
= get_url(url
);
250 populate_params(params
, &in_params
.uid
, self_zone_group
);
251 if (in_params
.prepend_metadata
) {
252 params
.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX
"prepend-metadata", "true"));
254 if (in_params
.rgwx_stat
) {
255 params
.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX
"stat", "true"));
257 if (in_params
.sync_manifest
) {
258 params
.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX
"sync-manifest", ""));
260 if (in_params
.skip_decrypt
) {
261 params
.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX
"skip-decrypt", ""));
263 if (!obj
->get_instance().empty()) {
264 const string
& instance
= obj
->get_instance();
265 params
.push_back(param_pair_t("versionId", instance
));
267 if (in_params
.get_op
) {
268 *req
= new RGWRESTStreamReadRequest(cct
, url
, in_params
.cb
, NULL
, ¶ms
, api_name
, host_style
);
270 *req
= new RGWRESTStreamHeadRequest(cct
, url
, in_params
.cb
, NULL
, ¶ms
, api_name
);
272 map
<string
, string
> extra_headers
;
273 if (in_params
.info
) {
274 const auto& orig_map
= in_params
.info
->env
->get_map();
276 /* add original headers that start with HTTP_X_AMZ_ */
277 static constexpr char SEARCH_AMZ_PREFIX
[] = "HTTP_X_AMZ_";
278 for (auto iter
= orig_map
.lower_bound(SEARCH_AMZ_PREFIX
); iter
!= orig_map
.end(); ++iter
) {
279 const string
& name
= iter
->first
;
280 if (name
== "HTTP_X_AMZ_DATE") /* don't forward date from original request */
282 if (name
.compare(0, strlen(SEARCH_AMZ_PREFIX
), SEARCH_AMZ_PREFIX
) != 0)
284 extra_headers
[iter
->first
] = iter
->second
;
288 set_date_header(in_params
.mod_ptr
, extra_headers
, in_params
.high_precision_time
, "HTTP_IF_MODIFIED_SINCE");
289 set_date_header(in_params
.unmod_ptr
, extra_headers
, in_params
.high_precision_time
, "HTTP_IF_UNMODIFIED_SINCE");
290 if (!in_params
.etag
.empty()) {
291 set_header(in_params
.etag
, extra_headers
, "HTTP_IF_MATCH");
293 if (in_params
.mod_zone_id
!= 0) {
294 set_header(in_params
.mod_zone_id
, extra_headers
, "HTTP_DEST_ZONE_SHORT_ID");
296 if (in_params
.mod_pg_ver
!= 0) {
297 set_header(in_params
.mod_pg_ver
, extra_headers
, "HTTP_DEST_PG_VER");
299 if (in_params
.range_is_set
) {
301 snprintf(buf
, sizeof(buf
), "bytes=%lld-%lld", (long long)in_params
.range_start
, (long long)in_params
.range_end
);
302 set_header(buf
, extra_headers
, "RANGE");
305 int r
= (*req
)->send_prepare(dpp
, key
, extra_headers
, obj
->get_obj());
314 r
= (*req
)->send(nullptr);
325 int RGWRESTConn::complete_request(RGWRESTStreamRWRequest
*req
,
329 map
<string
, string
> *pattrs
,
330 map
<string
, string
> *pheaders
,
333 int ret
= req
->complete_request(y
, etag
, mtime
, psize
, pattrs
, pheaders
);
339 int RGWRESTConn::get_resource(const DoutPrefixProvider
*dpp
,
340 const string
& resource
,
341 param_vec_t
*extra_params
,
342 map
<string
, string
> *extra_headers
,
344 bufferlist
*send_data
,
349 int ret
= get_url(url
);
356 params
.insert(params
.end(), extra_params
->begin(), extra_params
->end());
359 populate_params(params
, nullptr, self_zone_group
);
361 RGWStreamIntoBufferlist
cb(bl
);
363 RGWRESTStreamReadRequest
req(cct
, url
, &cb
, NULL
, ¶ms
, api_name
, host_style
);
365 map
<string
, string
> headers
;
367 headers
.insert(extra_headers
->begin(), extra_headers
->end());
370 ret
= req
.send_request(dpp
, &key
, headers
, resource
, mgr
, send_data
);
372 ldpp_dout(dpp
, 5) << __func__
<< ": send_request() resource=" << resource
<< " returned ret=" << ret
<< dendl
;
376 return req
.complete_request(y
);
379 int RGWRESTConn::send_resource(const DoutPrefixProvider
*dpp
, const std::string
& method
,
380 const std::string
& resource
, rgw_http_param_pair
*extra_params
,
381 std::map
<std::string
, std::string
> *extra_headers
, bufferlist
& bl
,
382 bufferlist
*send_data
, RGWHTTPManager
*mgr
, optional_yield y
)
385 int ret
= get_url(url
);
392 params
= make_param_list(extra_params
);
395 populate_params(params
, nullptr, self_zone_group
);
397 RGWStreamIntoBufferlist
cb(bl
);
399 RGWRESTStreamSendRequest
req(cct
, method
, url
, &cb
, NULL
, ¶ms
, api_name
, host_style
);
401 std::map
<std::string
, std::string
> headers
;
403 headers
.insert(extra_headers
->begin(), extra_headers
->end());
406 ret
= req
.send_request(dpp
, &key
, headers
, resource
, mgr
, send_data
);
408 ldpp_dout(dpp
, 5) << __func__
<< ": send_request() resource=" << resource
<< " returned ret=" << ret
<< dendl
;
412 return req
.complete_request(y
);
415 RGWRESTReadResource::RGWRESTReadResource(RGWRESTConn
*_conn
,
416 const string
& _resource
,
417 const rgw_http_param_pair
*pp
,
418 param_vec_t
*extra_headers
,
419 RGWHTTPManager
*_mgr
)
420 : cct(_conn
->get_ctx()), conn(_conn
), resource(_resource
),
421 params(make_param_list(pp
)), cb(bl
), mgr(_mgr
),
422 req(cct
, conn
->get_url(), &cb
, NULL
, NULL
, _conn
->get_api_name())
424 init_common(extra_headers
);
427 RGWRESTReadResource::RGWRESTReadResource(RGWRESTConn
*_conn
,
428 const string
& _resource
,
429 param_vec_t
& _params
,
430 param_vec_t
*extra_headers
,
431 RGWHTTPManager
*_mgr
)
432 : cct(_conn
->get_ctx()), conn(_conn
), resource(_resource
), params(_params
),
433 cb(bl
), mgr(_mgr
), req(cct
, conn
->get_url(), &cb
, NULL
, NULL
, _conn
->get_api_name())
435 init_common(extra_headers
);
438 void RGWRESTReadResource::init_common(param_vec_t
*extra_headers
)
440 conn
->populate_params(params
, nullptr, conn
->get_self_zonegroup());
443 headers
.insert(extra_headers
->begin(), extra_headers
->end());
446 req
.set_params(¶ms
);
449 int RGWRESTReadResource::read(const DoutPrefixProvider
*dpp
, optional_yield y
)
451 int ret
= req
.send_request(dpp
, &conn
->get_key(), headers
, resource
, mgr
);
453 ldpp_dout(dpp
, 5) << __func__
<< ": send_request() resource=" << resource
<< " returned ret=" << ret
<< dendl
;
457 return req
.complete_request(y
);
460 int RGWRESTReadResource::aio_read(const DoutPrefixProvider
*dpp
)
462 int ret
= req
.send_request(dpp
, &conn
->get_key(), headers
, resource
, mgr
);
464 ldpp_dout(dpp
, 5) << __func__
<< ": send_request() resource=" << resource
<< " returned ret=" << ret
<< dendl
;
471 RGWRESTSendResource::RGWRESTSendResource(RGWRESTConn
*_conn
,
472 const string
& _method
,
473 const string
& _resource
,
474 const rgw_http_param_pair
*pp
,
475 param_vec_t
*extra_headers
,
476 RGWHTTPManager
*_mgr
)
477 : cct(_conn
->get_ctx()), conn(_conn
), method(_method
), resource(_resource
),
478 params(make_param_list(pp
)), cb(bl
), mgr(_mgr
),
479 req(cct
, method
.c_str(), conn
->get_url(), &cb
, NULL
, NULL
, _conn
->get_api_name(), _conn
->get_host_style())
481 init_common(extra_headers
);
484 RGWRESTSendResource::RGWRESTSendResource(RGWRESTConn
*_conn
,
485 const string
& _method
,
486 const string
& _resource
,
488 param_vec_t
*extra_headers
,
489 RGWHTTPManager
*_mgr
)
490 : cct(_conn
->get_ctx()), conn(_conn
), method(_method
), resource(_resource
), params(params
),
491 cb(bl
), mgr(_mgr
), req(cct
, method
.c_str(), conn
->get_url(), &cb
, NULL
, NULL
, _conn
->get_api_name(), _conn
->get_host_style())
493 init_common(extra_headers
);
496 void RGWRESTSendResource::init_common(param_vec_t
*extra_headers
)
498 conn
->populate_params(params
, nullptr, conn
->get_self_zonegroup());
501 headers
.insert(extra_headers
->begin(), extra_headers
->end());
504 req
.set_params(¶ms
);
507 int RGWRESTSendResource::send(const DoutPrefixProvider
*dpp
, bufferlist
& outbl
, optional_yield y
)
509 req
.set_send_length(outbl
.length());
510 req
.set_outbl(outbl
);
512 int ret
= req
.send_request(dpp
, &conn
->get_key(), headers
, resource
, mgr
);
514 ldpp_dout(dpp
, 5) << __func__
<< ": send_request() resource=" << resource
<< " returned ret=" << ret
<< dendl
;
518 return req
.complete_request(y
);
521 int RGWRESTSendResource::aio_send(const DoutPrefixProvider
*dpp
, bufferlist
& outbl
)
523 req
.set_send_length(outbl
.length());
524 req
.set_outbl(outbl
);
526 int ret
= req
.send_request(dpp
, &conn
->get_key(), headers
, resource
, mgr
);
528 ldpp_dout(dpp
, 5) << __func__
<< ": send_request() resource=" << resource
<< " returned ret=" << ret
<< dendl
;