dagger_core/
session.rs

1use graphql_client::GraphQLQuery;
2use reqwest::{
3    header::{HeaderMap, HeaderValue, ACCEPT, CONTENT_TYPE},
4    Client, RequestBuilder,
5};
6
7use crate::{config::Config, connect_params::ConnectParams, introspection::IntrospectionResponse};
8
9#[derive(GraphQLQuery)]
10#[graphql(
11    schema_path = "src/graphql/introspection_schema.graphql",
12    query_path = "src/graphql/introspection_query.graphql",
13    responsive_path = "Serialize",
14    variable_derive = "Deserialize"
15)]
16struct IntrospectionQuery;
17
18pub struct Session;
19
20impl Session {
21    pub fn new() -> Self {
22        Self {}
23    }
24
25    pub fn start(&self, _cfg: &Config, conn: &ConnectParams) -> eyre::Result<RequestBuilder> {
26        let client = Client::builder()
27            .user_agent("graphql-rust/0.10.0")
28            .connection_verbose(true)
29            //.danger_accept_invalid_certs(true)
30            .build()?;
31
32        let req_builder = client
33            .post(conn.url())
34            .headers(construct_headers())
35            .basic_auth::<String, String>(conn.session_token.to_string(), None);
36
37        Ok(req_builder)
38    }
39
40    pub async fn schema(&self, req_builder: RequestBuilder) -> eyre::Result<IntrospectionResponse> {
41        let request_body: graphql_client::QueryBody<()> = graphql_client::QueryBody {
42            variables: (),
43            query: introspection_query::QUERY,
44            operation_name: introspection_query::OPERATION_NAME,
45        };
46
47        let res = req_builder.json(&request_body).send().await?;
48
49        if res.status().is_success() {
50            // do nothing
51        } else if res.status().is_server_error() {
52            return Err(eyre::anyhow!("server error!"));
53        } else {
54            let status = res.status();
55            let error_message = match res.text().await {
56                Ok(msg) => match serde_json::from_str::<serde_json::Value>(&msg) {
57                    Ok(json) => {
58                        format!("HTTP {}\n{}", status, serde_json::to_string_pretty(&json)?)
59                    }
60                    Err(_) => format!("HTTP {}: {}", status, msg),
61                },
62                Err(_) => format!("HTTP {}", status),
63            };
64            return Err(eyre::anyhow!(error_message));
65        }
66
67        let json: IntrospectionResponse = res.json().await?;
68
69        Ok(json)
70    }
71}
72
73fn construct_headers() -> HeaderMap {
74    let mut headers = HeaderMap::new();
75    headers.insert(CONTENT_TYPE, HeaderValue::from_static("application/json"));
76    headers.insert(ACCEPT, HeaderValue::from_static("application/json"));
77    headers
78}