mirror of
https://github.com/tribufu/rust-gamedig
synced 2026-05-06 07:17:27 +00:00
feat(http): add per-request headers option (#196)
* http: Add per-request headers option * http: Improve tests --------- Co-authored-by: Douile <douile@douile.com>
This commit is contained in:
parent
f54321da18
commit
6e53ef0c22
2 changed files with 43 additions and 15 deletions
|
|
@ -31,7 +31,7 @@ pub fn query_with_timeout_and_extra_settings(
|
|||
extra_settings.unwrap_or_default().into(),
|
||||
)?;
|
||||
|
||||
let response = client.get_json::<Root>("/frontpage")?;
|
||||
let response = client.get_json::<Root>("/frontpage", None)?;
|
||||
|
||||
Ok(response.into())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,9 @@ pub struct HttpClient {
|
|||
headers: Vec<(String, String)>,
|
||||
}
|
||||
|
||||
/// HttpHeaders for use with a single request.
|
||||
pub type HttpHeaders<'a> = Option<&'a [(&'a str, &'a str)]>;
|
||||
|
||||
/// HTTP Protocols.
|
||||
///
|
||||
/// Note: if the `tls` feature is disabled this will only contain Http.
|
||||
|
|
@ -65,10 +68,10 @@ impl HttpProtocol {
|
|||
///
|
||||
/// # Can be created using builder functions:
|
||||
/// ```ignore, We cannot test private functionality
|
||||
/// use gamedig::http::{HttpSettings, Protocol};
|
||||
/// use gamedig::http::{HttpSettings, HttpProtocol};
|
||||
///
|
||||
/// let _ = HttpSettings::default()
|
||||
/// .protocol(Protocol::Http)
|
||||
/// .protocol(HttpProtocol::Http)
|
||||
/// .hostname(String::from("test.com"))
|
||||
/// .header(String::from("Authorization"), String::from("Bearer Token"));
|
||||
/// ```
|
||||
|
|
@ -230,21 +233,29 @@ impl HttpClient {
|
|||
}
|
||||
|
||||
/// Send a HTTP GET request and return the response data as a buffer.
|
||||
pub fn get(&mut self, path: &str) -> GDResult<Vec<u8>> { self.request("GET", path) }
|
||||
pub fn get(&mut self, path: &str, headers: HttpHeaders) -> GDResult<Vec<u8>> { self.request("GET", path, headers) }
|
||||
|
||||
/// Send a HTTP GET request and parse the JSON resonse.
|
||||
pub fn get_json<T: DeserializeOwned>(&mut self, path: &str) -> GDResult<T> { self.request_json("GET", path) }
|
||||
pub fn get_json<T: DeserializeOwned>(&mut self, path: &str, headers: HttpHeaders) -> GDResult<T> {
|
||||
self.request_json("GET", path, headers)
|
||||
}
|
||||
|
||||
/// Send a HTTP Post request with JSON data and parse a JSON response.
|
||||
pub fn post_json<T: DeserializeOwned, S: Serialize>(&mut self, path: &str, data: S) -> GDResult<T> {
|
||||
self.request_with_json_data("POST", path, data)
|
||||
pub fn post_json<T: DeserializeOwned, S: Serialize>(
|
||||
&mut self,
|
||||
path: &str,
|
||||
headers: HttpHeaders,
|
||||
data: S,
|
||||
) -> GDResult<T> {
|
||||
self.request_with_json_data("POST", path, headers, data)
|
||||
}
|
||||
|
||||
// NOTE: More methods can be added here as required using the request_json or
|
||||
// request_with_json methods
|
||||
|
||||
/// Internal request method, makes a request with an arbitrary HTTP method.
|
||||
#[inline]
|
||||
fn request(&mut self, method: &str, path: &str) -> GDResult<Vec<u8>> {
|
||||
fn request(&mut self, method: &str, path: &str, headers: HttpHeaders) -> GDResult<Vec<u8>> {
|
||||
// Append the path to the pre-parsed URL and create a request object.
|
||||
self.address.set_path(path);
|
||||
let mut request = self.client.request_url(method, &self.address);
|
||||
|
|
@ -254,6 +265,12 @@ impl HttpClient {
|
|||
request = request.set(key, value);
|
||||
}
|
||||
|
||||
if let Some(headers) = headers {
|
||||
for (key, value) in headers {
|
||||
request = request.set(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
// Send the request.
|
||||
let http_response = request.call().map_err(|e| PacketSend.context(e))?;
|
||||
|
||||
|
|
@ -279,7 +296,7 @@ impl HttpClient {
|
|||
|
||||
/// Send a HTTP request without any data and parse the JSON response.
|
||||
#[inline]
|
||||
fn request_json<T: DeserializeOwned>(&mut self, method: &str, path: &str) -> GDResult<T> {
|
||||
fn request_json<T: DeserializeOwned>(&mut self, method: &str, path: &str, headers: HttpHeaders) -> GDResult<T> {
|
||||
// Append the path to the pre-parsed URL and create a request object.
|
||||
self.address.set_path(path);
|
||||
let mut request = self.client.request_url(method, &self.address);
|
||||
|
|
@ -288,6 +305,11 @@ impl HttpClient {
|
|||
for (key, value) in self.headers.iter() {
|
||||
request = request.set(key, value);
|
||||
}
|
||||
if let Some(headers) = headers {
|
||||
for (key, value) in headers {
|
||||
request = request.set(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
// Send the request and parse the response as JSON.
|
||||
request
|
||||
|
|
@ -303,6 +325,7 @@ impl HttpClient {
|
|||
&mut self,
|
||||
method: &str,
|
||||
path: &str,
|
||||
headers: HttpHeaders,
|
||||
data: S,
|
||||
) -> GDResult<T> {
|
||||
self.address.set_path(path);
|
||||
|
|
@ -311,6 +334,11 @@ impl HttpClient {
|
|||
for (key, value) in self.headers.iter() {
|
||||
request = request.set(key, value);
|
||||
}
|
||||
if let Some(headers) = headers {
|
||||
for (key, value) in headers {
|
||||
request = request.set(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
request
|
||||
.send_json(data)
|
||||
|
|
@ -384,7 +412,7 @@ mod tests {
|
|||
|
||||
let mut client = HttpClient::new(&address, &None, settings).unwrap();
|
||||
|
||||
let response: serde_json::Value = client.get_json("/events").unwrap();
|
||||
let response: serde_json::Value = client.get_json("/events", None).unwrap();
|
||||
|
||||
println!("{:?}", response);
|
||||
}
|
||||
|
|
@ -402,7 +430,7 @@ mod tests {
|
|||
|
||||
let mut client = HttpClient::new(&address, &None, settings).unwrap();
|
||||
|
||||
let response: serde_json::Value = client.get_json("/get").unwrap();
|
||||
let response: serde_json::Value = client.get_json("/get", None).unwrap();
|
||||
|
||||
println!("{:?}", response);
|
||||
}
|
||||
|
|
@ -418,7 +446,7 @@ mod tests {
|
|||
|
||||
let mut client = HttpClient::new(&address, &None, settings).unwrap();
|
||||
|
||||
let response = client.get("/").unwrap();
|
||||
let response = client.get("/", None).unwrap();
|
||||
|
||||
println!("{:?}", std::str::from_utf8(&response));
|
||||
}
|
||||
|
|
@ -428,7 +456,7 @@ mod tests {
|
|||
fn http_get_from_url() {
|
||||
let mut client = HttpClient::from_url("http://postman-echo.com/path-is-ignored", &None, None).unwrap();
|
||||
|
||||
let response: serde_json::Value = client.get_json("/get").unwrap();
|
||||
let response: serde_json::Value = client.get_json("/get", None).unwrap();
|
||||
|
||||
println!("{:?}", response);
|
||||
}
|
||||
|
|
@ -436,11 +464,11 @@ mod tests {
|
|||
#[test]
|
||||
#[ignore = "HTTP requests won't work without internet"]
|
||||
fn http_get_from_url_parsed() {
|
||||
let url = Url::parse("http://postman-echo.com:443/path-is-ignored").unwrap();
|
||||
let url = Url::parse("http://postman-echo.com/path-is-ignored").unwrap();
|
||||
|
||||
let mut client = HttpClient::from_url(url, &None, None).unwrap();
|
||||
|
||||
let response: serde_json::Value = client.get_json("/get").unwrap();
|
||||
let response: serde_json::Value = client.get_json("/get", None).unwrap();
|
||||
|
||||
println!("{:?}", response);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue