canic_core/ops/ic/
http.rs1pub use crate::cdk::mgmt::{HttpHeader, HttpMethod, HttpRequestArgs, HttpRequestResult};
2
3use crate::{
4 Error,
5 cdk::mgmt::http_request,
6 model::metrics::{
7 http::HttpMetrics,
8 system::{SystemMetricKind, SystemMetrics},
9 },
10};
11use num_traits::ToPrimitive;
12use serde::de::DeserializeOwned;
13
14pub struct Http;
19
20impl Http {
21 pub const MAX_RESPONSE_BYTES: u64 = 200_000;
22
23 fn record_metrics(verb: &'static str, url: &str, label: Option<&str>) {
24 SystemMetrics::increment(SystemMetricKind::HttpOutcall);
25 HttpMetrics::increment_with_label(verb, url, label);
26 }
27
28 pub async fn get<T: DeserializeOwned>(
29 url: &str,
30 headers: impl AsRef<[(&str, &str)]>,
31 ) -> Result<T, Error> {
32 Self::get_with_label(url, headers, None).await
33 }
34
35 pub async fn get_with_label<T: DeserializeOwned>(
36 url: &str,
37 headers: impl AsRef<[(&str, &str)]>,
38 label: Option<&str>,
39 ) -> Result<T, Error> {
40 Self::record_metrics("GET", url, label);
42
43 let headers: Vec<HttpHeader> = headers
44 .as_ref()
45 .iter()
46 .map(|(name, value)| HttpHeader {
47 name: name.to_string(),
48 value: value.to_string(),
49 })
50 .collect();
51
52 let args = HttpRequestArgs {
53 url: url.to_string(),
54 method: HttpMethod::GET,
55 headers,
56 max_response_bytes: Some(Self::MAX_RESPONSE_BYTES),
57 ..Default::default()
58 };
59
60 let res = http_request(&args)
61 .await
62 .map_err(|e| Error::HttpRequest(e.to_string()))?;
63
64 let status: u32 = res.status.0.to_u32().unwrap_or(0);
65 if status != 200 {
66 return Err(Error::HttpErrorCode(status));
67 }
68
69 serde_json::from_slice(&res.body).map_err(Into::into)
70 }
71
72 pub async fn get_raw(args: HttpRequestArgs) -> Result<HttpRequestResult, Error> {
73 Self::get_raw_with_label(args, None).await
74 }
75
76 pub async fn get_raw_with_label(
77 args: HttpRequestArgs,
78 label: Option<&str>,
79 ) -> Result<HttpRequestResult, Error> {
80 Self::record_metrics("GET", &args.url, label);
82
83 http_request(&args)
84 .await
85 .map_err(|e| crate::Error::HttpRequest(e.to_string()))
86 }
87}