1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
use std::{collections::HashMap, time::Duration};
use reqwest::{header::HeaderMap, Method, StatusCode};
/// # Request
/// Request is an internal struct that is used by each OIDC protocol methods.
#[derive(Debug)]
pub struct Request {
/// Url of the request without query params
pub url: String,
/// Expected status code from the server
pub expected: StatusCode,
/// Http method of the request
pub method: Method,
/// Whether or not to expect body with the response
pub expect_body: bool,
/// Headers that are sent in the request
pub headers: HeaderMap,
/// Query Params that are send with the request
pub search_params: HashMap<String, Vec<String>>,
}
impl Default for Request {
fn default() -> Self {
Self {
expect_body: true,
expected: StatusCode::OK,
headers: HeaderMap::default(),
method: Method::GET,
url: "".to_string(),
search_params: HashMap::new(),
}
}
}
impl Request {
/// Converts `search_params` to a [reqwest] compatible query params format
pub(crate) fn get_reqwest_query(&self) -> Vec<(String, String)> {
let mut query_list: Vec<(String, String)> = vec![];
for (k, v) in &self.search_params {
for val in v {
query_list.push((k.clone(), val.to_string()))
}
}
query_list
}
}
/// # Response
/// Response is the abstracted version of the [reqwest] Response (async and blocking).
#[derive(Debug)]
pub struct Response {
/// Body from the response
pub body: Option<String>,
/// Status code of the response
pub status: StatusCode,
/// Response headers from the server
pub headers: HeaderMap,
}
impl Response {
/// Creates a new instance of Response from [reqwest::blocking::Response]
pub fn from(response: reqwest::blocking::Response) -> Self {
let status = response.status();
let headers = response.headers().clone();
let body_result = response.text();
let mut body: Option<String> = None;
if let Ok(body_string) = body_result {
if !body_string.is_empty() {
body = Some(body_string);
}
}
Self {
body,
status,
headers,
}
}
/// Creates a new instance of Response from [reqwest::Response]
pub async fn from_async(response: reqwest::Response) -> Self {
let status = response.status();
let headers = response.headers().clone();
let body_result = response.text().await;
let mut body: Option<String> = None;
if let Ok(body_string) = body_result {
if !body_string.is_empty() {
body = Some(body_string);
}
}
Self {
body,
status,
headers,
}
}
}
/// # RequestOptions
/// This struct is the return type of the request interceptor that can be passed to various methods
/// such as:
/// 1. [crate::Issuer::webfinger_with_interceptor_async]
/// 2. [crate::Issuer::webfinger_with_interceptor]
/// 3. [crate::Issuer::discover_with_interceptor_async]
/// 4. [crate::Issuer::discover_with_interceptor]
#[derive(Debug)]
pub struct RequestOptions {
/// Headers that are tobe appended with the request that is going to be made
pub headers: HeaderMap,
/// Request timeout
pub timeout: Duration,
}