Skip to content

Commit

Permalink
refactor(service/http): Add HttpConfig to implement ConfigDeserializer (
Browse files Browse the repository at this point in the history
#3507)

* add HttpConfig

* aa

* add pub to Config member

* add docstring for pub member
  • Loading branch information
sd44 authored Nov 7, 2023
1 parent 95eae35 commit 8465d2d
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 27 deletions.
75 changes: 48 additions & 27 deletions core/src/services/http/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,25 +32,48 @@ use super::error::parse_error;
use crate::raw::*;
use crate::*;

use serde::Deserialize;

/// Config for Http service support.
#[derive(Default, Deserialize)]
#[serde(default)]
#[non_exhaustive]
pub struct HttpConfig {
/// endpoint of this backend
pub endpoint: Option<String>,
/// username of this backend
pub username: Option<String>,
/// password of this backend
pub password: Option<String>,
/// token of this backend
pub token: Option<String>,
/// root of this backend
pub root: Option<String>,
}

impl Debug for HttpConfig {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let mut de = f.debug_struct("HttpConfig");
de.field("endpoint", &self.endpoint);
de.field("root", &self.root);

de.finish_non_exhaustive()
}
}

/// HTTP Read-only service support like [Nginx](https://www.nginx.com/) and [Caddy](https://caddyserver.com/).
#[doc = include_str!("docs.md")]
#[derive(Default)]
pub struct HttpBuilder {
endpoint: Option<String>,
username: Option<String>,
password: Option<String>,
token: Option<String>,
root: Option<String>,
config: HttpConfig,
http_client: Option<HttpClient>,
}

impl Debug for HttpBuilder {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let mut de = f.debug_struct("Builder");
de.field("endpoint", &self.endpoint);
de.field("root", &self.root);
let mut de = f.debug_struct("HttpBuilder");

de.finish()
de.field("config", &self.config).finish()
}
}

Expand All @@ -59,7 +82,7 @@ impl HttpBuilder {
///
/// For example: `https://example.com`
pub fn endpoint(&mut self, endpoint: &str) -> &mut Self {
self.endpoint = if endpoint.is_empty() {
self.config.endpoint = if endpoint.is_empty() {
None
} else {
Some(endpoint.to_string())
Expand All @@ -73,7 +96,7 @@ impl HttpBuilder {
/// default: no password
pub fn username(&mut self, username: &str) -> &mut Self {
if !username.is_empty() {
self.username = Some(username.to_owned());
self.config.username = Some(username.to_owned());
}
self
}
Expand All @@ -83,7 +106,7 @@ impl HttpBuilder {
/// default: no password
pub fn password(&mut self, password: &str) -> &mut Self {
if !password.is_empty() {
self.password = Some(password.to_owned());
self.config.password = Some(password.to_owned());
}
self
}
Expand All @@ -93,14 +116,14 @@ impl HttpBuilder {
/// default: no access token
pub fn token(&mut self, token: &str) -> &mut Self {
if !token.is_empty() {
self.token = Some(token.to_owned());
self.config.token = Some(token.to_owned());
}
self
}

/// Set root path of http backend.
pub fn root(&mut self, root: &str) -> &mut Self {
self.root = if root.is_empty() {
self.config.root = if root.is_empty() {
None
} else {
Some(root.to_string())
Expand All @@ -126,29 +149,27 @@ impl Builder for HttpBuilder {
type Accessor = HttpBackend;

fn from_map(map: HashMap<String, String>) -> Self {
let mut builder = HttpBuilder::default();

map.get("root").map(|v| builder.root(v));
map.get("endpoint").map(|v| builder.endpoint(v));
map.get("username").map(|v| builder.username(v));
map.get("password").map(|v| builder.password(v));
map.get("token").map(|v| builder.token(v));
let config = HttpConfig::deserialize(ConfigDeserializer::new(map))
.expect("config deserialize must succeed");

builder
HttpBuilder {
config,
http_client: None,
}
}

fn build(&mut self) -> Result<Self::Accessor> {
debug!("backend build started: {:?}", &self);

let endpoint = match &self.endpoint {
let endpoint = match &self.config.endpoint {
Some(v) => v,
None => {
return Err(Error::new(ErrorKind::ConfigInvalid, "endpoint is empty")
.with_context("service", Scheme::Http))
}
};

let root = normalize_root(&self.root.take().unwrap_or_default());
let root = normalize_root(&self.config.root.take().unwrap_or_default());
debug!("backend use root {}", root);

let client = if let Some(client) = self.http_client.take() {
Expand All @@ -161,13 +182,13 @@ impl Builder for HttpBuilder {
};

let mut auth = None;
if let Some(username) = &self.username {
if let Some(username) = &self.config.username {
auth = Some(format_authorization_by_basic(
username,
self.password.as_deref().unwrap_or_default(),
self.config.password.as_deref().unwrap_or_default(),
)?);
}
if let Some(token) = &self.token {
if let Some(token) = &self.config.token {
auth = Some(format_authorization_by_bearer(token)?)
}

Expand Down
1 change: 1 addition & 0 deletions core/src/services/http/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@

mod backend;
pub use backend::HttpBuilder as Http;
pub use backend::HttpConfig;

mod error;
2 changes: 2 additions & 0 deletions core/src/services/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ pub use hdfs::Hdfs;
mod http;
#[cfg(feature = "services-http")]
pub use self::http::Http;
#[cfg(feature = "services-http")]
pub use self::http::HttpConfig;

#[cfg(feature = "services-ipfs")]
mod ipfs;
Expand Down

0 comments on commit 8465d2d

Please sign in to comment.