hac_core/net/
request_manager.rs1use crate::collection::types::{BodyType, Request};
2use crate::net::request_strategies::{http_strategy::HttpResponse, RequestStrategy};
3use crate::text_object::{Readonly, TextObject};
4
5use std::sync::{Arc, RwLock};
6use std::time::Duration;
7
8use reqwest::header::{HeaderMap, HeaderValue};
9use tokio::sync::mpsc::UnboundedSender;
10
11#[derive(Debug, PartialEq)]
12pub struct Response {
13 pub body: Option<String>,
14 pub pretty_body: Option<TextObject<Readonly>>,
15 pub headers: Option<HeaderMap<HeaderValue>>,
16 pub duration: Duration,
17 pub status: Option<reqwest::StatusCode>,
18 pub headers_size: Option<u64>,
19 pub body_size: Option<u64>,
20 pub size: Option<u64>,
21 pub is_error: bool,
22 pub cause: Option<String>,
23}
24
25pub struct RequestManager;
26
27impl RequestManager {
28 pub async fn handle<S>(strategy: S, request: Request) -> Response
29 where
30 S: RequestStrategy,
31 {
32 strategy.handle(request).await
33 }
34}
35
36pub enum ContentType {
37 TextPlain,
38 TextHtml,
39 TextCss,
40 TextJavascript,
41 ApplicationJson,
42 ApplicationXml,
43}
44
45impl From<&str> for ContentType {
46 fn from(value: &str) -> Self {
47 match value {
48 _ if value.to_ascii_lowercase().contains("application/json") => Self::ApplicationJson,
49 _ if value.to_ascii_lowercase().contains("application/xml") => Self::ApplicationXml,
50 _ if value.to_ascii_lowercase().contains("text/plain") => Self::TextPlain,
51 _ if value.to_ascii_lowercase().contains("text/plain") => Self::TextPlain,
52 _ if value.to_ascii_lowercase().contains("text/html") => Self::TextHtml,
53 _ if value.to_ascii_lowercase().contains("text/css") => Self::TextCss,
54 _ if value.to_ascii_lowercase().contains("text/javascript") => Self::TextJavascript,
55 _ => Self::TextPlain,
56 }
57 }
58}
59
60#[tracing::instrument(skip_all)]
61pub fn handle_request(request: &Arc<RwLock<Request>>, response_tx: UnboundedSender<Response>) {
62 let request = request.read().unwrap().clone();
63 tokio::spawn(async move {
64 let response = match request.body_type.as_ref() {
65 None => RequestManager::handle(HttpResponse, request).await,
67 Some(body_type) => match body_type {
68 BodyType::Json => RequestManager::handle(HttpResponse, request).await,
69 },
70 };
71
72 response_tx
73 .send(response)
74 .is_err()
75 .then(|| std::process::abort());
76 });
77}