1use reqwest::{
2 header::{HeaderName, HeaderValue},
3 Client, Method, Response,
4};
5use serde_json::Value;
6use std::collections::HashMap;
7use tracing::debug;
8
9use crate::{err::http_error, Result};
10
11fn get_http_client() -> Result<Client> {
13 let mut client_builder = reqwest::Client::builder();
14 if let Ok(proxy) = std::env::var("PROXY") {
15 debug!("PROXY is {}", &proxy);
16 client_builder = client_builder.proxy(reqwest::Proxy::https(&proxy)?);
17 }
18 Ok(client_builder.build()?)
19}
20
21#[derive(Debug, Default)]
22pub struct PostParameters {
23 form: Option<Value>,
24 json: Option<Value>,
25}
26
27impl PostParameters {
28 pub fn form(form: Value) -> Self {
29 PostParameters {
30 form: Some(form),
31 json: None,
32 }
33 }
34
35 pub fn json(json: Value) -> Self {
36 PostParameters {
37 form: None,
38 json: Some(json),
39 }
40 }
41}
42
43pub async fn do_http(
45 method: Method,
46 req_url: &str,
47 headers: Option<HashMap<HeaderName, String>>,
48 query: Option<Value>,
49 body: Option<PostParameters>,
50) -> Result<Response> {
51 debug!("request url: {}", req_url);
52
53 let client = get_http_client()?;
59
60 let mut req_builder = client.get(req_url);
61 if let Some(query) = query {
65 req_builder = req_builder.query(&query);
66 }
67
68 if let Some(params) = body {
70 if let Some(body) = params.json {
71 req_builder = req_builder.json(&body);
72 }
73 if let Some(form) = params.form {
74 req_builder = req_builder.form(&form)
75 }
76 }
77
78 let mut req = req_builder.build()?;
79
80 if let Some(headers) = headers {
82 for (key, value) in headers.iter() {
83 req.headers_mut().append(key, HeaderValue::from_str(value)?);
84 }
85 }
86
87 let m = req.method_mut();
89 *m = method;
90
91 let resp = client.execute(req).await?;
92
93 let status_code = resp.status();
94 if !status_code.is_success() {
95 let msg = resp.text().await?;
96 return Err(http_error(req_url.to_owned(), status_code, msg));
97 }
98
99 Ok(resp)
100}