use crate::common::frontend::{FrontendRequest, FrontendRequestMethod};
use std::collections::HashMap;
pub struct RequestFromRawHttp {
pub method: FrontendRequestMethod,
pub query: HashMap<String, String>,
pub headers: HashMap<String, String>,
pub body: HashMap<String, String>,
}
impl FrontendRequest for RequestFromRawHttp {
fn request_method(&self) -> FrontendRequestMethod {
self.method.clone()
}
fn header_param(&self, key: &str) -> Option<String> {
self.headers.get(key).cloned()
}
fn query_param(&self, key: &str) -> Option<String> {
self.query.get(key).cloned()
}
fn body_param(&self, key: &str) -> Option<String> {
self.body.get(key).cloned()
}
}
pub fn request_from_raw_http(request: &str) -> RequestFromRawHttp {
let mut request = request.trim().split('\n');
let mut first_line = request.next().unwrap().trim().split(' ');
let method = match first_line.next().unwrap() {
"GET" => FrontendRequestMethod::GET,
"POST" => FrontendRequestMethod::POST,
s => FrontendRequestMethod::OtherUnsupported(s.to_string()),
};
let query = match first_line.next().unwrap().split_once('?') {
Some((_, query)) => serde_urlencoded::from_str(query).unwrap(),
None => HashMap::new(),
};
let mut headers = HashMap::new();
for mut line in request.by_ref() {
line = line.trim();
if line.is_empty() {
break;
}
let (key, value) = line.split_once(':').unwrap();
headers.insert(key.trim().to_string(), value.trim().to_string());
}
let body = request.map(|s| s.trim().to_string()).collect::<Vec<String>>().join("\n");
let body = serde_urlencoded::from_str(&body).unwrap();
RequestFromRawHttp { method, query, headers, body }
}
#[test]
fn test_request_from_raw_http() {
let request = request_from_raw_http(
r#"
GET /authorize?client_id=1234&response_type=code HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
code_challenge=5678&code_challenge_method=S256
"#,
);
assert_eq!(FrontendRequestMethod::GET, request.request_method());
assert_eq!(Some("1234".to_string()), request.query_param("client_id"));
assert_eq!(Some("code".to_string()), request.query_param("response_type"));
assert_eq!(Some("localhost:8080".to_string()), request.header_param("Host"));
assert_eq!(
Some("application/x-www-form-urlencoded".to_string()),
request.header_param("Content-Type")
);
assert_eq!(Some("5678".to_string()), request.body_param("code_challenge"));
assert_eq!(Some("S256".to_string()), request.body_param("code_challenge_method"));
}