BucketWebsite #174

Merged
lx merged 4 commits from trinity-1686a/garage:BucketWebsite into main 2021-12-15 09:41:40 +00:00
2 changed files with 120 additions and 5 deletions
Showing only changes of commit 3999fd4a02 - Show all commits

View file

@ -1,8 +1,11 @@
use quick_xml::de::from_reader;
use std::sync::Arc; use std::sync::Arc;
use hyper::{Body, Request, Response, StatusCode}; use hyper::{Body, Request, Response, StatusCode};
use serde::{Deserialize, Serialize};
use crate::error::*; use crate::error::*;
use crate::s3_xml::{xmlns_tag, IntValue, Value};
use crate::signature::verify_signed_content; use crate::signature::verify_signed_content;
use garage_model::bucket_table::BucketState; use garage_model::bucket_table::BucketState;
use garage_model::garage::Garage; use garage_model::garage::Garage;
@ -45,7 +48,7 @@ pub async fn handle_put_website(
.await? .await?
.ok_or(Error::NotFound)?; .ok_or(Error::NotFound)?;
// TODO: parse xml let _conf: WebsiteConfiguration = from_reader(&body as &[u8])?;
if let BucketState::Present(state) = bucket.state.get_mut() { if let BucketState::Present(state) = bucket.state.get_mut() {
state.website.update(true); state.website.update(true);
@ -57,3 +60,115 @@ pub async fn handle_put_website(
.body(Body::from(vec![])) .body(Body::from(vec![]))
.unwrap()) .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<Key>,
#[serde(rename = "IndexDocument")]
pub index_document: Option<Suffix>,
#[serde(rename = "RedirectAllRequestsTo")]
pub redirect_all_requests_to: Option<Target>,
#[serde(rename = "RoutingRules")]
pub routing_rules: Option<Vec<RoutingRule>>,
}
#[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<Condition>,
#[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<Value>,
#[serde(rename = "Protocol")]
pub protocol: Option<Value>,
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
pub struct Condition {
#[serde(rename = "HttpErrorCodeReturnedEquals")]
pub http_error_code: Option<IntValue>,
#[serde(rename = "KeyPrefixEquals")]
pub prefix: Option<Value>,
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
pub struct Redirect {
#[serde(rename = "HostName")]
pub hostname: Option<Value>,
#[serde(rename = "Protocol")]
pub protocol: Option<Value>,
#[serde(rename = "HttpRedirectCode")]
pub http_redirect_code: Option<IntValue>,
#[serde(rename = "ReplaceKeyPrefixWith")]
pub replace_prefix: Option<Value>,
#[serde(rename = "ReplaceKeyWith")]
pub replace_full: Option<Value>,
}
#[cfg(test)]
mod tests {
use super::*;
use quick_xml::de::from_str;
#[test]
fn test_deserialize() {
let message = r#"<?xml version="1.0" encoding="UTF-8"?>
<WebsiteConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<ErrorDocument>
<Key>string</Key>
</ErrorDocument>
<IndexDocument>
<Suffix>string</Suffix>
</IndexDocument>
<RedirectAllRequestsTo>
<HostName>string</HostName>
<Protocol>string</Protocol>
</RedirectAllRequestsTo>
<RoutingRules>
<RoutingRule>
<Condition>
<HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
<KeyPrefixEquals>string</KeyPrefixEquals>
</Condition>
<Redirect>
<HostName>string</HostName>
<Protocol>string</Protocol>
<HttpRedirectCode>303</HttpRedirectCode>
<ReplaceKeyPrefixWith>string</ReplaceKeyPrefixWith>
<ReplaceKeyWith>string</ReplaceKeyWith>
</Redirect>
</RoutingRule>
</RoutingRules>
</WebsiteConfiguration>"#;
let _conf: WebsiteConfiguration = from_str(message).unwrap();
// TODO verify result is ok
// TODO cycle back and verify if ok
}
}

View file

@ -1,5 +1,5 @@
use quick_xml::se::to_string; use quick_xml::se::to_string;
use serde::{Serialize, Serializer}; use serde::{Deserialize, Serialize, Serializer};
use crate::Error as ApiError; use crate::Error as ApiError;
@ -9,14 +9,14 @@ pub fn to_xml_with_header<T: Serialize>(x: &T) -> Result<String, ApiError> {
Ok(xml) Ok(xml)
} }
fn xmlns_tag<S: Serializer>(_v: &(), s: S) -> Result<S::Ok, S::Error> { pub fn xmlns_tag<S: Serializer>(_v: &(), s: S) -> Result<S::Ok, S::Error> {
s.serialize_str("http://s3.amazonaws.com/doc/2006-03-01/") 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); 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); pub struct IntValue(#[serde(rename = "$value")] pub i64);
#[derive(Debug, Serialize, PartialEq)] #[derive(Debug, Serialize, PartialEq)]