bulwark_wasm_sdk/
from.rs

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
125
use {
    crate::{BodyChunk, Decision, Outcome, Request, Response},
    std::net::{IpAddr, Ipv4Addr, Ipv6Addr},
};

impl From<Request> for crate::bulwark_host::RequestInterface {
    fn from(request: Request) -> Self {
        crate::bulwark_host::RequestInterface {
            method: request.method().to_string(),
            uri: request.uri().to_string(),
            version: format!("{:?}", request.version()),
            headers: request
                .headers()
                .iter()
                .map(|(name, value)| (name.to_string(), value.as_bytes().to_vec()))
                .collect(),
            body_received: request.body().received,
            chunk: request.body().content.clone(),
            chunk_start: request.body().start,
            chunk_length: request.body().size,
            end_of_stream: request.body().end_of_stream,
        }
    }
}

impl From<crate::bulwark_host::ResponseInterface> for Response {
    fn from(response: crate::bulwark_host::ResponseInterface) -> Self {
        let mut builder = http::response::Builder::new();
        builder = builder.status::<u16>(response.status.try_into().unwrap());
        for (name, value) in response.headers {
            builder = builder.header(name, value);
        }
        builder
            .body(BodyChunk {
                received: response.body_received,
                end_of_stream: response.end_of_stream,
                size: response.chunk.len().try_into().unwrap(),
                start: 0,
                content: response.chunk,
            })
            .unwrap()
    }
}

impl From<crate::bulwark_host::IpInterface> for IpAddr {
    fn from(ip: crate::bulwark_host::IpInterface) -> Self {
        match ip {
            crate::bulwark_host::IpInterface::V4(v4) => {
                Self::V4(Ipv4Addr::new(v4.0, v4.1, v4.2, v4.3))
            }
            crate::bulwark_host::IpInterface::V6(v6) => Self::V6(Ipv6Addr::new(
                v6.0, v6.1, v6.2, v6.3, v6.4, v6.5, v6.6, v6.7,
            )),
        }
    }
}

// TODO: can we avoid conversions, perhaps by moving bindgen into lib.rs?

impl From<crate::bulwark_host::DecisionInterface> for Decision {
    fn from(decision: crate::bulwark_host::DecisionInterface) -> Self {
        Decision {
            accept: decision.accepted,
            restrict: decision.restricted,
            unknown: decision.unknown,
        }
    }
}

impl From<Decision> for crate::bulwark_host::DecisionInterface {
    fn from(decision: Decision) -> Self {
        crate::bulwark_host::DecisionInterface {
            accepted: decision.accept,
            restricted: decision.restrict,
            unknown: decision.unknown,
        }
    }
}

impl From<crate::bulwark_host::OutcomeInterface> for Outcome {
    fn from(outcome: crate::bulwark_host::OutcomeInterface) -> Self {
        match outcome {
            crate::bulwark_host::OutcomeInterface::Trusted => Outcome::Trusted,
            crate::bulwark_host::OutcomeInterface::Accepted => Outcome::Accepted,
            crate::bulwark_host::OutcomeInterface::Suspected => Outcome::Suspected,
            crate::bulwark_host::OutcomeInterface::Restricted => Outcome::Restricted,
        }
    }
}

impl From<&str> for BodyChunk {
    fn from(content: &str) -> Self {
        BodyChunk {
            received: true,
            end_of_stream: true,
            size: content.len() as u64,
            start: 0,
            content: content.as_bytes().to_owned(),
        }
    }
}

impl From<String> for BodyChunk {
    fn from(content: String) -> Self {
        BodyChunk {
            received: true,
            end_of_stream: true,
            size: content.len() as u64,
            start: 0,
            content: content.into_bytes(),
        }
    }
}

impl From<Vec<u8>> for BodyChunk {
    fn from(content: Vec<u8>) -> Self {
        BodyChunk {
            received: true,
            end_of_stream: true,
            size: content.len() as u64,
            start: 0,
            content,
        }
    }
}