From b547025e14877d8f33b25f4053835154755758ef Mon Sep 17 00:00:00 2001 From: Shilpa Jagannath Date: Mon, 7 Jul 2025 14:37:11 -0400 Subject: [PATCH] rgw/multisite: url-encode query param 'key-marker' in the bucket listing request Signed-off-by: Shilpa Jagannath (cherry picked from commit 0708a89240f265c07de2a61b3da8130f4ba4fc92) --- src/rgw/rgw_rest_client.cc | 4 +++- src/test/rgw/rgw_multi/tests.py | 37 +++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/rgw/rgw_rest_client.cc b/src/rgw/rgw_rest_client.cc index f7116c7bae7e2..b2b076e9cfcc8 100644 --- a/src/rgw/rgw_rest_client.cc +++ b/src/rgw/rgw_rest_client.cc @@ -587,7 +587,9 @@ void RGWRESTGenerateHTTPHeaders::init(const string& _method, const string& host, /* merge params with extra args so that we can sign correctly */ for (auto iter = params.begin(); iter != params.end(); ++iter) { - new_info->args.append(iter->first, iter->second); + constexpr bool encode_slash = false; // not for query params + new_info->args.append(url_encode(iter->first, encode_slash), + url_encode(iter->second, encode_slash)); } url = _url + resource + params_str; diff --git a/src/test/rgw/rgw_multi/tests.py b/src/test/rgw/rgw_multi/tests.py index 1d4ad5d47894f..b90e925e0b957 100644 --- a/src/test/rgw/rgw_multi/tests.py +++ b/src/test/rgw/rgw_multi/tests.py @@ -2161,6 +2161,43 @@ def test_zap_init_bucket_sync_run(): secondary.zone.start() zonegroup_bucket_checkpoint(zonegroup_conns, bucket.name) + +def test_list_bucket_key_marker_encoding(): + zonegroup = realm.master_zonegroup() + zonegroup_conns = ZonegroupConns(zonegroup) + primary = zonegroup_conns.rw_zones[0] + secondary = zonegroup_conns.rw_zones[1] + + bucket = primary.create_bucket(gen_bucket_name()) + log.debug('created bucket=%s', bucket.name) + zonegroup_meta_checkpoint(zonegroup) + + # test for object names with '%' character. + for obj in range(1, 1100): + k = new_key(primary, bucket.name, f'obj%{obj * 11}') + k.set_contents_from_string('foo') + + # wait for the secondary to catch up + zonegroup_bucket_checkpoint(zonegroup_conns, bucket.name) + + cmd = ['bucket', 'sync', 'init'] + secondary.zone.zone_args() + cmd += ['--bucket', bucket.name] + cmd += ['--source-zone', primary.name] + secondary.zone.cluster.admin(cmd) + + cmd = ['bucket', 'sync', 'run'] + secondary.zone.zone_args() + cmd += ['--bucket', bucket.name, '--source-zone', primary.name] + secondary.zone.cluster.admin(cmd) + + # write an object during incremental sync. + objname = 'test_incremental' + k = new_key(primary, bucket, objname) + k.set_contents_from_string('foo') + zonegroup_bucket_checkpoint(zonegroup_conns, bucket.name) + + # the object uploaded after bucket sync init should be replicated + check_object_exists(bucket, objname) + def test_role_sync(): zonegroup = realm.master_zonegroup() -- 2.39.5