diff --git a/src/api/s3_copy.rs b/src/api/s3_copy.rs
index 7e91ecd8..f8b3550e 100644
--- a/src/api/s3_copy.rs
+++ b/src/api/s3_copy.rs
@@ -148,9 +148,9 @@ pub async fn handle_copy(
}
let last_modified = msec_to_rfc3339(new_timestamp);
- let result = s3_xml::CopyObjectResult {
+ let result = CopyObjectResult {
last_modified: s3_xml::Value(last_modified),
- etag: s3_xml::Value(etag),
+ etag: s3_xml::Value(format!("\"{}\"", etag)),
};
let xml = s3_xml::to_xml_with_header(&result)?;
@@ -394,7 +394,7 @@ pub async fn handle_upload_part_copy(
// LGTM
let resp_xml = s3_xml::to_xml_with_header(&CopyPartResult {
xmlns: (),
- etag: s3_xml::Value(etag),
+ etag: s3_xml::Value(format!("\"{}\"", etag)),
last_modified: s3_xml::Value(msec_to_rfc3339(source_object_version.timestamp)),
})?;
@@ -553,6 +553,14 @@ impl CopyPreconditionHeaders {
}
}
+#[derive(Debug, Serialize, PartialEq)]
+pub struct CopyObjectResult {
+ #[serde(rename = "LastModified")]
+ pub last_modified: s3_xml::Value,
+ #[serde(rename = "ETag")]
+ pub etag: s3_xml::Value,
+}
+
#[derive(Debug, Serialize, PartialEq)]
pub struct CopyPartResult {
#[serde(serialize_with = "xmlns_tag")]
@@ -568,15 +576,35 @@ mod tests {
use super::*;
use crate::s3_xml::to_xml_with_header;
+ #[test]
+ fn copy_object_result() -> Result<(), Error> {
+ let copy_result = CopyObjectResult {
+ last_modified: s3_xml::Value(msec_to_rfc3339(0)),
+ etag: s3_xml::Value("\"9b2cf535f27731c974343645a3985328\"".to_string()),
+ };
+ assert_eq!(
+ to_xml_with_header(©_result)?,
+ "\
+\
+ 1970-01-01T00:00:00.000Z\
+ "9b2cf535f27731c974343645a3985328"\
+\
+ "
+ );
+ Ok(())
+ }
+
#[test]
fn serialize_copy_part_result() -> Result<(), Error> {
- // @FIXME: ETag should be quoted, but we can't add quotes
- // because XML serializer replaces them by `"`
- let expected_retval = r#"2011-04-11T20:34:56.000Z9b2cf535f27731c974343645a3985328"#;
+ let expected_retval = "\
+\
+ 2011-04-11T20:34:56.000Z\
+ "9b2cf535f27731c974343645a3985328"\
+";
let v = CopyPartResult {
xmlns: (),
last_modified: s3_xml::Value("2011-04-11T20:34:56.000Z".into()),
- etag: s3_xml::Value("9b2cf535f27731c974343645a3985328".into()),
+ etag: s3_xml::Value("\"9b2cf535f27731c974343645a3985328\"".into()),
};
println!("{}", to_xml_with_header(&v)?);
diff --git a/src/api/s3_put.rs b/src/api/s3_put.rs
index 421b94a1..37658172 100644
--- a/src/api/s3_put.rs
+++ b/src/api/s3_put.rs
@@ -532,7 +532,7 @@ pub async fn handle_complete_multipart_upload(
location: None,
bucket: s3_xml::Value(bucket_name.to_string()),
key: s3_xml::Value(key),
- etag: s3_xml::Value(etag),
+ etag: s3_xml::Value(format!("\"{}\"", etag)),
};
let xml = s3_xml::to_xml_with_header(&result)?;
diff --git a/src/api/s3_xml.rs b/src/api/s3_xml.rs
index 0747648e..7500e130 100644
--- a/src/api/s3_xml.rs
+++ b/src/api/s3_xml.rs
@@ -107,14 +107,6 @@ pub struct DeleteResult {
pub errors: Vec,
}
-#[derive(Debug, Serialize, PartialEq)]
-pub struct CopyObjectResult {
- #[serde(rename = "LastModified")]
- pub last_modified: Value,
- #[serde(rename = "ETag")]
- pub etag: Value,
-}
-
#[derive(Debug, Serialize, PartialEq)]
pub struct InitiateMultipartUploadResult {
#[serde(serialize_with = "xmlns_tag")]
@@ -372,26 +364,6 @@ mod tests {
Ok(())
}
- #[test]
- fn copy_object_result() -> Result<(), ApiError> {
- // @FIXME: ETag should be quoted, but we can't add quotes
- // because XML serializer replaces them by `"`
- let copy_result = CopyObjectResult {
- last_modified: Value(msec_to_rfc3339(0)),
- etag: Value("9b2cf535f27731c974343645a3985328".to_string()),
- };
- assert_eq!(
- to_xml_with_header(©_result)?,
- "\
-\
- 1970-01-01T00:00:00.000Z\
- 9b2cf535f27731c974343645a3985328\
-\
- "
- );
- Ok(())
- }
-
#[test]
fn initiate_multipart_upload_result() -> Result<(), ApiError> {
let result = InitiateMultipartUploadResult {
@@ -414,14 +386,12 @@ mod tests {
#[test]
fn complete_multipart_upload_result() -> Result<(), ApiError> {
- // @FIXME: ETag should be quoted, but we can't add quotes
- // because XML serializer replaces them by `"`
let result = CompleteMultipartUploadResult {
xmlns: (),
location: Some(Value("https://garage.tld/mybucket/a/plop".to_string())),
bucket: Value("mybucket".to_string()),
key: Value("a/plop".to_string()),
- etag: Value("3858f62230ac3c915f300c664312c11f-9".to_string()),
+ etag: Value("\"3858f62230ac3c915f300c664312c11f-9\"".to_string()),
};
assert_eq!(
to_xml_with_header(&result)?,
@@ -430,7 +400,7 @@ mod tests {
https://garage.tld/mybucket/a/plop\
mybucket\
a/plop\
- 3858f62230ac3c915f300c664312c11f-9\
+ "3858f62230ac3c915f300c664312c11f-9"\
"
);
Ok(())
@@ -438,8 +408,6 @@ mod tests {
#[test]
fn list_objects_v1_1() -> Result<(), ApiError> {
- // @FIXME: ETag should be quoted, but we can't add quotes
- // because XML serializer replaces them by `"`
let result = ListBucketResult {
xmlns: (),
name: Value("example-bucket".to_string()),
@@ -457,7 +425,7 @@ mod tests {
contents: vec![ListBucketItem {
key: Value("sample.jpg".to_string()),
last_modified: Value(msec_to_rfc3339(0)),
- etag: Value("bf1d737a4d46a19f3bced6905cc8b902".to_string()),
+ etag: Value("\"bf1d737a4d46a19f3bced6905cc8b902\"".to_string()),
size: IntValue(142863),
storage_class: Value("STANDARD".to_string()),
}],
@@ -478,7 +446,7 @@ mod tests {
\
sample.jpg\
1970-01-01T00:00:00.000Z\
- bf1d737a4d46a19f3bced6905cc8b902\
+ "bf1d737a4d46a19f3bced6905cc8b902"\
142863\
STANDARD\
\
@@ -539,8 +507,6 @@ mod tests {
#[test]
fn list_objects_v2_1() -> Result<(), ApiError> {
- // @FIXME: ETag should be quoted, but we can't add quotes
- // because XML serializer replaces them by `"`
let result = ListBucketResult {
xmlns: (),
name: Value("quotes".to_string()),
@@ -558,7 +524,7 @@ mod tests {
contents: vec![ListBucketItem {
key: Value("ExampleObject.txt".to_string()),
last_modified: Value(msec_to_rfc3339(0)),
- etag: Value("599bab3ed2c697f1d26842727561fd94".to_string()),
+ etag: Value("\"599bab3ed2c697f1d26842727561fd94\"".to_string()),
size: IntValue(857),
storage_class: Value("REDUCED_REDUNDANCY".to_string()),
}],
@@ -576,7 +542,7 @@ mod tests {
\
ExampleObject.txt\
1970-01-01T00:00:00.000Z\
- 599bab3ed2c697f1d26842727561fd94\
+ "599bab3ed2c697f1d26842727561fd94"\
857\
REDUCED_REDUNDANCY\
\
@@ -587,8 +553,6 @@ mod tests {
#[test]
fn list_objects_v2_2() -> Result<(), ApiError> {
- // @FIXME: ETag should be quoted, but we can't add quotes
- // because XML serializer replaces them by `"`
let result = ListBucketResult {
xmlns: (),
name: Value("bucket".to_string()),
@@ -608,7 +572,7 @@ mod tests {
contents: vec![ListBucketItem {
key: Value("happyfacex.jpg".to_string()),
last_modified: Value(msec_to_rfc3339(0)),
- etag: Value("70ee1738b6b21e2c8a43f3a5ab0eee71".to_string()),
+ etag: Value("\"70ee1738b6b21e2c8a43f3a5ab0eee71\"".to_string()),
size: IntValue(1111),
storage_class: Value("STANDARD".to_string()),
}],
@@ -628,7 +592,7 @@ mod tests {
\
happyfacex.jpg\
1970-01-01T00:00:00.000Z\
- 70ee1738b6b21e2c8a43f3a5ab0eee71\
+ "70ee1738b6b21e2c8a43f3a5ab0eee71"\
1111\
STANDARD\
\