mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-07 21:28:21 +00:00
Add wasix_http_client Rust client library
Adds a new crate "wasix_http_client", which is a wrapper around the WAI generated sys bindings to the wasix_http_client_v1.wai component. Enables easy http client usage from Rust code.
This commit is contained in:
77
Cargo.lock
generated
77
Cargo.lock
generated
@@ -3913,9 +3913,9 @@ checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||
|
||||
[[package]]
|
||||
name = "wai-bindgen-gen-core"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd16a4dc5fb71faaa3d21530a1d004b7fc88f0bf70cda6f5c4099220254d947b"
|
||||
checksum = "c43a21791697e899140bb82c27db1fac26ad28ef60eddca55f05e5ca365a6e4c"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"wai-parser",
|
||||
@@ -3923,9 +3923,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wai-bindgen-gen-rust"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17625f823712dd6eff5656b4308842b7aeac9eca429f6eea36443d4305cadf7d"
|
||||
checksum = "dd86fcd3046f63882137f46723c643b7cc33ea4c739c0f9999c6bd76f4ae21f2"
|
||||
dependencies = [
|
||||
"heck 0.3.3",
|
||||
"wai-bindgen-gen-core",
|
||||
@@ -3933,9 +3933,20 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wai-bindgen-gen-rust-wasm"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "757fbff15d11d0578ee879cea209b111bd09f8b39346c7b212a7e7f52585d2f7"
|
||||
checksum = "ab8850eeef5405252a368086f0b3e0eefef4ed47666f37ff9a321ecdcfc96376"
|
||||
dependencies = [
|
||||
"heck 0.3.3",
|
||||
"wai-bindgen-gen-core",
|
||||
"wai-bindgen-gen-rust",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wai-bindgen-gen-wasmer"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34f3b3d04d56cc09616cf8daab90b5601e0e894509f34c81a3829aab03f2b457"
|
||||
dependencies = [
|
||||
"heck 0.3.3",
|
||||
"wai-bindgen-gen-core",
|
||||
@@ -3944,19 +3955,20 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wai-bindgen-rust"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90e6c91f681f714599326252f4ae8b9897293110055d25c576fa09ffb01661cd"
|
||||
checksum = "de0eef889bfee6c2d1f21304b5e8c5786629827ae4f26c44e24d0e0ded80f6cd"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bitflags",
|
||||
"wai-bindgen-rust-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wai-bindgen-rust-impl"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb36c407339837a5e1fcd9b41641fbe36488fc53ab0664add14d5f7105f6fbbb"
|
||||
checksum = "6d3c00bda01d3cf02e9a0a6c7e6b738a6da5cbdefa92f979486f7968b74f290d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn",
|
||||
@@ -3965,10 +3977,37 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wai-parser"
|
||||
version = "0.2.1"
|
||||
name = "wai-bindgen-wasmer"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a24cfad91494925ba41c6a03bd7d092eb3c3cdbccf4ef680b06831030bd7a69"
|
||||
checksum = "b69eca47105340af3e4dc5ba47951a23534d7139a62b12550cc6702a5cb6ab70"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags",
|
||||
"once_cell",
|
||||
"thiserror",
|
||||
"tracing",
|
||||
"wai-bindgen-wasmer-impl",
|
||||
"wasmer",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wai-bindgen-wasmer-impl"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "faaf3a72820d1708185cdd26eafe034e3f88d740bae27b5d852379d242d9ff68"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn",
|
||||
"wai-bindgen-gen-core",
|
||||
"wai-bindgen-gen-wasmer",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wai-parser"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2811f0b0c8883f92b9c616b6c38a1b462dc37d04cfc700be60e4990497ed1f7d"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"id-arena",
|
||||
@@ -4048,6 +4087,15 @@ dependencies = [
|
||||
"wast 24.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasix_http_client"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"http",
|
||||
"wai-bindgen-rust",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.83"
|
||||
@@ -4664,6 +4712,7 @@ dependencies = [
|
||||
"generational-arena",
|
||||
"getrandom",
|
||||
"hex",
|
||||
"http",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"linked_hash_set",
|
||||
@@ -4734,6 +4783,7 @@ dependencies = [
|
||||
name = "wasmer-wasi-types"
|
||||
version = "3.0.2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags",
|
||||
"byteorder",
|
||||
"cfg-if 1.0.0",
|
||||
@@ -4745,6 +4795,7 @@ dependencies = [
|
||||
"wai-bindgen-gen-rust",
|
||||
"wai-bindgen-gen-rust-wasm",
|
||||
"wai-bindgen-rust",
|
||||
"wai-bindgen-wasmer",
|
||||
"wai-parser",
|
||||
"wasmer",
|
||||
"wasmer-derive",
|
||||
|
||||
@@ -47,6 +47,7 @@ members = [
|
||||
"lib/wasi-types",
|
||||
"lib/wasi-experimental-io-devices",
|
||||
"lib/wasi-local-networking",
|
||||
"lib/wasix/wasix-http-client",
|
||||
"lib/c-api/tests/wasmer-c-api-test-runner",
|
||||
"lib/c-api/examples/wasmer-capi-examples-runner",
|
||||
"lib/types",
|
||||
|
||||
12
lib/wasix/wasix-http-client/Cargo.toml
Normal file
12
lib/wasix/wasix-http-client/Cargo.toml
Normal file
@@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "wasix_http_client"
|
||||
description = "Wasix bindings library for Webassembly."
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.66"
|
||||
http = "0.2.8"
|
||||
wai-bindgen-rust = "0.2.2"
|
||||
20
lib/wasix/wasix-http-client/examples/http_client.rs
Normal file
20
lib/wasix/wasix-http-client/examples/http_client.rs
Normal file
@@ -0,0 +1,20 @@
|
||||
use wasix_http_client::{Body, HttpClient, RequestBuilder};
|
||||
|
||||
fn main() {
|
||||
let c = HttpClient::new().unwrap();
|
||||
let r = RequestBuilder::new()
|
||||
.uri("http://ferris2.christoph.app.wapm.dev/http-client-test")
|
||||
.body(Body::empty())
|
||||
.unwrap();
|
||||
eprintln!("fetching: {r:?}");
|
||||
|
||||
let res = c.send(r).unwrap();
|
||||
dbg!(&res);
|
||||
assert!(res.status().is_success());
|
||||
|
||||
let body = res.into_body().read_all().unwrap();
|
||||
let s = String::from_utf8(body).unwrap();
|
||||
eprintln!("Response body: {s}");
|
||||
|
||||
assert!(s.contains("http-client-test"));
|
||||
}
|
||||
140
lib/wasix/wasix-http-client/src/lib.rs
Normal file
140
lib/wasix/wasix-http-client/src/lib.rs
Normal file
@@ -0,0 +1,140 @@
|
||||
// Auto-generated sys bindings.
|
||||
#[allow(dead_code)]
|
||||
mod wasix_http_client_v1;
|
||||
|
||||
use anyhow::bail;
|
||||
|
||||
use crate::wasix_http_client_v1 as sys;
|
||||
|
||||
pub use http::{header, Method, StatusCode};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct HttpClient {
|
||||
client: sys::Client,
|
||||
}
|
||||
|
||||
// TODO: use proper custom error type
|
||||
impl HttpClient {
|
||||
pub fn new() -> Result<Self, anyhow::Error> {
|
||||
let client = sys::Client::new().map_err(anyhow::Error::msg)?;
|
||||
Ok(Self { client })
|
||||
}
|
||||
|
||||
pub fn send(&self, request: Request) -> Result<Response, anyhow::Error> {
|
||||
let (parts, body) = request.into_parts();
|
||||
|
||||
let uri = parts.uri.to_string();
|
||||
let method = match &parts.method {
|
||||
m if m == Method::GET => sys::Method::Get,
|
||||
m if m == Method::HEAD => sys::Method::Head,
|
||||
m if m == Method::POST => sys::Method::Post,
|
||||
m if m == Method::PUT => sys::Method::Put,
|
||||
m if m == Method::DELETE => sys::Method::Delete,
|
||||
m if m == Method::CONNECT => sys::Method::Connect,
|
||||
m if m == Method::OPTIONS => sys::Method::Options,
|
||||
m if m == Method::TRACE => sys::Method::Trace,
|
||||
m if m == Method::PATCH => sys::Method::Patch,
|
||||
m => sys::Method::Other(m.as_str()),
|
||||
};
|
||||
|
||||
let headers: Vec<_> = parts
|
||||
.headers
|
||||
.iter()
|
||||
.map(|(key, val)| sys::HeaderParam {
|
||||
key: key.as_str(),
|
||||
value: val.as_bytes(),
|
||||
})
|
||||
.collect();
|
||||
|
||||
let body = match &body.0 {
|
||||
BodyInner::Data(d) => Some(sys::BodyParam::Data(&d)),
|
||||
};
|
||||
|
||||
let req = sys::Request {
|
||||
url: &uri,
|
||||
method,
|
||||
headers: &headers,
|
||||
body,
|
||||
timeout: None,
|
||||
redirect_policy: None,
|
||||
};
|
||||
|
||||
let res = self.client.send(req).map_err(anyhow::Error::msg)?;
|
||||
|
||||
let body = match res.body {
|
||||
sys::BodyResult::Data(d) => Body::new_data(d),
|
||||
sys::BodyResult::Fd(_) => {
|
||||
bail!("Received file descriptor response body, which is not suppported yet");
|
||||
}
|
||||
};
|
||||
|
||||
let mut builder = http::Response::builder().status(res.status);
|
||||
for param in res.headers {
|
||||
builder = builder.header(param.key, param.value);
|
||||
}
|
||||
builder.body(body).map_err(anyhow::Error::from)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: use custom request which can also hold timeout config, etc.
|
||||
// #[derive(Clone, Debug)]
|
||||
// pub struct Request {
|
||||
// pub method: Method,
|
||||
// pub headers: http::HeaderMap,
|
||||
// }
|
||||
|
||||
pub type Request = http::Request<Body>;
|
||||
pub type Response = http::Response<Body>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Body(BodyInner);
|
||||
|
||||
impl Body {
|
||||
pub fn empty() -> Self {
|
||||
Self::new_data(Vec::<u8>::new())
|
||||
}
|
||||
|
||||
pub fn new_data<I>(data: I) -> Self
|
||||
where
|
||||
I: Into<Vec<u8>>,
|
||||
{
|
||||
Self(BodyInner::Data(data.into()))
|
||||
}
|
||||
|
||||
pub fn read_all(self) -> Result<Vec<u8>, anyhow::Error> {
|
||||
match self.0 {
|
||||
BodyInner::Data(d) => Ok(d),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum BodyInner {
|
||||
Data(Vec<u8>),
|
||||
}
|
||||
|
||||
impl From<Vec<u8>> for Body {
|
||||
fn from(value: Vec<u8>) -> Self {
|
||||
Self(BodyInner::Data(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a [u8]> for Body {
|
||||
fn from(value: &'a [u8]) -> Self {
|
||||
Self(BodyInner::Data(value.to_vec()))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for Body {
|
||||
fn from(value: String) -> Self {
|
||||
Self(BodyInner::Data(value.into_bytes()))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a str> for Body {
|
||||
fn from(value: &'a str) -> Self {
|
||||
Self(BodyInner::Data(value.as_bytes().to_vec()))
|
||||
}
|
||||
}
|
||||
|
||||
pub type RequestBuilder = http::request::Builder;
|
||||
514
lib/wasix/wasix-http-client/src/wasix_http_client_v1.rs
Normal file
514
lib/wasix/wasix-http-client/src/wasix_http_client_v1.rs
Normal file
@@ -0,0 +1,514 @@
|
||||
#[derive(Clone)]
|
||||
pub enum Method<'a> {
|
||||
Get,
|
||||
Head,
|
||||
Post,
|
||||
Put,
|
||||
Delete,
|
||||
Connect,
|
||||
Options,
|
||||
Trace,
|
||||
Patch,
|
||||
Other(&'a str),
|
||||
}
|
||||
impl<'a> core::fmt::Debug for Method<'a> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
match self {
|
||||
Method::Get => f.debug_tuple("Method::Get").finish(),
|
||||
Method::Head => f.debug_tuple("Method::Head").finish(),
|
||||
Method::Post => f.debug_tuple("Method::Post").finish(),
|
||||
Method::Put => f.debug_tuple("Method::Put").finish(),
|
||||
Method::Delete => f.debug_tuple("Method::Delete").finish(),
|
||||
Method::Connect => f.debug_tuple("Method::Connect").finish(),
|
||||
Method::Options => f.debug_tuple("Method::Options").finish(),
|
||||
Method::Trace => f.debug_tuple("Method::Trace").finish(),
|
||||
Method::Patch => f.debug_tuple("Method::Patch").finish(),
|
||||
Method::Other(e) => f.debug_tuple("Method::Other").field(e).finish(),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub struct HeaderParam<'a> {
|
||||
pub key: &'a str,
|
||||
pub value: &'a [u8],
|
||||
}
|
||||
impl<'a> core::fmt::Debug for HeaderParam<'a> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
f.debug_struct("HeaderParam")
|
||||
.field("key", &self.key)
|
||||
.field("value", &self.value)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub struct HeaderResult {
|
||||
pub key: String,
|
||||
pub value: Vec<u8>,
|
||||
}
|
||||
impl core::fmt::Debug for HeaderResult {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
f.debug_struct("HeaderResult")
|
||||
.field("key", &self.key)
|
||||
.field("value", &self.value)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
pub type HeaderListParam<'a> = &'a [HeaderParam<'a>];
|
||||
pub type HeaderListResult = Vec<HeaderResult>;
|
||||
pub type Fd = u32;
|
||||
pub type TimeoutMs = u32;
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct RedirectFollow {
|
||||
pub max: u32,
|
||||
}
|
||||
impl core::fmt::Debug for RedirectFollow {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
f.debug_struct("RedirectFollow")
|
||||
.field("max", &self.max)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum RedirectPolicy {
|
||||
NoFollow,
|
||||
Follow(RedirectFollow),
|
||||
}
|
||||
impl core::fmt::Debug for RedirectPolicy {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
match self {
|
||||
RedirectPolicy::NoFollow => f.debug_tuple("RedirectPolicy::NoFollow").finish(),
|
||||
RedirectPolicy::Follow(e) => f.debug_tuple("RedirectPolicy::Follow").field(e).finish(),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub enum BodyParam<'a> {
|
||||
Data(&'a [u8]),
|
||||
Fd(Fd),
|
||||
}
|
||||
impl<'a> core::fmt::Debug for BodyParam<'a> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
match self {
|
||||
BodyParam::Data(e) => f.debug_tuple("BodyParam::Data").field(e).finish(),
|
||||
BodyParam::Fd(e) => f.debug_tuple("BodyParam::Fd").field(e).finish(),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub enum BodyResult {
|
||||
Data(Vec<u8>),
|
||||
Fd(Fd),
|
||||
}
|
||||
impl core::fmt::Debug for BodyResult {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
match self {
|
||||
BodyResult::Data(e) => f.debug_tuple("BodyResult::Data").field(e).finish(),
|
||||
BodyResult::Fd(e) => f.debug_tuple("BodyResult::Fd").field(e).finish(),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub struct Request<'a> {
|
||||
pub url: &'a str,
|
||||
pub method: Method<'a>,
|
||||
pub headers: HeaderListParam<'a>,
|
||||
pub body: Option<BodyParam<'a>>,
|
||||
pub timeout: Option<TimeoutMs>,
|
||||
pub redirect_policy: Option<RedirectPolicy>,
|
||||
}
|
||||
impl<'a> core::fmt::Debug for Request<'a> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
f.debug_struct("Request")
|
||||
.field("url", &self.url)
|
||||
.field("method", &self.method)
|
||||
.field("headers", &self.headers)
|
||||
.field("body", &self.body)
|
||||
.field("timeout", &self.timeout)
|
||||
.field("redirect-policy", &self.redirect_policy)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub struct Response {
|
||||
pub status: u16,
|
||||
pub headers: HeaderListResult,
|
||||
pub body: BodyResult,
|
||||
pub redirect_urls: Option<Vec<String>>,
|
||||
}
|
||||
impl core::fmt::Debug for Response {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
f.debug_struct("Response")
|
||||
.field("status", &self.status)
|
||||
.field("headers", &self.headers)
|
||||
.field("body", &self.body)
|
||||
.field("redirect-urls", &self.redirect_urls)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
#[derive(Debug)]
|
||||
#[repr(transparent)]
|
||||
pub struct Client(i32);
|
||||
impl Client {
|
||||
pub unsafe fn from_raw(raw: i32) -> Self {
|
||||
Self(raw)
|
||||
}
|
||||
|
||||
pub fn into_raw(self) -> i32 {
|
||||
let ret = self.0;
|
||||
core::mem::forget(self);
|
||||
return ret;
|
||||
}
|
||||
|
||||
pub fn as_raw(&self) -> i32 {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
impl Drop for Client {
|
||||
fn drop(&mut self) {
|
||||
#[link(wasm_import_module = "canonical_abi")]
|
||||
extern "C" {
|
||||
#[link_name = "resource_drop_client"]
|
||||
fn close(fd: i32);
|
||||
}
|
||||
unsafe {
|
||||
close(self.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Clone for Client {
|
||||
fn clone(&self) -> Self {
|
||||
#[link(wasm_import_module = "canonical_abi")]
|
||||
extern "C" {
|
||||
#[link_name = "resource_clone_client"]
|
||||
fn clone(val: i32) -> i32;
|
||||
}
|
||||
unsafe { Self(clone(self.0)) }
|
||||
}
|
||||
}
|
||||
impl Client {
|
||||
pub fn new() -> Result<Client, String> {
|
||||
unsafe {
|
||||
let ptr0 = WASIX_HTTP_CLIENT_V1_RET_AREA.0.as_mut_ptr() as i32;
|
||||
#[link(wasm_import_module = "wasix_http_client_v1")]
|
||||
extern "C" {
|
||||
#[cfg_attr(target_arch = "wasm32", link_name = "client::new")]
|
||||
#[cfg_attr(
|
||||
not(target_arch = "wasm32"),
|
||||
link_name = "wasix_http_client_v1_client::new"
|
||||
)]
|
||||
fn wai_import(_: i32);
|
||||
}
|
||||
wai_import(ptr0);
|
||||
match i32::from(*((ptr0 + 0) as *const u8)) {
|
||||
0 => Ok(Client(*((ptr0 + 4) as *const i32))),
|
||||
1 => Err({
|
||||
let len1 = *((ptr0 + 8) as *const i32) as usize;
|
||||
|
||||
String::from_utf8(Vec::from_raw_parts(
|
||||
*((ptr0 + 4) as *const i32) as *mut _,
|
||||
len1,
|
||||
len1,
|
||||
))
|
||||
.unwrap()
|
||||
}),
|
||||
_ => panic!("invalid enum discriminant"),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Client {
|
||||
pub fn send(&self, request: Request<'_>) -> Result<Response, String> {
|
||||
unsafe {
|
||||
let ptr0 = WASIX_HTTP_CLIENT_V1_RET_AREA.0.as_mut_ptr() as i32;
|
||||
*((ptr0 + 0) as *mut i32) = self.0;
|
||||
let Request {
|
||||
url: url1,
|
||||
method: method1,
|
||||
headers: headers1,
|
||||
body: body1,
|
||||
timeout: timeout1,
|
||||
redirect_policy: redirect_policy1,
|
||||
} = request;
|
||||
let vec2 = url1;
|
||||
let ptr2 = vec2.as_ptr() as i32;
|
||||
let len2 = vec2.len() as i32;
|
||||
*((ptr0 + 8) as *mut i32) = len2;
|
||||
*((ptr0 + 4) as *mut i32) = ptr2;
|
||||
match method1 {
|
||||
Method::Get => {
|
||||
let e = ();
|
||||
{
|
||||
*((ptr0 + 12) as *mut u8) = (0i32) as u8;
|
||||
let () = e;
|
||||
}
|
||||
}
|
||||
Method::Head => {
|
||||
let e = ();
|
||||
{
|
||||
*((ptr0 + 12) as *mut u8) = (1i32) as u8;
|
||||
let () = e;
|
||||
}
|
||||
}
|
||||
Method::Post => {
|
||||
let e = ();
|
||||
{
|
||||
*((ptr0 + 12) as *mut u8) = (2i32) as u8;
|
||||
let () = e;
|
||||
}
|
||||
}
|
||||
Method::Put => {
|
||||
let e = ();
|
||||
{
|
||||
*((ptr0 + 12) as *mut u8) = (3i32) as u8;
|
||||
let () = e;
|
||||
}
|
||||
}
|
||||
Method::Delete => {
|
||||
let e = ();
|
||||
{
|
||||
*((ptr0 + 12) as *mut u8) = (4i32) as u8;
|
||||
let () = e;
|
||||
}
|
||||
}
|
||||
Method::Connect => {
|
||||
let e = ();
|
||||
{
|
||||
*((ptr0 + 12) as *mut u8) = (5i32) as u8;
|
||||
let () = e;
|
||||
}
|
||||
}
|
||||
Method::Options => {
|
||||
let e = ();
|
||||
{
|
||||
*((ptr0 + 12) as *mut u8) = (6i32) as u8;
|
||||
let () = e;
|
||||
}
|
||||
}
|
||||
Method::Trace => {
|
||||
let e = ();
|
||||
{
|
||||
*((ptr0 + 12) as *mut u8) = (7i32) as u8;
|
||||
let () = e;
|
||||
}
|
||||
}
|
||||
Method::Patch => {
|
||||
let e = ();
|
||||
{
|
||||
*((ptr0 + 12) as *mut u8) = (8i32) as u8;
|
||||
let () = e;
|
||||
}
|
||||
}
|
||||
Method::Other(e) => {
|
||||
*((ptr0 + 12) as *mut u8) = (9i32) as u8;
|
||||
let vec3 = e;
|
||||
let ptr3 = vec3.as_ptr() as i32;
|
||||
let len3 = vec3.len() as i32;
|
||||
*((ptr0 + 20) as *mut i32) = len3;
|
||||
*((ptr0 + 16) as *mut i32) = ptr3;
|
||||
}
|
||||
};
|
||||
let vec7 = headers1;
|
||||
let len7 = vec7.len() as i32;
|
||||
let layout7 = core::alloc::Layout::from_size_align_unchecked(vec7.len() * 16, 4);
|
||||
let result7 = std::alloc::alloc(layout7);
|
||||
if result7.is_null() {
|
||||
std::alloc::handle_alloc_error(layout7);
|
||||
}
|
||||
for (i, e) in vec7.into_iter().enumerate() {
|
||||
let base = result7 as i32 + (i as i32) * 16;
|
||||
{
|
||||
let HeaderParam {
|
||||
key: key4,
|
||||
value: value4,
|
||||
} = e;
|
||||
let vec5 = key4;
|
||||
let ptr5 = vec5.as_ptr() as i32;
|
||||
let len5 = vec5.len() as i32;
|
||||
*((base + 4) as *mut i32) = len5;
|
||||
*((base + 0) as *mut i32) = ptr5;
|
||||
let vec6 = value4;
|
||||
let ptr6 = vec6.as_ptr() as i32;
|
||||
let len6 = vec6.len() as i32;
|
||||
*((base + 12) as *mut i32) = len6;
|
||||
*((base + 8) as *mut i32) = ptr6;
|
||||
}
|
||||
}
|
||||
*((ptr0 + 28) as *mut i32) = len7;
|
||||
*((ptr0 + 24) as *mut i32) = result7 as i32;
|
||||
match body1 {
|
||||
Some(e) => {
|
||||
*((ptr0 + 32) as *mut u8) = (1i32) as u8;
|
||||
match e {
|
||||
BodyParam::Data(e) => {
|
||||
*((ptr0 + 36) as *mut u8) = (0i32) as u8;
|
||||
let vec8 = e;
|
||||
let ptr8 = vec8.as_ptr() as i32;
|
||||
let len8 = vec8.len() as i32;
|
||||
*((ptr0 + 44) as *mut i32) = len8;
|
||||
*((ptr0 + 40) as *mut i32) = ptr8;
|
||||
}
|
||||
BodyParam::Fd(e) => {
|
||||
*((ptr0 + 36) as *mut u8) = (1i32) as u8;
|
||||
*((ptr0 + 40) as *mut i32) = wai_bindgen_rust::rt::as_i32(e);
|
||||
}
|
||||
};
|
||||
}
|
||||
None => {
|
||||
let e = ();
|
||||
{
|
||||
*((ptr0 + 32) as *mut u8) = (0i32) as u8;
|
||||
let () = e;
|
||||
}
|
||||
}
|
||||
};
|
||||
match timeout1 {
|
||||
Some(e) => {
|
||||
*((ptr0 + 48) as *mut u8) = (1i32) as u8;
|
||||
*((ptr0 + 52) as *mut i32) = wai_bindgen_rust::rt::as_i32(e);
|
||||
}
|
||||
None => {
|
||||
let e = ();
|
||||
{
|
||||
*((ptr0 + 48) as *mut u8) = (0i32) as u8;
|
||||
let () = e;
|
||||
}
|
||||
}
|
||||
};
|
||||
match redirect_policy1 {
|
||||
Some(e) => {
|
||||
*((ptr0 + 56) as *mut u8) = (1i32) as u8;
|
||||
match e {
|
||||
RedirectPolicy::NoFollow => {
|
||||
let e = ();
|
||||
{
|
||||
*((ptr0 + 60) as *mut u8) = (0i32) as u8;
|
||||
let () = e;
|
||||
}
|
||||
}
|
||||
RedirectPolicy::Follow(e) => {
|
||||
*((ptr0 + 60) as *mut u8) = (1i32) as u8;
|
||||
let RedirectFollow { max: max9 } = e;
|
||||
*((ptr0 + 64) as *mut i32) = wai_bindgen_rust::rt::as_i32(max9);
|
||||
}
|
||||
};
|
||||
}
|
||||
None => {
|
||||
let e = ();
|
||||
{
|
||||
*((ptr0 + 56) as *mut u8) = (0i32) as u8;
|
||||
let () = e;
|
||||
}
|
||||
}
|
||||
};
|
||||
let ptr10 = WASIX_HTTP_CLIENT_V1_RET_AREA.0.as_mut_ptr() as i32;
|
||||
#[link(wasm_import_module = "wasix_http_client_v1")]
|
||||
extern "C" {
|
||||
#[cfg_attr(target_arch = "wasm32", link_name = "client::send")]
|
||||
#[cfg_attr(
|
||||
not(target_arch = "wasm32"),
|
||||
link_name = "wasix_http_client_v1_client::send"
|
||||
)]
|
||||
fn wai_import(_: i32, _: i32);
|
||||
}
|
||||
wai_import(ptr0, ptr10);
|
||||
std::alloc::dealloc(result7, layout7);
|
||||
match i32::from(*((ptr10 + 0) as *const u8)) {
|
||||
0 => Ok({
|
||||
let base13 = *((ptr10 + 8) as *const i32);
|
||||
let len13 = *((ptr10 + 12) as *const i32);
|
||||
let mut result13 = Vec::with_capacity(len13 as usize);
|
||||
for i in 0..len13 {
|
||||
let base = base13 + i * 16;
|
||||
result13.push({
|
||||
let len11 = *((base + 4) as *const i32) as usize;
|
||||
let len12 = *((base + 12) as *const i32) as usize;
|
||||
|
||||
HeaderResult {
|
||||
key: String::from_utf8(Vec::from_raw_parts(
|
||||
*((base + 0) as *const i32) as *mut _,
|
||||
len11,
|
||||
len11,
|
||||
))
|
||||
.unwrap(),
|
||||
value: Vec::from_raw_parts(
|
||||
*((base + 8) as *const i32) as *mut _,
|
||||
len12,
|
||||
len12,
|
||||
),
|
||||
}
|
||||
});
|
||||
}
|
||||
std::alloc::dealloc(
|
||||
base13 as *mut _,
|
||||
std::alloc::Layout::from_size_align_unchecked((len13 as usize) * 16, 4),
|
||||
);
|
||||
|
||||
Response {
|
||||
status: i32::from(*((ptr10 + 4) as *const u16)) as u16,
|
||||
headers: result13,
|
||||
body: match i32::from(*((ptr10 + 16) as *const u8)) {
|
||||
0 => BodyResult::Data({
|
||||
let len14 = *((ptr10 + 24) as *const i32) as usize;
|
||||
|
||||
Vec::from_raw_parts(
|
||||
*((ptr10 + 20) as *const i32) as *mut _,
|
||||
len14,
|
||||
len14,
|
||||
)
|
||||
}),
|
||||
1 => BodyResult::Fd(*((ptr10 + 20) as *const i32) as u32),
|
||||
_ => panic!("invalid enum discriminant"),
|
||||
},
|
||||
redirect_urls: match i32::from(*((ptr10 + 28) as *const u8)) {
|
||||
0 => None,
|
||||
1 => Some({
|
||||
let base16 = *((ptr10 + 32) as *const i32);
|
||||
let len16 = *((ptr10 + 36) as *const i32);
|
||||
let mut result16 = Vec::with_capacity(len16 as usize);
|
||||
for i in 0..len16 {
|
||||
let base = base16 + i * 8;
|
||||
result16.push({
|
||||
let len15 = *((base + 4) as *const i32) as usize;
|
||||
|
||||
String::from_utf8(Vec::from_raw_parts(
|
||||
*((base + 0) as *const i32) as *mut _,
|
||||
len15,
|
||||
len15,
|
||||
))
|
||||
.unwrap()
|
||||
});
|
||||
}
|
||||
std::alloc::dealloc(
|
||||
base16 as *mut _,
|
||||
std::alloc::Layout::from_size_align_unchecked(
|
||||
(len16 as usize) * 8,
|
||||
4,
|
||||
),
|
||||
);
|
||||
|
||||
result16
|
||||
}),
|
||||
_ => panic!("invalid enum discriminant"),
|
||||
},
|
||||
}
|
||||
}),
|
||||
1 => Err({
|
||||
let len17 = *((ptr10 + 8) as *const i32) as usize;
|
||||
|
||||
String::from_utf8(Vec::from_raw_parts(
|
||||
*((ptr10 + 4) as *const i32) as *mut _,
|
||||
len17,
|
||||
len17,
|
||||
))
|
||||
.unwrap()
|
||||
}),
|
||||
_ => panic!("invalid enum discriminant"),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(align(4))]
|
||||
struct RetArea([u8; 68]);
|
||||
static mut WASIX_HTTP_CLIENT_V1_RET_AREA: RetArea = RetArea([0; 68]);
|
||||
Reference in New Issue
Block a user