Skip to content

Commit 0c92c3a

Browse files
authored
Extract credentials passed in Url (#147)
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 25a89d1 commit 0c92c3a

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
@@ -373,10 +373,31 @@ impl Transport {
373373

374374
/// Creates a new instance of a [Transport] configured with a
375375
/// [SingleNodeConnectionPool].
376+
/// If the url contains credentials, these are removed and added
377+
/// as [Credentials::Basic] to the [Transport]
376378
pub fn single_node(url: &str) -> Result<Transport, Error> {
377-
let u = Url::parse(url)?;
379+
let mut u = Url::parse(url)?;
380+
381+
// if username and password are specified in the url, remove them and use
382+
// them to construct basic credentials. Not doing so can lead to a double
383+
// Authorization header being sent by reqwest.
384+
let credentials = if !u.username().is_empty() && u.password().is_some() {
385+
let username = u.username().to_string();
386+
let password = u.password().unwrap().to_string();
387+
u.set_username("").unwrap();
388+
u.set_password(None).unwrap();
389+
Some(Credentials::Basic(username, password))
390+
} else {
391+
None
392+
};
393+
378394
let conn_pool = SingleNodeConnectionPool::new(u);
379-
let transport = TransportBuilder::new(conn_pool).build()?;
395+
let mut transport_builder = TransportBuilder::new(conn_pool);
396+
if let Some(c) = credentials {
397+
transport_builder = transport_builder.auth(c);
398+
}
399+
400+
let transport = transport_builder.build()?;
380401
Ok(transport)
381402
}
382403

elasticsearch/tests/common/client.rs

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

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

57-
#[cfg(any(feature = "native-tls", feature = "rustls-tls"))]
58-
{
78+
if let Some(c) = credentials {
79+
builder = builder.auth(c);
80+
}
81+
82+
// assume if we're running with HTTPS then disable
83+
// certificate validation - we'll change this for tests that need to.
84+
#[cfg(any(feature = "native-tls", feature = "rustls-tls"))]
85+
{
86+
if url.scheme() == "https" {
5987
builder = builder.cert_validation(CertificateValidation::None);
6088
}
6189
}

0 commit comments

Comments
 (0)