diff --git a/src/client.rs b/src/client.rs index 9a070ff..1e3d28e 100644 --- a/src/client.rs +++ b/src/client.rs @@ -2,6 +2,7 @@ use crate::error::{Error, Result}; use crate::pagination::{PaginatedRequest, PaginationState, PaginationType}; use crate::request::{Request, RequestBuilderExt}; use futures::prelude::*; +use reqwest::header::{HeaderMap, HeaderValue}; use reqwest::Client as ReqwestClient; use std::borrow::Cow; use std::sync::Arc; @@ -11,6 +12,7 @@ enum Authentication<'a> { Bearer(Cow<'a, str>), Basic(Cow<'a, str>, Cow<'a, str>), Query(Vec<(Cow<'a, str>, Cow<'a, str>)>), + Header(HeaderMap), } /// The main client used for making requests. @@ -58,6 +60,19 @@ impl<'a> Client<'a> { self } + /// Enable custom header authentication for the client + pub fn header_auth(mut self, pairs: Vec<(&'static str, &'static str)>) -> Self { + let mut map = HeaderMap::new(); + for (k, v) in pairs { + map.insert( + k, + HeaderValue::from_str(v).expect("Unable to parse header value"), + ); + } + self.auth = Some(Authentication::Header(map)); + self + } + fn format_request(&'a self, request: &R) -> Result { let endpoint = request.endpoint(); let endpoint = endpoint.trim_matches('/'); @@ -74,6 +89,7 @@ impl<'a> Client<'a> { Some(Authentication::Bearer(token)) => req.bearer_auth(token), Some(Authentication::Basic(user, pass)) => req.basic_auth(user, Some(pass)), Some(Authentication::Query(pairs)) => req.query(&pairs), + Some(Authentication::Header(pairs)) => req.headers(pairs.clone()), }; req.build().map_err(From::from) } diff --git a/tests/integration/authentication/header.rs b/tests/integration/authentication/header.rs new file mode 100644 index 0000000..2f912f8 --- /dev/null +++ b/tests/integration/authentication/header.rs @@ -0,0 +1,33 @@ +use rest_client::{Client, EmptyResponse, Request}; +use std::borrow::Cow; +use wiremock::matchers::{header, method, path}; +use wiremock::{Mock, MockServer, ResponseTemplate}; + +struct EmptyHello; + +impl Request for EmptyHello { + type Body = (); + type Response = EmptyResponse; + + fn endpoint(&self) -> Cow { + "/hello".into() + } +} + +#[tokio::test] +async fn header_auth() { + let server = MockServer::start().await; + let uri = server.uri(); + let auth = vec![("key", "k"), ("secret", "s")]; + let client = Client::new(&uri).header_auth(auth); + + Mock::given(method("GET")) + .and(path("/hello")) + .and(header("key", "k")) + .and(header("secret", "s")) + .respond_with(ResponseTemplate::new(200)) + .mount(&server) + .await; + + client.send(&EmptyHello).await.unwrap(); +} diff --git a/tests/integration/authentication/mod.rs b/tests/integration/authentication/mod.rs index 19748c6..e71b07a 100644 --- a/tests/integration/authentication/mod.rs +++ b/tests/integration/authentication/mod.rs @@ -1,3 +1,4 @@ mod basic; mod bearer; +mod header; mod query;