mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-26 16:28:15 +00:00
fix(s3): hide internal list markers in v1 responses (#4274)
This commit is contained in:
@@ -351,7 +351,10 @@ fn calculate_next_marker(v2: &ListObjectsV2Output) -> Option<String> {
|
||||
}
|
||||
|
||||
if let Some(marker) = decoded_next_continuation_marker(v2) {
|
||||
return Some(encode_list_output_value(marker, v2.encoding_type.as_ref()));
|
||||
return Some(encode_list_output_value(
|
||||
public_list_marker(&marker).to_owned(),
|
||||
v2.encoding_type.as_ref(),
|
||||
));
|
||||
}
|
||||
|
||||
let last_key = v2
|
||||
@@ -392,6 +395,31 @@ fn calculate_next_marker(v2: &ListObjectsV2Output) -> Option<String> {
|
||||
}
|
||||
}
|
||||
|
||||
fn public_list_marker(marker: &str) -> &str {
|
||||
let Some(start_idx) = marker.rfind("[rustfs_cache:") else {
|
||||
return marker;
|
||||
};
|
||||
let Some(tag_body) = marker[start_idx + 1..].strip_suffix(']') else {
|
||||
return marker;
|
||||
};
|
||||
|
||||
let mut has_supported_version = false;
|
||||
let mut has_continuation_field = false;
|
||||
for tag in tag_body.split(',') {
|
||||
match tag.split_once(':') {
|
||||
Some(("rustfs_cache", "v1" | "v2")) => has_supported_version = true,
|
||||
Some(("id" | "return", _)) => has_continuation_field = true,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
if has_supported_version && has_continuation_field {
|
||||
&marker[..start_idx]
|
||||
} else {
|
||||
marker
|
||||
}
|
||||
}
|
||||
|
||||
fn decoded_next_continuation_marker(v2: &ListObjectsV2Output) -> Option<String> {
|
||||
let token = v2.next_continuation_token.as_ref()?;
|
||||
let bytes = base64_simd::STANDARD.decode_to_vec(token.as_bytes()).ok()?;
|
||||
@@ -487,7 +515,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_list_objects_next_marker_preserves_internal_continuation_marker() {
|
||||
fn test_list_objects_next_marker_removes_internal_continuation_marker() {
|
||||
let marker = "key-998[rustfs_cache:v2,id:list-cache-id,p:0,s:0]";
|
||||
let v2 = ListObjectsV2Output {
|
||||
is_truncated: Some(true),
|
||||
@@ -500,11 +528,11 @@ mod tests {
|
||||
};
|
||||
|
||||
let output = build_list_objects_output(v2, None);
|
||||
assert_eq!(output.next_marker.as_deref(), Some(marker));
|
||||
assert_eq!(output.next_marker.as_deref(), Some("key-998"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_list_objects_next_marker_encodes_internal_marker_when_url_encoded() {
|
||||
fn test_list_objects_next_marker_strips_internal_marker_when_url_encoded() {
|
||||
let marker = "dir a/key[rustfs_cache:v2,id:list-cache-id,p:0,s:0]";
|
||||
let v2 = ListObjectsV2Output {
|
||||
is_truncated: Some(true),
|
||||
@@ -518,10 +546,7 @@ mod tests {
|
||||
};
|
||||
|
||||
let output = build_list_objects_output(v2, None);
|
||||
assert_eq!(
|
||||
output.next_marker.as_deref(),
|
||||
Some("dir%20a/key%5Brustfs_cache%3Av2%2Cid%3Alist-cache-id%2Cp%3A0%2Cs%3A0%5D")
|
||||
);
|
||||
assert_eq!(output.next_marker.as_deref(), Some("dir%20a/key"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user