1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
5 #include "rgw_rest_conn.h"
7 #define dout_subsys ceph_subsys_rgw
9 RGWRESTConn::RGWRESTConn(CephContext
*_cct
, RGWRados
*store
,
10 const string
& _remote_id
,
11 const list
<string
>& remote_endpoints
)
13 endpoints(remote_endpoints
.begin(), remote_endpoints
.end()),
17 key
= store
->get_zone_params().system_key
;
18 self_zone_group
= store
->get_zonegroup().get_id();
22 RGWRESTConn::RGWRESTConn(RGWRESTConn
&& other
)
24 endpoints(std::move(other
.endpoints
)),
25 key(std::move(other
.key
)),
26 self_zone_group(std::move(other
.self_zone_group
)),
27 remote_id(std::move(other
.remote_id
)),
28 counter(other
.counter
.load())
32 RGWRESTConn
& RGWRESTConn::operator=(RGWRESTConn
&& other
)
35 endpoints
= std::move(other
.endpoints
);
36 key
= std::move(other
.key
);
37 self_zone_group
= std::move(other
.self_zone_group
);
38 remote_id
= std::move(other
.remote_id
);
39 counter
= other
.counter
.load();
43 int RGWRESTConn::get_url(string
& endpoint
)
45 if (endpoints
.empty()) {
46 ldout(cct
, 0) << "ERROR: endpoints not configured for upstream zone" << dendl
;
51 endpoint
= endpoints
[i
% endpoints
.size()];
56 string
RGWRESTConn::get_url()
59 if (endpoints
.empty()) {
60 ldout(cct
, 0) << "WARNING: endpoints not configured for upstream zone" << dendl
; /* we'll catch this later */
65 endpoint
= endpoints
[i
% endpoints
.size()];
70 static void populate_params(param_vec_t
& params
, const rgw_user
*uid
, const string
& zonegroup
)
73 string uid_str
= uid
->to_str();
75 params
.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX
"uid", uid_str
));
78 if (!zonegroup
.empty()) {
79 params
.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX
"zonegroup", zonegroup
));
83 int RGWRESTConn::forward(const rgw_user
& uid
, req_info
& info
, obj_version
*objv
, size_t max_response
, bufferlist
*inbl
, bufferlist
*outbl
)
86 int ret
= get_url(url
);
90 populate_params(params
, &uid
, self_zone_group
);
92 params
.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX
"tag", objv
->tag
));
94 snprintf(buf
, sizeof(buf
), "%lld", (long long)objv
->ver
);
95 params
.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX
"ver", buf
));
97 RGWRESTSimpleRequest
req(cct
, url
, NULL
, ¶ms
);
98 return req
.forward_request(key
, info
, max_response
, inbl
, outbl
);
101 class StreamObjData
: public RGWGetDataCB
{
104 explicit StreamObjData(rgw_obj
& _obj
) : obj(_obj
) {}
107 int RGWRESTConn::put_obj_init(const rgw_user
& uid
, rgw_obj
& obj
, uint64_t obj_size
,
108 map
<string
, bufferlist
>& attrs
, RGWRESTStreamWriteRequest
**req
)
111 int ret
= get_url(url
);
116 populate_params(params
, &uid
, self_zone_group
);
117 RGWRESTStreamWriteRequest
*wr
= new RGWRESTStreamWriteRequest(cct
, url
, NULL
, ¶ms
);
118 ret
= wr
->put_obj_init(key
, obj
, obj_size
, attrs
);
127 int RGWRESTConn::complete_request(RGWRESTStreamWriteRequest
*req
, string
& etag
, real_time
*mtime
)
129 int ret
= req
->complete(etag
, mtime
);
135 static void set_date_header(const real_time
*t
, map
<string
, string
>& headers
, const string
& header_name
)
141 utime_t tm
= utime_t(*t
);
143 headers
[header_name
] = s
.str();
147 static void set_header(T val
, map
<string
, string
>& headers
, const string
& header_name
)
151 headers
[header_name
] = s
.str();
155 int RGWRESTConn::get_obj(const rgw_user
& uid
, req_info
*info
/* optional */, rgw_obj
& obj
,
156 const real_time
*mod_ptr
, const real_time
*unmod_ptr
,
157 uint32_t mod_zone_id
, uint64_t mod_pg_ver
,
158 bool prepend_metadata
, bool get_op
, bool rgwx_stat
,
159 bool sync_manifest
, RGWGetDataCB
*cb
,
160 RGWRESTStreamRWRequest
**req
)
163 int ret
= get_url(url
);
168 populate_params(params
, &uid
, self_zone_group
);
169 if (prepend_metadata
) {
170 params
.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX
"prepend-metadata", self_zone_group
));
173 params
.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX
"stat", "true"));
176 params
.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX
"sync-manifest", ""));
178 if (!obj
.key
.instance
.empty()) {
179 const string
& instance
= obj
.key
.instance
;
180 params
.push_back(param_pair_t("versionId", instance
));
183 *req
= new RGWRESTStreamReadRequest(cct
, url
, cb
, NULL
, ¶ms
);
185 *req
= new RGWRESTStreamHeadRequest(cct
, url
, cb
, NULL
, ¶ms
);
187 map
<string
, string
> extra_headers
;
189 const auto& orig_map
= info
->env
->get_map();
191 /* add original headers that start with HTTP_X_AMZ_ */
192 static constexpr char SEARCH_AMZ_PREFIX
[] = "HTTP_X_AMZ_";
193 for (auto iter
= orig_map
.lower_bound(SEARCH_AMZ_PREFIX
); iter
!= orig_map
.end(); ++iter
) {
194 const string
& name
= iter
->first
;
195 if (name
== "HTTP_X_AMZ_DATE") /* dont forward date from original request */
197 if (name
.compare(0, strlen(SEARCH_AMZ_PREFIX
), SEARCH_AMZ_PREFIX
) != 0)
199 extra_headers
[iter
->first
] = iter
->second
;
203 set_date_header(mod_ptr
, extra_headers
, "HTTP_IF_MODIFIED_SINCE");
204 set_date_header(unmod_ptr
, extra_headers
, "HTTP_IF_UNMODIFIED_SINCE");
205 if (mod_zone_id
!= 0) {
206 set_header(mod_zone_id
, extra_headers
, "HTTP_DEST_ZONE_SHORT_ID");
208 if (mod_pg_ver
!= 0) {
209 set_header(mod_pg_ver
, extra_headers
, "HTTP_DEST_PG_VER");
212 int r
= (*req
)->send_request(key
, extra_headers
, obj
);
221 int RGWRESTConn::complete_request(RGWRESTStreamRWRequest
*req
, string
& etag
, real_time
*mtime
,
222 uint64_t *psize
, map
<string
, string
>& attrs
)
224 int ret
= req
->complete_request(etag
, mtime
, psize
, attrs
);
230 int RGWRESTConn::get_resource(const string
& resource
,
231 param_vec_t
*extra_params
,
232 map
<string
, string
> *extra_headers
,
234 bufferlist
*send_data
,
238 int ret
= get_url(url
);
245 params
.insert(params
.end(), extra_params
->begin(), extra_params
->end());
248 populate_params(params
, nullptr, self_zone_group
);
250 RGWStreamIntoBufferlist
cb(bl
);
252 RGWRESTStreamReadRequest
req(cct
, url
, &cb
, NULL
, ¶ms
);
254 map
<string
, string
> headers
;
256 headers
.insert(extra_headers
->begin(), extra_headers
->end());
259 ret
= req
.send_request(&key
, headers
, resource
, send_data
, mgr
);
261 ldout(cct
, 5) << __func__
<< ": send_request() resource=" << resource
<< " returned ret=" << ret
<< dendl
;
266 map
<string
, string
> attrs
;
267 return req
.complete_request(etag
, NULL
, NULL
, attrs
);
270 RGWRESTReadResource::RGWRESTReadResource(RGWRESTConn
*_conn
,
271 const string
& _resource
,
272 const rgw_http_param_pair
*pp
,
273 param_vec_t
*extra_headers
,
274 RGWHTTPManager
*_mgr
)
275 : cct(_conn
->get_ctx()), conn(_conn
), resource(_resource
),
276 params(make_param_list(pp
)), cb(bl
), mgr(_mgr
),
277 req(cct
, conn
->get_url(), &cb
, NULL
, NULL
)
279 init_common(extra_headers
);
282 RGWRESTReadResource::RGWRESTReadResource(RGWRESTConn
*_conn
,
283 const string
& _resource
,
284 param_vec_t
& _params
,
285 param_vec_t
*extra_headers
,
286 RGWHTTPManager
*_mgr
)
287 : cct(_conn
->get_ctx()), conn(_conn
), resource(_resource
), params(_params
),
288 cb(bl
), mgr(_mgr
), req(cct
, conn
->get_url(), &cb
, NULL
, NULL
)
290 init_common(extra_headers
);
293 void RGWRESTReadResource::init_common(param_vec_t
*extra_headers
)
295 populate_params(params
, nullptr, conn
->get_self_zonegroup());
298 headers
.insert(extra_headers
->begin(), extra_headers
->end());
301 req
.set_params(¶ms
);
304 int RGWRESTReadResource::read()
306 int ret
= req
.send_request(&conn
->get_key(), headers
, resource
, nullptr, mgr
);
308 ldout(cct
, 5) << __func__
<< ": send_request() resource=" << resource
<< " returned ret=" << ret
<< dendl
;
313 map
<string
, string
> attrs
;
314 return req
.complete_request(etag
, NULL
, NULL
, attrs
);
317 int RGWRESTReadResource::aio_read()
319 int ret
= req
.send_request(&conn
->get_key(), headers
, resource
, nullptr, mgr
);
321 ldout(cct
, 5) << __func__
<< ": send_request() resource=" << resource
<< " returned ret=" << ret
<< dendl
;
328 RGWRESTSendResource::RGWRESTSendResource(RGWRESTConn
*_conn
,
329 const string
& _method
,
330 const string
& _resource
,
331 const rgw_http_param_pair
*pp
,
332 param_vec_t
*extra_headers
,
333 RGWHTTPManager
*_mgr
)
334 : cct(_conn
->get_ctx()), conn(_conn
), method(_method
), resource(_resource
),
335 params(make_param_list(pp
)), cb(bl
), mgr(_mgr
),
336 req(cct
, method
.c_str(), conn
->get_url(), &cb
, NULL
, NULL
)
338 init_common(extra_headers
);
341 RGWRESTSendResource::RGWRESTSendResource(RGWRESTConn
*_conn
,
342 const string
& _method
,
343 const string
& _resource
,
345 param_vec_t
*extra_headers
,
346 RGWHTTPManager
*_mgr
)
347 : cct(_conn
->get_ctx()), conn(_conn
), method(_method
), resource(_resource
), params(params
),
348 cb(bl
), mgr(_mgr
), req(cct
, method
.c_str(), conn
->get_url(), &cb
, NULL
, NULL
)
350 init_common(extra_headers
);
353 void RGWRESTSendResource::init_common(param_vec_t
*extra_headers
)
355 populate_params(params
, nullptr, conn
->get_self_zonegroup());
358 headers
.insert(extra_headers
->begin(), extra_headers
->end());
361 req
.set_params(¶ms
);
364 int RGWRESTSendResource::send(bufferlist
& outbl
)
366 req
.set_outbl(outbl
);
367 int ret
= req
.send_request(&conn
->get_key(), headers
, resource
, nullptr, mgr
);
369 ldout(cct
, 5) << __func__
<< ": send_request() resource=" << resource
<< " returned ret=" << ret
<< dendl
;
374 map
<string
, string
> attrs
;
375 return req
.complete_request(etag
, NULL
, NULL
, attrs
);
378 int RGWRESTSendResource::aio_send(bufferlist
& outbl
)
380 req
.set_outbl(outbl
);
381 int ret
= req
.send_request(&conn
->get_key(), headers
, resource
, nullptr, mgr
);
383 ldout(cct
, 5) << __func__
<< ": send_request() resource=" << resource
<< " returned ret=" << ret
<< dendl
;