From f1c8a55b7a7ae533236564a195037128804445e6 Mon Sep 17 00:00:00 2001 From: Dean Li Date: Sun, 21 Feb 2021 16:55:17 +0800 Subject: Allow set custom headers from CLI --- src/args.rs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/args.rs') diff --git a/src/args.rs b/src/args.rs index f736941..53f1638 100644 --- a/src/args.rs +++ b/src/args.rs @@ -117,6 +117,10 @@ struct CliArgs { /// Shown instead of host in page title and heading #[structopt(short = "t", long = "title")] title: Option, + + /// Custom header from user + #[structopt(long = "header")] + header: Option, } /// Checks wether an interface is valid, i.e. it can be parsed into an IP address @@ -225,6 +229,7 @@ pub fn parse_args() -> crate::MiniserveConfig { zip_enabled: args.enable_zip, dirs_first: args.dirs_first, title: args.title, + header: args.header, } } -- cgit v1.2.3 From 7b4402238a19f187321a68088e6542d8d5fa8572 Mon Sep 17 00:00:00 2001 From: Dean Li Date: Mon, 22 Feb 2021 12:11:11 +0800 Subject: Move the parsing header logic to args.rs --- src/args.rs | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) (limited to 'src/args.rs') diff --git a/src/args.rs b/src/args.rs index 53f1638..ecfe151 100644 --- a/src/args.rs +++ b/src/args.rs @@ -119,8 +119,8 @@ struct CliArgs { title: Option, /// Custom header from user - #[structopt(long = "header")] - header: Option, + #[structopt(long = "header", parse(try_from_str = parse_header))] + header: Option
, } /// Checks wether an interface is valid, i.e. it can be parsed into an IP address @@ -174,6 +174,39 @@ fn parse_auth(src: &str) -> Result { }) } +/// A own header modified from [httparse](https://docs.rs/httparse/1.3.5/src/httparse/lib.rs.html#415-425) +#[derive(Clone, Eq, PartialEq, Debug)] +pub struct Header { + /// The name portion of a header. + /// + /// A header name must be valid ASCII-US, so it's safe to store as a `String`. + pub name: String, + /// The value portion of a header. + /// + /// While headers **should** be ASCII-US, the specification allows for + /// values that may not be, and so the value is stored as bytes. + pub value: Vec, +} + +impl Header { + fn new(header: &httparse::Header) -> Self { + Header { + name: header.name.to_string(), + value: header.value.to_vec(), + } + } +} + +fn parse_header(src: &str) -> Result { + let mut headers = [httparse::EMPTY_HEADER; 1]; + let mut header = src.to_string(); + header.push('\n'); + httparse::parse_headers(header.as_bytes(), &mut headers)?; + + let header = Header::new(&headers[0]); + Ok(header) +} + /// Parses the command line arguments pub fn parse_args() -> crate::MiniserveConfig { let args = CliArgs::from_args(); -- cgit v1.2.3 From 956ce204b4bda191c441fe5c4d385baa92c82b3e Mon Sep 17 00:00:00 2001 From: Dean Li Date: Mon, 22 Feb 2021 14:11:18 +0800 Subject: Multiple headers support for custom headers --- src/args.rs | 47 +++++++++++++++++++---------------------------- 1 file changed, 19 insertions(+), 28 deletions(-) (limited to 'src/args.rs') diff --git a/src/args.rs b/src/args.rs index ecfe151..7710cce 100644 --- a/src/args.rs +++ b/src/args.rs @@ -1,3 +1,5 @@ +use bytes::Bytes; +use http::header::{HeaderMap, HeaderName, HeaderValue}; use port_check::free_local_port; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; use std::path::PathBuf; @@ -120,7 +122,7 @@ struct CliArgs { /// Custom header from user #[structopt(long = "header", parse(try_from_str = parse_header))] - header: Option
, + header: Option, } /// Checks wether an interface is valid, i.e. it can be parsed into an IP address @@ -174,37 +176,26 @@ fn parse_auth(src: &str) -> Result { }) } -/// A own header modified from [httparse](https://docs.rs/httparse/1.3.5/src/httparse/lib.rs.html#415-425) -#[derive(Clone, Eq, PartialEq, Debug)] -pub struct Header { - /// The name portion of a header. - /// - /// A header name must be valid ASCII-US, so it's safe to store as a `String`. - pub name: String, - /// The value portion of a header. - /// - /// While headers **should** be ASCII-US, the specification allows for - /// values that may not be, and so the value is stored as bytes. - pub value: Vec, -} - -impl Header { - fn new(header: &httparse::Header) -> Self { - Header { - name: header.name.to_string(), - value: header.value.to_vec(), - } - } -} - -fn parse_header(src: &str) -> Result { - let mut headers = [httparse::EMPTY_HEADER; 1]; +/// Custom header parser (allow multiple headers input) +pub fn parse_header(src: &str) -> Result { + // Max customized header is limitted to 16 + let mut headers = [httparse::EMPTY_HEADER; 16]; let mut header = src.to_string(); header.push('\n'); httparse::parse_headers(header.as_bytes(), &mut headers)?; - let header = Header::new(&headers[0]); - Ok(header) + let mut header_map = HeaderMap::new(); + + for h in headers.iter() { + if h.name != httparse::EMPTY_HEADER.name { + header_map.insert( + HeaderName::from_bytes(&Bytes::copy_from_slice(h.name.as_bytes())).unwrap(), + HeaderValue::from_bytes(h.value).unwrap(), + ); + } + } + + Ok(header_map) } /// Parses the command line arguments -- cgit v1.2.3