Skip to main content

libnasu/providers/http/
provider.rs

1use anyhow::{Context, Result};
2use async_trait::async_trait;
3use hyper::client::HttpConnector;
4use hyper::{Body, Client as HyperClient, Method, Request, Uri};
5use hyper_tls::HttpsConnector;
6use std::collections::HashMap;
7use std::str::FromStr;
8use url::Url;
9
10use crate::report::Report;
11use crate::tasks::{Params as TaskParams, Task};
12use crate::utils::timestamp::current_timestamp;
13use crate::worker::perform::Perform;
14
15use super::{Params, Report as HttpReport};
16
17#[allow(dead_code)]
18pub struct Provider {
19    task_title: String,
20    http_client: HyperClient<HttpsConnector<HttpConnector>>,
21    http_method: Method,
22    params: Params,
23    url: String,
24}
25
26impl Provider {
27    pub fn new(task: Task) -> Result<Self> {
28        let params = match task.params {
29            TaskParams::Http(p) => p,
30        };
31
32        let url = Url::from_str(params.url.as_str())
33            .context(format!("Invalid URL provided for task {}", task.id))?;
34
35        let http_client = HyperClient::builder().build(HttpsConnector::new());
36        let http_method = Method::from_str(params.method.as_str())
37            .context(format!("Invalid HTTP Method provided for task {}", task.id))?;
38
39        Ok(Self {
40            task_title: task.id,
41            http_client,
42            http_method,
43            params,
44            url: url.to_string(),
45        })
46    }
47}
48
49#[async_trait]
50impl Perform for Provider {
51    async fn perform(&self) -> Result<Report> {
52        let req_start = current_timestamp();
53        let request = Request::builder()
54            .uri(Uri::from_str(self.url.as_str()).unwrap())
55            .method(self.http_method.clone())
56            .body(Body::empty())
57            .context(format!(
58                "Failed to build Request struct on {}",
59                self.task_title
60            ))?;
61
62        let response = self.http_client.request(request).await.unwrap();
63        let mut headers: HashMap<String, String> = HashMap::new();
64
65        for (k, v) in response.headers() {
66            headers.insert(k.to_string(), v.to_str().unwrap().to_string());
67        }
68
69        let http_report = HttpReport {
70            id: self.task_title.clone(),
71            status_code: response.status().as_u16(),
72            headers,
73            req_start,
74            req_end: current_timestamp(),
75        };
76
77        Ok(Report::Http(http_report))
78    }
79}