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, } 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), + } } }