mirror of
https://github.com/ceph/ceph
synced 2025-01-19 17:41:39 +00:00
Merge pull request #9354 from dreamhost/wip-15975
rgw: Fallback to Host header for bucket name. Reviewed-by: Orit Wasserman <owasserm@redhat.com>
This commit is contained in:
commit
f93bbc94f8
@ -1671,6 +1671,27 @@ int RGWREST::preprocess(struct req_state *s, RGWClientIO* cio)
|
||||
s->info.request_uri_aws4 = s->info.request_uri;
|
||||
|
||||
s->cio = cio;
|
||||
|
||||
// We need to know if this RGW instance is running the s3website API with a
|
||||
// higher priority than regular S3 API, or possibly in place of the regular
|
||||
// S3 API.
|
||||
// Map the listing of rgw_enable_apis in REVERSE order, so that items near
|
||||
// the front of the list have a higher number assigned (and -1 for items not in the list).
|
||||
list<string> apis;
|
||||
get_str_list(g_conf->rgw_enable_apis, apis);
|
||||
int api_priority_s3 = -1;
|
||||
int api_priority_s3website = -1;
|
||||
auto api_s3website_priority_rawpos = std::find(apis.begin(), apis.end(), "s3website");
|
||||
auto api_s3_priority_rawpos = std::find(apis.begin(), apis.end(), "s3");
|
||||
if (api_s3_priority_rawpos != apis.end()) {
|
||||
api_priority_s3 = apis.size() - std::distance(apis.begin(), api_s3_priority_rawpos);
|
||||
}
|
||||
if (api_s3website_priority_rawpos != apis.end()) {
|
||||
api_priority_s3website = apis.size() - std::distance(apis.begin(), api_s3website_priority_rawpos);
|
||||
}
|
||||
ldout(s->cct, 10) << "rgw api priority: s3=" << api_priority_s3 << " s3website=" << api_priority_s3website << dendl;
|
||||
bool s3website_enabled = api_priority_s3website >= 0;
|
||||
|
||||
if (info.host.size()) {
|
||||
ldout(s->cct, 10) << "host=" << info.host << dendl;
|
||||
string domain;
|
||||
@ -1678,7 +1699,6 @@ int RGWREST::preprocess(struct req_state *s, RGWClientIO* cio)
|
||||
bool in_hosted_domain_s3website = false;
|
||||
bool in_hosted_domain = rgw_find_host_in_domains(info.host, &domain, &subdomain, hostnames_set);
|
||||
|
||||
bool s3website_enabled = g_conf->rgw_enable_apis.find("s3website") != std::string::npos;
|
||||
string s3website_domain;
|
||||
string s3website_subdomain;
|
||||
|
||||
@ -1688,7 +1708,6 @@ int RGWREST::preprocess(struct req_state *s, RGWClientIO* cio)
|
||||
in_hosted_domain = true; // TODO: should hostnames be a strict superset of hostnames_s3website?
|
||||
domain = s3website_domain;
|
||||
subdomain = s3website_subdomain;
|
||||
s->prot_flags |= RGW_REST_WEBSITE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1728,7 +1747,6 @@ int RGWREST::preprocess(struct req_state *s, RGWClientIO* cio)
|
||||
// strict superset of hostnames_s3website?
|
||||
domain = s3website_domain;
|
||||
subdomain = s3website_subdomain;
|
||||
s->prot_flags |= RGW_REST_WEBSITE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1741,6 +1759,31 @@ int RGWREST::preprocess(struct req_state *s, RGWClientIO* cio)
|
||||
}
|
||||
}
|
||||
|
||||
// Handle A/CNAME records that point to the RGW storage, but do match the
|
||||
// CNAME test above, per issue http://tracker.ceph.com/issues/15975
|
||||
// If BOTH domain & subdomain variables are empty, then none of the above
|
||||
// cases matched anything, and we should fall back to using the Host header
|
||||
// directly as the bucket name.
|
||||
// As additional checks:
|
||||
// - if the Host header is an IP, we're using path-style access without DNS
|
||||
// - Also check that the Host header is a valid bucket name before using it.
|
||||
if (subdomain.empty()
|
||||
&& (domain.empty() || domain != info.host)
|
||||
&& !looks_like_ip_address(info.host.c_str())
|
||||
&& RGWHandler_REST::validate_bucket_name(info.host)) {
|
||||
subdomain.append(info.host);
|
||||
in_hosted_domain = 1;
|
||||
}
|
||||
|
||||
if (s3website_enabled && api_priority_s3website > api_priority_s3) {
|
||||
in_hosted_domain_s3website = 1;
|
||||
}
|
||||
|
||||
if (in_hosted_domain_s3website) {
|
||||
s->prot_flags |= RGW_REST_WEBSITE;
|
||||
}
|
||||
|
||||
|
||||
if (in_hosted_domain && !subdomain.empty()) {
|
||||
string encoded_bucket = "/";
|
||||
encoded_bucket.append(subdomain);
|
||||
@ -1753,6 +1796,16 @@ int RGWREST::preprocess(struct req_state *s, RGWClientIO* cio)
|
||||
if (!domain.empty()) {
|
||||
s->info.domain = domain;
|
||||
}
|
||||
|
||||
ldout(s->cct, 20)
|
||||
<< "final domain/bucket"
|
||||
<< " subdomain=" << subdomain
|
||||
<< " domain=" << domain
|
||||
<< " in_hosted_domain=" << in_hosted_domain
|
||||
<< " in_hosted_domain_s3website=" << in_hosted_domain_s3website
|
||||
<< " s->info.domain=" << s->info.domain
|
||||
<< " s->info.request_uri=" << s->info.request_uri
|
||||
<< dendl;
|
||||
}
|
||||
|
||||
if (s->info.domain.empty()) {
|
||||
|
@ -380,16 +380,16 @@ protected:
|
||||
virtual RGWOp *op_copy() { return NULL; }
|
||||
virtual RGWOp *op_options() { return NULL; }
|
||||
|
||||
virtual int validate_tenant_name(const string& bucket);
|
||||
virtual int validate_bucket_name(const string& bucket);
|
||||
virtual int validate_object_name(const string& object);
|
||||
|
||||
static int allocate_formatter(struct req_state *s, int default_formatter,
|
||||
bool configurable);
|
||||
public:
|
||||
RGWHandler_REST() {}
|
||||
virtual ~RGWHandler_REST() {}
|
||||
|
||||
static int validate_tenant_name(const string& bucket);
|
||||
static int validate_bucket_name(const string& bucket);
|
||||
static int validate_object_name(const string& object);
|
||||
|
||||
int init_permissions(RGWOp* op);
|
||||
int read_permissions(RGWOp* op);
|
||||
|
||||
|
@ -452,11 +452,8 @@ public:
|
||||
RGWHandler_Auth_S3() : RGWHandler_REST() {}
|
||||
virtual ~RGWHandler_Auth_S3() {}
|
||||
|
||||
virtual int validate_bucket_name(const string& bucket) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int validate_object_name(const string& bucket) { return 0; }
|
||||
static int validate_bucket_name(const string& bucket);
|
||||
static int validate_object_name(const string& bucket);
|
||||
|
||||
virtual int init(RGWRados *store, struct req_state *s, RGWClientIO *cio);
|
||||
virtual int authorize() {
|
||||
|
@ -197,7 +197,7 @@ public:
|
||||
RGWHandler_REST_SWIFT() {}
|
||||
virtual ~RGWHandler_REST_SWIFT() {}
|
||||
|
||||
int validate_bucket_name(const string& bucket);
|
||||
static int validate_bucket_name(const string& bucket);
|
||||
|
||||
int init(RGWRados *store, struct req_state *s, RGWClientIO *cio);
|
||||
int authorize();
|
||||
|
Loading…
Reference in New Issue
Block a user