Skip to main content

vrs_core_sdk/
http.rs

1//! Module for making http requests within nucleus.
2
3use crate::error::RuntimeError;
4use codec::{Decode, Encode};
5use std::collections::BTreeMap;
6
7#[derive(Debug, Clone, Copy, Eq, PartialEq, Encode, Decode)]
8pub enum HttpMethod {
9    Options,
10    Get,
11    Post,
12    Put,
13    Delete,
14    Head,
15    Trace,
16    Connect,
17    Patch,
18}
19
20#[derive(Debug, Clone, Eq, PartialEq, Encode, Decode)]
21pub struct RequestHead {
22    pub method: HttpMethod,
23    pub uri: String,
24    pub headers: BTreeMap<String, String>,
25}
26
27#[derive(Debug, Clone, Eq, PartialEq, Encode, Decode)]
28pub struct HttpRequest {
29    pub head: RequestHead,
30    pub body: Vec<u8>,
31}
32
33#[derive(Debug, Clone, Eq, PartialEq, Encode, Decode)]
34pub struct ResponseHead {
35    pub status: u16,
36    pub headers: BTreeMap<String, String>,
37}
38
39#[derive(Debug, Clone, Eq, PartialEq, Encode, Decode)]
40pub struct HttpResponse {
41    pub head: ResponseHead,
42    pub body: Vec<u8>,
43}
44
45#[link(wasm_import_module = "env")]
46extern "C" {
47    fn http_request(req_ptr: *const u8, req_len: u32, return_ptr: *mut u8) -> i32;
48}
49
50/// Make a http request and return the request_id immediately.
51///
52/// A `#[callback]` function will be called with the request_id when the response is ready.
53///
54/// ```
55/// use vrs_core_sdk::{CallResult, http::{*, self}, callback, post};
56///
57/// #[post]
58/// pub fn request_google() {
59///     let id = http::request(HttpRequest {
60///         head: RequestHead {
61///             method: HttpMethod::Get,
62///             uri: "https://www.google.com".to_string(),
63///             headers: Default::default(),
64///         },
65///         body: vec![],
66///     })
67///     .unwrap();
68///     vrs_core_sdk::println!("http request {} enqueued", id);
69/// }
70///
71/// #[callback]
72/// pub fn on_response(id: u64, response: CallResult<HttpResponse>) {
73///     match response {
74///         Ok(response) => {
75///             let body = String::from_utf8_lossy(&response.body);
76///             vrs_core_sdk::println!("id = {}, response: {}", id, body);
77///         }
78///         Err(e) => {
79///             vrs_core_sdk::eprintln!("id = {}, error: {:?}", id, e);
80///         }
81///     }
82/// }
83/// ```
84pub fn request(request: HttpRequest) -> Result<u64, RuntimeError> {
85    let bytes = request.encode();
86    let mut return_bytes = crate::allocate_buffer();
87    let status = unsafe {
88        http_request(
89            bytes.as_ptr(),
90            bytes.len() as u32,
91            return_bytes.as_mut_ptr(),
92        )
93    };
94    assert!(status == crate::NO_MORE_DATA);
95    Result::<u64, RuntimeError>::decode(&mut &return_bytes[..])
96        .map_err(|_| RuntimeError::DecodeReturnValueError)?
97}