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;
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;
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;
}
}
// strict superset of hostnames_s3website?
domain = s3website_domain;
subdomain = s3website_subdomain;
- s->prot_flags |= RGW_REST_WEBSITE;
}
}
}
}
+ // 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);
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()) {
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);