diff options
author | Alex Auvolat <alex@adnab.me> | 2021-05-03 22:45:42 +0200 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2021-05-06 22:37:15 +0200 |
commit | 6ccffc316228bb056fa135cc5fceb2ed75f545f5 (patch) | |
tree | 109e9334aaee5b7865a5d29fcfaea23010da0cc4 /src/api/s3_bucket.rs | |
parent | e4b9e4e24d006373a20cfcbdac9dba5e399ee182 (diff) | |
download | garage-6ccffc316228bb056fa135cc5fceb2ed75f545f5.tar.gz garage-6ccffc316228bb056fa135cc5fceb2ed75f545f5.zip |
Improved XML serializationbetter_xml
- Use quick_xml and serde for all XML response returned by the S3 API.
- Include tests for all structs used to generate XML
- Remove old manual XML escaping function which was unsafe
Diffstat (limited to 'src/api/s3_bucket.rs')
-rw-r--r-- | src/api/s3_bucket.rs | 92 |
1 files changed, 15 insertions, 77 deletions
diff --git a/src/api/s3_bucket.rs b/src/api/s3_bucket.rs index e7d89698..88d13cac 100644 --- a/src/api/s3_bucket.rs +++ b/src/api/s3_bucket.rs @@ -1,73 +1,20 @@ -use std::fmt::Write; use std::sync::Arc; use hyper::{Body, Response}; -use quick_xml::se::to_string; -use serde::Serialize; use garage_model::garage::Garage; use garage_model::key_table::Key; use garage_util::time::*; use crate::error::*; - -#[derive(Debug, Serialize, PartialEq)] -struct CreationDate { - #[serde(rename = "$value")] - pub body: String, -} -#[derive(Debug, Serialize, PartialEq)] -struct Name { - #[serde(rename = "$value")] - pub body: String, -} -#[derive(Debug, Serialize, PartialEq)] -struct Bucket { - #[serde(rename = "CreationDate")] - pub creation_date: CreationDate, - #[serde(rename = "Name")] - pub name: Name, -} -#[derive(Debug, Serialize, PartialEq)] -struct DisplayName { - #[serde(rename = "$value")] - pub body: String, -} -#[derive(Debug, Serialize, PartialEq)] -struct Id { - #[serde(rename = "$value")] - pub body: String, -} -#[derive(Debug, Serialize, PartialEq)] -struct Owner { - #[serde(rename = "DisplayName")] - display_name: DisplayName, - #[serde(rename = "ID")] - id: Id, -} -#[derive(Debug, Serialize, PartialEq)] -struct BucketList { - #[serde(rename = "Bucket")] - pub entries: Vec<Bucket>, -} -#[derive(Debug, Serialize, PartialEq)] -struct ListAllMyBucketsResult { - #[serde(rename = "Buckets")] - buckets: BucketList, - #[serde(rename = "Owner")] - owner: Owner, -} +use crate::s3_xml; pub fn handle_get_bucket_location(garage: Arc<Garage>) -> Result<Response<Body>, Error> { - let mut xml = String::new(); - - writeln!(&mut xml, r#"<?xml version="1.0" encoding="UTF-8"?>"#).unwrap(); - writeln!( - &mut xml, - r#"<LocationConstraint xmlns="http://s3.amazonaws.com/doc/2006-03-01/">{}</LocationConstraint>"#, - garage.config.s3_api.s3_region - ) - .unwrap(); + let loc = s3_xml::LocationConstraint { + xmlns: (), + region: garage.config.s3_api.s3_region.to_string(), + }; + let xml = s3_xml::to_xml_with_header(&loc)?; Ok(Response::builder() .header("Content-Type", "application/xml") @@ -75,34 +22,25 @@ pub fn handle_get_bucket_location(garage: Arc<Garage>) -> Result<Response<Body>, } pub fn handle_list_buckets(api_key: &Key) -> Result<Response<Body>, Error> { - let list_buckets = ListAllMyBucketsResult { - owner: Owner { - display_name: DisplayName { - body: api_key.name.get().to_string(), - }, - id: Id { - body: api_key.key_id.to_string(), - }, + let list_buckets = s3_xml::ListAllMyBucketsResult { + owner: s3_xml::Owner { + display_name: s3_xml::Value(api_key.name.get().to_string()), + id: s3_xml::Value(api_key.key_id.to_string()), }, - buckets: BucketList { + buckets: s3_xml::BucketList { entries: api_key .authorized_buckets .items() .iter() - .map(|(name, ts, _)| Bucket { - creation_date: CreationDate { - body: msec_to_rfc3339(*ts), - }, - name: Name { - body: name.to_string(), - }, + .map(|(name, ts, _)| s3_xml::Bucket { + creation_date: s3_xml::Value(msec_to_rfc3339(*ts)), + name: s3_xml::Value(name.to_string()), }) .collect(), }, }; - let mut xml = r#"<?xml version="1.0" encoding="UTF-8"?>"#.to_string(); - xml.push_str(&to_string(&list_buckets)?); + let xml = s3_xml::to_xml_with_header(&list_buckets)?; trace!("xml: {}", xml); Ok(Response::builder() |