diff --git a/src/api/api_server.rs b/src/api/api_server.rs index 6d6e5b68..2de86233 100644 --- a/src/api/api_server.rs +++ b/src/api/api_server.rs @@ -22,6 +22,7 @@ use crate::s3_get::*; use crate::s3_list::*; use crate::s3_put::*; use crate::s3_router::{Authorization, Endpoint}; +use crate::s3_website::*; /// Run the S3 API server pub async fn run_api_server( @@ -254,6 +255,10 @@ async fn handler_inner(garage: Arc, req: Request) -> Result { handle_delete_objects(garage, &bucket, req, content_sha256).await } + Endpoint::PutBucketWebsite { bucket } => { + handle_put_website(garage, bucket, req, content_sha256).await + } + Endpoint::DeleteBucketWebsite { bucket } => handle_delete_website(garage, bucket).await, endpoint => Err(Error::NotImplemented(endpoint.name().to_owned())), } } diff --git a/src/api/lib.rs b/src/api/lib.rs index 09a55d56..589ffe9f 100644 --- a/src/api/lib.rs +++ b/src/api/lib.rs @@ -20,4 +20,5 @@ pub mod s3_get; mod s3_list; mod s3_put; mod s3_router; +mod s3_website; mod s3_xml; diff --git a/src/api/s3_website.rs b/src/api/s3_website.rs new file mode 100644 index 00000000..1b5c62a5 --- /dev/null +++ b/src/api/s3_website.rs @@ -0,0 +1,59 @@ +use std::sync::Arc; + +use hyper::{Body, Request, Response, StatusCode}; + +use crate::error::*; +use crate::signature::verify_signed_content; +use garage_model::bucket_table::BucketState; +use garage_model::garage::Garage; +use garage_table::*; +use garage_util::data::Hash; + +pub async fn handle_delete_website( + garage: Arc, + bucket: String, +) -> Result, Error> { + let mut bucket = garage + .bucket_table + .get(&EmptyKey, &bucket) + .await? + .ok_or(Error::NotFound)?; + + if let BucketState::Present(state) = bucket.state.get_mut() { + state.website.update(false); + garage.bucket_table.insert(&bucket).await?; + } + + Ok(Response::builder() + .status(StatusCode::NO_CONTENT) + .body(Body::from(vec![])) + .unwrap()) +} + +pub async fn handle_put_website( + garage: Arc, + bucket: String, + req: Request, + content_sha256: Option, +) -> Result, Error> { + let body = hyper::body::to_bytes(req.into_body()).await?; + verify_signed_content(content_sha256, &body[..])?; + + let mut bucket = garage + .bucket_table + .get(&EmptyKey, &bucket) + .await? + .ok_or(Error::NotFound)?; + + // TODO: parse xml + + if let BucketState::Present(state) = bucket.state.get_mut() { + state.website.update(true); + garage.bucket_table.insert(&bucket).await?; + } + + Ok(Response::builder() + .status(StatusCode::OK) + .body(Body::from(vec![])) + .unwrap()) +}