1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
use crate::wasi::http::types::{Method, RequestOptions, Scheme};
use bytes::{BufMut, Bytes, BytesMut};
use std::collections::HashMap;

#[derive(Clone, Default)]
pub struct Stream {
    pub closed: bool,
    pub data: BytesMut,
}

#[derive(Clone)]
pub struct WasiHttp {
    pub request_id_base: u32,
    pub response_id_base: u32,
    pub fields_id_base: u32,
    pub streams_id_base: u32,
    pub future_id_base: u32,
    pub requests: HashMap<u32, ActiveRequest>,
    pub responses: HashMap<u32, ActiveResponse>,
    pub fields: HashMap<u32, HashMap<String, Vec<Vec<u8>>>>,
    pub streams: HashMap<u32, Stream>,
    pub futures: HashMap<u32, ActiveFuture>,
}

#[derive(Clone)]
pub struct ActiveRequest {
    pub id: u32,
    pub active_request: bool,
    pub method: Method,
    pub scheme: Option<Scheme>,
    pub path_with_query: String,
    pub authority: String,
    pub headers: HashMap<String, Vec<Vec<u8>>>,
    pub body: u32,
}

#[derive(Clone)]
pub struct ActiveResponse {
    pub id: u32,
    pub active_response: bool,
    pub status: u16,
    pub body: u32,
    pub response_headers: HashMap<String, Vec<Vec<u8>>>,
    pub trailers: u32,
}

#[derive(Clone)]
pub struct ActiveFuture {
    pub id: u32,
    pub request_id: u32,
    pub options: Option<RequestOptions>,
}

impl ActiveRequest {
    pub fn new(id: u32) -> Self {
        Self {
            id,
            active_request: false,
            method: Method::Get,
            scheme: Some(Scheme::Http),
            path_with_query: "".to_string(),
            authority: "".to_string(),
            headers: HashMap::new(),
            body: 0,
        }
    }
}

impl ActiveResponse {
    pub fn new(id: u32) -> Self {
        Self {
            id,
            active_response: false,
            status: 0,
            body: 0,
            response_headers: HashMap::new(),
            trailers: 0,
        }
    }
}

impl ActiveFuture {
    pub fn new(id: u32, request_id: u32, options: Option<RequestOptions>) -> Self {
        Self {
            id,
            request_id,
            options,
        }
    }
}

impl Stream {
    pub fn new() -> Self {
        Self::default()
    }
}

impl From<Bytes> for Stream {
    fn from(bytes: Bytes) -> Self {
        let mut buf = BytesMut::with_capacity(bytes.len());
        buf.put(bytes);
        Self {
            closed: false,
            data: buf,
        }
    }
}

impl WasiHttp {
    pub fn new() -> Self {
        Self {
            request_id_base: 1,
            response_id_base: 1,
            fields_id_base: 1,
            streams_id_base: 1,
            future_id_base: 1,
            requests: HashMap::new(),
            responses: HashMap::new(),
            fields: HashMap::new(),
            streams: HashMap::new(),
            futures: HashMap::new(),
        }
    }
}