From: Oguzhan Ozmen Date: Wed, 21 Jan 2026 20:11:29 +0000 (+0000) Subject: rgw/http: introduce RGWEndpoint to carry url + connect_to (refactor) X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=2690e2a2cb8a98625be35127f24a57a89f0692f1;p=ceph.git rgw/http: introduce RGWEndpoint to carry url + connect_to (refactor) This commit is meant to be non-functional. Replace the "URL as plain string" plumbing with an RGWEndpoint value type that carries: - the URL string, and - optional per-request connect_to data for libcurl, - it also encapsulates related functions/methods This commit is intended to be non-functional: behavior should remain unchanged until callers populate connect_to. Signed-off-by: Oguzhan Ozmen --- diff --git a/src/rgw/driver/rados/rgw_sal_rados.cc b/src/rgw/driver/rados/rgw_sal_rados.cc index 841ac0a6ec0..1683fb71f1c 100644 --- a/src/rgw/driver/rados/rgw_sal_rados.cc +++ b/src/rgw/driver/rados/rgw_sal_rados.cc @@ -5398,7 +5398,7 @@ bool RadosZone::is_writeable() bool RadosZone::get_redirect_endpoint(std::string* endpoint) { if (local_zone) - return store->svc()->zone->get_redirect_zone_endpoint(endpoint); + return store->svc()->zone->get_redirect_zone_endpoint_url(endpoint); endpoint = &rgw_zone.redirect_zone; return true; diff --git a/src/rgw/rgw_http_client.cc b/src/rgw/rgw_http_client.cc index dc798943ee4..4cf35d09f26 100644 --- a/src/rgw/rgw_http_client.cc +++ b/src/rgw/rgw_http_client.cc @@ -294,7 +294,7 @@ void RGWIOProvider::assign_io(RGWIOIDProvider& io_id_provider, int io_type) RGWHTTPClient::RGWHTTPClient(CephContext *cct, const string& _method, - const string& _url) + const RGWEndpoint& _endpoint) : NoDoutPrefix(cct, dout_subsys), has_send_len(false), http_status(HTTP_STATUS_NOSTATUS), @@ -302,14 +302,14 @@ RGWHTTPClient::RGWHTTPClient(CephContext *cct, verify_ssl(cct->_conf->rgw_verify_ssl), cct(cct), method(_method), - url_orig(_url), - url(_url) { + endpoint_orig(_endpoint), + endpoint(_endpoint) { init(); } std::ostream& RGWHTTPClient::gen_prefix(std::ostream& out) const { - out << "http_client[" << method << "/" << url << "]"; + out << "http_client[" << method << "/" << endpoint.get_url() << "]"; return out; } @@ -326,6 +326,8 @@ void RGWHTTPClient::init() } } + const string& url = endpoint.get_url(); + auto pos = url.find("://"); if (pos == string::npos) { host = url; @@ -551,7 +553,7 @@ int RGWHTTPClient::process(const DoutPrefixProvider* dpp, optional_yield y) string RGWHTTPClient::to_str() { string method_str = (method.empty() ? "" : method); - string url_str = (url.empty() ? "" : url); + string url_str = (endpoint.get_url().empty() ? "" : endpoint.get_url()); return method_str + " " + url_str; } @@ -577,14 +579,15 @@ int RGWHTTPClient::init_request(rgw_http_req_data *_req_data) CURL *easy_handle = req_data->get_easy_handle(); - dout(20) << "sending request to " << url << dendl; + dout(20) << "sending request to url=" << endpoint.get_url() + << " connect_to=" << endpoint.get_connect_to() << dendl; curl_slist *h = headers_to_slist(headers); req_data->h = h; curl_easy_setopt(easy_handle, CURLOPT_CUSTOMREQUEST, method.c_str()); - curl_easy_setopt(easy_handle, CURLOPT_URL, url.c_str()); + curl_easy_setopt(easy_handle, CURLOPT_URL, endpoint.get_url().c_str()); curl_easy_setopt(easy_handle, CURLOPT_NOPROGRESS, 1L); curl_easy_setopt(easy_handle, CURLOPT_NOSIGNAL, 1L); curl_easy_setopt(easy_handle, CURLOPT_HEADERFUNCTION, receive_http_header); diff --git a/src/rgw/rgw_http_client.h b/src/rgw/rgw_http_client.h index 37b3991297a..6eaf1844401 100644 --- a/src/rgw/rgw_http_client.h +++ b/src/rgw/rgw_http_client.h @@ -20,6 +20,41 @@ void rgw_http_client_cleanup(); struct rgw_http_req_data; class RGWHTTPManager; +struct RGWEndpoint { +private: + std::string url; + std::string connect_to; + +public: + RGWEndpoint() = default; + + RGWEndpoint(const char* u) : RGWEndpoint(std::string(u)) {} + + RGWEndpoint(std::string u, std::string c = {}) + : url(std::move(u)), connect_to(std::move(c)) {} + + RGWEndpoint with_url(std::string new_url) const { + RGWEndpoint e = *this; + e.set_url(std::move(new_url)); + return e; + } + + void set_url(const std::string& _url) { url = _url; } + const std::string& get_url() const { return url; } + + void set_connect_to(const std::string& _connect_to) { connect_to = _connect_to; } + const std::string& get_connect_to() const { return connect_to; } + + void add_trailing_slash() { + if (! url.empty() && url.back() != '/') + append_to_url("/"); + } + + void append_to_url(const std::string& suffix) { + url.append(suffix); + } +}; + class RGWHTTPClient : public RGWIOProvider, public NoDoutPrefix { @@ -47,13 +82,12 @@ class RGWHTTPClient : public RGWIOProvider, std::atomic stopped { 0 }; - protected: CephContext *cct; std::string method; - std::string url_orig; - std::string url; + RGWEndpoint endpoint_orig; + RGWEndpoint endpoint; std::string protocol; std::string host; @@ -116,7 +150,7 @@ public: virtual ~RGWHTTPClient(); explicit RGWHTTPClient(CephContext *cct, const std::string& _method, - const std::string& _url); + const RGWEndpoint& _endpoint); std::ostream& gen_prefix(std::ostream& out) const override; @@ -170,12 +204,16 @@ public: int get_req_retcode(); + void set_endpoint(const RGWEndpoint& _endpoint) { + endpoint = _endpoint; + } + void set_url(const std::string& _url) { - url = _url; + endpoint.set_url(_url); } - const std::string& get_url_orig() const { - return url_orig; + const RGWEndpoint& get_endpoint_orig() const { + return endpoint_orig; } void set_method(const std::string& _method) { @@ -212,9 +250,9 @@ public: RGWHTTPHeadersCollector(CephContext * const cct, const std::string& method, - const std::string& url, + const RGWEndpoint& endpoint, const header_spec_t &relevant_headers) - : RGWHTTPClient(cct, method, url), + : RGWHTTPClient(cct, method, endpoint), relevant_headers(relevant_headers) { } @@ -244,21 +282,21 @@ class RGWHTTPTransceiver : public RGWHTTPHeadersCollector { public: RGWHTTPTransceiver(CephContext * const cct, const std::string& method, - const std::string& url, + const RGWEndpoint& endpoint, bufferlist * const read_bl, const header_spec_t intercept_headers = {}) - : RGWHTTPHeadersCollector(cct, method, url, intercept_headers), + : RGWHTTPHeadersCollector(cct, method, endpoint, intercept_headers), read_bl(read_bl), post_data_index(0) { } RGWHTTPTransceiver(CephContext * const cct, const std::string& method, - const std::string& url, + const RGWEndpoint& endpoint, bufferlist * const read_bl, const bool verify_ssl, const header_spec_t intercept_headers = {}) - : RGWHTTPHeadersCollector(cct, method, url, intercept_headers), + : RGWHTTPHeadersCollector(cct, method, endpoint, intercept_headers), read_bl(read_bl), post_data_index(0) { set_verify_ssl(verify_ssl); diff --git a/src/rgw/rgw_keystone.h b/src/rgw/rgw_keystone.h index 2dc17dfeabe..e183b9d3965 100644 --- a/src/rgw/rgw_keystone.h +++ b/src/rgw/rgw_keystone.h @@ -89,9 +89,9 @@ public: public: RGWKeystoneHTTPTransceiver(CephContext * const cct, const std::string& method, - const std::string& url, + const RGWEndpoint& endpoint, bufferlist * const token_body_bl) - : RGWHTTPTransceiver(cct, method, url, token_body_bl, + : RGWHTTPTransceiver(cct, method, endpoint, token_body_bl, cct->_conf->rgw_keystone_verify_ssl, { "X-Subject-Token" }) { } diff --git a/src/rgw/rgw_opa.cc b/src/rgw/rgw_opa.cc index c096fd0bd37..6840227cffe 100644 --- a/src/rgw/rgw_opa.cc +++ b/src/rgw/rgw_opa.cc @@ -28,7 +28,7 @@ int rgw_opa_authorize(RGWOp *& op, int ret; bufferlist bl; - RGWHTTPTransceiver req(s->cct, "POST", opa_url.c_str(), &bl); + RGWHTTPTransceiver req(s->cct, "POST", opa_url, &bl); /* set required headers for OPA request */ req.append_header("X-Auth-Token", opa_token); diff --git a/src/rgw/rgw_rest_client.cc b/src/rgw/rgw_rest_client.cc index 8cd692aa9dc..9317587ac78 100644 --- a/src/rgw/rgw_rest_client.cc +++ b/src/rgw/rgw_rest_client.cc @@ -425,7 +425,7 @@ auto RGWRESTSimpleRequest::forward_request(const DoutPrefixProvider *dpp, const string params_str; get_params_str(new_info.args.get_params(), params_str); - string new_url = url; + string new_url = endpoint.get_url(); string& resource = new_info.request_uri; string new_resource = resource; if (new_url[new_url.size() - 1] == '/' && resource[0] == '/') { @@ -446,7 +446,7 @@ auto RGWRESTSimpleRequest::forward_request(const DoutPrefixProvider *dpp, const } method = new_info.method; - url = new_url; + endpoint.set_url(new_url); std::ignore = process(dpp, y); @@ -564,7 +564,7 @@ RGWRESTGenerateHTTPHeaders::RGWRESTGenerateHTTPHeaders(CephContext *_cct, RGWEnv } void RGWRESTGenerateHTTPHeaders::init(const string& _method, const string& host, - const string& resource_prefix, const string& _url, + const string& resource_prefix, const RGWEndpoint& _endpoint, const string& resource, const param_vec_t& params, std::optional api_name) { @@ -581,7 +581,7 @@ void RGWRESTGenerateHTTPHeaders::init(const string& _method, const string& host, url_encode(iter->second, encode_slash)); } - url = _url + resource + params_str; + endpoint = _endpoint.with_url(_endpoint.get_url() + resource + params_str); const std::string date_str = get_gmt_date_str(); new_env->set("HTTP_DATE", date_str.c_str()); @@ -685,32 +685,29 @@ void RGWRESTStreamS3PutObj::send_init(const rgw_obj& obj) { string resource_str; string resource; - string new_url = url; + RGWEndpoint new_endpoint = endpoint; string new_host = host; const auto& bucket_name = obj.bucket.name; if (host_style == VirtualStyle) { resource_str = obj.get_oid(); - - new_url = protocol + "://" + bucket_name + "." + host; + new_endpoint.set_url(protocol + "://" + bucket_name + "." + host); new_host = bucket_name + "." + new_host; } else { resource_str = bucket_name + "/" + obj.get_oid(); } + new_endpoint.add_trailing_slash(); //do not encode slash in object key name url_encode(resource_str, resource, false); - if (new_url[new_url.size() - 1] != '/') - new_url.append("/"); - - ldpp_dout(this, 20) << __func__ << "(): host = " << host << " , resource = " << resource << " , new_host = " << new_host << " , new_url = " << new_url << dendl; + ldpp_dout(this, 20) << __func__ << "(): host = " << host << " , resource = " << resource << " , new_host = " << new_host << " , new_url = " << new_endpoint.get_url() << dendl; method = "PUT"; - headers_gen.init(method, new_host, resource_prefix, new_url, resource, params, api_name); + headers_gen.init(method, new_host, resource_prefix, new_endpoint, resource, params, api_name); - url = headers_gen.get_url(); + endpoint = headers_gen.get_endpoint(); } void RGWRESTStreamS3PutObj::send_ready(const DoutPrefixProvider *dpp, RGWAccessKey& key, map& rgw_attrs) @@ -825,10 +822,10 @@ int RGWRESTStreamRWRequest::send_prepare(const DoutPrefixProvider *dpp, RGWAcces int RGWRESTStreamRWRequest::do_send_prepare(const DoutPrefixProvider *dpp, RGWAccessKey *key, map& extra_headers, const string& resource, bufferlist *send_data) { - string new_url = url; - if (!new_url.empty() && new_url.back() != '/') - new_url.append("/"); - + RGWEndpoint new_endpoint = endpoint; + + new_endpoint.add_trailing_slash(); + string new_resource; string bucket_name; string old_resource = resource; @@ -849,7 +846,7 @@ int RGWRESTStreamRWRequest::do_send_prepare(const DoutPrefixProvider *dpp, RGWAc } if (host_style == VirtualStyle) { - new_url = protocol + "://" + bucket_name + "." + host; + new_endpoint.set_url(protocol + "://" + bucket_name + "." + host); if(pos == string::npos) { new_resource = ""; } else { @@ -857,15 +854,13 @@ int RGWRESTStreamRWRequest::do_send_prepare(const DoutPrefixProvider *dpp, RGWAc } new_host = bucket_name + "." + host; } - - if (new_url[new_url.size() - 1] != '/') - new_url.append("/"); + new_endpoint.add_trailing_slash(); headers_gen.emplace(cct, &new_env, &new_info); - ldpp_dout(this, 20) << __func__ << "(): host = " << host << " , resource = " << resource << " , new_host = " << new_host << " , new_url = " << new_url << " , new_resource = " << new_resource << dendl; + ldpp_dout(this, 20) << __func__ << "(): host = " << host << " , resource = " << resource << " , new_host = " << new_host << " , new_url = " << new_endpoint.get_url() << " , new_resource = " << new_resource << dendl; - headers_gen->init(method, new_host, resource_prefix, new_url, new_resource, params, api_name); + headers_gen->init(method, new_host, resource_prefix, new_endpoint, new_resource, params, api_name); headers_gen->set_http_attrs(extra_headers); @@ -880,7 +875,7 @@ int RGWRESTStreamRWRequest::do_send_prepare(const DoutPrefixProvider *dpp, RGWAc } method = new_info.method; - url = headers_gen->get_url(); + endpoint = headers_gen->get_endpoint(); return 0; } diff --git a/src/rgw/rgw_rest_client.h b/src/rgw/rgw_rest_client.h index 2d30e8313f6..e9458f44f7e 100644 --- a/src/rgw/rgw_rest_client.h +++ b/src/rgw/rgw_rest_client.h @@ -29,8 +29,8 @@ protected: void get_params_str(std::map& extra_args, std::string& dest); public: - RGWHTTPSimpleRequest(CephContext *_cct, const std::string& _method, const std::string& _url, - param_vec_t *_headers, param_vec_t *_params) : RGWHTTPClient(_cct, _method, _url), + RGWHTTPSimpleRequest(CephContext *_cct, const std::string& _method, const RGWEndpoint& _endpoint, + param_vec_t *_headers, param_vec_t *_params) : RGWHTTPClient(_cct, _method, _endpoint), http_status(0), status(0), send_iter(NULL), max_response(0) { @@ -63,9 +63,9 @@ public: class RGWRESTSimpleRequest : public RGWHTTPSimpleRequest { std::optional api_name; public: - RGWRESTSimpleRequest(CephContext *_cct, const std::string& _method, const std::string& _url, + RGWRESTSimpleRequest(CephContext *_cct, const std::string& _method, const RGWEndpoint& _endpoint, param_vec_t *_headers, param_vec_t *_params, - std::optional _api_name) : RGWHTTPSimpleRequest(_cct, _method, _url, _headers, _params), api_name(_api_name) {} + std::optional _api_name) : RGWHTTPSimpleRequest(_cct, _method, _endpoint, _headers, _params), api_name(_api_name) {} // return the http status of the response or an error code from the transport auto forward_request(const DoutPrefixProvider *dpp, const RGWAccessKey& key, const req_info& info, size_t max_response, bufferlist *inbl, bufferlist *outbl, optional_yield y, std::string service="") @@ -86,13 +86,13 @@ class RGWRESTGenerateHTTPHeaders : public DoutPrefix { std::string region; std::string service; std::string method; - std::string url; + RGWEndpoint endpoint; std::string resource; public: RGWRESTGenerateHTTPHeaders(CephContext *_cct, RGWEnv *_env, req_info *_info); void init(const std::string& method, const std::string& host, - const std::string& resource_prefix, const std::string& url, + const std::string& resource_prefix, const RGWEndpoint& endpoint, const std::string& resource, const param_vec_t& params, std::optional api_name); void set_extra_headers(const std::map& extra_headers); @@ -101,7 +101,7 @@ public: void set_policy(const RGWAccessControlPolicy& policy); int sign(const DoutPrefixProvider *dpp, RGWAccessKey& key, const bufferlist *opt_content); - const std::string& get_url() { return url; } + const RGWEndpoint& get_endpoint() { return endpoint; } }; class RGWHTTPStreamRWRequest : public RGWHTTPSimpleRequest { @@ -145,11 +145,11 @@ public: } }; - RGWHTTPStreamRWRequest(CephContext *_cct, const std::string& _method, const std::string& _url, - param_vec_t *_headers, param_vec_t *_params) : RGWHTTPSimpleRequest(_cct, _method, _url, _headers, _params) { + RGWHTTPStreamRWRequest(CephContext *_cct, const std::string& _method, const RGWEndpoint& _endpoint, + param_vec_t *_headers, param_vec_t *_params) : RGWHTTPSimpleRequest(_cct, _method, _endpoint, _headers, _params) { } - RGWHTTPStreamRWRequest(CephContext *_cct, const std::string& _method, const std::string& _url, ReceiveCB *_cb, - param_vec_t *_headers, param_vec_t *_params) : RGWHTTPSimpleRequest(_cct, _method, _url, _headers, _params), + RGWHTTPStreamRWRequest(CephContext *_cct, const std::string& _method, const RGWEndpoint& _endpoint, ReceiveCB *_cb, + param_vec_t *_headers, param_vec_t *_params) : RGWHTTPSimpleRequest(_cct, _method, _endpoint, _headers, _params), cb(_cb) { } virtual ~RGWHTTPStreamRWRequest() override {} @@ -192,10 +192,10 @@ protected: std::optional api_name; HostStyle host_style; public: - RGWRESTStreamRWRequest(CephContext *_cct, const std::string& _method, const std::string& _url, RGWHTTPStreamRWRequest::ReceiveCB *_cb, + RGWRESTStreamRWRequest(CephContext *_cct, const std::string& _method, const RGWEndpoint& _endpoint, RGWHTTPStreamRWRequest::ReceiveCB *_cb, param_vec_t *_headers, param_vec_t *_params, std::optional _api_name, HostStyle _host_style = PathStyle) : - RGWHTTPStreamRWRequest(_cct, _method, _url, _cb, _headers, _params), + RGWHTTPStreamRWRequest(_cct, _method, _endpoint, _cb, _headers, _params), new_info(_cct, &new_env), api_name(_api_name), host_style(_host_style) { } @@ -216,24 +216,24 @@ private: class RGWRESTStreamReadRequest : public RGWRESTStreamRWRequest { public: - RGWRESTStreamReadRequest(CephContext *_cct, const std::string& _url, ReceiveCB *_cb, param_vec_t *_headers, + RGWRESTStreamReadRequest(CephContext *_cct, const RGWEndpoint& _endpoint, ReceiveCB *_cb, param_vec_t *_headers, param_vec_t *_params, std::optional _api_name, - HostStyle _host_style = PathStyle) : RGWRESTStreamRWRequest(_cct, "GET", _url, _cb, _headers, _params, _api_name, _host_style) {} + HostStyle _host_style = PathStyle) : RGWRESTStreamRWRequest(_cct, "GET", _endpoint, _cb, _headers, _params, _api_name, _host_style) {} }; class RGWRESTStreamHeadRequest : public RGWRESTStreamRWRequest { public: - RGWRESTStreamHeadRequest(CephContext *_cct, const std::string& _url, ReceiveCB *_cb, param_vec_t *_headers, - param_vec_t *_params, std::optional _api_name) : RGWRESTStreamRWRequest(_cct, "HEAD", _url, _cb, _headers, _params, _api_name) {} + RGWRESTStreamHeadRequest(CephContext *_cct, const RGWEndpoint& _endpoint, ReceiveCB *_cb, param_vec_t *_headers, + param_vec_t *_params, std::optional _api_name) : RGWRESTStreamRWRequest(_cct, "HEAD", _endpoint, _cb, _headers, _params, _api_name) {} }; class RGWRESTStreamSendRequest : public RGWRESTStreamRWRequest { public: RGWRESTStreamSendRequest(CephContext *_cct, const std::string& method, - const std::string& _url, + const RGWEndpoint& _endpoint, ReceiveCB *_cb, param_vec_t *_headers, param_vec_t *_params, std::optional _api_name, - HostStyle _host_style = PathStyle) : RGWRESTStreamRWRequest(_cct, method, _url, _cb, _headers, _params, _api_name, _host_style) {} + HostStyle _host_style = PathStyle) : RGWRESTStreamRWRequest(_cct, method, _endpoint, _cb, _headers, _params, _api_name, _host_style) {} }; class RGWRESTStreamS3PutObj : public RGWHTTPStreamRWRequest { @@ -244,9 +244,9 @@ class RGWRESTStreamS3PutObj : public RGWHTTPStreamRWRequest { req_info new_info; RGWRESTGenerateHTTPHeaders headers_gen; public: - RGWRESTStreamS3PutObj(CephContext *_cct, const std::string& _method, const std::string& _url, param_vec_t *_headers, + RGWRESTStreamS3PutObj(CephContext *_cct, const std::string& _method, const RGWEndpoint& _endpoint, param_vec_t *_headers, param_vec_t *_params, std::optional _api_name, - HostStyle _host_style) : RGWHTTPStreamRWRequest(_cct, _method, _url, nullptr, _headers, _params), + HostStyle _host_style) : RGWHTTPStreamRWRequest(_cct, _method, _endpoint, nullptr, _headers, _params), api_name(_api_name), host_style(_host_style), out_cb(NULL), new_info(cct, &new_env), headers_gen(_cct, &new_env, &new_info) {} ~RGWRESTStreamS3PutObj() override; diff --git a/src/rgw/rgw_rest_conn.cc b/src/rgw/rgw_rest_conn.cc index aab716e47a4..0f32cc201f1 100644 --- a/src/rgw/rgw_rest_conn.cc +++ b/src/rgw/rgw_rest_conn.cc @@ -78,7 +78,7 @@ RGWRESTConn& RGWRESTConn::operator=(RGWRESTConn&& other) return *this; } -int RGWRESTConn::get_url(string& endpoint) +int RGWRESTConn::get_endpoint(RGWEndpoint& endpoint) { if (endpoints.empty()) { ldout(cct, 0) << "ERROR: endpoints not configured for upstream zone" << dendl; @@ -88,15 +88,17 @@ int RGWRESTConn::get_url(string& endpoint) size_t num = 0; while (num < endpoints.size()) { int i = ++counter; - endpoint = endpoints[i % endpoints.size()]; - if (endpoints_status.find(endpoint) == endpoints_status.end()) { - ldout(cct, 1) << "ERROR: missing status for endpoint " << endpoint << dendl; + const string& ep_url = endpoints[i % endpoints.size()]; + endpoint.set_url(ep_url); + + if (endpoints_status.find(ep_url) == endpoints_status.end()) { + ldout(cct, 1) << "ERROR: missing status for endpoint " << ep_url << dendl; num++; continue; } - const auto& upd_time = endpoints_status[endpoint].load(); + const auto& upd_time = endpoints_status[ep_url].load(); if (ceph::real_clock::is_zero(upd_time)) { break; @@ -104,15 +106,15 @@ int RGWRESTConn::get_url(string& endpoint) auto diff = ceph::to_seconds(ceph::real_clock::now() - upd_time); - ldout(cct, 20) << "endpoint url=" << endpoint + ldout(cct, 20) << "endpoint url=" << ep_url << " last endpoint status update time=" << ceph::real_clock::to_double(upd_time) << " diff=" << diff << dendl; static constexpr uint32_t CONN_STATUS_EXPIRE_SECS = 2; if (diff >= CONN_STATUS_EXPIRE_SECS) { - endpoints_status[endpoint].store(ceph::real_clock::zero()); - ldout(cct, 10) << "endpoint " << endpoint << " unconnectable status expired. mark it connectable" << dendl; + endpoints_status[ep_url].store(ceph::real_clock::zero()); + ldout(cct, 10) << "endpoint " << endpoint.get_url() << " unconnectable status expired. mark it connectable" << dendl; break; } num++; @@ -122,29 +124,32 @@ int RGWRESTConn::get_url(string& endpoint) ldout(cct, 5) << "ERROR: no valid endpoint" << dendl; return -EINVAL; } - ldout(cct, 20) << "get_url picked endpoint=" << endpoint << dendl; + ldout(cct, 20) << "get_endpoint picked url=" << endpoint.get_url() + << " connect_to=" << endpoint.get_connect_to() << dendl; return 0; } -string RGWRESTConn::get_url() +RGWEndpoint RGWRESTConn::get_endpoint() { - string endpoint; - get_url(endpoint); + RGWEndpoint endpoint; + get_endpoint(endpoint); return endpoint; } -void RGWRESTConn::set_url_unconnectable(const std::string& endpoint) +void RGWRESTConn::set_endpoint_unconnectable(const RGWEndpoint& endpoint) { - if (endpoint.empty() || endpoints_status.find(endpoint) == endpoints_status.end()) { + const string& url = endpoint.get_url(); + + if (url.empty() || endpoints_status.find(url) == endpoints_status.end()) { ldout(cct, 0) << "ERROR: endpoint is not a valid or doesn't have status. endpoint=" - << endpoint << dendl; + << url << dendl; return; } - endpoints_status[endpoint].store(ceph::real_clock::now()); + endpoints_status[url].store(ceph::real_clock::now()); - ldout(cct, 10) << "set endpoint unconnectable. url=" << endpoint << dendl; + ldout(cct, 10) << "set endpoint unconnectable. url=" << url << dendl; } void RGWRESTConn::populate_params(param_vec_t& params, const rgw_owner* uid, const string& zonegroup) @@ -160,21 +165,22 @@ auto RGWRESTConn::forward(const DoutPrefixProvider *dpp, const rgw_owner& uid, { static constexpr int NUM_ENPOINT_IOERROR_RETRIES = 20; for (int tries = 0; tries < NUM_ENPOINT_IOERROR_RETRIES; tries++) { - string url; - int ret = get_url(url); + RGWEndpoint endpoint; + int ret = get_endpoint(endpoint); if (ret < 0) { return tl::unexpected(ret); } + param_vec_t params; populate_params(params, &uid, self_zone_group); - RGWRESTSimpleRequest req(cct, info.method, url, NULL, ¶ms, api_name); + RGWRESTSimpleRequest req(cct, info.method, endpoint, NULL, ¶ms, api_name); auto result = req.forward_request(dpp, key, info, max_response, inbl, outbl, y); if (result) { return result; } else if (result.error() != -EIO) { return result; } - set_url_unconnectable(url); + set_endpoint_unconnectable(endpoint); if (tries < NUM_ENPOINT_IOERROR_RETRIES - 1) { ldpp_dout(dpp, 20) << __func__ << "(): failed to forward request. retries=" << tries << dendl; } @@ -189,14 +195,15 @@ auto RGWRESTConn::forward_iam(const DoutPrefixProvider *dpp, const req_info& inf { static constexpr int NUM_ENPOINT_IOERROR_RETRIES = 20; for (int tries = 0; tries < NUM_ENPOINT_IOERROR_RETRIES; tries++) { - string url; - int ret = get_url(url); + RGWEndpoint endpoint; + int ret = get_endpoint(endpoint); if (ret < 0) { return tl::unexpected(ret); } + param_vec_t params; std::string service = "iam"; - RGWRESTSimpleRequest req(cct, info.method, url, NULL, ¶ms, api_name); + RGWRESTSimpleRequest req(cct, info.method, endpoint, NULL, ¶ms, api_name); // coverity[uninit_use_in_call:SUPPRESS] auto result = req.forward_request(dpp, key, info, max_response, inbl, outbl, y, service); if (result) { @@ -204,7 +211,7 @@ auto RGWRESTConn::forward_iam(const DoutPrefixProvider *dpp, const req_info& inf } else if (result.error() != -EIO) { return result; } - set_url_unconnectable(url); + set_endpoint_unconnectable(endpoint); if (tries < NUM_ENPOINT_IOERROR_RETRIES - 1) { ldpp_dout(dpp, 20) << __func__ << "(): failed to forward request. retries=" << tries << dendl; } @@ -214,8 +221,8 @@ auto RGWRESTConn::forward_iam(const DoutPrefixProvider *dpp, const req_info& inf int RGWRESTConn::put_obj_send_init(const rgw_obj& obj, const rgw_http_param_pair *extra_params, RGWRESTStreamS3PutObj **req) { - string url; - int ret = get_url(url); + RGWEndpoint endpoint; + int ret = get_endpoint(endpoint); if (ret < 0) return ret; @@ -226,7 +233,7 @@ int RGWRESTConn::put_obj_send_init(const rgw_obj& obj, const rgw_http_param_pair append_param_list(params, extra_params); } - RGWRESTStreamS3PutObj *wr = new RGWRESTStreamS3PutObj(cct, "PUT", url, NULL, ¶ms, api_name, host_style); + RGWRESTStreamS3PutObj *wr = new RGWRESTStreamS3PutObj(cct, "PUT", endpoint, NULL, ¶ms, api_name, host_style); // coverity[uninit_use_in_call:SUPPRESS] wr->send_init(obj); *req = wr; @@ -237,14 +244,14 @@ int RGWRESTConn::put_obj_async_init(const DoutPrefixProvider *dpp, const rgw_own map& attrs, RGWRESTStreamS3PutObj **req) { - string url; - int ret = get_url(url); + RGWEndpoint endpoint; + int ret = get_endpoint(endpoint); if (ret < 0) return ret; param_vec_t params; populate_params(params, &uid, self_zone_group); - RGWRESTStreamS3PutObj *wr = new RGWRESTStreamS3PutObj(cct, "PUT", url, NULL, ¶ms, api_name, host_style); + RGWRESTStreamS3PutObj *wr = new RGWRESTStreamS3PutObj(cct, "PUT", endpoint, NULL, ¶ms, api_name, host_style); // coverity[uninit_use_in_call:SUPPRESS] wr->put_obj_init(dpp, key, obj, attrs); *req = wr; @@ -258,7 +265,7 @@ int RGWRESTConn::complete_request(const DoutPrefixProvider* dpp, int ret = req->complete_request(dpp, y, &etag, mtime); if (ret == -EIO) { ldout(cct, 5) << __func__ << ": complete_request() returned ret=" << ret << dendl; - set_url_unconnectable(req->get_url_orig()); + set_endpoint_unconnectable(req->get_endpoint_orig()); } delete req; @@ -319,8 +326,8 @@ int RGWRESTConn::get_obj(const DoutPrefixProvider *dpp, const rgw_owner *uid, int RGWRESTConn::get_obj(const DoutPrefixProvider *dpp, const rgw_obj& obj, const get_obj_params& in_params, bool send, RGWRESTStreamRWRequest **req) { - string url; - int ret = get_url(url); + RGWEndpoint endpoint; + int ret = get_endpoint(endpoint); if (ret < 0) return ret; @@ -351,9 +358,9 @@ int RGWRESTConn::get_obj(const DoutPrefixProvider *dpp, const rgw_obj& obj, cons params.push_back(param_pair_t("versionId", obj.key.instance)); } if (in_params.get_op) { - *req = new RGWRESTStreamReadRequest(cct, url, in_params.cb, NULL, ¶ms, api_name, host_style); + *req = new RGWRESTStreamReadRequest(cct, endpoint, in_params.cb, NULL, ¶ms, api_name, host_style); } else { - *req = new RGWRESTStreamHeadRequest(cct, url, in_params.cb, NULL, ¶ms, api_name); + *req = new RGWRESTStreamHeadRequest(cct, endpoint, in_params.cb, NULL, ¶ms, api_name); } map extra_headers; if (in_params.info) { @@ -421,7 +428,7 @@ int RGWRESTConn::complete_request(const DoutPrefixProvider* dpp, int ret = req->complete_request(dpp, y, etag, mtime, psize, pattrs, pheaders); if (ret == -EIO) { ldout(cct, 5) << __func__ << ": complete_request() returned ret=" << ret << dendl; - set_url_unconnectable(req->get_url_orig()); + set_endpoint_unconnectable(req->get_endpoint_orig()); } delete req; @@ -441,8 +448,8 @@ int RGWRESTConn::get_resource(const DoutPrefixProvider *dpp, static constexpr int NUM_ENPOINT_IOERROR_RETRIES = 20; for (int tries = 0; tries < NUM_ENPOINT_IOERROR_RETRIES; tries++) { - string url; - ret = get_url(url); + RGWEndpoint endpoint; + ret = get_endpoint(endpoint); if (ret < 0) return ret; @@ -456,7 +463,7 @@ int RGWRESTConn::get_resource(const DoutPrefixProvider *dpp, RGWStreamIntoBufferlist cb(bl); - RGWRESTStreamReadRequest req(cct, url, &cb, NULL, ¶ms, api_name, host_style); + RGWRESTStreamReadRequest req(cct, endpoint, &cb, NULL, ¶ms, api_name, host_style); map headers; if (extra_headers) { @@ -471,7 +478,7 @@ int RGWRESTConn::get_resource(const DoutPrefixProvider *dpp, ret = req.complete_request(dpp, y); if (ret == -EIO) { - set_url_unconnectable(url); + set_endpoint_unconnectable(endpoint); if (tries < NUM_ENPOINT_IOERROR_RETRIES - 1) { ldpp_dout(dpp, 20) << __func__ << "(): failed to get resource. retries=" << tries << dendl; continue; @@ -495,8 +502,8 @@ int RGWRESTConn::send_resource(const DoutPrefixProvider *dpp, const std::string& static constexpr int NUM_ENPOINT_IOERROR_RETRIES = 20; for (int tries = 0; tries < NUM_ENPOINT_IOERROR_RETRIES; tries++) { - std::string url; - ret = get_url(url); + RGWEndpoint endpoint; + ret = get_endpoint(endpoint); if (ret < 0) return ret; @@ -510,7 +517,7 @@ int RGWRESTConn::send_resource(const DoutPrefixProvider *dpp, const std::string& RGWStreamIntoBufferlist cb(bl); - RGWRESTStreamSendRequest req(cct, method, url, &cb, NULL, ¶ms, api_name, host_style); + RGWRESTStreamSendRequest req(cct, method, endpoint, &cb, NULL, ¶ms, api_name, host_style); std::map headers; if (extra_headers) { @@ -525,7 +532,7 @@ int RGWRESTConn::send_resource(const DoutPrefixProvider *dpp, const std::string& ret = req.complete_request(dpp, y); if (ret == -EIO) { - set_url_unconnectable(url); + set_endpoint_unconnectable(endpoint); if (tries < NUM_ENPOINT_IOERROR_RETRIES - 1) { ldpp_dout(dpp, 20) << __func__ << "(): failed to send resource. retries=" << tries << dendl; continue; @@ -547,7 +554,7 @@ RGWRESTReadResource::RGWRESTReadResource(RGWRESTConn *_conn, RGWHTTPManager *_mgr) : cct(_conn->get_ctx()), conn(_conn), resource(_resource), params(make_param_list(pp)), cb(bl), mgr(_mgr), - req(cct, conn->get_url(), &cb, NULL, NULL, _conn->get_api_name()) + req(cct, conn->get_endpoint(), &cb, NULL, NULL, _conn->get_api_name()) { init_common(extra_headers); } @@ -558,7 +565,7 @@ RGWRESTReadResource::RGWRESTReadResource(RGWRESTConn *_conn, param_vec_t *extra_headers, RGWHTTPManager *_mgr) : cct(_conn->get_ctx()), conn(_conn), resource(_resource), params(_params), - cb(bl), mgr(_mgr), req(cct, conn->get_url(), &cb, NULL, NULL, _conn->get_api_name()) + cb(bl), mgr(_mgr), req(cct, conn->get_endpoint(), &cb, NULL, NULL, _conn->get_api_name()) { init_common(extra_headers); } @@ -584,7 +591,7 @@ int RGWRESTReadResource::read(const DoutPrefixProvider *dpp, optional_yield y) ret = req.complete_request(dpp, y); if (ret == -EIO) { - conn->set_url_unconnectable(req.get_url_orig()); + conn->set_endpoint_unconnectable(req.get_endpoint_orig()); ldpp_dout(dpp, 20) << __func__ << ": complete_request() returned ret=" << ret << dendl; } @@ -610,7 +617,7 @@ RGWRESTSendResource::RGWRESTSendResource(RGWRESTConn *_conn, RGWHTTPManager *_mgr) : cct(_conn->get_ctx()), conn(_conn), method(_method), resource(_resource), params(make_param_list(pp)), cb(bl), mgr(_mgr), - req(cct, method.c_str(), conn->get_url(), &cb, NULL, NULL, _conn->get_api_name(), _conn->get_host_style()) + req(cct, method.c_str(), conn->get_endpoint(), &cb, NULL, NULL, _conn->get_api_name(), _conn->get_host_style()) { init_common(extra_headers); } @@ -622,7 +629,7 @@ RGWRESTSendResource::RGWRESTSendResource(RGWRESTConn *_conn, param_vec_t *extra_headers, RGWHTTPManager *_mgr) : cct(_conn->get_ctx()), conn(_conn), method(_method), resource(_resource), params(params), - cb(bl), mgr(_mgr), req(cct, method.c_str(), conn->get_url(), &cb, NULL, NULL, _conn->get_api_name(), _conn->get_host_style()) + cb(bl), mgr(_mgr), req(cct, method.c_str(), conn->get_endpoint(), &cb, NULL, NULL, _conn->get_api_name(), _conn->get_host_style()) { init_common(extra_headers); } @@ -651,7 +658,7 @@ int RGWRESTSendResource::send(const DoutPrefixProvider *dpp, bufferlist& outbl, ret = req.complete_request(dpp, y); if (ret == -EIO) { - conn->set_url_unconnectable(req.get_url_orig()); + conn->set_endpoint_unconnectable(req.get_endpoint_orig()); ldpp_dout(dpp, 20) << __func__ << ": complete_request() returned ret=" << ret << dendl; } diff --git a/src/rgw/rgw_rest_conn.h b/src/rgw/rgw_rest_conn.h index 0672e5bc138..5042add9d50 100644 --- a/src/rgw/rgw_rest_conn.h +++ b/src/rgw/rgw_rest_conn.h @@ -101,9 +101,9 @@ public: RGWRESTConn& operator=(RGWRESTConn&& other); virtual ~RGWRESTConn() = default; - int get_url(std::string& endpoint); - std::string get_url(); - void set_url_unconnectable(const std::string& endpoint); + int get_endpoint(RGWEndpoint& endpoint); + RGWEndpoint get_endpoint(); + void set_endpoint_unconnectable(const RGWEndpoint& endpoint); const std::string& get_self_zonegroup() { return self_zone_group; } @@ -358,7 +358,7 @@ public: int ret = req.wait(dpp, y); if (ret < 0) { if (ret == -ERR_INTERNAL_ERROR) { - conn->set_url_unconnectable(req.get_url_orig()); + conn->set_endpoint_unconnectable(req.get_endpoint_orig()); } return ret; } @@ -414,7 +414,7 @@ int RGWRESTReadResource::wait(const DoutPrefixProvider* dpp, T *dest, int ret = req.wait(dpp, y); if (ret < 0) { if (ret == -ERR_INTERNAL_ERROR) { - conn->set_url_unconnectable(req.get_url_orig()); + conn->set_endpoint_unconnectable(req.get_endpoint_orig()); } return ret; } @@ -489,7 +489,7 @@ public: *pbl = bl; if (ret == -ERR_INTERNAL_ERROR) { - conn->set_url_unconnectable(req.get_url_orig()); + conn->set_endpoint_unconnectable(req.get_endpoint_orig()); } if (ret < 0 && err_result ) { @@ -510,7 +510,7 @@ int RGWRESTSendResource::wait(const DoutPrefixProvider* dpp, T *dest, { int ret = req.wait(dpp, y); if (ret == -ERR_INTERNAL_ERROR) { - conn->set_url_unconnectable(req.get_url_orig()); + conn->set_endpoint_unconnectable(req.get_endpoint_orig()); } if (ret >= 0) { diff --git a/src/rgw/services/svc_zone.cc b/src/rgw/services/svc_zone.cc index 1bce12e934b..055a5f6fe69 100644 --- a/src/rgw/services/svc_zone.cc +++ b/src/rgw/services/svc_zone.cc @@ -671,7 +671,7 @@ int RGWSI_Zone::select_bucket_placement(const DoutPrefixProvider *dpp, const RGW pselected_rule, rule_info, y); } -bool RGWSI_Zone::get_redirect_zone_endpoint(string *endpoint) +bool RGWSI_Zone::get_redirect_zone_endpoint_url(string *url) { if (zone_public_config->redirect_zone.empty()) { return false; @@ -685,11 +685,13 @@ bool RGWSI_Zone::get_redirect_zone_endpoint(string *endpoint) RGWRESTConn *conn = iter->second; - int ret = conn->get_url(*endpoint); + RGWEndpoint ep{*url}; + int ret = conn->get_endpoint(ep); if (ret < 0) { ldout(cct, 0) << "ERROR: redirect zone, conn->get_endpoint() returned ret=" << ret << dendl; return false; } + *url = ep.get_url(); return true; } diff --git a/src/rgw/services/svc_zone.h b/src/rgw/services/svc_zone.h index 568c6d5603e..451faac8bef 100644 --- a/src/rgw/services/svc_zone.h +++ b/src/rgw/services/svc_zone.h @@ -92,7 +92,7 @@ public: bool zone_is_writeable(); bool zone_syncs_from(const RGWZone& target_zone, const RGWZone& source_zone) const; bool zone_syncs_from(const RGWZone& source_zone) const; - bool get_redirect_zone_endpoint(std::string *endpoint); + bool get_redirect_zone_endpoint_url(std::string *url); bool sync_module_supports_writes() const { return writeable_zone; } bool sync_module_exports_data() const { return exports_data; }