Skip to main content

http_wasm_guest/host/
feature.rs

1//! Host feature flags for configuring runtime capabilities.
2//!
3//! Use these flags to enable host-supported functionality such as buffering
4//! request/response bodies or accessing trailers. Combine multiple flags with
5//! bitwise OR and pass the result to `admin::enable`.
6use std::ops::{BitOr, BitOrAssign};
7
8#[allow(non_upper_case_globals, non_snake_case)]
9/// Enables buffering of the entire request body before your handler is invoked.
10///
11/// When enabled, the host reads the full request body into memory and then makes it
12/// available to the guest. This allows multiple reads and supports request body
13/// inspection or mutation workflows that need complete payload access.
14///
15/// Trade-offs:
16/// - Increased memory usage proportional to request size
17/// - Potential latency from buffering large payloads
18///
19/// Use this flag only when your plugin must read or modify the request body.
20pub const BufferRequest: Feature = Feature(1);
21#[allow(non_upper_case_globals, non_snake_case)]
22/// Enables buffering of the entire response body before it is sent.
23///
24/// When enabled, the host collects the full response body so the guest can read and
25/// modify it during response handling. This is required for plugins that rewrite,
26/// filter, or analyze full response payloads.
27///
28/// Trade-offs:
29/// - Increased memory usage proportional to response size
30/// - Potential latency from buffering large payloads
31///
32/// Use this flag only when your plugin needs full response body access.
33pub const BufferResponse: Feature = Feature(2);
34#[allow(non_upper_case_globals, non_snake_case)]
35/// Enables HTTP trailer support for chunked transfer encoding.
36///
37/// When enabled, the guest can access and modify trailer headers that arrive after
38/// the body. Trailers are typically used to convey metadata computed during streaming,
39/// such as checksums or signatures.
40///
41/// Notes:
42/// - Not all hosts or upstream servers support trailers
43/// - Trailers are only applicable to chunked or streaming responses
44pub const Trailers: Feature = Feature(4);
45
46/// Bitflag wrapper used to configure host capabilities.
47///
48/// Combine flags with `|` and pass the result to `admin::enable`.
49#[derive(Debug, PartialEq, Clone, Copy)]
50pub struct Feature(i32);
51
52impl From<Feature> for i32 {
53    fn from(val: Feature) -> Self {
54        val.0
55    }
56}
57
58impl BitOr for Feature {
59    type Output = Feature;
60
61    fn bitor(self, rhs: Self) -> Feature {
62        Feature(self.0 | rhs.0)
63    }
64}
65
66impl BitOrAssign for Feature {
67    fn bitor_assign(&mut self, rhs: Self) {
68        self.0 |= rhs.0;
69    }
70}
71
72#[cfg(test)]
73mod tests {
74    use super::*;
75
76    #[test]
77    fn feature_buffer_request() {
78        assert_eq!(BufferRequest.0, 1);
79    }
80
81    #[test]
82    fn feature_buffer_response() {
83        assert_eq!(BufferResponse.0, 2);
84    }
85
86    #[test]
87    fn feature_trailers() {
88        assert_eq!(Trailers.0, 4);
89    }
90
91    #[test]
92    fn feature_combine_with_bitor() {
93        let combined = BufferRequest | BufferResponse;
94        assert_eq!(combined, Feature(3));
95    }
96
97    #[test]
98    fn feature_combine_with_bitorassign() {
99        let mut f = BufferRequest;
100        f |= BufferResponse;
101        assert_eq!(f, Feature(3));
102    }
103
104    #[test]
105    fn feature_combine_all() {
106        let combined = BufferRequest | BufferResponse | Trailers;
107        assert_eq!(combined, Feature(7));
108    }
109
110    #[test]
111    fn feature_debug_output() {
112        let f = Feature(42);
113        let debug_str = format!("{:?}", f);
114        assert!(debug_str.contains("42"));
115    }
116
117    #[test]
118    fn feature_partial_eq() {
119        assert_eq!(Feature(5), Feature(5));
120        assert_ne!(Feature(1), Feature(2));
121    }
122
123    #[test]
124    fn feature_into_i32() {
125        let f = Feature(123);
126        let val: i32 = f.into();
127        assert_eq!(val, 123);
128    }
129}