use std::collections::HashMap;
use candid::CandidType;
use serde::{Deserialize, Serialize};
pub use ic_cdk::api::management_canister::http_request::{
CanisterHttpRequestArgument, HttpHeader, HttpMethod, HttpResponse, TransformArgs,
TransformContext,
};
use crate::{
canister::{fetch_tuple0, types::CanisterCallError},
identity::CanisterId,
};
pub const MAX_RESPONSE_LENGTH: usize = 1024 * 1024 * 3 - 1024 * 64;
#[derive(CandidType, Serialize, Deserialize, Debug, Clone)]
pub struct CustomHttpRequest {
pub url: String,
pub method: String,
pub headers: HashMap<String, String>,
pub body: Vec<u8>,
}
#[derive(CandidType, Serialize, Deserialize, Debug, Clone)]
pub struct StreamingCallbackToken {
pub path: String,
pub params: String,
pub headers: HashMap<String, String>,
pub start: u64,
pub end: u64,
}
#[derive(CandidType, Serialize, Deserialize, Debug, Clone)]
pub struct StreamingCallbackHttpResponse {
pub body: Vec<u8>,
pub token: Option<StreamingCallbackToken>,
}
#[allow(missing_docs)]
mod callback {
use super::*;
candid::define_function!(pub HttpRequestStreamingCallback : (StreamingCallbackToken) -> (StreamingCallbackHttpResponse) query);
}
pub use callback::HttpRequestStreamingCallback;
#[derive(CandidType, Deserialize, Debug, Clone)]
pub enum StreamingStrategy {
Callback {
callback: HttpRequestStreamingCallback,
token: StreamingCallbackToken,
},
}
#[derive(CandidType, Debug, Clone)]
pub struct CustomHttpResponse {
pub status_code: u16,
pub headers: HashMap<String, String>,
pub body: Vec<u8>,
pub streaming_strategy: Option<StreamingStrategy>,
pub upgrade: Option<bool>,
}
pub fn http_transform(response: TransformArgs) -> HttpResponse {
let mut t = response.response;
t.headers = vec![];
t
}
pub async fn do_http_request(
arg: CanisterHttpRequestArgument,
cycles: u128,
) -> super::types::CanisterCallResult<HttpResponse> {
ic_cdk::api::management_canister::http_request::http_request(arg, cycles)
.await
.map(fetch_tuple0)
.map_err(|(rejection_code, message)| CanisterCallError {
canister_id: CanisterId::anonymous(),
method: "ic#http_request".to_string(),
rejection_code,
message,
})
}
#[allow(clippy::future_not_send)]
pub async fn do_http_request_with_closure(
arg: CanisterHttpRequestArgument,
cycles: u128,
transform_func: impl FnOnce(HttpResponse) -> HttpResponse + 'static,
) -> super::types::CanisterCallResult<HttpResponse> {
ic_cdk::api::management_canister::http_request::http_request_with_closure(
arg,
cycles,
transform_func,
)
.await
.map(fetch_tuple0)
.map_err(|(rejection_code, message)| CanisterCallError {
canister_id: CanisterId::anonymous(),
method: "ic#http_request".to_string(),
rejection_code,
message,
})
}