made it also possible to download individual beacons as opposed to just the installer, to provide more options and make it easier to test
97 lines
2.8 KiB
Rust
97 lines
2.8 KiB
Rust
use std::{future::Future, pin::Pin, task::{self, Poll}};
|
|
|
|
use http::Uri;
|
|
use hyper_util::{client::legacy::Client, rt::{TokioExecutor, TokioIo}};
|
|
use rustls::RootCertStore;
|
|
use tower_service::Service;
|
|
|
|
use sparse_actions::payload_types::Parameters;
|
|
|
|
use crate::{adapter, error, tcp::{self, setup_network}};
|
|
|
|
#[derive(Clone)]
|
|
pub struct ServerConnector<T>
|
|
where
|
|
T: adapter::BeaconAdapter + Clone + Send + 'static
|
|
{
|
|
adapter: T,
|
|
parameters: Parameters
|
|
}
|
|
|
|
impl<T> Service<Uri> for ServerConnector<T>
|
|
where
|
|
T: adapter::BeaconAdapter + Clone + Send + Sync + 'static
|
|
{
|
|
type Response = TokioIo<tcp::NetInterfaceHandle>;
|
|
type Error = error::BeaconError<T::Error>;
|
|
type Future = Pin<Box<
|
|
dyn Future<Output = Result<Self::Response, Self::Error>> + Send
|
|
>>;
|
|
|
|
fn poll_ready(&mut self, _: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>> {
|
|
Poll::Ready(Ok(()))
|
|
}
|
|
|
|
fn call(&mut self, _: Uri) -> Self::Future {
|
|
Box::pin({
|
|
let adapter = self.adapter.clone();
|
|
let params = self.parameters.clone();
|
|
async move {
|
|
setup_network(adapter, params)
|
|
.await
|
|
.map(TokioIo::new)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
pub async fn obtain_https_client<T, B>(
|
|
adapter: &T,
|
|
parameters: &Parameters,
|
|
) -> Result<Client<hyper_rustls::HttpsConnector<ServerConnector<T>>, B>, error::BeaconError<T::Error>>
|
|
where
|
|
T: adapter::BeaconAdapter + Clone + Send + Sync + 'static,
|
|
B: hyper::body::Body + Send,
|
|
<B as hyper::body::Body>::Data: Send
|
|
{
|
|
let server_cert = rustls::pki_types::CertificateDer::from(
|
|
parameters.pubkey_cert[..parameters.pubkey_cert_size as usize].to_owned()
|
|
);
|
|
|
|
let client_cert = rustls::pki_types::CertificateDer::from(
|
|
parameters.client_cert[..parameters.client_cert_length as usize].to_owned()
|
|
);
|
|
|
|
let client_key = rustls::pki_types::PrivateKeyDer::try_from(
|
|
parameters.client_key[..parameters.client_key_length as usize].to_owned()
|
|
)
|
|
.map_err(|_| rustls::Error::InvalidCertificate(
|
|
rustls::CertificateError::BadEncoding
|
|
))?;
|
|
|
|
let mut root_store = RootCertStore::empty();
|
|
root_store.add(server_cert.clone())?;
|
|
|
|
let tls_config = rustls::ClientConfig::builder()
|
|
.with_root_certificates(root_store)
|
|
.with_client_auth_cert(
|
|
vec![client_cert, server_cert],
|
|
client_key
|
|
)?;
|
|
|
|
let https = hyper_rustls::HttpsConnectorBuilder::new()
|
|
.with_tls_config(tls_config)
|
|
.https_only()
|
|
.enable_http1()
|
|
.enable_http2()
|
|
.wrap_connector(ServerConnector {
|
|
adapter: adapter.clone(),
|
|
parameters: parameters.clone()
|
|
});
|
|
|
|
let client = Client::builder(TokioExecutor::new())
|
|
.build(https);
|
|
|
|
Ok(client)
|
|
}
|