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", "clap",
"dashmap", "dashmap",
"dragonfly-api", "dragonfly-api",
"dragonfly-client-backend",
"dragonfly-client-config", "dragonfly-client-config",
"dragonfly-client-core", "dragonfly-client-core",
"dragonfly-client-storage", "dragonfly-client-storage",
"dragonfly-client-util", "dragonfly-client-util",
"fs2", "fs2",
"fslock", "fslock",
"futures",
"futures-util", "futures-util",
"hashring", "hashring",
"http 1.0.0", "http 1.0.0",
@ -662,6 +662,19 @@ dependencies = [
"warp", "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]] [[package]]
name = "dragonfly-client-config" name = "dragonfly-client-config"
version = "0.1.17" version = "0.1.17"

View File

@ -23,7 +23,7 @@ name = "dfstore"
path = "src/bin/dfstore/main.rs" path = "src/bin/dfstore/main.rs"
[workspace] [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] [workspace.package]
version = "0.1.17" version = "0.1.17"
@ -36,9 +36,10 @@ readme = "README.md"
edition = "2021" edition = "2021"
[workspace.dependencies] [workspace.dependencies]
dragonfly-client-core = { path = "dragonfly-client-core", version = "*" } dragonfly-client-core = { path = "dragonfly-client-core", version = "0.1.17" }
dragonfly-client-config = { path = "dragonfly-client-config", version = "*" } dragonfly-client-config = { path = "dragonfly-client-config", version = "0.1.17" }
dragonfly-client-storage = { path = "dragonfly-client-storage", version = "*" } 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 = "*" } dragonfly-client-util = { path = "dragonfly-client-util", version = "*" }
thiserror = "1.0" thiserror = "1.0"
dragonfly-api = "2.0.102" 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"] } rcgen = { version = "0.12.1", features = ["x509-parser"] }
hyper = { version = "1.1", features = ["full"] } hyper = { version = "1.1", features = ["full"] }
hyper-util = { version = "0.1.2", features = ["client", "client-legacy", "tokio", "server-auto", "http1", "http2"] } 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" http-range-header = "0.4.0"
tracing = "0.1" tracing = "0.1"
url = "2.4.0" url = "2.4.0"
@ -76,9 +78,11 @@ chrono = { version = "0.4.34", features = ["serde"] }
dragonfly-client-core.workspace = true dragonfly-client-core.workspace = true
dragonfly-client-config.workspace = true dragonfly-client-config.workspace = true
dragonfly-client-storage.workspace = true dragonfly-client-storage.workspace = true
dragonfly-client-backend.workspace = true
dragonfly-client-util.workspace = true dragonfly-client-util.workspace = true
rcgen.workspace = true rcgen.workspace = true
hyper-util.workspace = true hyper-util.workspace = true
hyper-rustls.workspace = true
tracing.workspace = true tracing.workspace = true
validator.workspace = true validator.workspace = true
humantime.workspace = true humantime.workspace = true
@ -88,6 +92,7 @@ chrono.workspace = true
prost-wkt-types.workspace = true prost-wkt-types.workspace = true
tokio.workspace = true tokio.workspace = true
tokio-util.workspace = true tokio-util.workspace = true
rustls-pki-types.workspace = true
clap = { version = "4.5.1", features = [ "derive" ] } clap = { version = "4.5.1", features = [ "derive" ] }
tracing-log = "0.1" tracing-log = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] } tracing-subscriber = { version = "0.3", features = ["env-filter"] }
@ -103,7 +108,6 @@ tonic-health = "0.9.2"
tonic-reflection = "0.9.2" tonic-reflection = "0.9.2"
tokio-stream = "0.1.14" tokio-stream = "0.1.14"
reqwest = { version = "0.11.24", features = ["stream", "native-tls", "rustls-tls"] } reqwest = { version = "0.11.24", features = ["stream", "native-tls", "rustls-tls"] }
futures = "0.3.28"
bytes = "1.4" bytes = "1.4"
rocksdb = "0.22.0" rocksdb = "0.22.0"
dragonfly-api = "2.0.102" dragonfly-api = "2.0.102"
@ -125,8 +129,6 @@ openssl = { version = "0.10", features = ["vendored"] }
leaky-bucket = "1.0.1" leaky-bucket = "1.0.1"
hyper = { version = "1.1", features = ["full"] } hyper = { version = "1.1", features = ["full"] }
tokio-rustls = "0.25" tokio-rustls = "0.25"
hyper-rustls = { version = "0.26", features = [ "http1", "http2", "logging" ] }
http-body-util = "0.1.0" http-body-util = "0.1.0"
futures-util = "0.3.30" futures-util = "0.3.30"
rustls = "0.22.2" 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/Cargo.toml ./dragonfly-client-storage/Cargo.toml
COPY dragonfly-client-storage/src ./dragonfly-client-storage/src 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/Cargo.toml ./dragonfly-client-util/Cargo.toml
COPY dragonfly-client-util/src ./dragonfly-client-util/src 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,6 +17,7 @@
use dragonfly_client_core::Result; use dragonfly_client_core::Result;
use futures::TryStreamExt; use futures::TryStreamExt;
use reqwest::header::HeaderMap; use reqwest::header::HeaderMap;
use rustls_pki_types::CertificateDer;
use std::time::Duration; use std::time::Duration;
use tokio::io::AsyncRead; use tokio::io::AsyncRead;
use tokio_util::compat::FuturesAsyncReadCompatExt; use tokio_util::compat::FuturesAsyncReadCompatExt;
@ -31,6 +32,9 @@ pub struct Request {
// timeout is the timeout of the request. // timeout is the timeout of the request.
pub timeout: Duration, 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. // 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 // 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 // through the HEAD method. Use GET request to replace of HEAD request
// to get header and status code. // 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); request_builder = request_builder.timeout(request.timeout);
let response = request_builder.send().await?; let response = request_builder.send().await?;
@ -85,7 +92,10 @@ impl HTTP {
// Get gets the content of the request. // Get gets the content of the request.
pub async fn get(&self, request: Request) -> Result<GetResponse<impl AsyncRead>> { 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); request_builder = request_builder.timeout(request.timeout);
let response = request_builder.send().await?; let response = request_builder.send().await?;
@ -105,8 +115,32 @@ impl HTTP {
} }
// client returns a new reqwest client. // client returns a new reqwest client.
fn client(&self) -> Result<reqwest::Client> { fn client(
Ok(reqwest::Client::builder().build()?) &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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

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

View File

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

View File

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

View File

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