Skip to content

Commit

Permalink
Upgrade to hyper 1 and hyper-rustls 0.27
Browse files Browse the repository at this point in the history
  • Loading branch information
djc committed May 26, 2024
1 parent cbc9de6 commit be61d9c
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 24 deletions.
10 changes: 7 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,20 @@ readme = "README.md"
license = "MIT"

[features]
default = ["hyper-rustls/rustls-native-certs"]
default = ["hyper-rustls/rustls-native-certs", "hyper-rustls/ring"]
webpki-roots = ["hyper-rustls/webpki-roots"]

[dependencies]
async-trait = "0.1"
base64 = "0.22"
bytes = "1"
chrono = { version = "0.4.31", features = ["serde"] }
home = "0.5.5"
hyper = { version = "0.14.2", features = ["client", "runtime", "http2"] }
hyper-rustls = { version = "0.25", default-features = false, features = ["http1", "http2", "ring", "tokio-runtime"] }
http = "1"
http-body-util = "0.1"
hyper = { version = "1", default-features = false, features = ["client", "http1", "http2"] }
hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2"] }
hyper-util = { version = "0.1.4", features = ["client-legacy"] }
ring = "0.17"
rustls = "0.22"
rustls-pemfile = "2"
Expand Down
9 changes: 5 additions & 4 deletions src/config_default_credentials.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use std::fs;
use std::sync::Arc;

use async_trait::async_trait;
use hyper::body::Body;
use bytes::Bytes;
use http_body_util::Full;
use hyper::header::CONTENT_TYPE;
use hyper::{Method, Request};
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -57,15 +58,15 @@ impl ConfigDefaultCredentials {
.method(Method::POST)
.uri(DEFAULT_TOKEN_GCP_URI)
.header(CONTENT_TYPE, "application/json")
.body(Body::from(
serde_json::to_string(&RefreshRequest {
.body(Full::from(Bytes::from(
serde_json::to_vec(&RefreshRequest {
client_id: &cred.client_id,
client_secret: &cred.client_secret,
grant_type: "refresh_token",
refresh_token: &cred.refresh_token,
})
.unwrap(),
))
)))
.unwrap()
},
"ConfigDefaultCredentials",
Expand Down
15 changes: 10 additions & 5 deletions src/custom_service_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ use std::{env, fmt};

use async_trait::async_trait;
use base64::{engine::general_purpose::URL_SAFE, Engine};
use bytes::Bytes;
use chrono::Utc;
use hyper::body::Body;
use http_body_util::Full;
use hyper::header::CONTENT_TYPE;
use hyper::Request;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -75,16 +76,20 @@ impl CustomServiceAccount {
async fn fetch_token(&self, scopes: &[&str]) -> Result<Arc<Token>, Error> {
let jwt =
Claims::new(&self.credentials, scopes, self.subject.as_deref()).to_jwt(&self.signer)?;
let body = form_urlencoded::Serializer::new(String::new())
.extend_pairs(&[("grant_type", GRANT_TYPE), ("assertion", jwt.as_str())])
.finish();
let body = Bytes::from(
form_urlencoded::Serializer::new(String::new())
.extend_pairs(&[("grant_type", GRANT_TYPE), ("assertion", jwt.as_str())])
.finish()
.into_bytes(),
);

let token = self
.client
.token(
&|| {
Request::post(&self.credentials.token_uri)
.header(CONTENT_TYPE, "application/x-www-form-urlencoded")
.body(Body::from(body.clone()))
.body(Full::from(body.clone()))
.unwrap()
},
"CustomServiceAccount",
Expand Down
7 changes: 4 additions & 3 deletions src/metadata_service_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use std::str;
use std::sync::Arc;

use async_trait::async_trait;
use hyper::body::Body;
use bytes::Bytes;
use http_body_util::Full;
use hyper::{Method, Request};
use tokio::sync::RwLock;
use tracing::{debug, instrument, Level};
Expand Down Expand Up @@ -85,12 +86,12 @@ impl TokenProvider for MetadataServiceAccount {
}
}

fn metadata_request(uri: &str) -> Request<Body> {
fn metadata_request(uri: &str) -> Request<Full<Bytes>> {
Request::builder()
.method(Method::GET)
.uri(uri)
.header("Metadata-Flavor", "Google")
.body(Body::empty())
.body(Full::from(Bytes::new()))
.unwrap()
}

Expand Down
29 changes: 20 additions & 9 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@ use std::fmt;
use std::sync::Arc;
use std::time::Duration;

use bytes::Buf;
use chrono::{DateTime, Utc};
use hyper::body::{Body, Bytes};
use hyper::{Client, Request};
use http_body_util::{BodyExt, Full};
use hyper::body::Bytes;
use hyper::Request;
use hyper_rustls::HttpsConnectorBuilder;
use hyper_util::client::legacy::Client;
use hyper_util::rt::TokioExecutor;
use ring::rand::SystemRandom;
use ring::signature::{RsaKeyPair, RSA_PKCS1_SHA256};
use serde::{Deserialize, Deserializer};
Expand All @@ -15,7 +19,10 @@ use crate::Error;

#[derive(Clone, Debug)]
pub(crate) struct HttpClient {
inner: Client<hyper_rustls::HttpsConnector<hyper::client::HttpConnector>>,
inner: Client<
hyper_rustls::HttpsConnector<hyper_util::client::legacy::connect::HttpConnector>,
Full<Bytes>,
>,
}

impl HttpClient {
Expand All @@ -30,13 +37,14 @@ impl HttpClient {
})?;

Ok(Self {
inner: Client::builder().build::<_, Body>(https.https_or_http().enable_http2().build()),
inner: Client::builder(TokioExecutor::new())
.build(https.https_or_http().enable_http2().build()),
})
}

pub(crate) async fn token(
&self,
request: &impl Fn() -> Request<Body>,
request: &impl Fn() -> Request<Full<Bytes>>,
provider: &'static str,
) -> Result<Arc<Token>, Error> {
let mut retries = 0;
Expand Down Expand Up @@ -64,21 +72,24 @@ impl HttpClient {

pub(crate) async fn request(
&self,
req: Request<Body>,
req: Request<Full<Bytes>>,
provider: &'static str,
) -> Result<Bytes, Error> {
debug!(url = ?req.uri(), provider, "requesting token");
let (parts, body) = self
.inner
.request(req)
.await
.map_err(|err| Error::Http("HTTP request failed", err))?
.map_err(|err| Error::Other("HTTP request failed", Box::new(err)))?
.into_parts();

let body = hyper::body::to_bytes(body)
let mut body = body
.collect()
.await
.map_err(|err| Error::Http("failed to read HTTP response body", err))?;
.map_err(|err| Error::Http("failed to read HTTP response body", err))?
.aggregate();

let body = body.copy_to_bytes(body.remaining());
if !parts.status.is_success() {
let body = String::from_utf8_lossy(body.as_ref());
warn!(%body, status = ?parts.status, "token request failed");
Expand Down

0 comments on commit be61d9c

Please sign in to comment.