canic_core/ops/ic/
http.rs1use crate::{
2 Error,
3 infra::ic::http::{
5 HttpHeader, HttpMethod, HttpRequestArgs, HttpRequestResult, http_request_raw,
6 },
7 ops::{adapter::metrics::http::record_http_request, runtime::metrics::record_http_outcall},
9};
10use num_traits::ToPrimitive;
11use serde::de::DeserializeOwned;
12
13pub struct Http;
19
20impl Http {
21 pub const MAX_RESPONSE_BYTES: u64 = 200_000;
23
24 fn record_metrics(method: HttpMethod, url: &str, label: Option<&str>) {
30 record_http_outcall();
31 record_http_request(method, url, label);
32 }
33
34 pub async fn get<T: DeserializeOwned>(
40 url: &str,
41 headers: impl AsRef<[(&str, &str)]>,
42 ) -> Result<T, Error> {
43 Self::get_with_label(url, headers, None).await
44 }
45
46 pub async fn get_with_label<T: DeserializeOwned>(
48 url: &str,
49 headers: impl AsRef<[(&str, &str)]>,
50 label: Option<&str>,
51 ) -> Result<T, Error> {
52 Self::record_metrics(HttpMethod::GET, url, label);
54
55 let headers: Vec<HttpHeader> = headers
57 .as_ref()
58 .iter()
59 .map(|(name, value)| HttpHeader {
60 name: name.to_string(),
61 value: value.to_string(),
62 })
63 .collect();
64
65 let args = HttpRequestArgs {
67 url: url.to_string(),
68 method: HttpMethod::GET,
69 headers,
70 max_response_bytes: Some(Self::MAX_RESPONSE_BYTES),
71 ..Default::default()
72 };
73
74 let res = http_request_raw(&args)
76 .await
77 .map_err(|e| Error::HttpRequest(e.to_string()))?;
78
79 let status: u32 = res.status.0.to_u32().unwrap_or(0);
81 if !(200..300).contains(&status) {
82 return Err(Error::HttpErrorCode(status));
83 }
84
85 serde_json::from_slice(&res.body).map_err(Into::into)
87 }
88
89 pub async fn get_raw(args: HttpRequestArgs) -> Result<HttpRequestResult, Error> {
95 Self::get_raw_with_label(args, None).await
96 }
97
98 pub async fn get_raw_with_label(
100 args: HttpRequestArgs,
101 label: Option<&str>,
102 ) -> Result<HttpRequestResult, Error> {
103 Self::record_metrics(args.method, &args.url, label);
105
106 http_request_raw(&args)
108 .await
109 .map_err(|e| Error::HttpRequest(e.to_string()))
110 }
111}