diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a6deae..6c47c8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ## 0.7.0 (unreleased) - Breaking: `hyper`-1.0 for both server and client modules. -- Breaking: Remove `override_host` option in upstream options. Add a reverse option, i.e., `keep_original_host`. That is, `rpxy` always override the host header by the upstream hostname (backend uri host name) by default. If this reverse option specified, original `host` header is maintained or added from the value of url request line. +- Breaking: Remove `override_host` option in upstream options. Add a reverse option, i.e., `keep_original_host`, and the similar option `set_upstream_host`. While `keep_original_host` can be explicitly specified, `rpxy` keeps the original `host` given by the incoming request by default. Then, the original `host` header is maintained or added from the value of url request line. If `host` header needs to be overridden with the upstream host name (backend uri's host name), `set_upstream_host` has to be set. If both of `set_upstream_host` and `keep_original_host` are set, `keep_original_host` is prioritized since it is explicitly specified. - Breaking: Introduced `native-tls-backend` feature to use the native TLS engine to access backend applications. - Redesigned: Cache structure is totally redesigned with more memory-efficient way to read from cache file, and more secure way to strongly bind memory-objects with files with hash values. - Redesigned: HTTP body handling flow is also redesigned with more memory-and-time efficient techniques without putting the whole objects on memory by using `futures::stream::Stream` and `futures::channel::mpsc` diff --git a/config-example.toml b/config-example.toml index 7460c35..4777a57 100644 --- a/config-example.toml +++ b/config-example.toml @@ -57,7 +57,7 @@ upstream = [ ] load_balance = "round_robin" # or "random" or "sticky" (sticky session) or "none" (fix to the first one, default) upstream_options = [ - "keep_original_host", # do not overwrite HOST value with upstream hostname (like 192.168.xx.x seen from rpxy) + "keep_original_host", # [default] do not overwrite HOST value with upstream hostname (like 192.168.xx.x seen from rpxy), which is prior to "set_upstream_host" if both are specified. "force_http2_upstream", # mutually exclusive with "force_http11_upstream" ] @@ -76,9 +76,9 @@ upstream = [ ] load_balance = "random" # or "round_robin" or "sticky" (sticky session) or "none" (fix to the first one, default) upstream_options = [ - "disable_override_host", "upgrade_insecure_requests", "force_http11_upstream", + "set_upstream_host", # overwrite HOST value with upstream hostname (like www.yahoo.com) ] ###################################################################### diff --git a/rpxy-lib/src/backend/upstream_opts.rs b/rpxy-lib/src/backend/upstream_opts.rs index c4c3db5..68309ca 100644 --- a/rpxy-lib/src/backend/upstream_opts.rs +++ b/rpxy-lib/src/backend/upstream_opts.rs @@ -1,10 +1,17 @@ use crate::error::*; +/// Options for request message to be sent to upstream. #[derive(Debug, Clone, Hash, Eq, PartialEq)] pub enum UpstreamOption { + /// Keep original host header, which is prioritized over SetUpstreamHost KeepOriginalHost, + /// Overwrite host header with upstream hostname + SetUpstreamHost, + /// Add upgrade-insecure-requests header UpgradeInsecureRequests, + /// Force HTTP/1.1 upstream ForceHttp11Upstream, + /// Force HTTP/2 upstream ForceHttp2Upstream, // TODO: Adds more options for heder override } @@ -13,6 +20,7 @@ impl TryFrom<&str> for UpstreamOption { fn try_from(val: &str) -> RpxyResult { match val { "keep_original_host" => Ok(Self::KeepOriginalHost), + "set_upstream_host" => Ok(Self::SetUpstreamHost), "upgrade_insecure_requests" => Ok(Self::UpgradeInsecureRequests), "force_http11_upstream" => Ok(Self::ForceHttp11Upstream), "force_http2_upstream" => Ok(Self::ForceHttp2Upstream), diff --git a/rpxy-lib/src/message_handler/handler_manipulate_messages.rs b/rpxy-lib/src/message_handler/handler_manipulate_messages.rs index a0b37e0..ecfd53c 100644 --- a/rpxy-lib/src/message_handler/handler_manipulate_messages.rs +++ b/rpxy-lib/src/message_handler/handler_manipulate_messages.rs @@ -99,14 +99,14 @@ where headers.insert(header::TE, HeaderValue::from_bytes("trailers".as_bytes()).unwrap()); } - // add "host" header of original server_name if not exist (default) + // by default, add "host" header of original server_name if not exist if req.headers().get(header::HOST).is_none() { let org_host = req.uri().host().ok_or_else(|| anyhow!("Invalid request"))?.to_owned(); req .headers_mut() .insert(header::HOST, HeaderValue::from_str(&org_host)?); }; - let original_host_header = req.headers().get(header::HOST).unwrap().clone(); + println!("{:?}", req.headers().get(header::HOST)); ///////////////////////////////////////////// // Fix unique upstream destination since there could be multiple ones. @@ -133,10 +133,8 @@ where // apply upstream-specific headers given in upstream_option let headers = req.headers_mut(); - // by default, host header is overwritten with upstream hostname - override_host_header(headers, &upstream_chosen.uri)?; // apply upstream options to header - apply_upstream_options_to_header(headers, &original_host_header, upstream_candidates)?; + apply_upstream_options_to_header(headers, &upstream_chosen.uri, upstream_candidates)?; // update uri in request ensure!( @@ -182,7 +180,6 @@ where update_request_line(req, upstream_chosen, upstream_candidates)?; } - Ok(context) } } diff --git a/rpxy-lib/src/message_handler/utils_headers.rs b/rpxy-lib/src/message_handler/utils_headers.rs index df2d57b..9be45e5 100644 --- a/rpxy-lib/src/message_handler/utils_headers.rs +++ b/rpxy-lib/src/message_handler/utils_headers.rs @@ -86,8 +86,8 @@ pub(super) fn set_sticky_cookie_lb_context( Ok(()) } -/// default: overwrite HOST value with upstream hostname (like 192.168.xx.x seen from rpxy) -pub(super) fn override_host_header(headers: &mut HeaderMap, upstream_base_uri: &Uri) -> Result<()> { +/// overwrite HOST value with upstream hostname (like 192.168.xx.x seen from rpxy) +fn override_host_header(headers: &mut HeaderMap, upstream_base_uri: &Uri) -> Result<()> { let mut upstream_host = upstream_base_uri .host() .ok_or_else(|| anyhow!("No hostname is given"))? @@ -105,18 +105,18 @@ pub(super) fn override_host_header(headers: &mut HeaderMap, upstream_base_uri: & /// Apply options to request header, which are specified in the configuration pub(super) fn apply_upstream_options_to_header( headers: &mut HeaderMap, - original_host_header: &HeaderValue, + upstream_base_uri: &Uri, // _client_addr: &SocketAddr, upstream: &UpstreamCandidates, - // _upstream_base_uri: &Uri, ) -> Result<()> { for opt in upstream.options.iter() { match opt { - UpstreamOption::KeepOriginalHost => { - // revert hostname - headers - .insert(header::HOST, original_host_header.to_owned()) - .ok_or_else(|| anyhow!("Failed to revert host header in keep_original_host option"))?; + UpstreamOption::SetUpstreamHost => { + // prioritize KeepOriginalHost + if !upstream.options.contains(&UpstreamOption::KeepOriginalHost) { + // overwrite host header, this removes all the HOST header values + override_host_header(headers, upstream_base_uri)?; + } } UpstreamOption::UpgradeInsecureRequests => { // add upgrade-insecure-requests in request header if not exist