refactor: add dragonfly-client-backend crate (#298)

Signed-off-by: Gaius <gaius.qi@gmail.com>
This commit is contained in:
Gaius 2024-03-05 17:01:36 +08:00 committed by GitHub
parent a653b401da
commit 2fda6c7ea3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 93 additions and 18 deletions

15
Cargo.lock generated
View File

@ -610,13 +610,13 @@ dependencies = [
"clap",
"dashmap",
"dragonfly-api",
"dragonfly-client-backend",
"dragonfly-client-config",
"dragonfly-client-core",
"dragonfly-client-storage",
"dragonfly-client-util",
"fs2",
"fslock",
"futures",
"futures-util",
"hashring",
"http 1.0.0",
@ -662,6 +662,19 @@ dependencies = [
"warp",
]
[[package]]
name = "dragonfly-client-backend"
version = "0.1.17"
dependencies = [
"dragonfly-client-core",
"futures",
"reqwest",
"rustls 0.21.10",
"rustls-pki-types",
"tokio",
"tokio-util",
]
[[package]]
name = "dragonfly-client-config"
version = "0.1.17"

View File

@ -23,7 +23,7 @@ name = "dfstore"
path = "src/bin/dfstore/main.rs"
[workspace]
members = ["dragonfly-client-config","dragonfly-client-core", "dragonfly-client-storage", "dragonfly-client-util"]
members = [ "dragonfly-client-backend","dragonfly-client-config","dragonfly-client-core", "dragonfly-client-storage", "dragonfly-client-util"]
[workspace.package]
version = "0.1.17"
@ -36,9 +36,10 @@ readme = "README.md"
edition = "2021"
[workspace.dependencies]
dragonfly-client-core = { path = "dragonfly-client-core", version = "*" }
dragonfly-client-config = { path = "dragonfly-client-config", version = "*" }
dragonfly-client-storage = { path = "dragonfly-client-storage", version = "*" }
dragonfly-client-core = { path = "dragonfly-client-core", version = "0.1.17" }
dragonfly-client-config = { path = "dragonfly-client-config", version = "0.1.17" }
dragonfly-client-storage = { path = "dragonfly-client-storage", version = "0.1.17" }
dragonfly-client-backend = { path = "dragonfly-client-backend", version = "0.1.17" }
dragonfly-client-util = { path = "dragonfly-client-util", version = "*" }
thiserror = "1.0"
dragonfly-api = "2.0.102"
@ -46,6 +47,7 @@ reqwest = { version = "0.11.24", features = ["stream", "native-tls", "rustls-tls
rcgen = { version = "0.12.1", features = ["x509-parser"] }
hyper = { version = "1.1", features = ["full"] }
hyper-util = { version = "0.1.2", features = ["client", "client-legacy", "tokio", "server-auto", "http1", "http2"] }
hyper-rustls = { version = "0.26", features = [ "http1", "http2", "logging" ] }
http-range-header = "0.4.0"
tracing = "0.1"
url = "2.4.0"
@ -76,9 +78,11 @@ chrono = { version = "0.4.34", features = ["serde"] }
dragonfly-client-core.workspace = true
dragonfly-client-config.workspace = true
dragonfly-client-storage.workspace = true
dragonfly-client-backend.workspace = true
dragonfly-client-util.workspace = true
rcgen.workspace = true
hyper-util.workspace = true
hyper-rustls.workspace = true
tracing.workspace = true
validator.workspace = true
humantime.workspace = true
@ -88,6 +92,7 @@ chrono.workspace = true
prost-wkt-types.workspace = true
tokio.workspace = true
tokio-util.workspace = true
rustls-pki-types.workspace = true
clap = { version = "4.5.1", features = [ "derive" ] }
tracing-log = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
@ -103,7 +108,6 @@ tonic-health = "0.9.2"
tonic-reflection = "0.9.2"
tokio-stream = "0.1.14"
reqwest = { version = "0.11.24", features = ["stream", "native-tls", "rustls-tls"] }
futures = "0.3.28"
bytes = "1.4"
rocksdb = "0.22.0"
dragonfly-api = "2.0.102"
@ -125,8 +129,6 @@ openssl = { version = "0.10", features = ["vendored"] }
leaky-bucket = "1.0.1"
hyper = { version = "1.1", features = ["full"] }
tokio-rustls = "0.25"
hyper-rustls = { version = "0.26", features = [ "http1", "http2", "logging" ] }
http-body-util = "0.1.0"
futures-util = "0.3.30"
rustls = "0.22.2"
rustls-pki-types = "1.2.0"

View File

@ -16,6 +16,9 @@ COPY dragonfly-client-config/src ./dragonfly-client-config/src
COPY dragonfly-client-storage/Cargo.toml ./dragonfly-client-storage/Cargo.toml
COPY dragonfly-client-storage/src ./dragonfly-client-storage/src
COPY dragonfly-client-backend/Cargo.toml ./dragonfly-client-backend/Cargo.toml
COPY dragonfly-client-backend/src ./dragonfly-client-backend/src
COPY dragonfly-client-util/Cargo.toml ./dragonfly-client-util/Cargo.toml
COPY dragonfly-client-util/src ./dragonfly-client-util/src

View File

@ -0,0 +1,22 @@
[package]
name = "dragonfly-client-backend"
description = "Backend for the dragonfly client"
version.workspace = true
authors.workspace = true
homepage.workspace = true
repository.workspace = true
keywords.workspace = true
license.workspace = true
readme.workspace = true
edition.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
dragonfly-client-core.workspace = true
reqwest.workspace = true
tokio.workspace = true
tokio-util.workspace = true
rustls-pki-types.workspace = true
futures = "0.3.28"
rustls = "0.21.6"

View File

@ -1,5 +1,5 @@
/*
* Copyright 2023 The Dragonfly Authors
* Copyright 2024 The Dragonfly Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,6 +17,7 @@
use dragonfly_client_core::Result;
use futures::TryStreamExt;
use reqwest::header::HeaderMap;
use rustls_pki_types::CertificateDer;
use std::time::Duration;
use tokio::io::AsyncRead;
use tokio_util::compat::FuturesAsyncReadCompatExt;
@ -31,6 +32,9 @@ pub struct Request {
// timeout is the timeout of the request.
pub timeout: Duration,
// client_certs is the client certificates for the request.
pub client_certs: Option<Vec<CertificateDer<'static>>>,
}
// HeadResponse is the head response for HTTP backend.
@ -70,7 +74,10 @@ impl HTTP {
// the request method. Therefore, the signed URL of the GET method cannot be requested
// through the HEAD method. Use GET request to replace of HEAD request
// to get header and status code.
let mut request_builder = self.client()?.get(&request.url).headers(request.header);
let mut request_builder = self
.client(request.client_certs)?
.get(&request.url)
.headers(request.header);
request_builder = request_builder.timeout(request.timeout);
let response = request_builder.send().await?;
@ -85,7 +92,10 @@ impl HTTP {
// Get gets the content of the request.
pub async fn get(&self, request: Request) -> Result<GetResponse<impl AsyncRead>> {
let mut request_builder = self.client()?.get(&request.url).headers(request.header);
let mut request_builder = self
.client(request.client_certs)?
.get(&request.url)
.headers(request.header);
request_builder = request_builder.timeout(request.timeout);
let response = request_builder.send().await?;
@ -105,8 +115,32 @@ impl HTTP {
}
// client returns a new reqwest client.
fn client(&self) -> Result<reqwest::Client> {
Ok(reqwest::Client::builder().build()?)
fn client(
&self,
client_certs: Option<Vec<CertificateDer<'static>>>,
) -> Result<reqwest::Client> {
match client_certs {
Some(client_certs) => {
// TLS client config using the custom CA store for lookups.
let mut root_cert_store = rustls::RootCertStore::empty();
root_cert_store.add_parsable_certificates(&client_certs);
let client_config = rustls::ClientConfig::builder()
.with_safe_defaults()
.with_root_certificates(root_cert_store)
.with_no_client_auth();
let client = reqwest::Client::builder()
.use_preconfigured_tls(client_config)
.build()?;
Ok(client)
}
None => {
// Default TLS client config with native roots.
let client = reqwest::Client::builder().build()?;
Ok(client)
}
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2023 The Dragonfly Authors
* Copyright 2024 The Dragonfly Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -16,7 +16,6 @@
use clap::Parser;
use dragonfly_client::announcer::{ManagerAnnouncer, SchedulerAnnouncer};
use dragonfly_client::backend::http::HTTP;
use dragonfly_client::dynconfig::Dynconfig;
use dragonfly_client::gc::GC;
use dragonfly_client::grpc::{
@ -28,6 +27,7 @@ use dragonfly_client::proxy::Proxy;
use dragonfly_client::shutdown;
use dragonfly_client::task::Task;
use dragonfly_client::tracing::init_tracing;
use dragonfly_client_backend::http::HTTP;
use dragonfly_client_config::dfdaemon;
use dragonfly_client_storage::Storage;
use dragonfly_client_util::id_generator::IDGenerator;

View File

@ -15,7 +15,6 @@
*/
pub mod announcer;
pub mod backend;
pub mod dynconfig;
pub mod gc;
pub mod grpc;

View File

@ -14,7 +14,6 @@
* limitations under the License.
*/
use crate::backend::http::{Request as HTTPRequest, HTTP};
use crate::grpc::{scheduler::SchedulerClient, REQUEST_TIMEOUT};
use dragonfly_api::common::v2::Range;
use dragonfly_api::common::v2::{Download, Peer, Piece, TrafficType};
@ -32,6 +31,7 @@ use dragonfly_api::scheduler::v2::{
DownloadPieceFailedRequest, DownloadPieceFinishedRequest, RegisterPeerRequest,
RescheduleRequest,
};
use dragonfly_client_backend::http::{Request as HTTPRequest, HTTP};
use dragonfly_client_config::dfdaemon::Config;
use dragonfly_client_core::{
DownloadFromRemotePeerFailed, Error, HTTPError, Result as ClientResult,
@ -136,6 +136,7 @@ impl Task {
url: download.url,
header: request_header,
timeout: self.config.download.piece_timeout,
client_certs: None,
})
.await?;

View File

@ -14,11 +14,11 @@
* limitations under the License.
*/
use crate::backend::http::{Request as HTTPRequest, HTTP};
use crate::grpc::dfdaemon_upload::DfdaemonUploadClient;
use chrono::Utc;
use dragonfly_api::common::v2::{Peer, Range};
use dragonfly_api::dfdaemon::v2::DownloadPieceRequest;
use dragonfly_client_backend::http::{Request as HTTPRequest, HTTP};
use dragonfly_client_config::dfdaemon::Config;
use dragonfly_client_core::{Error, HTTPError, Result};
use dragonfly_client_storage::{metadata, Storage};
@ -367,6 +367,7 @@ impl Piece {
url: url.to_string(),
header: request_header.to_owned(),
timeout: self.config.download.piece_timeout,
client_certs: None,
})
.await
.map_err(|err| {