diff options
author | Alex Auvolat <alex@adnab.me> | 2022-01-12 11:41:20 +0100 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2022-01-13 14:03:33 +0100 |
commit | f7349f40050dfb5dc4f4f49df5732686c8d846ba (patch) | |
tree | d471d9968dbbe1823198443ee3c81834083b886c | |
parent | 1ee8f596ee6792b987b07dc08617feb4a3480c1a (diff) | |
download | garage-f7349f40050dfb5dc4f4f49df5732686c8d846ba.tar.gz garage-f7349f40050dfb5dc4f4f49df5732686c8d846ba.zip |
Add quotes in returned etagsimprove-copies
-rw-r--r-- | src/api/s3_copy.rs | 42 | ||||
-rw-r--r-- | src/api/s3_list.rs | 2 | ||||
-rw-r--r-- | src/api/s3_put.rs | 2 | ||||
-rw-r--r-- | src/api/s3_xml.rs | 52 |
4 files changed, 45 insertions, 53 deletions
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)), })?; @@ -554,6 +554,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")] pub xmlns: (), @@ -569,14 +577,34 @@ mod tests { 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)?, + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\ +<CopyObjectResult>\ + <LastModified>1970-01-01T00:00:00.000Z</LastModified>\ + <ETag>"9b2cf535f27731c974343645a3985328"</ETag>\ +</CopyObjectResult>\ + " + ); + 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#"<?xml version="1.0" encoding="UTF-8"?><CopyPartResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><LastModified>2011-04-11T20:34:56.000Z</LastModified><ETag>9b2cf535f27731c974343645a3985328</ETag></CopyPartResult>"#; + let expected_retval = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\ +<CopyPartResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\">\ + <LastModified>2011-04-11T20:34:56.000Z</LastModified>\ + <ETag>"9b2cf535f27731c974343645a3985328"</ETag>\ +</CopyPartResult>"; 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_list.rs b/src/api/s3_list.rs index ddc03375..f991b07d 100644 --- a/src/api/s3_list.rs +++ b/src/api/s3_list.rs @@ -121,7 +121,7 @@ pub async fn handle_list( key: uriencode_maybe(key, query.common.urlencode_resp), last_modified: s3_xml::Value(msec_to_rfc3339(info.last_modified)), size: s3_xml::IntValue(info.size as i64), - etag: s3_xml::Value(info.etag.to_string()), + etag: s3_xml::Value(format!("\"{}\"", info.etag.to_string())), storage_class: s3_xml::Value("STANDARD".to_string()), }) .collect(), 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 962b4780..1df4ed60 100644 --- a/src/api/s3_xml.rs +++ b/src/api/s3_xml.rs @@ -108,14 +108,6 @@ pub struct DeleteResult { } #[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")] pub xmlns: (), @@ -427,26 +419,6 @@ mod tests { } #[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)?, - "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\ -<CopyObjectResult>\ - <LastModified>1970-01-01T00:00:00.000Z</LastModified>\ - <ETag>9b2cf535f27731c974343645a3985328</ETag>\ -</CopyObjectResult>\ - " - ); - Ok(()) - } - - #[test] fn initiate_multipart_upload_result() -> Result<(), ApiError> { let result = InitiateMultipartUploadResult { xmlns: (), @@ -468,14 +440,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)?, @@ -484,7 +454,7 @@ mod tests { <Location>https://garage.tld/mybucket/a/plop</Location>\ <Bucket>mybucket</Bucket>\ <Key>a/plop</Key>\ - <ETag>3858f62230ac3c915f300c664312c11f-9</ETag>\ + <ETag>"3858f62230ac3c915f300c664312c11f-9"</ETag>\ </CompleteMultipartUploadResult>" ); Ok(()) @@ -544,8 +514,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()), @@ -563,7 +531,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()), }], @@ -584,7 +552,7 @@ mod tests { <Contents>\ <Key>sample.jpg</Key>\ <LastModified>1970-01-01T00:00:00.000Z</LastModified>\ - <ETag>bf1d737a4d46a19f3bced6905cc8b902</ETag>\ + <ETag>"bf1d737a4d46a19f3bced6905cc8b902"</ETag>\ <Size>142863</Size>\ <StorageClass>STANDARD</StorageClass>\ </Contents>\ @@ -645,8 +613,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()), @@ -664,7 +630,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()), }], @@ -682,7 +648,7 @@ mod tests { <Contents>\ <Key>ExampleObject.txt</Key>\ <LastModified>1970-01-01T00:00:00.000Z</LastModified>\ - <ETag>599bab3ed2c697f1d26842727561fd94</ETag>\ + <ETag>"599bab3ed2c697f1d26842727561fd94"</ETag>\ <Size>857</Size>\ <StorageClass>REDUCED_REDUNDANCY</StorageClass>\ </Contents>\ @@ -693,8 +659,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()), @@ -714,7 +678,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()), }], @@ -734,7 +698,7 @@ mod tests { <Contents>\ <Key>happyfacex.jpg</Key>\ <LastModified>1970-01-01T00:00:00.000Z</LastModified>\ - <ETag>70ee1738b6b21e2c8a43f3a5ab0eee71</ETag>\ + <ETag>"70ee1738b6b21e2c8a43f3a5ab0eee71"</ETag>\ <Size>1111</Size>\ <StorageClass>STANDARD</StorageClass>\ </Contents>\ |