From 3b2d191846104a274456e7bd100eb86651acd339 Mon Sep 17 00:00:00 2001 From: Jose Quintana Date: Mon, 25 Apr 2022 00:16:46 +0200 Subject: [PATCH] chore: http headers map deserialization --- Cargo.lock | 11 +++++++++++ Cargo.toml | 1 + src/config.rs | 9 ++------- src/manifest.rs | 17 ++++++----------- src/server.rs | 21 ++++++++++++++++++++- tests/toml/config.toml | 32 +++++++++++++++----------------- 6 files changed, 55 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b51976c..34a1c4e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -401,6 +401,16 @@ dependencies = [ ] [[package]] +name = "http-serde" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d98b3d9662de70952b14c4840ee0f37e23973542a363e2275f4b9d024ff6cca" +dependencies = [ + "http", + "serde", +] + +[[package]] name = "httparse" version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -894,6 +904,7 @@ dependencies = [ "futures-util", "headers", "http", + "http-serde", "humansize", "hyper", "listenfd", diff --git a/Cargo.toml b/Cargo.toml index 8f936ae..f8727ab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,6 +54,7 @@ form_urlencoded = "1.0" serde = { version = "1.0", default-features = false, features = ["derive"] } serde_ignored = "0.1" toml = "0.5" +http-serde = "1.1" [target.'cfg(all(target_env = "musl", target_pointer_width = "64"))'.dependencies.tikv-jemallocator] version = "0.4" diff --git a/src/config.rs b/src/config.rs index e46f497..3d12d16 100644 --- a/src/config.rs +++ b/src/config.rs @@ -176,12 +176,7 @@ pub struct Config { /// Defines a grace period in seconds after a `SIGTERM` signal is caught which will delay the server before to shut it down gracefully. The maximum value is 255 seconds. pub grace_period: u8, - #[structopt( - long, - short = "w", - default_value = "config.toml", - env = "SEVER_CONFIG_FILE" - )] + #[structopt(long, short = "w", env = "SERVER_CONFIG_FILE")] /// Server TOML configuration file path. - pub config_file: PathBuf, + pub config_file: Option, } diff --git a/src/manifest.rs b/src/manifest.rs index 2ce9066..8daad27 100644 --- a/src/manifest.rs +++ b/src/manifest.rs @@ -1,5 +1,6 @@ //! The server configuration file (Manifest) +use headers::HeaderMap; use serde::Deserialize; use std::collections::BTreeSet; use std::path::{Path, PathBuf}; @@ -16,18 +17,12 @@ pub enum LogLevel { Trace, } -#[derive(Debug, Serialize, Deserialize, Clone, Default)] -#[serde(rename_all = "kebab-case")] -pub struct Header { - pub key: String, - pub value: String, -} - -#[derive(Debug, Serialize, Deserialize, Clone, Default)] +#[derive(Debug, Serialize, Deserialize, Clone)] #[serde(rename_all = "kebab-case")] pub struct Headers { pub source: String, - pub headers: Option>, + #[serde(with = "http_serde::header_map")] + pub headers: HeaderMap, } #[derive(Debug, Serialize, Deserialize, Clone)] @@ -61,11 +56,11 @@ pub struct Manifest { // CORS pub cors_allow_origins: String, - pub cors_allow_headers: String, + pub cors_allow_headers: Option, // Directoy listing pub directory_listing: bool, - pub directory_listing_order: u8, + pub directory_listing_order: Option, // Basich Authentication pub basic_auth: Option, diff --git a/src/server.rs b/src/server.rs index a46fb66..45ef981 100644 --- a/src/server.rs +++ b/src/server.rs @@ -8,7 +8,7 @@ use structopt::StructOpt; use crate::handler::{RequestHandler, RequestHandlerOpts}; use crate::tls::{TlsAcceptor, TlsConfigBuilder}; use crate::{config::Config, service::RouterService, Context, Result}; -use crate::{cors, helpers, logger, signals}; +use crate::{cors, helpers, logger, manifest, signals}; /// Define a multi-thread HTTP or HTTP/2 web server. pub struct Server { @@ -59,6 +59,25 @@ impl Server { logger::init(&opts.log_level) .with_context(|| "failed to initialize logging".to_string())?; + // TODO: + // Check for a config file + if let Some(config_file) = &opts.config_file { + if config_file.is_file() { + let path_resolved = config_file + .canonicalize() + .with_context(|| "error resolving config file path.")?; + + let manifest = manifest::read_manifest(&path_resolved).with_context(|| { + format!( + "can not get \"{}\" config file because has invalid format or inaccessible", + path_resolved.display() + ) + })?; + + println!("{:?}", manifest.unwrap().headers); + } + } + // Determine TCP listener either file descriptor or TCP socket let (tcp_listener, addr_str); match opts.fd { diff --git a/tests/toml/config.toml b/tests/toml/config.toml index 842d6cf..4479753 100644 --- a/tests/toml/config.toml +++ b/tests/toml/config.toml @@ -32,35 +32,33 @@ directory-listing = false basic-auth = "" # File descriptor binding -fd = "" +# fd = "" # Worker threads threads-multiplier = 1 +# Grace period after a graceful shutdown grace-period = 0 +# Page fallback for 404s page-fallback = "" +# HTTP Headers customization + +# a. Online version [[headers]] source = "**/*.@(eot|otf|ttf|ttc|woff|font.css)" - [[headers.headers]] - key = "Access-Control-Allow-Origin" - value = "*" - [[headers.headers]] - key = "Access-Control-Allow-Origin" - value = "*" - [[headers.headers]] - key = "Access-Control-Allow-Origin" - value = "*" +headers = { Access-Control-Allow-Origin = "*", X-XSS-PROTECTION = "1; mode=block" } +# b. Multiline version [[headers]] -source = "**/*.@(jpg|jpeg|gif|png)" - [[headers.headers]] - key = "Cache-Control" - value = "max-age=7200" + source = "**/*.@(jpg|jpeg|gif|png)" +[headers.headers] + Cache-Control = "max-age=7200" + Content-Security-Policy = "frame-ancestors 'self'" +# c. Multiline version with explicit key (dotted) [[headers]] source = "404.html" - [[headers.headers]] - key = "Cache-Control" - value = "max-age=300" +headers.Cache-Control = "max-age=300" +headers.Strict-Transport-Security = "max-age=63072000; includeSubDomains; preload" -- libgit2 1.7.2