bucketwarden-server 0.1.0

BucketWarden storage server runtime.
Documentation
use super::*;
pub(crate) fn parse_s3_path(path: &str) -> Result<(Option<&str>, Option<&str>), RuntimeError> {
    let path = path.trim_start_matches('/');
    if path.is_empty() {
        return Ok((None, None));
    }
    let (bucket, key) = path.split_once('/').unwrap_or((path, ""));
    if bucket.is_empty() {
        return Err(RuntimeError::InvalidBucketName(path.to_string()));
    }
    if key.is_empty() {
        Ok((Some(bucket), None))
    } else {
        Ok((Some(bucket), Some(key)))
    }
}
pub(crate) fn resolve_s3_request_target(
    request: &S3HttpRequest,
) -> Result<S3RequestTarget, RuntimeError> {
    if let Some(bucket) = header(&request.headers, "host").and_then(virtual_host_bucket) {
        if !validate_bucket_name(&bucket) {
            return Err(RuntimeError::InvalidBucketName(bucket));
        }
        let key = percent_decode(request.path.trim_start_matches('/'));
        return Ok(S3RequestTarget {
            bucket: Some(bucket),
            key: if key.is_empty() {
                None
            } else {
                Some(key.to_string())
            },
        });
    }
    let (bucket, key) = parse_s3_path(&request.path)?;
    Ok(S3RequestTarget {
        bucket: bucket.map(str::to_string),
        key: key.map(percent_decode),
    })
}
pub(crate) fn resolve_s3_website_request_target(
    request: &S3HttpRequest,
) -> Result<Option<S3RequestTarget>, RuntimeError> {
    let Some(bucket) = header(&request.headers, "host").and_then(website_host_bucket) else {
        return Ok(None);
    };
    if !validate_bucket_name(&bucket) {
        return Err(RuntimeError::InvalidBucketName(bucket));
    }
    let key = percent_decode(request.path.trim_start_matches('/'));
    Ok(Some(S3RequestTarget {
        bucket: Some(bucket),
        key: if key.is_empty() { None } else { Some(key) },
    }))
}
pub(crate) fn virtual_host_bucket(host: &str) -> Option<String> {
    let host = host
        .split_once(':')
        .map(|(host, _)| host)
        .unwrap_or(host)
        .trim_end_matches('.');
    for suffix in [".s3.bucketwarden.test", ".s3.localhost", ".localhost"] {
        if let Some(bucket) = host.strip_suffix(suffix) {
            if !bucket.is_empty() && !bucket.contains('.') {
                return Some(bucket.to_string());
            }
        }
    }
    None
}
pub(crate) fn website_host_bucket(host: &str) -> Option<String> {
    let host = host
        .split_once(':')
        .map(|(host, _)| host)
        .unwrap_or(host)
        .trim_end_matches('.');
    for suffix in [
        ".s3-website.bucketwarden.test",
        ".s3-website.localhost",
        ".website.localhost",
    ] {
        if let Some(bucket) = host.strip_suffix(suffix) {
            if !bucket.is_empty() && !bucket.contains('.') {
                return Some(bucket.to_string());
            }
        }
    }
    None
}

pub(crate) fn is_directory_bucket_control_host(host: &str) -> bool {
    let host = host
        .split_once(':')
        .map(|(host, _)| host)
        .unwrap_or(host)
        .trim_end_matches('.');
    host.starts_with("s3express-control.")
}

pub(crate) fn is_object_lambda_host(host: &str) -> bool {
    let host = host
        .split_once(':')
        .map(|(host, _)| host)
        .unwrap_or(host)
        .trim_end_matches('.');
    host.contains(".s3-object-lambda.") || host.ends_with(".s3-object-lambda.bucketwarden.test")
}