From 96ca98a169d0fd6cee07355d81c11a514eb72d10 Mon Sep 17 00:00:00 2001 From: Jane Zhu Date: Thu, 30 Mar 2023 01:23:55 -0400 Subject: [PATCH] rgw/swift: preserve dashes/underscores in swift user metadata names Signed-off-by: Juan Zhu --- qa/suites/rgw/tempest/tasks/tempest.yaml | 2 - src/rgw/rgw_common.cc | 73 +++++++++++++++++++----- src/rgw/rgw_common.h | 2 + src/rgw/rgw_rest_swift.cc | 8 +-- 4 files changed, 66 insertions(+), 19 deletions(-) diff --git a/qa/suites/rgw/tempest/tasks/tempest.yaml b/qa/suites/rgw/tempest/tasks/tempest.yaml index 988c7515b51fd..44afe7efede34 100644 --- a/qa/suites/rgw/tempest/tasks/tempest.yaml +++ b/qa/suites/rgw/tempest/tasks/tempest.yaml @@ -38,8 +38,6 @@ tasks: - .*test_container_synchronization.* - .*test_object_services.PublicObjectTest.test_access_public_container_object_without_using_creds - .*test_object_services.ObjectTest.test_create_object_with_transfer_encoding - - .*test_container_services.ContainerTest.test_create_container_with_remove_metadata_key - - .*test_container_services.ContainerTest.test_create_container_with_remove_metadata_value - .*test_object_expiry.ObjectExpiryTest.test_get_object_after_expiry_time - .*test_object_expiry.ObjectExpiryTest.test_get_object_at_expiry_time - .*test_account_services.AccountTest.test_list_no_account_metadata diff --git a/src/rgw/rgw_common.cc b/src/rgw/rgw_common.cc index a8a4dea5c8a90..287322634be4c 100644 --- a/src/rgw/rgw_common.cc +++ b/src/rgw/rgw_common.cc @@ -420,18 +420,9 @@ void req_info::init_meta_info(const DoutPrefixProvider *dpp, bool *found_bad_met if (found_bad_meta && strncmp(name, "META_", name_len) == 0) *found_bad_meta = true; - char name_low[meta_prefixes[0].len + name_len + 1]; - snprintf(name_low, meta_prefixes[0].len - 5 + name_len + 1, "%s%s", meta_prefixes[0].str + 5 /* skip HTTP_ */, name); // normalize meta prefix - int j; - for (j = 0; name_low[j]; j++) { - if (name_low[j] == '_') - name_low[j] = '-'; - else if (name_low[j] == '-') - name_low[j] = '_'; - else - name_low[j] = tolower(name_low[j]); - } - name_low[j] = 0; + stringstream ss; + ss << meta_prefixes[0].str + 5 /* skip HTTP_ */ << name; + string name_low = lowercase_dash_underscore_http_attr(ss.str()); auto it = x_meta_map.find(name_low); if (it != x_meta_map.end()) { @@ -443,7 +434,7 @@ void req_info::init_meta_info(const DoutPrefixProvider *dpp, bool *found_bad_met } else { x_meta_map[name_low] = val; } - if (strncmp(name_low, "x-amz-server-side-encryption", 20) == 0) { + if (strncmp(name_low.c_str(), "x-amz-server-side-encryption", 20) == 0) { crypt_attribute_map[name_low] = val; } } @@ -2218,6 +2209,31 @@ bool match_policy(std::string_view pattern, std::string_view input, } } +/* + * make attrs look-like_this + * converts underscores to dashes, and dashes to underscores + */ +string lowercase_dash_underscore_http_attr(const string& orig) +{ + const char *s = orig.c_str(); + char buf[orig.size() + 1]; + buf[orig.size()] = '\0'; + + for (size_t i = 0; i < orig.size(); ++i, ++s) { + switch (*s) { + case '_': + buf[i] = '-'; + break; + case '-': + buf[i] = '_'; + break; + default: + buf[i] = tolower(*s); + } + } + return string(buf); +} + /* * make attrs look-like-this * converts underscores to dashes @@ -2240,6 +2256,37 @@ string lowercase_dash_http_attr(const string& orig) return string(buf); } +/* + * make attrs Look-Like-This or Look_Like_This + * converts attrs to camelcase + */ +string camelcase_http_attr(const string& orig) +{ + const char *s = orig.c_str(); + char buf[orig.size() + 1]; + buf[orig.size()] = '\0'; + + bool last_sep = true; + + for (size_t i = 0; i < orig.size(); ++i, ++s) { + switch (*s) { + case '_': + case '-': + buf[i] = *s; + last_sep = true; + break; + default: + if (last_sep) { + buf[i] = toupper(*s); + } else { + buf[i] = tolower(*s); + } + last_sep = false; + } + } + return string(buf); +} + /* * make attrs Look-Like-This * converts underscores to dashes diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index 5165f9008b9fd..29d4e2870d59d 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -1771,7 +1771,9 @@ extern bool match_policy(std::string_view pattern, std::string_view input, uint32_t flag); extern std::string camelcase_dash_http_attr(const std::string& orig); +extern std::string camelcase_http_attr(const std::string& orig); extern std::string lowercase_dash_http_attr(const std::string& orig); +extern std::string lowercase_dash_underscore_http_attr(const std::string& orig); void rgw_setup_saved_curl_handles(); void rgw_release_all_curl_handles(); diff --git a/src/rgw/rgw_rest_swift.cc b/src/rgw/rgw_rest_swift.cc index 53815e11d1f2c..c2c938fb4e560 100644 --- a/src/rgw/rgw_rest_swift.cc +++ b/src/rgw/rgw_rest_swift.cc @@ -159,7 +159,7 @@ static void dump_account_metadata(req_state * const s, dump_header(s, geniter->second, iter->second); } else if (strncmp(name, RGW_ATTR_META_PREFIX, PREFIX_LEN) == 0) { dump_header_prefixed(s, "X-Account-Meta-", - camelcase_dash_http_attr(name + PREFIX_LEN), + camelcase_http_attr(name + PREFIX_LEN), iter->second); } } @@ -499,7 +499,7 @@ static void dump_container_metadata(req_state *s, dump_header(s, geniter->second, iter->second); } else if (strncmp(name, RGW_ATTR_META_PREFIX, PREFIX_LEN) == 0) { dump_header_prefixed(s, "X-Container-Meta-", - camelcase_dash_http_attr(name + PREFIX_LEN), + camelcase_http_attr(name + PREFIX_LEN), iter->second); } } @@ -674,7 +674,7 @@ static void get_rmattrs_from_headers(const req_state * const s, if (prefix_len > 0) { string name(RGW_ATTR_META_PREFIX); - name.append(lowercase_dash_http_attr(p + prefix_len)); + name.append(lowercase_dash_underscore_http_attr(p + prefix_len)); rmattr_names.insert(name); } } @@ -1339,7 +1339,7 @@ static void dump_object_metadata(const DoutPrefixProvider* dpp, req_state * cons sizeof(RGW_ATTR_META_PREFIX)-1) == 0) { name += sizeof(RGW_ATTR_META_PREFIX) - 1; dump_header_prefixed(s, "X-Object-Meta-", - camelcase_dash_http_attr(name), kv.second); + camelcase_http_attr(name), kv.second); } } -- 2.39.5