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]
|
||||
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]
|
||||
[workspace]
|
||||
|
||||
members = ["rpxy-bin", "rpxy-lib"]
|
||||
exclude = ["quinn", "h3-quinn", "h3"]
|
||||
|
||||
[profile.release]
|
||||
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::{
|
||||
certs::{CertsAndKeys, CryptoSource},
|
||||
log::*,
|
||||
};
|
||||
use crate::log::*;
|
||||
use async_trait::async_trait;
|
||||
use derive_builder::Builder;
|
||||
use rustls::{Certificate, PrivateKey};
|
||||
use rpxy_lib::{
|
||||
reexports::{Certificate, PrivateKey},
|
||||
CertsAndKeys, CryptoSource,
|
||||
};
|
||||
use std::{
|
||||
fs::File,
|
||||
io::{self, BufReader, Cursor, Read},
|
||||
|
|
@ -1,13 +1,11 @@
|
|||
use super::toml::ConfigToml;
|
||||
use crate::{
|
||||
backend::Backends,
|
||||
cert_file_reader::CryptoFileSource,
|
||||
error::{anyhow, ensure},
|
||||
globals::*,
|
||||
log::*,
|
||||
utils::BytesName,
|
||||
};
|
||||
use clap::Arg;
|
||||
use rpxy_lib::{Backends, BytesName, Globals, ProxyConfig};
|
||||
use tokio::runtime::Handle;
|
||||
|
||||
pub fn build_globals(runtime_handle: Handle) -> std::result::Result<Globals<CryptoFileSource>, anyhow::Error> {
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
use crate::{
|
||||
backend::{Backend, BackendBuilder, ReverseProxy, Upstream, UpstreamGroup, UpstreamGroupBuilder, UpstreamOption},
|
||||
cert_file_reader::{CryptoFileSource, CryptoFileSourceBuilder},
|
||||
constants::*,
|
||||
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 serde::Deserialize;
|
||||
|
|
@ -265,7 +266,7 @@ impl TryInto<Upstream> for &UpstreamParams {
|
|||
};
|
||||
let location = format!("{}://{}", scheme, self.location);
|
||||
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
|
||||
T: CryptoSource,
|
||||
{
|
||||
#[allow(clippy::new_without_default)]
|
||||
pub fn new() -> Self {
|
||||
Backends {
|
||||
apps: HashMap::<ServerNameBytesExp, Backend<T>>::default(),
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
pub const LISTEN_ADDRESSES_V4: &[&str] = &["0.0.0.0"];
|
||||
pub const LISTEN_ADDRESSES_V6: &[&str] = &["[::]"];
|
||||
// pub const LISTEN_ADDRESSES_V4: &[&str] = &["0.0.0.0"];
|
||||
// pub const LISTEN_ADDRESSES_V6: &[&str] = &["[::]"];
|
||||
// pub const HTTP_LISTEN_PORT: u16 = 8080;
|
||||
// pub const HTTPS_LISTEN_PORT: u16 = 8443;
|
||||
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 cert_file_reader;
|
||||
mod certs;
|
||||
mod config;
|
||||
mod constants;
|
||||
mod error;
|
||||
mod globals;
|
||||
|
|
@ -18,39 +8,27 @@ mod log;
|
|||
mod proxy;
|
||||
mod utils;
|
||||
|
||||
use crate::{
|
||||
cert_file_reader::CryptoFileSource, config::build_globals, error::*, globals::*, handler::HttpMessageHandlerBuilder,
|
||||
log::*, proxy::ProxyBuilder,
|
||||
};
|
||||
use crate::{error::*, handler::HttpMessageHandlerBuilder, log::*, proxy::ProxyBuilder};
|
||||
use futures::future::select_all;
|
||||
use hyper::Client;
|
||||
// use hyper_trust_dns::TrustDnsResolver;
|
||||
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);
|
||||
}
|
||||
pub use crate::{
|
||||
backend::{
|
||||
Backend, BackendBuilder, Backends, ReverseProxy, Upstream, UpstreamGroup, UpstreamGroupBuilder, UpstreamOption,
|
||||
},
|
||||
certs::{CertsAndKeys, CryptoSource},
|
||||
globals::{Globals, ProxyConfig}, // TODO: BackendConfigに変える
|
||||
utils::{BytesName, PathNameBytesExp},
|
||||
};
|
||||
|
||||
entrypoint(Arc::new(globals)).await.unwrap()
|
||||
});
|
||||
warn!("rpxy exited!");
|
||||
pub mod reexports {
|
||||
pub use hyper::Uri;
|
||||
pub use rustls::{Certificate, PrivateKey};
|
||||
}
|
||||
|
||||
// entrypoint creates and spawns tasks of proxy services
|
||||
async fn entrypoint<T>(globals: Arc<Globals<T>>) -> Result<()>
|
||||
/// Entrypoint that creates and spawns tasks of reverse proxy services
|
||||
pub async fn entrypoint<T>(globals: Arc<Globals<T>>) -> Result<()>
|
||||
where
|
||||
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 {
|
||||
self.0.len()
|
||||
}
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.len() == 0
|
||||
}
|
||||
pub fn get<I>(&self, index: I) -> Option<&I::Output>
|
||||
where
|
||||
I: std::slice::SliceIndex<[u8]>,
|
||||
Loading…
Add table
Add a link
Reference in a new issue