Skip to content

Commit e68245a

Browse files
authored
Add method, url, content_length and content_type to Response (#96)
This commit adds functions to Response for: - request HTTP method - request Url - response Content-Type - response Content-Length Reexport url::Url and reqwest::StatusCode in http module for convenience. Closes: #6
1 parent 5963f06 commit e68245a

File tree

7 files changed

+152
-98
lines changed

7 files changed

+152
-98
lines changed

elasticsearch/build.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ fn main() {
1616
println!("cargo:rustc-cfg=RUSTC_IS_DEV");
1717
}
1818
}
19-
}
19+
}

elasticsearch/src/http/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ pub mod request;
55
pub mod response;
66
pub mod transport;
77

8+
pub use reqwest::StatusCode;
9+
pub use url::Url;
10+
811
/// Http methods supported by Elasticsearch
12+
#[derive(Debug, Clone, Copy, PartialEq)]
913
pub enum Method {
1014
/// get
1115
Get,

elasticsearch/src/http/response.rs

+56-27
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,54 @@
11
//! HTTP response components
22
33
use crate::error::Error;
4-
use reqwest::header::HeaderMap;
5-
use reqwest::StatusCode;
4+
use crate::http::{headers::HeaderMap, Method, StatusCode, Url};
65
use serde::de::DeserializeOwned;
76

87
/// A response from Elasticsearch
9-
pub struct Response(reqwest::Response);
8+
pub struct Response(reqwest::Response, Method);
109

1110
impl Response {
1211
/// Creates a new instance of an Elasticsearch response
13-
pub fn new(response: reqwest::Response) -> Self {
14-
Self(response)
12+
pub fn new(response: reqwest::Response, method: Method) -> Self {
13+
Self(response, method)
1514
}
1615

17-
/// The HTTP status code of the response
18-
pub fn status_code(&self) -> StatusCode {
19-
self.0.status()
16+
/// Get the response content-length, if known.
17+
///
18+
/// Reasons it may not be known:
19+
///
20+
/// - The server didn't send a `content-length` header.
21+
/// - The response is compressed and automatically decoded (thus changing
22+
/// the actual decoded length).
23+
pub fn content_length(&self) -> Option<u64> {
24+
self.0.content_length()
25+
}
26+
27+
/// Gets the response content-type.
28+
pub fn content_type(&self) -> &str {
29+
self.0
30+
.headers()
31+
.get(crate::http::headers::CONTENT_TYPE)
32+
.and_then(|value| value.to_str().ok())
33+
.unwrap()
2034
}
2135

22-
/// Turn the response into an `Error` if Elasticsearch returned an error.
36+
/// Turn the response into an [Error] if Elasticsearch returned an error.
2337
pub fn error_for_status_code(self) -> Result<Self, Error> {
2438
match self.0.error_for_status_ref() {
2539
Ok(_) => Ok(self),
2640
Err(err) => Err(err.into()),
2741
}
2842
}
2943

30-
/// Turn the response into an `Error` if Elasticsearch returned an error.
44+
/// Turn the response into an [Error] if Elasticsearch returned an error.
3145
pub fn error_for_status_code_ref(&self) -> Result<&Self, Error> {
3246
match self.0.error_for_status_ref() {
3347
Ok(_) => Ok(self),
3448
Err(err) => Err(err.into()),
3549
}
3650
}
3751

38-
/// The response headers
39-
pub fn headers(&self) -> &HeaderMap {
40-
self.0.headers()
41-
}
42-
43-
/// Gets the Deprecation warning response headers
44-
///
45-
/// Deprecation headers signal the use of Elasticsearch functionality
46-
/// or features that are deprecated and will be removed in a future release.
47-
pub fn warning_headers(&self) -> impl Iterator<Item = &str> {
48-
self.0
49-
.headers()
50-
.get_all("Warning")
51-
.iter()
52-
.map(|w| w.to_str().unwrap())
53-
}
54-
5552
/// Asynchronously reads the response body as JSON
5653
///
5754
/// Reading the response body consumes `self`
@@ -63,11 +60,43 @@ impl Response {
6360
Ok(body)
6461
}
6562

63+
/// Gets the response headers.
64+
pub fn headers(&self) -> &HeaderMap {
65+
self.0.headers()
66+
}
67+
68+
/// Gets the request method.
69+
pub fn method(&self) -> Method {
70+
self.1
71+
}
72+
73+
/// Get the HTTP status code of the response
74+
pub fn status_code(&self) -> StatusCode {
75+
self.0.status()
76+
}
77+
6678
/// Asynchronously reads the response body as plain text
6779
///
6880
/// Reading the response body consumes `self`
6981
pub async fn text(self) -> Result<String, Error> {
7082
let body = self.0.text().await?;
7183
Ok(body)
7284
}
85+
86+
/// Gets the request URL
87+
pub fn url(&self) -> &Url {
88+
self.0.url()
89+
}
90+
91+
/// Gets the Deprecation warning response headers
92+
///
93+
/// Deprecation headers signal the use of Elasticsearch functionality
94+
/// or features that are deprecated and will be removed in a future release.
95+
pub fn warning_headers(&self) -> impl Iterator<Item = &str> {
96+
self.0
97+
.headers()
98+
.get_all("Warning")
99+
.iter()
100+
.map(|w| w.to_str().unwrap())
101+
}
73102
}

elasticsearch/src/http/transport.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use crate::{
66
error::Error,
77
http::{
88
headers::{
9-
HeaderMap, HeaderName, HeaderValue, ACCEPT, AUTHORIZATION, CONTENT_TYPE, DEFAULT_ACCEPT,
10-
DEFAULT_CONTENT_TYPE, DEFAULT_USER_AGENT, USER_AGENT,
9+
HeaderMap, HeaderName, HeaderValue, ACCEPT, AUTHORIZATION, CONTENT_TYPE,
10+
DEFAULT_ACCEPT, DEFAULT_CONTENT_TYPE, DEFAULT_USER_AGENT, USER_AGENT,
1111
},
1212
request::Body,
1313
response::Response,
@@ -86,7 +86,7 @@ pub struct TransportBuilder {
8686
proxy: Option<Url>,
8787
proxy_credentials: Option<Credentials>,
8888
disable_proxy: bool,
89-
headers: HeaderMap
89+
headers: HeaderMap,
9090
}
9191

9292
impl TransportBuilder {
@@ -104,7 +104,7 @@ impl TransportBuilder {
104104
proxy: None,
105105
proxy_credentials: None,
106106
disable_proxy: false,
107-
headers: HeaderMap::new()
107+
headers: HeaderMap::new(),
108108
}
109109
}
110110

@@ -372,7 +372,7 @@ impl Transport {
372372

373373
let response = request_builder.send().await;
374374
match response {
375-
Ok(r) => Ok(Response::new(r)),
375+
Ok(r) => Ok(Response::new(r, method)),
376376
Err(e) => {
377377
if e.is_timeout() {
378378
Err(Error::lib(format!("Request timed out to {:?}", e.url())))

elasticsearch/tests/cert.rs

+39-47
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ fn expected_error_message() -> String {
1919
let os = os_type::current_platform();
2020
match os.os_type {
2121
OSType::OSX => "The certificate was not trusted".to_string(),
22-
_ => "unable to get local issuer certificate".to_string()
22+
_ => "unable to get local issuer certificate".to_string(),
2323
}
2424
}
2525
}
@@ -96,31 +96,27 @@ async fn full_certificate_validation() -> Result<(), failure::Error> {
9696
let result = client.ping().send().await;
9797
let os_type = os_type::current_platform();
9898
match os_type.os_type {
99-
OSType::OSX => {
100-
match result {
101-
Ok(_) => Ok(()),
102-
Err(e) => Err(failure::err_msg(e.to_string())),
103-
}
99+
OSType::OSX => match result {
100+
Ok(_) => Ok(()),
101+
Err(e) => Err(failure::err_msg(e.to_string())),
104102
},
105-
_ => {
106-
match result {
107-
Ok(response) => Err(failure::err_msg(format!(
108-
"Expected error but response was {}",
109-
response.status_code()
110-
))),
111-
Err(e) => {
112-
let expected = expected_error_message();
113-
let actual = e.to_string();
114-
assert!(
115-
actual.contains(&expected),
116-
"Expected error message to contain '{}' but was '{}'",
117-
expected,
118-
actual
119-
);
120-
Ok(())
121-
}
103+
_ => match result {
104+
Ok(response) => Err(failure::err_msg(format!(
105+
"Expected error but response was {}",
106+
response.status_code()
107+
))),
108+
Err(e) => {
109+
let expected = expected_error_message();
110+
let actual = e.to_string();
111+
assert!(
112+
actual.contains(&expected),
113+
"Expected error message to contain '{}' but was '{}'",
114+
expected,
115+
actual
116+
);
117+
Ok(())
122118
}
123-
}
119+
},
124120
}
125121
}
126122

@@ -148,31 +144,27 @@ async fn certificate_certificate_validation() -> Result<(), failure::Error> {
148144
let result = client.ping().send().await;
149145
let os_type = os_type::current_platform();
150146
match os_type.os_type {
151-
OSType::OSX => {
152-
match result {
153-
Ok(_) => Ok(()),
154-
Err(e) => Err(failure::err_msg(e.to_string())),
155-
}
147+
OSType::OSX => match result {
148+
Ok(_) => Ok(()),
149+
Err(e) => Err(failure::err_msg(e.to_string())),
156150
},
157-
_ => {
158-
match result {
159-
Ok(response) => Err(failure::err_msg(format!(
160-
"Expected error but response was {}",
161-
response.status_code()
162-
))),
163-
Err(e) => {
164-
let expected = expected_error_message();
165-
let actual = e.to_string();
166-
assert!(
167-
actual.contains(&expected),
168-
"Expected error message to contain '{}' but was '{}'",
169-
expected,
170-
actual
171-
);
172-
Ok(())
173-
}
151+
_ => match result {
152+
Ok(response) => Err(failure::err_msg(format!(
153+
"Expected error but response was {}",
154+
response.status_code()
155+
))),
156+
Err(e) => {
157+
let expected = expected_error_message();
158+
let actual = e.to_string();
159+
assert!(
160+
actual.contains(&expected),
161+
"Expected error message to contain '{}' but was '{}'",
162+
expected,
163+
actual
164+
);
165+
Ok(())
174166
}
175-
}
167+
},
176168
}
177169
}
178170

0 commit comments

Comments
 (0)