Skip to content

Commit 872ad84

Browse files
committed
Extract credentials passed in Url
This commit extracts the credentials passed in a Url and uses them to pass Basic Credentials when constructing the single node Transport, as well as constructing a client for elasticsearch integration tests. Leaving the credentials in the Url and also configuring credentials through .auth() fn, results in reqwest sending two Authorization headers.
1 parent 7c680c6 commit 872ad84

File tree

2 files changed

+58
-9
lines changed

2 files changed

+58
-9
lines changed

elasticsearch/src/http/transport.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -329,10 +329,31 @@ impl Transport {
329329

330330
/// Creates a new instance of a [Transport] configured with a
331331
/// [SingleNodeConnectionPool].
332+
/// If the url contains credentials, these are removed and added
333+
/// as [Credentials::Basic] to the [Transport]
332334
pub fn single_node(url: &str) -> Result<Transport, Error> {
333-
let u = Url::parse(url)?;
335+
let mut u = Url::parse(url)?;
336+
337+
// if username and password are specified in the url, remove them and use
338+
// them to construct basic credentials. Not doing so can lead to a double
339+
// Authorization header being sent by reqwest.
340+
let credentials = if !u.username().is_empty() && u.password().is_some() {
341+
let username = u.username().to_string();
342+
let password = u.password().unwrap().to_string();
343+
u.set_username("").unwrap();
344+
u.set_password(None).unwrap();
345+
Some(Credentials::Basic(username, password))
346+
} else {
347+
None
348+
};
349+
334350
let conn_pool = SingleNodeConnectionPool::new(u);
335-
let transport = TransportBuilder::new(conn_pool).build()?;
351+
let mut transport_builder = TransportBuilder::new(conn_pool);
352+
if let Some(c) = credentials {
353+
transport_builder = transport_builder.auth(c);
354+
}
355+
356+
let transport = transport_builder.build()?;
336357
Ok(transport)
337358
}
338359

elasticsearch/tests/common/client.rs

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,16 +53,44 @@ pub fn create_default_builder() -> TransportBuilder {
5353
}
5454

5555
pub fn create_builder(addr: &str) -> TransportBuilder {
56-
let url = Url::parse(addr).unwrap();
56+
let mut url = Url::parse(addr).unwrap();
57+
58+
// if the url is https and specifies a username and password, remove from the url and set credentials
59+
let credentials = if url.scheme() == "https" {
60+
let username = if !url.username().is_empty() {
61+
let u = url.username().to_string();
62+
url.set_username("").unwrap();
63+
u
64+
} else {
65+
"elastic".into()
66+
};
67+
68+
let password = match url.password() {
69+
Some(p) => {
70+
let pass = p.to_string();
71+
url.set_password(None).unwrap();
72+
pass
73+
}
74+
None => "changeme".into(),
75+
};
76+
77+
Some(Credentials::Basic(username, password))
78+
} else {
79+
None
80+
};
81+
5782
let conn_pool = SingleNodeConnectionPool::new(url.clone());
5883
let mut builder = TransportBuilder::new(conn_pool);
59-
// assume if we're running with HTTPS then authentication is also enabled and disable
60-
// certificate validation - we'll change this for tests that need to.
61-
if url.scheme() == "https" {
62-
builder = builder.auth(Credentials::Basic("elastic".into(), "changeme".into()));
6384

64-
#[cfg(any(feature = "native-tls", feature = "rustls-tls"))]
65-
{
85+
if let Some(c) = credentials {
86+
builder = builder.auth(c);
87+
}
88+
89+
// assume if we're running with HTTPS then disable
90+
// certificate validation - we'll change this for tests that need to.
91+
#[cfg(any(feature = "native-tls", feature = "rustls-tls"))]
92+
{
93+
if url.scheme() == "https" {
6694
builder = builder.cert_validation(CertificateValidation::None);
6795
}
6896
}

0 commit comments

Comments
 (0)