return -1;
return 0;
}
+
+static inline uint8_t get_cors_method_flags(const char *req_meth) {
+ uint8_t flags = 0;
+
+ if (strcmp(req_meth, "GET") == 0) flags = RGW_CORS_GET;
+ else if (strcmp(req_meth, "POST") == 0) flags = RGW_CORS_POST;
+ else if (strcmp(req_meth, "PUT") == 0) flags = RGW_CORS_PUT;
+ else if (strcmp(req_meth, "DELETE") == 0) flags = RGW_CORS_DELETE;
+ else if (strcmp(req_meth, "HEAD") == 0) flags = RGW_CORS_HEAD;
+
+ return flags;
+}
+
#endif /*CEPH_RGW_CORS_H*/
}
static bool validate_cors_rule_method(RGWCORSRule *rule, const char *req_meth) {
- uint8_t flags = 0;
-
if (!req_meth) {
dout(5) << "req_meth is null" << dendl;
return false;
}
- if (strcmp(req_meth, "GET") == 0) flags = RGW_CORS_GET;
- else if (strcmp(req_meth, "POST") == 0) flags = RGW_CORS_POST;
- else if (strcmp(req_meth, "PUT") == 0) flags = RGW_CORS_PUT;
- else if (strcmp(req_meth, "DELETE") == 0) flags = RGW_CORS_DELETE;
- else if (strcmp(req_meth, "HEAD") == 0) flags = RGW_CORS_HEAD;
+ uint8_t flags = get_cors_method_flags(req_meth);
if (rule->get_allowed_methods() & flags) {
dout(10) << "Method " << req_meth << " is supported" << dendl;
/* Craft canonical query string. std::moving later so non-const here. */
auto canonical_qs = rgw::auth::s3::get_v4_canonical_qs(s->info, using_qs);
+ const char *req_meth = s->info.method;
+
+ /* If this is a OPTIONS request we need to compute the v4 signature for the
+ * intended HTTP method and not the OPTIONS request itself. */
+ if (s->op_type == RGW_OP_OPTIONS_CORS) {
+ /* Validate signature for CORS header if set otherwise use HTTP request method. */
+ const char *cors_method = s->info.env->get("HTTP_ACCESS_CONTROL_REQUEST_METHOD");
+
+ if (cors_method) {
+ /* Validate request method passed in access-control-request-method is valid. */
+ auto cors_flags = get_cors_method_flags(cors_method);
+ if (!cors_flags) {
+ ldpp_dout(s, 1) << "invalid access-control-request-method header = "
+ << cors_method << dendl;
+ throw -EINVAL;
+ }
+
+ req_meth = cors_method;
+ ldpp_dout(s, 10) << "setting canonical req method = " << cors_method
+ << ", due to access-control-request-method header" << dendl;
+ } else {
+ ldpp_dout(s, 1) << "invalid http options req missing "
+ << "access-control-request-method header" << dendl;
+ throw -EINVAL;
+ }
+ }
+
/* Craft canonical request. */
auto canonical_req_hash = \
rgw::auth::s3::get_v4_canon_req_hash(s->cct,
- s->info.method,
+ req_meth,
std::move(canonical_uri),
std::move(canonical_qs),
std::move(*canonical_headers),