From 925a4e8f1d624e6f266774bec7bfe0213fe13131 Mon Sep 17 00:00:00 2001 From: Dmitry Samoylov Date: Wed, 13 Nov 2024 17:31:47 +0700 Subject: [PATCH 1/2] Disable re-using digest auth headers by default One of our VMSes doesn't work well when headers are reused. --- onvif/src/soap/auth/digest.rs | 10 +++++++++- onvif/src/soap/client.rs | 13 ++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/onvif/src/soap/auth/digest.rs b/onvif/src/soap/auth/digest.rs index 91f39c5..232dfc0 100644 --- a/onvif/src/soap/auth/digest.rs +++ b/onvif/src/soap/auth/digest.rs @@ -20,6 +20,7 @@ pub struct Digest { creds: Option, uri: Url, state: State, + reuse_headers: bool, } enum State { @@ -31,11 +32,12 @@ enum State { } impl Digest { - pub fn new(uri: &Url, creds: &Option) -> Self { + pub fn new(uri: &Url, creds: &Option, reuse_headers: bool) -> Self { Self { creds: creds.clone(), uri: uri.clone(), state: State::Default, + reuse_headers, } } } @@ -43,6 +45,12 @@ impl Digest { impl Digest { /// Call this when the authentication was successful. pub fn set_success(&mut self) { + if !self.reuse_headers { + // Since we don't need to preserve the headers, reset all the state to default. + *self = Self::new(&self.uri, &self.creds, self.reuse_headers); + return; + } + if let State::Got401 { count, .. } = &mut self.state { // We always store at least one request, so it's never zero. *count = nonzero!(1_u8); diff --git a/onvif/src/soap/client.rs b/onvif/src/soap/client.rs index 5daa919..95fe966 100644 --- a/onvif/src/soap/client.rs +++ b/onvif/src/soap/client.rs @@ -41,6 +41,7 @@ impl ClientBuilder { credentials: None, response_patcher: None, auth_type: AuthType::Any, + reuse_digest_auth_headers: false, timeout: ClientBuilder::DEFAULT_TIMEOUT, fix_time_gap: None, }, @@ -67,6 +68,11 @@ impl ClientBuilder { self } + pub fn reuse_digest_auth_headers(mut self, reuse_digest_auth_headers: bool) -> Self { + self.config.reuse_digest_auth_headers = reuse_digest_auth_headers; + self + } + pub fn timeout(mut self, timeout: Duration) -> Self { self.config.timeout = timeout; self @@ -87,7 +93,11 @@ impl ClientBuilder { .unwrap() }; - let digest = Digest::new(&self.config.uri, &self.config.credentials); + let digest = Digest::new( + &self.config.uri, + &self.config.credentials, + self.config.reuse_digest_auth_headers, + ); Client { client, @@ -121,6 +131,7 @@ struct Config { credentials: Option, response_patcher: Option, auth_type: AuthType, + reuse_digest_auth_headers: bool, timeout: Duration, fix_time_gap: Option, } From 3c45b5a666ff8b4b0c269843d11e94652ffd6c28 Mon Sep 17 00:00:00 2001 From: Dmitry Samoylov Date: Wed, 13 Nov 2024 21:46:48 +0700 Subject: [PATCH 2/2] Ignore encoding case in `assert_xml_eq` This fixes flaky tests where encoding is either `utf-8` or `UTF-8`. --- schema/src/tests/utils.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/schema/src/tests/utils.rs b/schema/src/tests/utils.rs index 31cf80f..5977eed 100644 --- a/schema/src/tests/utils.rs +++ b/schema/src/tests/utils.rs @@ -1,6 +1,26 @@ +use xml::reader::XmlEvent; + pub fn assert_xml_eq(actual: &str, expected: &str) { for (a, e) in without_whitespaces(actual).zip(without_whitespaces(expected)) { - assert_eq!(a, e); + match (a, e) { + ( + Ok(XmlEvent::StartDocument { + version, + encoding, + standalone, + }), + Ok(XmlEvent::StartDocument { + version: version_expected, + encoding: encoding_expected, + standalone: standalone_expected, + }), + ) => { + assert_eq!(version, version_expected); + assert_eq!(encoding.to_lowercase(), encoding_expected.to_lowercase()); + assert_eq!(standalone, standalone_expected); + } + (a, e) => assert_eq!(a, e), + } } }