[dep-upgrade-202402] wip: port to http/hyper crates v1

This commit is contained in:
Alex Auvolat
2024-02-05 18:49:54 +01:00
parent 6e69a1fffc
commit 0bb5b77530
28 changed files with 765 additions and 477 deletions
+18 -13
View File
@@ -5,7 +5,7 @@ use async_trait::async_trait;
use futures::future::Future;
use http::header::{ACCESS_CONTROL_ALLOW_METHODS, ACCESS_CONTROL_ALLOW_ORIGIN, ALLOW};
use hyper::{Body, Request, Response, StatusCode};
use hyper::{body::Incoming as IncomingBody, Request, Response, StatusCode};
use opentelemetry::trace::SpanRef;
@@ -27,7 +27,9 @@ use crate::admin::error::*;
use crate::admin::key::*;
use crate::admin::router_v0;
use crate::admin::router_v1::{Authorization, Endpoint};
use crate::helpers::host_to_bucket;
use crate::helpers::*;
pub type ResBody = BoxBody<Error>;
pub struct AdminApiServer {
garage: Arc<Garage>,
@@ -71,16 +73,19 @@ impl AdminApiServer {
.await
}
fn handle_options(&self, _req: &Request<Body>) -> Result<Response<Body>, Error> {
fn handle_options(&self, _req: &Request<IncomingBody>) -> Result<Response<ResBody>, Error> {
Ok(Response::builder()
.status(StatusCode::NO_CONTENT)
.header(ALLOW, "OPTIONS, GET, POST")
.header(ACCESS_CONTROL_ALLOW_METHODS, "OPTIONS, GET, POST")
.header(ACCESS_CONTROL_ALLOW_ORIGIN, "*")
.body(Body::empty())?)
.body(empty_body())?)
}
async fn handle_check_domain(&self, req: Request<Body>) -> Result<Response<Body>, Error> {
async fn handle_check_domain(
&self,
req: Request<IncomingBody>,
) -> Result<Response<ResBody>, Error> {
let query_params: HashMap<String, String> = req
.uri()
.query()
@@ -104,7 +109,7 @@ impl AdminApiServer {
if self.check_domain(domain).await? {
Ok(Response::builder()
.status(StatusCode::OK)
.body(Body::from(format!(
.body(string_body(format!(
"Domain '{domain}' is managed by Garage"
)))?)
} else {
@@ -167,7 +172,7 @@ impl AdminApiServer {
}
}
fn handle_health(&self) -> Result<Response<Body>, Error> {
fn handle_health(&self) -> Result<Response<ResBody>, Error> {
let health = self.garage.system.health();
let (status, status_str) = match health.status {
@@ -189,10 +194,10 @@ impl AdminApiServer {
Ok(Response::builder()
.status(status)
.header(http::header::CONTENT_TYPE, "text/plain")
.body(Body::from(status_str))?)
.body(string_body(status_str))?)
}
fn handle_metrics(&self) -> Result<Response<Body>, Error> {
fn handle_metrics(&self) -> Result<Response<ResBody>, Error> {
#[cfg(feature = "metrics")]
{
use opentelemetry::trace::Tracer;
@@ -212,7 +217,7 @@ impl AdminApiServer {
Ok(Response::builder()
.status(StatusCode::OK)
.header(http::header::CONTENT_TYPE, encoder.format_type())
.body(Body::from(buffer))?)
.body(bytes_body(buffer.into()))?)
}
#[cfg(not(feature = "metrics"))]
Err(Error::bad_request(
@@ -229,7 +234,7 @@ impl ApiHandler for AdminApiServer {
type Endpoint = Endpoint;
type Error = Error;
fn parse_endpoint(&self, req: &Request<Body>) -> Result<Endpoint, Error> {
fn parse_endpoint(&self, req: &Request<IncomingBody>) -> Result<Endpoint, Error> {
if req.uri().path().starts_with("/v0/") {
let endpoint_v0 = router_v0::Endpoint::from_request(req)?;
Endpoint::from_v0(endpoint_v0)
@@ -240,9 +245,9 @@ impl ApiHandler for AdminApiServer {
async fn handle(
&self,
req: Request<Body>,
req: Request<IncomingBody>,
endpoint: Endpoint,
) -> Result<Response<Body>, Error> {
) -> Result<Response<ResBody>, Error> {
let expected_auth_header =
match endpoint.authorization_type() {
Authorization::None => None,
+18 -17
View File
@@ -1,7 +1,7 @@
use std::collections::HashMap;
use std::sync::Arc;
use hyper::{Body, Request, Response, StatusCode};
use hyper::{body::Incoming as IncomingBody, Request, Response, StatusCode};
use serde::{Deserialize, Serialize};
use garage_util::crdt::*;
@@ -17,12 +17,13 @@ use garage_model::permission::*;
use garage_model::s3::mpu_table;
use garage_model::s3::object_table::*;
use crate::admin::api_server::ResBody;
use crate::admin::error::*;
use crate::admin::key::ApiBucketKeyPerm;
use crate::common_error::CommonError;
use crate::helpers::{json_ok_response, parse_json_body};
use crate::helpers::*;
pub async fn handle_list_buckets(garage: &Arc<Garage>) -> Result<Response<Body>, Error> {
pub async fn handle_list_buckets(garage: &Arc<Garage>) -> Result<Response<ResBody>, Error> {
let buckets = garage
.bucket_table
.get_range(
@@ -90,7 +91,7 @@ pub async fn handle_get_bucket_info(
garage: &Arc<Garage>,
id: Option<String>,
global_alias: Option<String>,
) -> Result<Response<Body>, Error> {
) -> Result<Response<ResBody>, Error> {
let bucket_id = match (id, global_alias) {
(Some(id), None) => parse_bucket_id(&id)?,
(None, Some(ga)) => garage
@@ -111,7 +112,7 @@ pub async fn handle_get_bucket_info(
async fn bucket_info_results(
garage: &Arc<Garage>,
bucket_id: Uuid,
) -> Result<Response<Body>, Error> {
) -> Result<Response<ResBody>, Error> {
let bucket = garage
.bucket_helper()
.get_existing_bucket(bucket_id)
@@ -268,8 +269,8 @@ struct GetBucketInfoKey {
pub async fn handle_create_bucket(
garage: &Arc<Garage>,
req: Request<Body>,
) -> Result<Response<Body>, Error> {
req: Request<IncomingBody>,
) -> Result<Response<ResBody>, Error> {
let req = parse_json_body::<CreateBucketRequest>(req).await?;
if let Some(ga) = &req.global_alias {
@@ -360,7 +361,7 @@ struct CreateBucketLocalAlias {
pub async fn handle_delete_bucket(
garage: &Arc<Garage>,
id: String,
) -> Result<Response<Body>, Error> {
) -> Result<Response<ResBody>, Error> {
let helper = garage.bucket_helper();
let bucket_id = parse_bucket_id(&id)?;
@@ -403,14 +404,14 @@ pub async fn handle_delete_bucket(
Ok(Response::builder()
.status(StatusCode::NO_CONTENT)
.body(Body::empty())?)
.body(empty_body())?)
}
pub async fn handle_update_bucket(
garage: &Arc<Garage>,
id: String,
req: Request<Body>,
) -> Result<Response<Body>, Error> {
req: Request<IncomingBody>,
) -> Result<Response<ResBody>, Error> {
let req = parse_json_body::<UpdateBucketRequest>(req).await?;
let bucket_id = parse_bucket_id(&id)?;
@@ -470,9 +471,9 @@ struct UpdateBucketWebsiteAccess {
pub async fn handle_bucket_change_key_perm(
garage: &Arc<Garage>,
req: Request<Body>,
req: Request<IncomingBody>,
new_perm_flag: bool,
) -> Result<Response<Body>, Error> {
) -> Result<Response<ResBody>, Error> {
let req = parse_json_body::<BucketKeyPermChangeRequest>(req).await?;
let bucket_id = parse_bucket_id(&req.bucket_id)?;
@@ -526,7 +527,7 @@ pub async fn handle_global_alias_bucket(
garage: &Arc<Garage>,
bucket_id: String,
alias: String,
) -> Result<Response<Body>, Error> {
) -> Result<Response<ResBody>, Error> {
let bucket_id = parse_bucket_id(&bucket_id)?;
garage
@@ -541,7 +542,7 @@ pub async fn handle_global_unalias_bucket(
garage: &Arc<Garage>,
bucket_id: String,
alias: String,
) -> Result<Response<Body>, Error> {
) -> Result<Response<ResBody>, Error> {
let bucket_id = parse_bucket_id(&bucket_id)?;
garage
@@ -557,7 +558,7 @@ pub async fn handle_local_alias_bucket(
bucket_id: String,
access_key_id: String,
alias: String,
) -> Result<Response<Body>, Error> {
) -> Result<Response<ResBody>, Error> {
let bucket_id = parse_bucket_id(&bucket_id)?;
garage
@@ -573,7 +574,7 @@ pub async fn handle_local_unalias_bucket(
bucket_id: String,
access_key_id: String,
alias: String,
) -> Result<Response<Body>, Error> {
) -> Result<Response<ResBody>, Error> {
let bucket_id = parse_bucket_id(&bucket_id)?;
garage
+13 -12
View File
@@ -1,7 +1,7 @@
use std::net::SocketAddr;
use std::sync::Arc;
use hyper::{Body, Request, Response};
use hyper::{body::Incoming as IncomingBody, Request, Response};
use serde::{Deserialize, Serialize};
use garage_util::crdt::*;
@@ -11,10 +11,11 @@ use garage_rpc::layout;
use garage_model::garage::Garage;
use crate::admin::api_server::ResBody;
use crate::admin::error::*;
use crate::helpers::{json_ok_response, parse_json_body};
pub async fn handle_get_cluster_status(garage: &Arc<Garage>) -> Result<Response<Body>, Error> {
pub async fn handle_get_cluster_status(garage: &Arc<Garage>) -> Result<Response<ResBody>, Error> {
let res = GetClusterStatusResponse {
node: hex::encode(garage.system.id),
garage_version: garage_util::version::garage_version(),
@@ -39,7 +40,7 @@ pub async fn handle_get_cluster_status(garage: &Arc<Garage>) -> Result<Response<
Ok(json_ok_response(&res)?)
}
pub async fn handle_get_cluster_health(garage: &Arc<Garage>) -> Result<Response<Body>, Error> {
pub async fn handle_get_cluster_health(garage: &Arc<Garage>) -> Result<Response<ResBody>, Error> {
use garage_rpc::system::ClusterHealthStatus;
let health = garage.system.health();
let health = ClusterHealth {
@@ -61,8 +62,8 @@ pub async fn handle_get_cluster_health(garage: &Arc<Garage>) -> Result<Response<
pub async fn handle_connect_cluster_nodes(
garage: &Arc<Garage>,
req: Request<Body>,
) -> Result<Response<Body>, Error> {
req: Request<IncomingBody>,
) -> Result<Response<ResBody>, Error> {
let req = parse_json_body::<Vec<String>>(req).await?;
let res = futures::future::join_all(req.iter().map(|node| garage.system.connect(node)))
@@ -83,7 +84,7 @@ pub async fn handle_connect_cluster_nodes(
Ok(json_ok_response(&res)?)
}
pub async fn handle_get_cluster_layout(garage: &Arc<Garage>) -> Result<Response<Body>, Error> {
pub async fn handle_get_cluster_layout(garage: &Arc<Garage>) -> Result<Response<ResBody>, Error> {
let res = format_cluster_layout(&garage.system.get_cluster_layout());
Ok(json_ok_response(&res)?)
@@ -203,8 +204,8 @@ struct KnownNodeResp {
pub async fn handle_update_cluster_layout(
garage: &Arc<Garage>,
req: Request<Body>,
) -> Result<Response<Body>, Error> {
req: Request<IncomingBody>,
) -> Result<Response<ResBody>, Error> {
let updates = parse_json_body::<UpdateClusterLayoutRequest>(req).await?;
let mut layout = garage.system.get_cluster_layout();
@@ -243,8 +244,8 @@ pub async fn handle_update_cluster_layout(
pub async fn handle_apply_cluster_layout(
garage: &Arc<Garage>,
req: Request<Body>,
) -> Result<Response<Body>, Error> {
req: Request<IncomingBody>,
) -> Result<Response<ResBody>, Error> {
let param = parse_json_body::<ApplyRevertLayoutRequest>(req).await?;
let layout = garage.system.get_cluster_layout();
@@ -261,8 +262,8 @@ pub async fn handle_apply_cluster_layout(
pub async fn handle_revert_cluster_layout(
garage: &Arc<Garage>,
req: Request<Body>,
) -> Result<Response<Body>, Error> {
req: Request<IncomingBody>,
) -> Result<Response<ResBody>, Error> {
let param = parse_json_body::<ApplyRevertLayoutRequest>(req).await?;
let layout = garage.system.get_cluster_layout();
+6 -5
View File
@@ -1,13 +1,13 @@
use err_derive::Error;
use hyper::header::HeaderValue;
use hyper::{Body, HeaderMap, StatusCode};
use hyper::{HeaderMap, StatusCode};
pub use garage_model::helper::error::Error as HelperError;
use crate::common_error::CommonError;
pub use crate::common_error::{CommonErrorDerivative, OkOrBadRequest, OkOrInternalError};
use crate::generic_server::ApiError;
use crate::helpers::CustomApiErrorBody;
use crate::helpers::{BytesBody, CustomApiErrorBody};
/// Errors of this crate
#[derive(Debug, Error)]
@@ -77,14 +77,14 @@ impl ApiError for Error {
header_map.append(header::CONTENT_TYPE, "application/json".parse().unwrap());
}
fn http_body(&self, garage_region: &str, path: &str) -> Body {
fn http_body(&self, garage_region: &str, path: &str) -> BytesBody {
let error = CustomApiErrorBody {
code: self.code().to_string(),
message: format!("{}", self),
path: path.to_string(),
region: garage_region.to_string(),
};
Body::from(serde_json::to_string_pretty(&error).unwrap_or_else(|_| {
let error_str = serde_json::to_string_pretty(&error).unwrap_or_else(|_| {
r#"
{
"code": "InternalError",
@@ -92,6 +92,7 @@ impl ApiError for Error {
}
"#
.into()
}))
});
BytesBody::from(bytes::Bytes::from(error_str.into_bytes()))
}
}
+17 -13
View File
@@ -1,7 +1,7 @@
use std::collections::HashMap;
use std::sync::Arc;
use hyper::{Body, Request, Response, StatusCode};
use hyper::{body::Incoming as IncomingBody, Request, Response, StatusCode};
use serde::{Deserialize, Serialize};
use garage_table::*;
@@ -9,10 +9,11 @@ use garage_table::*;
use garage_model::garage::Garage;
use garage_model::key_table::*;
use crate::admin::api_server::ResBody;
use crate::admin::error::*;
use crate::helpers::{is_default, json_ok_response, parse_json_body};
use crate::helpers::*;
pub async fn handle_list_keys(garage: &Arc<Garage>) -> Result<Response<Body>, Error> {
pub async fn handle_list_keys(garage: &Arc<Garage>) -> Result<Response<ResBody>, Error> {
let res = garage
.key_table
.get_range(
@@ -45,7 +46,7 @@ pub async fn handle_get_key_info(
id: Option<String>,
search: Option<String>,
show_secret_key: bool,
) -> Result<Response<Body>, Error> {
) -> Result<Response<ResBody>, Error> {
let key = if let Some(id) = id {
garage.key_helper().get_existing_key(&id).await?
} else if let Some(search) = search {
@@ -62,8 +63,8 @@ pub async fn handle_get_key_info(
pub async fn handle_create_key(
garage: &Arc<Garage>,
req: Request<Body>,
) -> Result<Response<Body>, Error> {
req: Request<IncomingBody>,
) -> Result<Response<ResBody>, Error> {
let req = parse_json_body::<CreateKeyRequest>(req).await?;
let key = Key::new(req.name.as_deref().unwrap_or("Unnamed key"));
@@ -80,8 +81,8 @@ struct CreateKeyRequest {
pub async fn handle_import_key(
garage: &Arc<Garage>,
req: Request<Body>,
) -> Result<Response<Body>, Error> {
req: Request<IncomingBody>,
) -> Result<Response<ResBody>, Error> {
let req = parse_json_body::<ImportKeyRequest>(req).await?;
let prev_key = garage.key_table.get(&EmptyKey, &req.access_key_id).await?;
@@ -111,8 +112,8 @@ struct ImportKeyRequest {
pub async fn handle_update_key(
garage: &Arc<Garage>,
id: String,
req: Request<Body>,
) -> Result<Response<Body>, Error> {
req: Request<IncomingBody>,
) -> Result<Response<ResBody>, Error> {
let req = parse_json_body::<UpdateKeyRequest>(req).await?;
let mut key = garage.key_helper().get_existing_key(&id).await?;
@@ -146,7 +147,10 @@ struct UpdateKeyRequest {
deny: Option<KeyPerm>,
}
pub async fn handle_delete_key(garage: &Arc<Garage>, id: String) -> Result<Response<Body>, Error> {
pub async fn handle_delete_key(
garage: &Arc<Garage>,
id: String,
) -> Result<Response<ResBody>, Error> {
let mut key = garage.key_helper().get_existing_key(&id).await?;
key.state.as_option().unwrap();
@@ -155,14 +159,14 @@ pub async fn handle_delete_key(garage: &Arc<Garage>, id: String) -> Result<Respo
Ok(Response::builder()
.status(StatusCode::NO_CONTENT)
.body(Body::empty())?)
.body(empty_body())?)
}
async fn key_info_results(
garage: &Arc<Garage>,
key: Key,
show_secret: bool,
) -> Result<Response<Body>, Error> {
) -> Result<Response<ResBody>, Error> {
let mut relevant_buckets = HashMap::new();
let key_state = key.state.as_option().unwrap();