chore: static error pages content
Diff
src/bin/server.rs | 5 +-
src/config.rs | 9 ++-
src/lib.rs | 2 +-
src/rejection.rs | 20 ++--
src/server.rs | 284 ++++++++++++++++++++++++++++---------------------------
5 files changed, 171 insertions(+), 149 deletions(-)
@@ -6,11 +6,10 @@ static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
extern crate static_web_server;
use self::static_web_server::{Config, Result, Server};
use structopt::StructOpt;
use self::static_web_server::{Result, Server};
fn main() -> Result {
Server::new(Config::from_args()).run()?;
Server::new().run()?;
Ok(())
}
@@ -1,5 +1,8 @@
use once_cell::sync::OnceCell;
use structopt::StructOpt;
pub static CONFIG: OnceCell<Config> = OnceCell::new();
#[derive(Debug, StructOpt)]
pub struct Config {
@@ -73,3 +76,9 @@ pub struct Config {
pub http2_tls_key: String,
}
impl Config {
pub fn global() -> &'static Config {
CONFIG.get().expect("Config is not initialized")
}
}
@@ -16,6 +16,6 @@ pub mod signals;
#[macro_use]
pub mod error;
pub use config::Config;
pub use config::{Config, CONFIG};
pub use error::*;
pub use server::Server;
@@ -1,17 +1,20 @@
use anyhow::Result;
use once_cell::sync::OnceCell;
use std::convert::Infallible;
use warp::http::StatusCode;
use warp::{Rejection, Reply};
pub static PAGE_404: OnceCell<String> = OnceCell::new();
pub static PAGE_50X: OnceCell<String> = OnceCell::new();
pub async fn handle_rejection(
page_404: String,
page_50x: String,
err: Rejection,
) -> Result<impl Reply, Infallible> {
pub async fn handle_rejection(err: Rejection) -> Result<impl Reply, Infallible> {
let mut content = String::new();
let code = if err.is_not_found() {
content = page_404;
content = PAGE_404
.get()
.expect("page 404 is not initialized")
.to_string();
StatusCode::NOT_FOUND
} else if err
.find::<warp::filters::body::BodyDeserializeError>()
@@ -25,7 +28,10 @@ pub async fn handle_rejection(
} else if err.find::<warp::reject::UnsupportedMediaType>().is_some() {
StatusCode::UNSUPPORTED_MEDIA_TYPE
} else {
content = page_50x;
content = PAGE_50X
.get()
.expect("page 50x is not initialized")
.to_string();
StatusCode::INTERNAL_SERVER_ERROR
};
@@ -1,24 +1,27 @@
use std::net::{IpAddr, SocketAddr};
use structopt::StructOpt;
use warp::Filter;
use crate::{cache, config, cors, filters, helpers, logger, rejection, signals, Result};
use crate::config::{Config, CONFIG};
use crate::{cache, cors, filters, helpers, logger, rejection, signals, Result};
pub struct Server {
opts: config::Config,
threads: usize,
}
impl Server {
pub fn new(opts: config::Config) -> Self {
let n = if opts.threads_multiplier == 0 {
1
} else {
opts.threads_multiplier
pub fn new() -> Self {
CONFIG.set(Config::from_args()).unwrap();
let opts = Config::global();
let threads = match opts.threads_multiplier {
0 | 1 => 1,
_ => num_cpus::get() * opts.threads_multiplier,
};
let threads = num_cpus::get() * n;
Self { opts, threads }
Self { threads }
}
@@ -27,7 +30,6 @@ impl Server {
.enable_all()
.thread_name("static-web-server")
.worker_threads(self.threads)
.max_blocking_threads(self.threads)
.build()?
.block_on(async {
let r = self.start_server().await;
@@ -41,7 +43,7 @@ impl Server {
async fn start_server(self) -> Result {
let opts = self.opts;
let opts = Config::global();
logger::init(&opts.log_level)?;
@@ -52,13 +54,15 @@ impl Server {
let addr = SocketAddr::from((ip, opts.port));
let root_dir = helpers::get_valid_dirpath(opts.root)?;
let root_dir = helpers::get_valid_dirpath(&opts.root)?;
let page404 = helpers::read_file_content(opts.page404.as_ref());
let page50x = helpers::read_file_content(opts.page50x.as_ref());
let page404_a = page404.clone();
let page50x_a = page50x.clone();
rejection::PAGE_404
.set(helpers::read_file_content(opts.page404.as_ref()))
.expect("page 404 is not initialized");
rejection::PAGE_50X
.set(helpers::read_file_content(opts.page50x.as_ref()))
.expect("page 50x is not initialized");
let (cors_filter, cors_allowed_origins) =
@@ -68,11 +72,7 @@ impl Server {
let base_dir_filter = warp::fs::dir(root_dir.clone())
.map(cache::control_headers)
.with(warp::trace::request())
.recover(move |rej| {
let page404_a = page404_a.clone();
let page50x_a = page50x_a.clone();
async move { rejection::handle_rejection(page404_a, page50x_a, rej).await }
});
.recover(rejection::handle_rejection);
let public_head = warp::head().and(base_dir_filter.clone());
@@ -82,8 +82,8 @@ impl Server {
let http2 = opts.http2;
let http2_tls_cert_path = opts.http2_tls_cert;
let http2_tls_key_path = opts.http2_tls_key;
let http2_tls_cert_path = &opts.http2_tls_cert;
let http2_tls_key_path = &opts.http2_tls_key;
match opts.compression.as_ref() {
@@ -92,50 +92,49 @@ impl Server {
.map(cache::control_headers)
.with(warp::trace::request())
.with(warp::compression::brotli(true))
.recover(move |rej| {
let page404 = page404.clone();
let page50x = page50x.clone();
async move { rejection::handle_rejection(page404, page50x, rej).await }
});
if let Some(cors_filter) = cors_filter {
tracing::info!(
cors_enabled = ?true,
allowed_origins = ?cors_allowed_origins
);
let server = warp::serve(
public_head.with(cors_filter.clone()).or(warp::get()
.and(filters::has_accept_encoding("br"))
.and(with_dir)
.with(cors_filter.clone())
.or(public_get_default.with(cors_filter))),
);
if http2 {
server
.tls()
.cert_path(http2_tls_cert_path)
.key_path(http2_tls_key_path)
.run(addr)
.await;
} else {
server.run(addr).await
.recover(rejection::handle_rejection);
match cors_filter {
Some(cors_filter) => {
tracing::info!(
cors_enabled = ?true,
allowed_origins = ?cors_allowed_origins
);
let server = warp::serve(
public_head.with(cors_filter.clone()).or(warp::get()
.and(filters::has_accept_encoding("br"))
.and(with_dir)
.with(cors_filter.clone())
.or(public_get_default.with(cors_filter))),
);
if http2 {
server
.tls()
.cert_path(http2_tls_cert_path)
.key_path(http2_tls_key_path)
.run(addr)
.await;
} else {
server.run(addr).await
}
}
} else {
let server = warp::serve(
public_head.or(warp::get()
.and(filters::has_accept_encoding("br"))
.and(with_dir)
.or(public_get_default)),
);
if http2 {
server
.tls()
.cert_path(http2_tls_cert_path)
.key_path(http2_tls_key_path)
.run(addr)
.await;
} else {
server.run(addr).await
None => {
let server = warp::serve(
public_head.or(warp::get()
.and(filters::has_accept_encoding("br"))
.and(with_dir)
.or(public_get_default)),
);
if http2 {
server
.tls()
.cert_path(http2_tls_cert_path)
.key_path(http2_tls_key_path)
.run(addr)
.await;
} else {
server.run(addr).await
}
}
}
}),
@@ -144,84 +143,87 @@ impl Server {
.map(cache::control_headers)
.with(warp::trace::request())
.with(warp::compression::gzip(true))
.recover(move |rej| {
let page404 = page404.clone();
let page50x = page50x.clone();
async move { rejection::handle_rejection(page404, page50x, rej).await }
});
if let Some(cors_filter) = cors_filter {
tracing::info!(
cors_enabled = ?true,
allowed_origins = ?cors_allowed_origins
);
let server = warp::serve(
public_head.with(cors_filter.clone()).or(warp::get()
.and(filters::has_accept_encoding("gzip"))
.and(with_dir)
.with(cors_filter.clone())
.or(public_get_default.with(cors_filter))),
);
if http2 {
server
.tls()
.cert_path(http2_tls_cert_path)
.key_path(http2_tls_key_path)
.run(addr)
.await;
} else {
server.run(addr).await
.recover(rejection::handle_rejection);
match cors_filter {
Some(cors_filter) => {
tracing::info!(
cors_enabled = ?true,
allowed_origins = ?cors_allowed_origins
);
let server = warp::serve(
public_head.with(cors_filter.clone()).or(warp::get()
.and(filters::has_accept_encoding("gzip"))
.and(with_dir)
.with(cors_filter.clone())
.or(public_get_default.with(cors_filter))),
);
if http2 {
server
.tls()
.cert_path(http2_tls_cert_path)
.key_path(http2_tls_key_path)
.run(addr)
.await;
} else {
server.run(addr).await
}
}
} else {
let server = warp::serve(
public_head.or(warp::get()
.and(filters::has_accept_encoding("gzip"))
.and(with_dir)
.or(public_get_default)),
);
if http2 {
server
.tls()
.cert_path(http2_tls_cert_path)
.key_path(http2_tls_key_path)
.run(addr)
.await;
} else {
server.run(addr).await
None => {
let server = warp::serve(
public_head.or(warp::get()
.and(filters::has_accept_encoding("gzip"))
.and(with_dir)
.or(public_get_default)),
);
if http2 {
server
.tls()
.cert_path(http2_tls_cert_path)
.key_path(http2_tls_key_path)
.run(addr)
.await;
} else {
server.run(addr).await
}
}
}
}),
_ => tokio::task::spawn(async move {
if let Some(cors_filter) = cors_filter {
tracing::info!(
cors_enabled = ?true,
allowed_origins = ?cors_allowed_origins
);
let public_get_default = warp::get()
.and(base_dir_filter.clone())
.with(cors_filter.clone());
let server = warp::serve(public_head.or(public_get_default.with(cors_filter)));
if http2 {
server
.tls()
.cert_path(http2_tls_cert_path)
.key_path(http2_tls_key_path)
.run(addr)
.await;
} else {
server.run(addr).await
match cors_filter {
Some(cors_filter) => {
tracing::info!(
cors_enabled = ?true,
allowed_origins = ?cors_allowed_origins
);
let public_get_default = warp::get()
.and(base_dir_filter.clone())
.with(cors_filter.clone());
let server =
warp::serve(public_head.or(public_get_default.with(cors_filter)));
if http2 {
server
.tls()
.cert_path(http2_tls_cert_path)
.key_path(http2_tls_key_path)
.run(addr)
.await;
} else {
server.run(addr).await
}
}
} else {
let server = warp::serve(public_head.or(public_get_default));
if http2 {
server
.tls()
.cert_path(http2_tls_cert_path)
.key_path(http2_tls_key_path)
.run(addr)
.await;
} else {
server.run(addr).await
None => {
let server = warp::serve(public_head.or(public_get_default));
if http2 {
server
.tls()
.cert_path(http2_tls_cert_path)
.key_path(http2_tls_key_path)
.run(addr)
.await;
} else {
server.run(addr).await
}
}
}
}),
@@ -236,3 +238,9 @@ impl Server {
Ok(())
}
}
impl Default for Server {
fn default() -> Self {
Self::new()
}
}