From 180ca7b56ba91a3995c76dac698aa4ee31d9a2ce Mon Sep 17 00:00:00 2001 From: Jeff Weber Date: Wed, 5 Aug 2015 19:06:46 -0400 Subject: [PATCH] rgw: implement s3 encoding-type for get bucket This change introduces handling for the encoding-type request parameter on the get bucket operation. An object key may contain characters which are not supported in XML. Passing the value "url" for the encoding-type parameter will cause the key to be urlencoded in the response. Fixes: #12735 Signed-off-by: Jeff Weber --- src/rgw/rgw_op.h | 1 + src/rgw/rgw_rest_s3.cc | 25 +++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index 764078b949289..32e8c80fe4974 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -258,6 +258,7 @@ protected: rgw_obj_key end_marker; string max_keys; string delimiter; + string encoding_type; bool list_versions; int max; int ret; diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 2dce3e1b46ae9..570b00c0e9b10 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -243,6 +243,7 @@ int RGWListBucket_ObjStore_S3::get_params() return ret; } delimiter = s->info.args.get("delimiter"); + encoding_type = s->info.args.get("encoding-type"); return 0; } @@ -261,13 +262,23 @@ void RGWListBucket_ObjStore_S3::send_versioned_response() s->formatter->dump_string("IsTruncated", (max && is_truncated ? "true" : "false")); + bool encode_key = false; + if (strcasecmp(encoding_type.c_str(), "url") == 0) + encode_key = true; + if (ret >= 0) { vector::iterator iter; for (iter = objs.begin(); iter != objs.end(); ++iter) { time_t mtime = iter->mtime.sec(); const char *section_name = (iter->is_delete_marker() ? "DeleteMarker" : "Version"); s->formatter->open_array_section(section_name); - s->formatter->dump_string("Key", iter->key.name); + if (encode_key) { + string key_name; + url_encode(iter->key.name, key_name); + s->formatter->dump_string("Key", key_name); + } else { + s->formatter->dump_string("Key", iter->key.name); + } string version_id = iter->key.instance; if (version_id.empty()) { version_id = "null"; @@ -328,11 +339,21 @@ void RGWListBucket_ObjStore_S3::send_response() s->formatter->dump_string("IsTruncated", (max && is_truncated ? "true" : "false")); + bool encode_key = false; + if (strcasecmp(encoding_type.c_str(), "url") == 0) + encode_key = true; + if (ret >= 0) { vector::iterator iter; for (iter = objs.begin(); iter != objs.end(); ++iter) { s->formatter->open_array_section("Contents"); - s->formatter->dump_string("Key", iter->key.name); + if (encode_key) { + string key_name; + url_encode(iter->key.name, key_name); + s->formatter->dump_string("Key", key_name); + } else { + s->formatter->dump_string("Key", iter->key.name); + } time_t mtime = iter->mtime.sec(); dump_time(s, "LastModified", &mtime); s->formatter->dump_format("ETag", "\"%s\"", iter->etag.c_str()); -- 2.39.5