Handle OPTIONS on website endpoint
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing

This commit is contained in:
Alex 2022-01-24 12:03:57 +01:00
parent ea7fb901eb
commit 513a6b15f9
No known key found for this signature in database
GPG key ID: EDABF9711E244EB1
4 changed files with 13 additions and 36 deletions

View file

@ -156,7 +156,7 @@ async fn handler_inner(garage: Arc<Garage>, req: Request<Body>) -> Result<Respon
}; };
let resp = match endpoint { let resp = match endpoint {
Endpoint::Options => handle_options(garage, &req, bucket_id).await, Endpoint::Options => handle_options(&req, &bucket).await,
Endpoint::HeadObject { key, .. } => handle_head(garage, &req, bucket_id, &key).await, Endpoint::HeadObject { key, .. } => handle_head(garage, &req, bucket_id, &key).await,
Endpoint::GetObject { key, .. } => handle_get(garage, &req, bucket_id, &key).await, Endpoint::GetObject { key, .. } => handle_get(garage, &req, bucket_id, &key).await,
Endpoint::UploadPart { Endpoint::UploadPart {
@ -334,12 +334,12 @@ async fn handler_inner(garage: Arc<Garage>, req: Request<Body>) -> Result<Respon
Endpoint::DeleteObjects {} => { Endpoint::DeleteObjects {} => {
handle_delete_objects(garage, bucket_id, req, content_sha256).await handle_delete_objects(garage, bucket_id, req, content_sha256).await
} }
Endpoint::GetBucketWebsite {} => handle_get_website(garage, bucket_id).await, Endpoint::GetBucketWebsite {} => handle_get_website(&bucket).await,
Endpoint::PutBucketWebsite {} => { Endpoint::PutBucketWebsite {} => {
handle_put_website(garage, bucket_id, req, content_sha256).await handle_put_website(garage, bucket_id, req, content_sha256).await
} }
Endpoint::DeleteBucketWebsite {} => handle_delete_website(garage, bucket_id).await, Endpoint::DeleteBucketWebsite {} => handle_delete_website(garage, bucket_id).await,
Endpoint::GetBucketCors {} => handle_get_cors(garage, bucket_id).await, Endpoint::GetBucketCors {} => handle_get_cors(&bucket).await,
Endpoint::PutBucketCors {} => handle_put_cors(garage, bucket_id, req, content_sha256).await, Endpoint::PutBucketCors {} => handle_put_cors(garage, bucket_id, req, content_sha256).await,
Endpoint::DeleteBucketCors {} => handle_delete_cors(garage, bucket_id).await, Endpoint::DeleteBucketCors {} => handle_delete_cors(garage, bucket_id).await,
endpoint => Err(Error::NotImplemented(endpoint.name().to_owned())), endpoint => Err(Error::NotImplemented(endpoint.name().to_owned())),

View file

@ -18,16 +18,7 @@ use garage_model::garage::Garage;
use garage_table::*; use garage_table::*;
use garage_util::data::*; use garage_util::data::*;
pub async fn handle_get_cors( pub async fn handle_get_cors(bucket: &Bucket) -> Result<Response<Body>, Error> {
garage: Arc<Garage>,
bucket_id: Uuid,
) -> Result<Response<Body>, Error> {
let bucket = garage
.bucket_table
.get(&EmptyKey, &bucket_id)
.await?
.ok_or(Error::NoSuchBucket)?;
let param = bucket let param = bucket
.params() .params()
.ok_or_internal_error("Bucket should not be deleted at this point")?; .ok_or_internal_error("Bucket should not be deleted at this point")?;
@ -109,16 +100,7 @@ pub async fn handle_put_cors(
.body(Body::empty())?) .body(Body::empty())?)
} }
pub async fn handle_options( pub async fn handle_options(req: &Request<Body>, bucket: &Bucket) -> Result<Response<Body>, Error> {
garage: Arc<Garage>,
req: &Request<Body>,
bucket_id: Uuid,
) -> Result<Response<Body>, Error> {
let bucket = garage
.bucket_table
.get(&EmptyKey, &bucket_id)
.await?
.ok_or(Error::NoSuchBucket)?;
let origin = req let origin = req
.headers() .headers()
.get("Origin") .get("Origin")

View file

@ -13,16 +13,7 @@ use garage_model::garage::Garage;
use garage_table::*; use garage_table::*;
use garage_util::data::*; use garage_util::data::*;
pub async fn handle_get_website( pub async fn handle_get_website(bucket: &Bucket) -> Result<Response<Body>, Error> {
garage: Arc<Garage>,
bucket_id: Uuid,
) -> Result<Response<Body>, Error> {
let bucket = garage
.bucket_table
.get(&EmptyKey, &bucket_id)
.await?
.ok_or(Error::NoSuchBucket)?;
let param = bucket let param = bucket
.params() .params()
.ok_or_internal_error("Bucket should not be deleted at this point")?; .ok_or_internal_error("Bucket should not be deleted at this point")?;

View file

@ -13,7 +13,7 @@ use crate::error::*;
use garage_api::error::{Error as ApiError, OkOrBadRequest, OkOrInternalError}; use garage_api::error::{Error as ApiError, OkOrBadRequest, OkOrInternalError};
use garage_api::helpers::{authority_to_host, host_to_bucket}; use garage_api::helpers::{authority_to_host, host_to_bucket};
use garage_api::s3_cors::{add_cors_headers, find_matching_cors_rule}; use garage_api::s3_cors::{add_cors_headers, find_matching_cors_rule, handle_options};
use garage_api::s3_get::{handle_get, handle_head}; use garage_api::s3_get::{handle_get, handle_head};
use garage_model::garage::Garage; use garage_model::garage::Garage;
@ -133,6 +133,7 @@ async fn serve_file(garage: Arc<Garage>, req: &Request<Body>) -> Result<Response
); );
let ret_doc = match *req.method() { let ret_doc = match *req.method() {
Method::OPTIONS => handle_options(req, &bucket).await,
Method::HEAD => handle_head(garage.clone(), req, bucket_id, &key).await, Method::HEAD => handle_head(garage.clone(), req, bucket_id, &key).await,
Method::GET => handle_get(garage.clone(), req, bucket_id, &key).await, Method::GET => handle_get(garage.clone(), req, bucket_id, &key).await,
_ => Err(ApiError::BadRequest("HTTP method not supported".into())), _ => Err(ApiError::BadRequest("HTTP method not supported".into())),
@ -141,11 +142,14 @@ async fn serve_file(garage: Arc<Garage>, req: &Request<Body>) -> Result<Response
match ret_doc { match ret_doc {
Err(error) => { Err(error) => {
// For a HEAD method, and for non-4xx errors, // For a HEAD or OPTIONS method, and for non-4xx errors,
// we don't return the error document as content, // we don't return the error document as content,
// we return above and just return the error message // we return above and just return the error message
// by relying on err_to_res that is called when we return an Err. // by relying on err_to_res that is called when we return an Err.
if *req.method() == Method::HEAD || !error.http_status_code().is_client_error() { if *req.method() == Method::HEAD
|| *req.method() == Method::OPTIONS
|| !error.http_status_code().is_client_error()
{
return Err(error); return Err(error);
} }