diff --git a/src/api/s3_website.rs b/src/api/s3_website.rs index 1b5c62a5..6587015b 100644 --- a/src/api/s3_website.rs +++ b/src/api/s3_website.rs @@ -1,8 +1,11 @@ +use quick_xml::de::from_reader; use std::sync::Arc; use hyper::{Body, Request, Response, StatusCode}; +use serde::{Deserialize, Serialize}; use crate::error::*; +use crate::s3_xml::{xmlns_tag, IntValue, Value}; use crate::signature::verify_signed_content; use garage_model::bucket_table::BucketState; use garage_model::garage::Garage; @@ -45,7 +48,7 @@ pub async fn handle_put_website( .await? .ok_or(Error::NotFound)?; - // TODO: parse xml + let _conf: WebsiteConfiguration = from_reader(&body as &[u8])?; if let BucketState::Present(state) = bucket.state.get_mut() { state.website.update(true); @@ -57,3 +60,115 @@ pub async fn handle_put_website( .body(Body::from(vec![])) .unwrap()) } + +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] +pub struct WebsiteConfiguration { + #[serde(serialize_with = "xmlns_tag", skip_deserializing)] + pub xmlns: (), + #[serde(rename = "ErrorDocument")] + pub error_document: Option, + #[serde(rename = "IndexDocument")] + pub index_document: Option, + #[serde(rename = "RedirectAllRequestsTo")] + pub redirect_all_requests_to: Option, + #[serde(rename = "RoutingRules")] + pub routing_rules: Option>, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] +pub struct RoutingRule { + #[serde(rename = "RoutingRule")] + pub routing_rule: RoutingRuleInner, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] +pub struct RoutingRuleInner { + #[serde(rename = "Condition")] + pub condition: Option, + #[serde(rename = "Redirect")] + pub redirect: Redirect, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] +pub struct Key { + #[serde(rename = "Key")] + pub key: Value, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] +pub struct Suffix { + #[serde(rename = "Suffix")] + pub suffix: Value, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] +pub struct Target { + #[serde(rename = "HostName")] + pub hostname: Option, + #[serde(rename = "Protocol")] + pub protocol: Option, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] +pub struct Condition { + #[serde(rename = "HttpErrorCodeReturnedEquals")] + pub http_error_code: Option, + #[serde(rename = "KeyPrefixEquals")] + pub prefix: Option, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] +pub struct Redirect { + #[serde(rename = "HostName")] + pub hostname: Option, + #[serde(rename = "Protocol")] + pub protocol: Option, + #[serde(rename = "HttpRedirectCode")] + pub http_redirect_code: Option, + #[serde(rename = "ReplaceKeyPrefixWith")] + pub replace_prefix: Option, + #[serde(rename = "ReplaceKeyWith")] + pub replace_full: Option, +} + +#[cfg(test)] +mod tests { + use super::*; + + use quick_xml::de::from_str; + + #[test] + fn test_deserialize() { + let message = r#" + + + string + + + string + + + string + string + + + + + 404 + string + + + string + string + 303 + string + string + + + +"#; + let _conf: WebsiteConfiguration = from_str(message).unwrap(); + // TODO verify result is ok + // TODO cycle back and verify if ok + } +} diff --git a/src/api/s3_xml.rs b/src/api/s3_xml.rs index f0547961..9b5a0202 100644 --- a/src/api/s3_xml.rs +++ b/src/api/s3_xml.rs @@ -1,5 +1,5 @@ use quick_xml::se::to_string; -use serde::{Serialize, Serializer}; +use serde::{Deserialize, Serialize, Serializer}; use crate::Error as ApiError; @@ -9,14 +9,14 @@ pub fn to_xml_with_header(x: &T) -> Result { Ok(xml) } -fn xmlns_tag(_v: &(), s: S) -> Result { +pub fn xmlns_tag(_v: &(), s: S) -> Result { s.serialize_str("http://s3.amazonaws.com/doc/2006-03-01/") } -#[derive(Debug, Serialize, PartialEq)] +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] pub struct Value(#[serde(rename = "$value")] pub String); -#[derive(Debug, Serialize, PartialEq)] +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] pub struct IntValue(#[serde(rename = "$value")] pub i64); #[derive(Debug, Serialize, PartialEq)]