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:
Orit Wasserman 2016-06-15 11:42:09 +02:00 committed by GitHub
commit f93bbc94f8
4 changed files with 63 additions and 13 deletions

View File

@ -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()) {

View File

@ -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);

View File

@ -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() {

View File

@ -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();