Compare commits

...

6 commits

Author SHA1 Message Date
asonix 232a1a04a1 Update ructe
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-01 16:45:27 -06:00
asonix aebc6ba814 Update tracing-log 2024-02-01 16:43:16 -06:00
asonix f43c3948fe Update opentelemtry to 0.21 2024-02-01 16:42:42 -06:00
asonix d18a33940f Update console-subscriber 2024-02-01 16:38:36 -06:00
asonix f123f7d60a Update minify-html, dependencies (minor & point) 2024-02-01 16:35:19 -06:00
asonix 7a862bc8ff Enable connecting to pict-rs over TLS 2024-02-01 16:32:17 -06:00
3 changed files with 1412 additions and 605 deletions

1868
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -19,41 +19,46 @@ default = []
actix-rt = "2.7.0"
actix-web = { version = "4.0.0", default-features = false }
anyhow = "1.0"
awc = { version = "3.0.0", default-features = false }
awc = { version = "3.0.0", default-features = false, features = ["rustls-0_21"] }
clap = { version = "4.0.2", features = ["derive", "env"] }
console-subscriber = "0.1"
console-subscriber = "0.2"
dotenv = "0.15.0"
mime = "0.3"
minify-html = "0.11.1"
minify-html = "0.15.0"
once_cell = "1.4"
opentelemetry = { version = "0.19", features = ["rt-tokio"] }
opentelemetry-otlp = "0.12"
opentelemetry = "0.21"
opentelemetry_sdk = { version = "0.21", features = ["rt-tokio"] }
opentelemetry-otlp = "0.14"
rustls = "0.21"
rustls-pemfile = "2.0.0"
serde = { version = "1.0", features = ["derive"] }
serde_qs = { version = "0.12", features = ["actix4"] }
thiserror = "1.0"
tokio = { version = "1", features = ["fs"] }
tracing = "0.1"
tracing-error = "0.2"
tracing-futures = "0.2"
tracing-log = "0.1"
tracing-opentelemetry = "0.19"
tracing-log = "0.2"
tracing-opentelemetry = "0.22"
tracing-subscriber = { version = "0.3", features = [
"ansi",
"env-filter",
"fmt",
] }
url = "2.1"
webpki-roots = "0.26"
[dependencies.tracing-actix-web]
version = "0.7.5"
version = "0.7.9"
default-features = false
features = ["emit_event_on_error", "opentelemetry_0_19"]
features = ["emit_event_on_error", "opentelemetry_0_21"]
[dependencies.tracing-awc]
version = "0.1.7"
version = "0.1.9"
default-features = false
features = ["emit_event_on_error", "opentelemetry_0_19"]
features = ["emit_event_on_error", "opentelemetry_0_21"]
[build-dependencies]
anyhow = "1.0"
dotenv = "0.15.0"
ructe = { version = "0.16.1", features = ["sass", "mime03"] }
ructe = { version = "0.17.0", features = ["sass", "mime03"] }

View file

@ -10,18 +10,19 @@ use actix_web::{
middleware::NormalizePath,
web, App, HttpRequest, HttpResponse, HttpResponseBuilder, HttpServer, ResponseError,
};
use awc::Client;
use awc::{Client, Connector};
use clap::Parser;
use console_subscriber::ConsoleLayer;
use once_cell::sync::Lazy;
use opentelemetry::{
sdk::{propagation::TraceContextPropagator, Resource},
KeyValue,
};
use opentelemetry::KeyValue;
use opentelemetry_otlp::WithExportConfig;
use opentelemetry_sdk::{propagation::TraceContextPropagator, Resource};
use rustls::{Certificate, ClientConfig, OwnedTrustAnchor, RootCertStore};
use std::{
io::Cursor,
net::SocketAddr,
path::PathBuf,
sync::Arc,
time::{Duration, SystemTime},
};
use tracing_actix_web::TracingLogger;
@ -29,8 +30,7 @@ use tracing_awc::Tracing;
use tracing_error::{ErrorLayer, SpanTrace};
use tracing_log::LogTracer;
use tracing_subscriber::{
filter::Targets, fmt::format::FmtSpan, layer::SubscriberExt, registry::LookupSpan, Layer,
Registry,
filter::Targets, layer::SubscriberExt, registry::LookupSpan, Layer, Registry,
};
use url::Url;
@ -47,7 +47,7 @@ struct Config {
short,
long,
env = "PICTRS_PROXY_ADDR",
default_value = "0.0.0.0:8081",
default_value = "[::]:8081",
help = "The address and port the server binds to"
)]
addr: SocketAddr,
@ -73,10 +73,17 @@ struct Config {
#[arg(
long,
env = "PICTRS_PROXY_CONSOLE_BUFFER_SIZE",
help = "Number of events to buffer for the console subscriber. When unset, console will be disabled"
help = "Number of events to buffer for the console subscriber"
)]
console_event_buffer_size: Option<usize>,
#[arg(
long,
env = "PICTRS_PROXY_CONSOLE",
help = "Enable the tokio-console at the specified address"
)]
console_addr: Option<SocketAddr>,
#[arg(
short,
long,
@ -84,6 +91,14 @@ struct Config {
help = "URL of OpenTelemetry Collector"
)]
opentelemetry_url: Option<Url>,
#[arg(
short,
long,
env = "PICTRS_PROXY_CERTIFICATE",
help = "Path to the certificate file to connec to pict-rs over TLS"
)]
certificate: Option<PathBuf>,
}
impl Config {
@ -834,6 +849,7 @@ fn render(
fn init_tracing(
service_name: &'static str,
opentelemetry_url: Option<&Url>,
console_addr: Option<SocketAddr>,
console_event_buffer_size: Option<usize>,
) -> Result<(), anyhow::Error> {
opentelemetry::global::set_text_map_propagator(TraceContextPropagator::new());
@ -844,27 +860,32 @@ fn init_tracing(
.unwrap_or_else(|_| "info".into())
.parse()?;
let format_layer = tracing_subscriber::fmt::layer()
.with_span_events(FmtSpan::NEW | FmtSpan::CLOSE)
.with_filter(targets.clone());
let format_layer = tracing_subscriber::fmt::layer().with_filter(targets.clone());
let subscriber = Registry::default()
.with(format_layer)
.with(ErrorLayer::default());
if let Some(buffer_size) = console_event_buffer_size {
let console_layer = ConsoleLayer::builder()
if let Some(console_addr) = console_addr {
let console_builder = ConsoleLayer::builder()
.with_default_env()
.server_addr(([0, 0, 0, 0], 6669))
.event_buffer_capacity(buffer_size)
.spawn();
.server_addr(console_addr);
let console_layer = if let Some(buffer_size) = console_event_buffer_size {
console_builder.event_buffer_capacity(buffer_size).spawn()
} else {
console_builder.spawn()
};
let subscriber = subscriber.with(console_layer);
init_subscriber(subscriber, targets, opentelemetry_url, service_name)
init_subscriber(subscriber, targets, opentelemetry_url, service_name)?;
tracing::info!("Launched console on {console_addr}");
} else {
init_subscriber(subscriber, targets, opentelemetry_url, service_name)
init_subscriber(subscriber, targets, opentelemetry_url, service_name)?;
}
Ok(())
}
fn init_subscriber<S>(
@ -878,18 +899,19 @@ where
for<'a> S: LookupSpan<'a>,
{
if let Some(url) = opentelemetry_url {
let tracer =
opentelemetry_otlp::new_pipeline()
.tracing()
.with_trace_config(opentelemetry::sdk::trace::config().with_resource(
Resource::new(vec![KeyValue::new("service.name", service_name)]),
))
.with_exporter(
opentelemetry_otlp::new_exporter()
.tonic()
.with_endpoint(url.as_str()),
)
.install_batch(opentelemetry::runtime::Tokio)?;
let tracer = opentelemetry_otlp::new_pipeline()
.tracing()
.with_trace_config(
opentelemetry_sdk::trace::config().with_resource(Resource::new(vec![
KeyValue::new("service.name", service_name),
])),
)
.with_exporter(
opentelemetry_otlp::new_exporter()
.tonic()
.with_endpoint(url.as_str()),
)
.install_batch(opentelemetry_sdk::runtime::Tokio)?;
let otel_layer = tracing_opentelemetry::layer()
.with_tracer(tracer)
@ -905,22 +927,54 @@ where
Ok(())
}
async fn create_rustls_config() -> anyhow::Result<ClientConfig> {
let mut cert_store = RootCertStore {
roots: webpki_roots::TLS_SERVER_ROOTS
.into_iter()
.map(|anchor| {
OwnedTrustAnchor::from_subject_spki_name_constraints(
anchor.subject.to_vec(),
anchor.subject_public_key_info.to_vec(),
anchor.name_constraints.as_ref().map(|d| d.to_vec()),
)
})
.collect(),
};
if let Some(cert) = CONFIG.certificate.as_ref() {
let cert_bytes = tokio::fs::read(&cert).await?;
for res in rustls_pemfile::certs(&mut cert_bytes.as_slice()) {
cert_store.add(&Certificate(res?.to_vec()))?;
}
};
Ok(ClientConfig::builder()
.with_safe_defaults()
.with_root_certificates(cert_store)
.with_no_client_auth())
}
#[actix_rt::main]
async fn main() -> Result<(), anyhow::Error> {
async fn main() -> anyhow::Result<()> {
dotenv::dotenv().ok();
init_tracing(
"pict-rs-proxy",
CONFIG.opentelemetry_url.as_ref(),
CONFIG.console_addr,
CONFIG.console_event_buffer_size,
)?;
let client_config = create_rustls_config().await?;
HttpServer::new(move || {
let client = Client::builder()
.wrap(Tracing)
.add_default_header(("User-Agent", "pict-rs-frontend, v0.5.0-alpha.1"))
.add_default_header(("User-Agent", "pict-rs-frontend, v0.5.0"))
.timeout(Duration::from_secs(30))
.disable_redirects()
.connector(Connector::new().rustls_021(Arc::new(client_config.clone())))
.finish();
App::new()