refactor: initial implementation of separeted lib and bin
This commit is contained in:
parent
ec85b0bb28
commit
13e82035a8
37 changed files with 225 additions and 157 deletions
87
Cargo.toml
87
Cargo.toml
|
|
@ -1,88 +1,7 @@
|
||||||
[package]
|
[workspace]
|
||||||
name = "rpxy"
|
|
||||||
version = "0.3.0"
|
|
||||||
authors = ["Jun Kurihara"]
|
|
||||||
homepage = "https://github.com/junkurihara/rust-rpxy"
|
|
||||||
repository = "https://github.com/junkurihara/rust-rpxy"
|
|
||||||
license = "MIT"
|
|
||||||
readme = "README.md"
|
|
||||||
edition = "2021"
|
|
||||||
publish = false
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[features]
|
|
||||||
default = ["http3", "sticky-cookie"]
|
|
||||||
http3 = ["quinn", "h3", "h3-quinn"]
|
|
||||||
sticky-cookie = ["base64", "sha2", "chrono"]
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
anyhow = "1.0.72"
|
|
||||||
clap = { version = "4.3.17", features = ["std", "cargo", "wrap_help"] }
|
|
||||||
rand = "0.8.5"
|
|
||||||
toml = { version = "0.7.6", default-features = false, features = ["parse"] }
|
|
||||||
rustc-hash = "1.1.0"
|
|
||||||
serde = { version = "1.0.174", default-features = false, features = ["derive"] }
|
|
||||||
bytes = "1.4.0"
|
|
||||||
thiserror = "1.0.44"
|
|
||||||
x509-parser = "0.15.0"
|
|
||||||
derive_builder = "0.12.0"
|
|
||||||
futures = { version = "0.3.28", features = ["alloc", "async-await"] }
|
|
||||||
tokio = { version = "1.29.1", default-features = false, features = [
|
|
||||||
"net",
|
|
||||||
"rt-multi-thread",
|
|
||||||
"time",
|
|
||||||
"sync",
|
|
||||||
"macros",
|
|
||||||
] }
|
|
||||||
async-trait = "0.1.72"
|
|
||||||
hot_reload = "0.1.2" # reloading certs
|
|
||||||
|
|
||||||
# http and tls
|
|
||||||
hyper = { version = "0.14.27", default-features = false, features = [
|
|
||||||
"server",
|
|
||||||
"http1",
|
|
||||||
"http2",
|
|
||||||
"stream",
|
|
||||||
] }
|
|
||||||
hyper-rustls = { version = "0.24.1", default-features = false, features = [
|
|
||||||
"tokio-runtime",
|
|
||||||
"webpki-tokio",
|
|
||||||
"http1",
|
|
||||||
"http2",
|
|
||||||
] }
|
|
||||||
tokio-rustls = { version = "0.24.1", features = ["early-data"] }
|
|
||||||
rustls-pemfile = "1.0.3"
|
|
||||||
rustls = { version = "0.21.5", default-features = false }
|
|
||||||
webpki = "0.22.0"
|
|
||||||
|
|
||||||
# logging
|
|
||||||
tracing = { version = "0.1.37" }
|
|
||||||
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
|
|
||||||
|
|
||||||
# http/3
|
|
||||||
# quinn = { version = "0.9.3", optional = true }
|
|
||||||
quinn = { path = "./quinn/quinn", optional = true } # Tentative to support rustls-0.21
|
|
||||||
h3 = { path = "./h3/h3/", optional = true }
|
|
||||||
# h3-quinn = { path = "./h3/h3-quinn/", optional = true }
|
|
||||||
h3-quinn = { path = "./h3-quinn/", optional = true } # Tentative to support rustls-0.21
|
|
||||||
|
|
||||||
# cookie handling for sticky cookie
|
|
||||||
chrono = { version = "0.4.26", default-features = false, features = [
|
|
||||||
"unstable-locales",
|
|
||||||
"alloc",
|
|
||||||
"clock",
|
|
||||||
], optional = true }
|
|
||||||
base64 = { version = "0.21.2", optional = true }
|
|
||||||
sha2 = { version = "0.10.7", default-features = false, optional = true }
|
|
||||||
|
|
||||||
|
|
||||||
[target.'cfg(not(target_env = "msvc"))'.dependencies]
|
|
||||||
tikv-jemallocator = "0.5.0"
|
|
||||||
|
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
|
|
||||||
|
members = ["rpxy-bin", "rpxy-lib"]
|
||||||
|
exclude = ["quinn", "h3-quinn", "h3"]
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
codegen-units = 1
|
codegen-units = 1
|
||||||
|
|
|
||||||
49
rpxy-bin/Cargo.toml
Normal file
49
rpxy-bin/Cargo.toml
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
[package]
|
||||||
|
name = "rpxy"
|
||||||
|
version = "0.4.0"
|
||||||
|
authors = ["Jun Kurihara"]
|
||||||
|
homepage = "https://github.com/junkurihara/rust-rpxy"
|
||||||
|
repository = "https://github.com/junkurihara/rust-rpxy"
|
||||||
|
license = "MIT"
|
||||||
|
readme = "README.md"
|
||||||
|
edition = "2021"
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[features]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
rpxy-lib = { path = "../rpxy-lib/", features = ["http3", "sticky-cookie"] }
|
||||||
|
|
||||||
|
anyhow = "1.0.72"
|
||||||
|
rustc-hash = "1.1.0"
|
||||||
|
serde = { version = "1.0.174", default-features = false, features = ["derive"] }
|
||||||
|
derive_builder = "0.12.0"
|
||||||
|
tokio = { version = "1.29.1", default-features = false, features = [
|
||||||
|
"net",
|
||||||
|
"rt-multi-thread",
|
||||||
|
"time",
|
||||||
|
"sync",
|
||||||
|
"macros",
|
||||||
|
] }
|
||||||
|
async-trait = "0.1.72"
|
||||||
|
|
||||||
|
# config
|
||||||
|
clap = { version = "4.3.17", features = ["std", "cargo", "wrap_help"] }
|
||||||
|
toml = { version = "0.7.6", default-features = false, features = ["parse"] }
|
||||||
|
|
||||||
|
# reloading certs
|
||||||
|
hot_reload = "0.1.2"
|
||||||
|
rustls-pemfile = "1.0.3"
|
||||||
|
|
||||||
|
# logging
|
||||||
|
tracing = { version = "0.1.37" }
|
||||||
|
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
|
||||||
|
|
||||||
|
|
||||||
|
[target.'cfg(not(target_env = "msvc"))'.dependencies]
|
||||||
|
tikv-jemallocator = "0.5.0"
|
||||||
|
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
use crate::{
|
use crate::log::*;
|
||||||
certs::{CertsAndKeys, CryptoSource},
|
|
||||||
log::*,
|
|
||||||
};
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use derive_builder::Builder;
|
use derive_builder::Builder;
|
||||||
use rustls::{Certificate, PrivateKey};
|
use rpxy_lib::{
|
||||||
|
reexports::{Certificate, PrivateKey},
|
||||||
|
CertsAndKeys, CryptoSource,
|
||||||
|
};
|
||||||
use std::{
|
use std::{
|
||||||
fs::File,
|
fs::File,
|
||||||
io::{self, BufReader, Cursor, Read},
|
io::{self, BufReader, Cursor, Read},
|
||||||
|
|
@ -1,13 +1,11 @@
|
||||||
use super::toml::ConfigToml;
|
use super::toml::ConfigToml;
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::Backends,
|
|
||||||
cert_file_reader::CryptoFileSource,
|
cert_file_reader::CryptoFileSource,
|
||||||
error::{anyhow, ensure},
|
error::{anyhow, ensure},
|
||||||
globals::*,
|
|
||||||
log::*,
|
log::*,
|
||||||
utils::BytesName,
|
|
||||||
};
|
};
|
||||||
use clap::Arg;
|
use clap::Arg;
|
||||||
|
use rpxy_lib::{Backends, BytesName, Globals, ProxyConfig};
|
||||||
use tokio::runtime::Handle;
|
use tokio::runtime::Handle;
|
||||||
|
|
||||||
pub fn build_globals(runtime_handle: Handle) -> std::result::Result<Globals<CryptoFileSource>, anyhow::Error> {
|
pub fn build_globals(runtime_handle: Handle) -> std::result::Result<Globals<CryptoFileSource>, anyhow::Error> {
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::{Backend, BackendBuilder, ReverseProxy, Upstream, UpstreamGroup, UpstreamGroupBuilder, UpstreamOption},
|
|
||||||
cert_file_reader::{CryptoFileSource, CryptoFileSourceBuilder},
|
cert_file_reader::{CryptoFileSource, CryptoFileSourceBuilder},
|
||||||
constants::*,
|
constants::*,
|
||||||
error::{anyhow, ensure},
|
error::{anyhow, ensure},
|
||||||
globals::ProxyConfig,
|
};
|
||||||
utils::PathNameBytesExp,
|
use rpxy_lib::{
|
||||||
|
reexports::Uri, Backend, BackendBuilder, PathNameBytesExp, ProxyConfig, ReverseProxy, Upstream, UpstreamGroup,
|
||||||
|
UpstreamGroupBuilder, UpstreamOption,
|
||||||
};
|
};
|
||||||
use rustc_hash::FxHashMap as HashMap;
|
use rustc_hash::FxHashMap as HashMap;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
@ -265,7 +266,7 @@ impl TryInto<Upstream> for &UpstreamParams {
|
||||||
};
|
};
|
||||||
let location = format!("{}://{}", scheme, self.location);
|
let location = format!("{}://{}", scheme, self.location);
|
||||||
Ok(Upstream {
|
Ok(Upstream {
|
||||||
uri: location.parse::<hyper::Uri>().map_err(|e| anyhow!("{}", e))?,
|
uri: location.parse::<Uri>().map_err(|e| anyhow!("{}", e))?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
2
rpxy-bin/src/constants.rs
Normal file
2
rpxy-bin/src/constants.rs
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
pub const LISTEN_ADDRESSES_V4: &[&str] = &["0.0.0.0"];
|
||||||
|
pub const LISTEN_ADDRESSES_V6: &[&str] = &["[::]"];
|
||||||
1
rpxy-bin/src/error.rs
Normal file
1
rpxy-bin/src/error.rs
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
pub use anyhow::{anyhow, bail, ensure, Context};
|
||||||
24
rpxy-bin/src/log.rs
Normal file
24
rpxy-bin/src/log.rs
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
pub use tracing::{debug, error, info, warn};
|
||||||
|
|
||||||
|
pub fn init_logger() {
|
||||||
|
use tracing_subscriber::{fmt, prelude::*, EnvFilter};
|
||||||
|
|
||||||
|
let format_layer = fmt::layer()
|
||||||
|
.with_line_number(false)
|
||||||
|
.with_thread_ids(false)
|
||||||
|
.with_target(false)
|
||||||
|
.with_thread_names(true)
|
||||||
|
.with_target(true)
|
||||||
|
.with_level(true)
|
||||||
|
.compact();
|
||||||
|
|
||||||
|
// This limits the logger to emits only rpxy crate
|
||||||
|
let level_string = std::env::var(EnvFilter::DEFAULT_ENV).unwrap_or_else(|_| "info".to_string());
|
||||||
|
let filter_layer = EnvFilter::new(format!("{}={}", env!("CARGO_PKG_NAME"), level_string));
|
||||||
|
// let filter_layer = EnvFilter::from_default_env();
|
||||||
|
|
||||||
|
tracing_subscriber::registry()
|
||||||
|
.with(format_layer)
|
||||||
|
.with(filter_layer)
|
||||||
|
.init();
|
||||||
|
}
|
||||||
38
rpxy-bin/src/main.rs
Normal file
38
rpxy-bin/src/main.rs
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
#[cfg(not(target_env = "msvc"))]
|
||||||
|
use tikv_jemallocator::Jemalloc;
|
||||||
|
|
||||||
|
#[cfg(not(target_env = "msvc"))]
|
||||||
|
#[global_allocator]
|
||||||
|
static GLOBAL: Jemalloc = Jemalloc;
|
||||||
|
|
||||||
|
mod cert_file_reader;
|
||||||
|
mod config;
|
||||||
|
mod constants;
|
||||||
|
mod error;
|
||||||
|
mod log;
|
||||||
|
|
||||||
|
use crate::{cert_file_reader::CryptoFileSource, config::build_globals, log::*};
|
||||||
|
use rpxy_lib::{entrypoint, Globals};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
init_logger();
|
||||||
|
|
||||||
|
let mut runtime_builder = tokio::runtime::Builder::new_multi_thread();
|
||||||
|
runtime_builder.enable_all();
|
||||||
|
runtime_builder.thread_name("rpxy");
|
||||||
|
let runtime = runtime_builder.build().unwrap();
|
||||||
|
|
||||||
|
runtime.block_on(async {
|
||||||
|
let globals: Globals<CryptoFileSource> = match build_globals(runtime.handle().clone()) {
|
||||||
|
Ok(g) => g,
|
||||||
|
Err(e) => {
|
||||||
|
error!("Invalid configuration: {}", e);
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
entrypoint(Arc::new(globals)).await.unwrap()
|
||||||
|
});
|
||||||
|
warn!("rpxy exited!");
|
||||||
|
}
|
||||||
77
rpxy-lib/Cargo.toml
Normal file
77
rpxy-lib/Cargo.toml
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
[package]
|
||||||
|
name = "rpxy-lib"
|
||||||
|
version = "0.4.0"
|
||||||
|
authors = ["Jun Kurihara"]
|
||||||
|
homepage = "https://github.com/junkurihara/rust-rpxy"
|
||||||
|
repository = "https://github.com/junkurihara/rust-rpxy"
|
||||||
|
license = "MIT"
|
||||||
|
readme = "README.md"
|
||||||
|
edition = "2021"
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["http3", "sticky-cookie"]
|
||||||
|
http3 = ["quinn", "h3", "h3-quinn"]
|
||||||
|
sticky-cookie = ["base64", "sha2", "chrono"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
rand = "0.8.5"
|
||||||
|
rustc-hash = "1.1.0"
|
||||||
|
bytes = "1.4.0"
|
||||||
|
derive_builder = "0.12.0"
|
||||||
|
futures = { version = "0.3.28", features = ["alloc", "async-await"] }
|
||||||
|
tokio = { version = "1.29.1", default-features = false, features = [
|
||||||
|
"net",
|
||||||
|
"rt-multi-thread",
|
||||||
|
"time",
|
||||||
|
"sync",
|
||||||
|
"macros",
|
||||||
|
] }
|
||||||
|
async-trait = "0.1.72"
|
||||||
|
hot_reload = "0.1.2" # reloading certs
|
||||||
|
|
||||||
|
# Error handling
|
||||||
|
anyhow = "1.0.72"
|
||||||
|
thiserror = "1.0.44"
|
||||||
|
|
||||||
|
# http and tls
|
||||||
|
hyper = { version = "0.14.27", default-features = false, features = [
|
||||||
|
"server",
|
||||||
|
"http1",
|
||||||
|
"http2",
|
||||||
|
"stream",
|
||||||
|
] }
|
||||||
|
hyper-rustls = { version = "0.24.1", default-features = false, features = [
|
||||||
|
"tokio-runtime",
|
||||||
|
"webpki-tokio",
|
||||||
|
"http1",
|
||||||
|
"http2",
|
||||||
|
] }
|
||||||
|
tokio-rustls = { version = "0.24.1", features = ["early-data"] }
|
||||||
|
rustls = { version = "0.21.5", default-features = false }
|
||||||
|
webpki = "0.22.0"
|
||||||
|
x509-parser = "0.15.0"
|
||||||
|
|
||||||
|
# logging
|
||||||
|
tracing = { version = "0.1.37" }
|
||||||
|
|
||||||
|
# http/3
|
||||||
|
# quinn = { version = "0.9.3", optional = true }
|
||||||
|
quinn = { path = "../quinn/quinn", optional = true } # Tentative to support rustls-0.21
|
||||||
|
h3 = { path = "../h3/h3/", optional = true }
|
||||||
|
# h3-quinn = { path = "./h3/h3-quinn/", optional = true }
|
||||||
|
h3-quinn = { path = "../h3-quinn/", optional = true } # Tentative to support rustls-0.21
|
||||||
|
|
||||||
|
# cookie handling for sticky cookie
|
||||||
|
chrono = { version = "0.4.26", default-features = false, features = [
|
||||||
|
"unstable-locales",
|
||||||
|
"alloc",
|
||||||
|
"clock",
|
||||||
|
], optional = true }
|
||||||
|
base64 = { version = "0.21.2", optional = true }
|
||||||
|
sha2 = { version = "0.10.7", default-features = false, optional = true }
|
||||||
|
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
|
@ -67,6 +67,7 @@ impl<T> Backends<T>
|
||||||
where
|
where
|
||||||
T: CryptoSource,
|
T: CryptoSource,
|
||||||
{
|
{
|
||||||
|
#[allow(clippy::new_without_default)]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Backends {
|
Backends {
|
||||||
apps: HashMap::<ServerNameBytesExp, Backend<T>>::default(),
|
apps: HashMap::<ServerNameBytesExp, Backend<T>>::default(),
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
pub const LISTEN_ADDRESSES_V4: &[&str] = &["0.0.0.0"];
|
// pub const LISTEN_ADDRESSES_V4: &[&str] = &["0.0.0.0"];
|
||||||
pub const LISTEN_ADDRESSES_V6: &[&str] = &["[::]"];
|
// pub const LISTEN_ADDRESSES_V6: &[&str] = &["[::]"];
|
||||||
// pub const HTTP_LISTEN_PORT: u16 = 8080;
|
// pub const HTTP_LISTEN_PORT: u16 = 8080;
|
||||||
// pub const HTTPS_LISTEN_PORT: u16 = 8443;
|
// pub const HTTPS_LISTEN_PORT: u16 = 8443;
|
||||||
pub const PROXY_TIMEOUT_SEC: u64 = 60;
|
pub const PROXY_TIMEOUT_SEC: u64 = 60;
|
||||||
|
|
@ -1,15 +1,5 @@
|
||||||
use certs::CryptoSource;
|
|
||||||
#[cfg(not(target_env = "msvc"))]
|
|
||||||
use tikv_jemallocator::Jemalloc;
|
|
||||||
|
|
||||||
#[cfg(not(target_env = "msvc"))]
|
|
||||||
#[global_allocator]
|
|
||||||
static GLOBAL: Jemalloc = Jemalloc;
|
|
||||||
|
|
||||||
mod backend;
|
mod backend;
|
||||||
mod cert_file_reader;
|
|
||||||
mod certs;
|
mod certs;
|
||||||
mod config;
|
|
||||||
mod constants;
|
mod constants;
|
||||||
mod error;
|
mod error;
|
||||||
mod globals;
|
mod globals;
|
||||||
|
|
@ -18,39 +8,27 @@ mod log;
|
||||||
mod proxy;
|
mod proxy;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
use crate::{
|
use crate::{error::*, handler::HttpMessageHandlerBuilder, log::*, proxy::ProxyBuilder};
|
||||||
cert_file_reader::CryptoFileSource, config::build_globals, error::*, globals::*, handler::HttpMessageHandlerBuilder,
|
|
||||||
log::*, proxy::ProxyBuilder,
|
|
||||||
};
|
|
||||||
use futures::future::select_all;
|
use futures::future::select_all;
|
||||||
use hyper::Client;
|
use hyper::Client;
|
||||||
// use hyper_trust_dns::TrustDnsResolver;
|
// use hyper_trust_dns::TrustDnsResolver;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
fn main() {
|
pub use crate::{
|
||||||
init_logger();
|
backend::{
|
||||||
|
Backend, BackendBuilder, Backends, ReverseProxy, Upstream, UpstreamGroup, UpstreamGroupBuilder, UpstreamOption,
|
||||||
let mut runtime_builder = tokio::runtime::Builder::new_multi_thread();
|
},
|
||||||
runtime_builder.enable_all();
|
certs::{CertsAndKeys, CryptoSource},
|
||||||
runtime_builder.thread_name("rpxy");
|
globals::{Globals, ProxyConfig}, // TODO: BackendConfigに変える
|
||||||
let runtime = runtime_builder.build().unwrap();
|
utils::{BytesName, PathNameBytesExp},
|
||||||
|
};
|
||||||
runtime.block_on(async {
|
pub mod reexports {
|
||||||
let globals: Globals<CryptoFileSource> = match build_globals(runtime.handle().clone()) {
|
pub use hyper::Uri;
|
||||||
Ok(g) => g,
|
pub use rustls::{Certificate, PrivateKey};
|
||||||
Err(e) => {
|
|
||||||
error!("Invalid configuration: {}", e);
|
|
||||||
std::process::exit(1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
entrypoint(Arc::new(globals)).await.unwrap()
|
|
||||||
});
|
|
||||||
warn!("rpxy exited!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// entrypoint creates and spawns tasks of proxy services
|
/// Entrypoint that creates and spawns tasks of reverse proxy services
|
||||||
async fn entrypoint<T>(globals: Arc<Globals<T>>) -> Result<()>
|
pub async fn entrypoint<T>(globals: Arc<Globals<T>>) -> Result<()>
|
||||||
where
|
where
|
||||||
T: CryptoSource + Clone + Send + Sync + 'static,
|
T: CryptoSource + Clone + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
|
|
@ -95,26 +95,3 @@ impl MessageLog {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_logger() {
|
|
||||||
use tracing_subscriber::{fmt, prelude::*, EnvFilter};
|
|
||||||
|
|
||||||
let format_layer = fmt::layer()
|
|
||||||
.with_line_number(false)
|
|
||||||
.with_thread_ids(false)
|
|
||||||
.with_target(false)
|
|
||||||
.with_thread_names(true)
|
|
||||||
.with_target(true)
|
|
||||||
.with_level(true)
|
|
||||||
.compact();
|
|
||||||
|
|
||||||
// This limits the logger to emits only rpxy crate
|
|
||||||
let level_string = std::env::var(EnvFilter::DEFAULT_ENV).unwrap_or_else(|_| "info".to_string());
|
|
||||||
let filter_layer = EnvFilter::new(format!("{}={}", env!("CARGO_PKG_NAME"), level_string));
|
|
||||||
// let filter_layer = EnvFilter::from_default_env();
|
|
||||||
|
|
||||||
tracing_subscriber::registry()
|
|
||||||
.with(format_layer)
|
|
||||||
.with(filter_layer)
|
|
||||||
.init();
|
|
||||||
}
|
|
||||||
|
|
@ -23,6 +23,9 @@ impl PathNameBytesExp {
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.0.len()
|
self.0.len()
|
||||||
}
|
}
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.0.len() == 0
|
||||||
|
}
|
||||||
pub fn get<I>(&self, index: I) -> Option<&I::Output>
|
pub fn get<I>(&self, index: I) -> Option<&I::Output>
|
||||||
where
|
where
|
||||||
I: std::slice::SliceIndex<[u8]>,
|
I: std::slice::SliceIndex<[u8]>,
|
||||||
Loading…
Add table
Add a link
Reference in a new issue