diff --git a/src/xhttp/server.rs b/src/xhttp/server.rs index f3683b43..3a92ad90 100644 --- a/src/xhttp/server.rs +++ b/src/xhttp/server.rs @@ -3907,9 +3907,10 @@ impl State { request: &Request<()>, body: Reader, ) -> Result<(Body, bool), Rejection> { - wire::check_matching_headers(&self.config, request.headers()) - .inspect_err(|error| log::debug!("XHTTP request rejected: {error}")) - .map_err(|_| StatusCode::NOT_FOUND)?; + if !wire::check_matching_headers(&self.config, request.headers()) { + log::debug!("XHTTP request rejected: headers do not match"); + return Err(StatusCode::NOT_FOUND.into()); + } match wire::classify(&self.config, &self.path, request)? { Kind::Options => Ok((Body::Empty, false)), Kind::One => self.stream_one(body).map_err(Into::into), @@ -4387,7 +4388,9 @@ impl State { if !self.config.close_on_http1_error { return Ok(()); } - wire::check_matching_headers(&self.config, request.headers())?; + if !wire::check_matching_headers(&self.config, request.headers()) { + return Err(io::Error::other("XHTTP request headers do not match")); + } if !percent_encoding::percent_decode_str(request.uri().path()) .take(self.path.base.len()) .eq(self.path.base.bytes()) diff --git a/src/xhttp/wire.rs b/src/xhttp/wire.rs index f9661618..6680bcdf 100644 --- a/src/xhttp/wire.rs +++ b/src/xhttp/wire.rs @@ -108,21 +108,14 @@ pub enum Kind { Packet(String, u64), } -pub fn check_matching_headers(config: &XhttpServerConfig, headers: &HeaderMap) -> io::Result<()> { - for (name, expected) in &config.matching_headers { +pub fn check_matching_headers(config: &XhttpServerConfig, headers: &HeaderMap) -> bool { + config.matching_headers.iter().all(|(name, expected)| { let mut values = headers.get_all(name.as_str()).iter(); - let matches = values + values .next() .is_some_and(|value| bool::from(value.as_bytes().ct_eq(expected.as_bytes()))) - && values.next().is_none(); - if !matches { - return Err(io::Error::new( - io::ErrorKind::PermissionDenied, - "XHTTP request headers do not match", - )); - } - } - Ok(()) + && values.next().is_none() + }) } fn query_padding(query: &str) -> Option { @@ -308,7 +301,7 @@ mod tests { "protocol": {"type": "socks"} })) .unwrap(); - assert!(check_matching_headers(&config, &HeaderMap::new()).is_ok()); + assert!(check_matching_headers(&config, &HeaderMap::new())); config .matching_headers .insert("X-Token".into(), "Secret".into()); @@ -319,10 +312,10 @@ mod tests { let mut headers = HeaderMap::new(); headers.insert("x-token", "Secret".parse().unwrap()); - assert!(check_matching_headers(&config, &headers).is_err()); + assert!(!check_matching_headers(&config, &headers)); headers.insert("x-empty", "".parse().unwrap()); headers.insert("x-extra", "allowed".parse().unwrap()); - assert!(check_matching_headers(&config, &headers).is_ok()); + assert!(check_matching_headers(&config, &headers)); for values in [ vec![], vec![""], @@ -337,12 +330,7 @@ mod tests { for value in values { headers.append("x-token", value.parse().unwrap()); } - assert_eq!( - check_matching_headers(&config, &headers) - .unwrap_err() - .kind(), - io::ErrorKind::PermissionDenied - ); + assert!(!check_matching_headers(&config, &headers)); } }