Hi,
I was not able to get diqwest
to successfully work against an embedded device with an HTTP server that requires digest authentication. I was able to get it to work with curl --digest
, so I compared the requests generated by curl vs. those generated by reqwest+diqwest.
It turns out curl generates an Authorization header that looks like:
Authorization: Digest username="...", realm="...", nonce="...", uri="/cgi-bin/egauge-show?c&T=1639976400,1642654800", cnonce="...", nc=00000001, qop=auth, response="..."
while reqwest+diqwest generates an Authorization header that looks like:
authorization: Digest username="...", realm="...", nonce="...", uri="http://100.100.0.208/cgi-bin/egauge-show?c&T=1639976400,1642654800", qop=auth, nc=00000001, cnonce="...", response="...", algorithm=MD5
I was able to get diqwest to generate an Authorization header closer to what curl generates with something like this:
diff --git a/src/core.rs b/src/core.rs
index 14d714a..2c2e9f5 100644
--- a/src/core.rs
+++ b/src/core.rs
@@ -25,11 +25,24 @@ impl WithDigestAuth for RequestBuilder {
match first_response.status() {
StatusCode::UNAUTHORIZED => {
let request = clone_request_builder(self)?.build()?;
- let url = request.url();
+ let full_url = request.url();
let method = HttpMethod::from(request.method().as_str());
let body = request.body().and_then(|b| b.as_bytes());
- let answer =
- DigestAuthHelper::parse_digest_auth_header(first_response, url.as_str(), method, body, username, password)?;
+
+ let mut base_url = full_url.clone();
+ match base_url.path_segments_mut() {
+ Ok(mut path) => {
+ path.clear();
+ }
+ Err(_) => {}
+ }
+
+ let url = format!(
+ "/{}",
+ base_url.make_relative(&full_url).ok_or(RequestBuilderNotCloneableError)?
+ );
+
+ let answer = DigestAuthHelper::parse_digest_auth_header(first_response, &url, method, body, username, password)?;
Ok(clone_request_builder(self)?.header("Authorization", answer).send().await?)
}
Is this a bug in diqwest?
Thanks!