Skip to main content

dagger_sdk/core/
session.rs

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