mirror of
https://github.com/deuxfleurs-org/garage.git
synced 2026-08-06 12:57:41 +00:00
[dep-upgrade-202402] upgrade to http/hyper 1.x for tests
This commit is contained in:
@@ -66,7 +66,9 @@ aws-sdk-s3.workspace = true
|
||||
chrono.workspace = true
|
||||
http.workspace = true
|
||||
hmac.workspace = true
|
||||
http-body-util.workspace = true
|
||||
hyper.workspace = true
|
||||
hyper-util.workspace = true
|
||||
mktemp.workspace = true
|
||||
sha2.workspace = true
|
||||
|
||||
|
||||
@@ -5,12 +5,17 @@ use std::convert::TryFrom;
|
||||
|
||||
use chrono::{offset::Utc, DateTime};
|
||||
use hmac::{Hmac, Mac};
|
||||
use hyper::client::HttpConnector;
|
||||
use hyper::{Body, Client, Method, Request, Response, Uri};
|
||||
use http_body_util::BodyExt;
|
||||
use http_body_util::Full as FullBody;
|
||||
use hyper::{Method, Request, Response, Uri};
|
||||
use hyper_util::client::legacy::{connect::HttpConnector, Client};
|
||||
use hyper_util::rt::TokioExecutor;
|
||||
|
||||
use super::garage::{Instance, Key};
|
||||
use garage_api::signature;
|
||||
|
||||
pub type Body = FullBody<hyper::body::Bytes>;
|
||||
|
||||
/// You should ever only use this to send requests AWS sdk won't send,
|
||||
/// like to reproduce behavior of unusual implementations found to be
|
||||
/// problematic.
|
||||
@@ -19,7 +24,7 @@ pub struct CustomRequester {
|
||||
key: Key,
|
||||
uri: Uri,
|
||||
service: &'static str,
|
||||
client: Client<HttpConnector>,
|
||||
client: Client<HttpConnector, Body>,
|
||||
}
|
||||
|
||||
impl CustomRequester {
|
||||
@@ -28,7 +33,7 @@ impl CustomRequester {
|
||||
key: key.clone(),
|
||||
uri: instance.s3_uri(),
|
||||
service: "s3",
|
||||
client: Client::new(),
|
||||
client: Client::builder(TokioExecutor::new()).build_http(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +42,7 @@ impl CustomRequester {
|
||||
key: key.clone(),
|
||||
uri: instance.k2v_uri(),
|
||||
service: "k2v",
|
||||
client: Client::new(),
|
||||
client: Client::builder(TokioExecutor::new()).build_http(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +144,7 @@ impl<'a> RequestBuilder<'a> {
|
||||
self
|
||||
}
|
||||
|
||||
pub async fn send(&mut self) -> hyper::Result<Response<Body>> {
|
||||
pub async fn send(&mut self) -> Result<Response<Body>, String> {
|
||||
// TODO this is a bit incorrect in that path and query params should be url-encoded and
|
||||
// aren't, but this is good enought for now.
|
||||
|
||||
@@ -242,7 +247,22 @@ impl<'a> RequestBuilder<'a> {
|
||||
.method(self.method.clone())
|
||||
.body(Body::from(body))
|
||||
.unwrap();
|
||||
self.requester.client.request(request).await
|
||||
|
||||
let result = self
|
||||
.requester
|
||||
.client
|
||||
.request(request)
|
||||
.await
|
||||
.map_err(|err| format!("hyper client error: {}", err))?;
|
||||
|
||||
let (head, body) = result.into_parts();
|
||||
let body = Body::new(
|
||||
body.collect()
|
||||
.await
|
||||
.map_err(|err| format!("hyper client error in body.collect: {}", err))?
|
||||
.to_bytes(),
|
||||
);
|
||||
Ok(Response::from_parts(head, body))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,8 @@ use base64::prelude::*;
|
||||
use serde_json::json;
|
||||
|
||||
use crate::json_body;
|
||||
use hyper::{body::HttpBody, Method, StatusCode};
|
||||
use http_body_util::BodyExt;
|
||||
use hyper::{Method, StatusCode};
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_batch() {
|
||||
|
||||
@@ -7,7 +7,8 @@ use base64::prelude::*;
|
||||
use serde_json::json;
|
||||
|
||||
use crate::json_body;
|
||||
use hyper::{body::HttpBody, Method, StatusCode};
|
||||
use http_body_util::BodyExt;
|
||||
use hyper::{Method, StatusCode};
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_items_and_indices() {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use base64::prelude::*;
|
||||
use hyper::{body::HttpBody, Method, StatusCode};
|
||||
use http_body_util::BodyExt;
|
||||
use hyper::{Method, StatusCode};
|
||||
use std::time::Duration;
|
||||
|
||||
use assert_json_diff::assert_json_eq;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::common;
|
||||
|
||||
use hyper::{body::HttpBody, Method, StatusCode};
|
||||
use http_body_util::BodyExt;
|
||||
use hyper::{Method, StatusCode};
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_simple() {
|
||||
|
||||
@@ -11,9 +11,14 @@ mod k2v;
|
||||
#[cfg(feature = "k2v")]
|
||||
mod k2v_client;
|
||||
|
||||
use hyper::{body::HttpBody, Body, Response};
|
||||
use http_body_util::BodyExt;
|
||||
use hyper::{body::Body, Response};
|
||||
|
||||
pub async fn json_body(res: Response<Body>) -> serde_json::Value {
|
||||
pub async fn json_body<B>(res: Response<B>) -> serde_json::Value
|
||||
where
|
||||
B: Body,
|
||||
<B as Body>::Error: std::fmt::Debug,
|
||||
{
|
||||
let body = res.into_body().collect().await.unwrap().to_bytes();
|
||||
let res_body: serde_json::Value = serde_json::from_slice(&body).unwrap();
|
||||
res_body
|
||||
|
||||
@@ -8,15 +8,18 @@ use aws_sdk_s3::{
|
||||
types::{CorsConfiguration, CorsRule, ErrorDocument, IndexDocument, WebsiteConfiguration},
|
||||
};
|
||||
use http::{Request, StatusCode};
|
||||
use hyper::{
|
||||
body::{Body, HttpBody},
|
||||
Client,
|
||||
};
|
||||
use http_body_util::BodyExt;
|
||||
use http_body_util::Full as FullBody;
|
||||
use hyper::body::Bytes;
|
||||
use hyper_util::client::legacy::Client;
|
||||
use hyper_util::rt::TokioExecutor;
|
||||
use serde_json::json;
|
||||
|
||||
const BODY: &[u8; 16] = b"<h1>bonjour</h1>";
|
||||
const BODY_ERR: &[u8; 6] = b"erreur";
|
||||
|
||||
pub type Body = FullBody<Bytes>;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_website() {
|
||||
const BCKT_NAME: &str = "my-website";
|
||||
@@ -34,14 +37,14 @@ async fn test_website() {
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let client = Client::new();
|
||||
let client = Client::builder(TokioExecutor::new()).build_http();
|
||||
|
||||
let req = || {
|
||||
Request::builder()
|
||||
.method("GET")
|
||||
.uri(format!("http://127.0.0.1:{}/", ctx.garage.web_port))
|
||||
.header("Host", format!("{}.web.garage", BCKT_NAME))
|
||||
.body(Body::empty())
|
||||
.body(Body::new(Bytes::new()))
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
@@ -49,7 +52,7 @@ async fn test_website() {
|
||||
|
||||
assert_eq!(resp.status(), StatusCode::NOT_FOUND);
|
||||
assert_ne!(
|
||||
resp.into_body().collect().await.unwrap().to_bytes(),
|
||||
BodyExt::collect(resp.into_body()).await.unwrap().to_bytes(),
|
||||
BODY.as_ref()
|
||||
); /* check that we do not leak body */
|
||||
|
||||
@@ -61,7 +64,7 @@ async fn test_website() {
|
||||
ctx.garage.admin_port,
|
||||
BCKT_NAME.to_string()
|
||||
))
|
||||
.body(Body::empty())
|
||||
.body(Body::new(Bytes::new()))
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
@@ -103,7 +106,7 @@ async fn test_website() {
|
||||
"http://127.0.0.1:{0}/check?domain={1}",
|
||||
ctx.garage.admin_port, bname
|
||||
))
|
||||
.body(Body::empty())
|
||||
.body(Body::new(Bytes::new()))
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
@@ -136,7 +139,7 @@ async fn test_website() {
|
||||
ctx.garage.admin_port,
|
||||
BCKT_NAME.to_string()
|
||||
))
|
||||
.body(Body::empty())
|
||||
.body(Body::new(Bytes::new()))
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
@@ -248,7 +251,7 @@ async fn test_website_s3_api() {
|
||||
);
|
||||
}
|
||||
|
||||
let client = Client::new();
|
||||
let client = Client::builder(TokioExecutor::new()).build_http();
|
||||
|
||||
// Test direct requests with CORS
|
||||
{
|
||||
@@ -257,7 +260,7 @@ async fn test_website_s3_api() {
|
||||
.uri(format!("http://127.0.0.1:{}/site/", ctx.garage.web_port))
|
||||
.header("Host", format!("{}.web.garage", BCKT_NAME))
|
||||
.header("Origin", "https://example.com")
|
||||
.body(Body::empty())
|
||||
.body(Body::new(Bytes::new()))
|
||||
.unwrap();
|
||||
|
||||
let resp = client.request(req).await.unwrap();
|
||||
@@ -282,7 +285,7 @@ async fn test_website_s3_api() {
|
||||
ctx.garage.web_port
|
||||
))
|
||||
.header("Host", format!("{}.web.garage", BCKT_NAME))
|
||||
.body(Body::empty())
|
||||
.body(Body::new(Bytes::new()))
|
||||
.unwrap();
|
||||
|
||||
let resp = client.request(req).await.unwrap();
|
||||
@@ -302,7 +305,7 @@ async fn test_website_s3_api() {
|
||||
.header("Host", format!("{}.web.garage", BCKT_NAME))
|
||||
.header("Origin", "https://example.com")
|
||||
.header("Access-Control-Request-Method", "PUT")
|
||||
.body(Body::empty())
|
||||
.body(Body::new(Bytes::new()))
|
||||
.unwrap();
|
||||
|
||||
let resp = client.request(req).await.unwrap();
|
||||
@@ -326,7 +329,7 @@ async fn test_website_s3_api() {
|
||||
.header("Host", format!("{}.web.garage", BCKT_NAME))
|
||||
.header("Origin", "https://example.com")
|
||||
.header("Access-Control-Request-Method", "DELETE")
|
||||
.body(Body::empty())
|
||||
.body(Body::new(Bytes::new()))
|
||||
.unwrap();
|
||||
|
||||
let resp = client.request(req).await.unwrap();
|
||||
@@ -367,7 +370,7 @@ async fn test_website_s3_api() {
|
||||
.header("Host", format!("{}.web.garage", BCKT_NAME))
|
||||
.header("Origin", "https://example.com")
|
||||
.header("Access-Control-Request-Method", "PUT")
|
||||
.body(Body::empty())
|
||||
.body(Body::new(Bytes::new()))
|
||||
.unwrap();
|
||||
|
||||
let resp = client.request(req).await.unwrap();
|
||||
@@ -393,7 +396,7 @@ async fn test_website_s3_api() {
|
||||
.method("GET")
|
||||
.uri(format!("http://127.0.0.1:{}/site/", ctx.garage.web_port))
|
||||
.header("Host", format!("{}.web.garage", BCKT_NAME))
|
||||
.body(Body::empty())
|
||||
.body(Body::new(Bytes::new()))
|
||||
.unwrap();
|
||||
|
||||
let resp = client.request(req).await.unwrap();
|
||||
@@ -409,13 +412,13 @@ async fn test_website_s3_api() {
|
||||
async fn test_website_check_domain() {
|
||||
let ctx = common::context();
|
||||
|
||||
let client = Client::new();
|
||||
let client = Client::builder(TokioExecutor::new()).build_http();
|
||||
|
||||
let admin_req = || {
|
||||
Request::builder()
|
||||
.method("GET")
|
||||
.uri(format!("http://127.0.0.1:{}/check", ctx.garage.admin_port))
|
||||
.body(Body::empty())
|
||||
.body(Body::new(Bytes::new()))
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
@@ -439,7 +442,7 @@ async fn test_website_check_domain() {
|
||||
"http://127.0.0.1:{}/check?domain=",
|
||||
ctx.garage.admin_port
|
||||
))
|
||||
.body(Body::empty())
|
||||
.body(Body::new(Bytes::new()))
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
@@ -463,7 +466,7 @@ async fn test_website_check_domain() {
|
||||
"http://127.0.0.1:{}/check?domain=foobar",
|
||||
ctx.garage.admin_port
|
||||
))
|
||||
.body(Body::empty())
|
||||
.body(Body::new(Bytes::new()))
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
@@ -487,7 +490,7 @@ async fn test_website_check_domain() {
|
||||
"http://127.0.0.1:{}/check?domain=%E2%98%B9",
|
||||
ctx.garage.admin_port
|
||||
))
|
||||
.body(Body::empty())
|
||||
.body(Body::new(Bytes::new()))
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
|
||||
@@ -13,11 +13,13 @@ base64.workspace = true
|
||||
sha2.workspace = true
|
||||
hex.workspace = true
|
||||
http.workspace = true
|
||||
http-body-util.workspace = true
|
||||
log.workspace = true
|
||||
aws-sigv4.workspace = true
|
||||
aws-sdk-config.workspace = true
|
||||
percent-encoding.workspace = true
|
||||
hyper = { workspace = true, default-features = false, features = ["client", "http1", "http2"] }
|
||||
hyper = { workspace = true, default-features = false, features = ["http1", "http2"] }
|
||||
hyper-util.workspace = true
|
||||
hyper-rustls.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
|
||||
@@ -22,6 +22,8 @@ pub enum Error {
|
||||
Http(#[from] http::Error),
|
||||
#[error("hyper error: {0}")]
|
||||
Hyper(#[from] hyper::Error),
|
||||
#[error("hyper client error: {0}")]
|
||||
HyperClient(#[from] hyper_util::client::legacy::Error),
|
||||
#[error("invalid header: {0}")]
|
||||
Header(#[from] hyper::header::ToStrError),
|
||||
#[error("deserialization error: {0}")]
|
||||
|
||||
+11
-7
@@ -9,9 +9,11 @@ use percent_encoding::{utf8_percent_encode, AsciiSet, NON_ALPHANUMERIC};
|
||||
use http::header::{ACCEPT, CONTENT_TYPE};
|
||||
use http::status::StatusCode;
|
||||
use http::{HeaderName, HeaderValue, Request};
|
||||
use hyper::{body::Bytes, body::HttpBody, Body};
|
||||
use hyper::{client::connect::HttpConnector, Client as HttpClient};
|
||||
use http_body_util::{BodyExt, Full as FullBody};
|
||||
use hyper::{body::Body as BodyTrait, body::Bytes};
|
||||
use hyper_rustls::HttpsConnector;
|
||||
use hyper_util::client::legacy::{connect::HttpConnector, Client as HttpClient};
|
||||
use hyper_util::rt::TokioExecutor;
|
||||
|
||||
use aws_sdk_config::config::Credentials;
|
||||
use aws_sigv4::http_request::{sign, SignableBody, SignableRequest, SigningSettings};
|
||||
@@ -24,6 +26,8 @@ mod error;
|
||||
|
||||
pub use error::Error;
|
||||
|
||||
pub type Body = FullBody<Bytes>;
|
||||
|
||||
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(5);
|
||||
const DEFAULT_POLL_TIMEOUT: Duration = Duration::from_secs(300);
|
||||
const SERVICE: &str = "k2v";
|
||||
@@ -55,19 +59,19 @@ pub struct K2vClientConfig {
|
||||
pub struct K2vClient {
|
||||
config: K2vClientConfig,
|
||||
user_agent: HeaderValue,
|
||||
client: HttpClient<HttpsConnector<HttpConnector>>,
|
||||
client: HttpClient<HttpsConnector<HttpConnector>, Body>,
|
||||
}
|
||||
|
||||
impl K2vClient {
|
||||
/// Create a new K2V client.
|
||||
pub fn new(config: K2vClientConfig) -> Result<Self, Error> {
|
||||
let connector = hyper_rustls::HttpsConnectorBuilder::new()
|
||||
.with_native_roots()
|
||||
.with_native_roots()?
|
||||
.https_or_http()
|
||||
.enable_http1()
|
||||
.enable_http2()
|
||||
.build();
|
||||
let client = HttpClient::builder().build(connector);
|
||||
let client = HttpClient::builder(TokioExecutor::new()).build(connector);
|
||||
let user_agent: std::borrow::Cow<str> = match &config.user_agent {
|
||||
Some(ua) => ua.into(),
|
||||
None => format!("k2v/{}", env!("CARGO_PKG_VERSION")).into(),
|
||||
@@ -395,7 +399,7 @@ impl K2vClient {
|
||||
// Sign and then apply the signature to the request
|
||||
let (signing_instructions, _signature) =
|
||||
sign(signable_request, &signing_params)?.into_parts();
|
||||
signing_instructions.apply_to_request_http0x(&mut req);
|
||||
signing_instructions.apply_to_request_http1x(&mut req);
|
||||
|
||||
// Send and wait for timeout
|
||||
let res = tokio::select! {
|
||||
@@ -416,7 +420,7 @@ impl K2vClient {
|
||||
};
|
||||
|
||||
let body = match res.status {
|
||||
StatusCode::OK => body.collect().await?.to_bytes(),
|
||||
StatusCode::OK => BodyExt::collect(body).await?.to_bytes(),
|
||||
StatusCode::NO_CONTENT => Bytes::new(),
|
||||
StatusCode::NOT_FOUND => return Err(Error::NotFound),
|
||||
StatusCode::NOT_MODIFIED => Bytes::new(),
|
||||
|
||||
Reference in New Issue
Block a user