wasm_http_hyper/
incoming_message.rs1use bytes::Bytes;
2use futures::Stream;
3use futures::StreamExt;
4use gloo_utils::format::JsValueSerdeExt;
5use std::{collections::HashMap, future::Future};
6use wasm_bindgen::prelude::*;
7
8#[wasm_bindgen(typescript_custom_section)]
9const TS_IMPORT: &'static str = r#"
10import { IncomingMessage } from "node:http";
11"#;
12
13#[wasm_bindgen]
14extern "C" {
15 #[wasm_bindgen(typescript_type = "IncomingMessage")]
16 pub type IncomingMessage;
17
18 #[wasm_bindgen(method)]
19 pub fn on(this: &IncomingMessage, event: &str, callback: &js_sys::Function) -> JsValue;
20
21 #[wasm_bindgen(method, getter)]
22 pub fn method(this: &IncomingMessage) -> String;
23
24 #[wasm_bindgen(method, getter)]
25 pub fn url(this: &IncomingMessage) -> String;
26
27 #[wasm_bindgen(method, getter, js_name = headers)]
28 pub fn headers(this: &IncomingMessage) -> js_sys::Object;
29}
30
31impl IncomingMessage {
32 pub fn body_fut(&self) -> impl Future<Output = Bytes> {
33 let body = self.body_stream();
34 async move {
35 let bytes: Vec<_> = body.collect().await;
36 let mut result = Vec::new();
37 for chunk in bytes {
38 result.extend_from_slice(&chunk);
39 }
40 Bytes::from(result)
41 }
42 }
43
44 pub fn body_stream(&self) -> impl Stream<Item = Bytes> {
45 let (tx, rx) = futures::channel::mpsc::unbounded();
46
47 let data_handler = Closure::wrap(Box::new({
48 let tx = tx.clone();
49 move |chunk: JsValue| {
50 let buffer = js_sys::Uint8Array::new(&chunk).to_vec();
51 let _ = tx.unbounded_send(Bytes::from(buffer));
52 }
53 }) as Box<dyn FnMut(JsValue)>);
54 let end_handler = Closure::wrap(Box::new(move || {
55 let _ = tx.close_channel();
56 }) as Box<dyn FnMut()>);
57
58 self.on("data", data_handler.as_ref().unchecked_ref());
59 self.on("end", end_handler.as_ref().unchecked_ref());
60
61 data_handler.forget();
63 end_handler.forget();
64
65 rx
66 }
67
68 pub fn headers_map(&self) -> HashMap<String, String> {
69 self.headers()
70 .into_serde::<HashMap<String, String>>()
71 .expect("headers is not a map")
72 }
73}