1use {
4 crate::{
5 error::Error,
6 session::{Session, ViceroyResponseMetadata},
7 upstream,
8 wiggle_abi::{
9 fastly_http_resp::FastlyHttpResp,
10 headers::HttpHeaders,
11 types::{
12 BodyHandle, FramingHeadersMode, HttpKeepaliveMode, HttpStatus, HttpVersion,
13 MultiValueCursor, MultiValueCursorResult, ResponseHandle,
14 },
15 },
16 },
17 cfg_if::cfg_if,
18 hyper::http::response::Response,
19 std::net::IpAddr,
20 wiggle::{GuestMemory, GuestPtr},
21};
22
23impl FastlyHttpResp for Session {
24 fn new(&mut self, _memory: &mut GuestMemory<'_>) -> Result<ResponseHandle, Error> {
25 let (parts, _) = Response::new(()).into_parts();
27 Ok(self.insert_response_parts(parts))
28 }
29
30 fn header_names_get(
31 &mut self,
32 memory: &mut GuestMemory<'_>,
33 resp_handle: ResponseHandle,
34 buf: GuestPtr<u8>,
35 buf_len: u32,
36 cursor: MultiValueCursor,
37 ending_cursor_out: GuestPtr<MultiValueCursorResult>,
38 nwritten_out: GuestPtr<u32>,
39 ) -> Result<(), Error> {
40 let headers = &self.response_parts(resp_handle)?.headers;
41 multi_value_result!(
42 memory,
43 headers.names_get(memory, buf, buf_len, cursor, nwritten_out),
44 ending_cursor_out
45 )
46 }
47
48 fn header_value_get(
49 &mut self,
50 memory: &mut GuestMemory<'_>,
51 resp_handle: ResponseHandle,
52 name: GuestPtr<[u8]>,
53 value: GuestPtr<u8>,
54 value_max_len: u32,
55 nwritten_out: GuestPtr<u32>,
56 ) -> Result<(), Error> {
57 let headers = &self.response_parts(resp_handle)?.headers;
58 headers.value_get(memory, name, value, value_max_len, nwritten_out)
59 }
60
61 fn header_values_get(
62 &mut self,
63 memory: &mut GuestMemory<'_>,
64 resp_handle: ResponseHandle,
65 name: GuestPtr<[u8]>,
66 buf: GuestPtr<u8>,
67 buf_len: u32,
68 cursor: MultiValueCursor,
69 ending_cursor_out: GuestPtr<MultiValueCursorResult>,
70 nwritten_out: GuestPtr<u32>,
71 ) -> Result<(), Error> {
72 cfg_if! {
73 if #[cfg(feature = "test-fatalerror-config")] {
74 let _ = (memory, resp_handle, name, buf, buf_len, cursor, ending_cursor_out, nwritten_out);
76 return Err(Error::FatalError("A fatal error occurred in the test-only implementation of header_values_get".to_string()));
77 } else {
78 let headers = &self.response_parts(resp_handle)?.headers;
79 multi_value_result!(
80 memory,
81 headers.values_get(memory, name, buf, buf_len, cursor, nwritten_out),
82 ending_cursor_out
83 )
84 }
85 }
86 }
87
88 fn header_values_set(
89 &mut self,
90 memory: &mut GuestMemory<'_>,
91 resp_handle: ResponseHandle,
92 name: GuestPtr<[u8]>,
93 values: GuestPtr<[u8]>,
94 ) -> Result<(), Error> {
95 let headers = &mut self.response_parts_mut(resp_handle)?.headers;
96 headers.values_set(memory, name, values)
97 }
98
99 fn header_insert(
100 &mut self,
101 memory: &mut GuestMemory<'_>,
102 resp_handle: ResponseHandle,
103 name: GuestPtr<[u8]>,
104 value: GuestPtr<[u8]>,
105 ) -> Result<(), Error> {
106 let headers = &mut self.response_parts_mut(resp_handle)?.headers;
107 HttpHeaders::insert(headers, memory, name, value)
108 }
109
110 fn header_append<'a>(
111 &mut self,
112 memory: &mut GuestMemory<'_>,
113 resp_handle: ResponseHandle,
114 name: GuestPtr<[u8]>,
115 value: GuestPtr<[u8]>,
116 ) -> Result<(), Error> {
117 let headers = &mut self.response_parts_mut(resp_handle)?.headers;
118 HttpHeaders::append(headers, memory, name, value)
119 }
120
121 fn header_remove<'a>(
122 &mut self,
123 memory: &mut GuestMemory<'_>,
124 resp_handle: ResponseHandle,
125 name: GuestPtr<[u8]>,
126 ) -> Result<(), Error> {
127 let headers = &mut self.response_parts_mut(resp_handle)?.headers;
128 HttpHeaders::remove(headers, memory, name)
129 }
130
131 fn version_get(
132 &mut self,
133 _memory: &mut GuestMemory<'_>,
134 resp_handle: ResponseHandle,
135 ) -> Result<HttpVersion, Error> {
136 let resp = self.response_parts(resp_handle)?;
137 HttpVersion::try_from(resp.version).map_err(|msg| Error::Unsupported { msg })
138 }
139
140 fn version_set(
141 &mut self,
142 _memory: &mut GuestMemory<'_>,
143 resp_handle: ResponseHandle,
144 version: HttpVersion,
145 ) -> Result<(), Error> {
146 let resp = self.response_parts_mut(resp_handle)?;
147
148 let version = hyper::Version::try_from(version)?;
149 resp.version = version;
150 Ok(())
151 }
152
153 fn send_downstream(
154 &mut self,
155 _memory: &mut GuestMemory<'_>,
156 resp_handle: ResponseHandle,
157 body_handle: BodyHandle,
158 streaming: u32,
159 ) -> Result<(), Error> {
160 let resp = {
161 let resp_parts = self.take_response_parts(resp_handle)?;
164 let body = if streaming == 1 {
165 self.begin_streaming(body_handle)?
166 } else {
167 self.take_body(body_handle)?
168 };
169 Response::from_parts(resp_parts, body)
170 }; self.send_downstream_response(resp)
172 }
173
174 fn status_get(
175 &mut self,
176 _memory: &mut GuestMemory<'_>,
177 resp_handle: ResponseHandle,
178 ) -> Result<HttpStatus, Error> {
179 Ok(self.response_parts(resp_handle)?.status.as_u16())
180 }
181
182 fn status_set(
183 &mut self,
184 _memory: &mut GuestMemory<'_>,
185 resp_handle: ResponseHandle,
186 status: HttpStatus,
187 ) -> Result<(), Error> {
188 let resp = self.response_parts_mut(resp_handle)?;
189 let status = hyper::StatusCode::from_u16(status)?;
190 resp.status = status;
191 Ok(())
192 }
193
194 fn framing_headers_mode_set(
195 &mut self,
196 _memory: &mut GuestMemory<'_>,
197 resp_handle: ResponseHandle,
198 mode: FramingHeadersMode,
199 ) -> Result<(), Error> {
200 let extensions = &mut self.response_parts_mut(resp_handle)?.extensions;
201
202 match extensions.get_mut::<ViceroyResponseMetadata>() {
203 None => {
204 extensions.insert(ViceroyResponseMetadata {
205 framing_headers_mode: mode,
206 });
212 }
213 Some(vrm) => {
214 vrm.framing_headers_mode = mode;
215 }
216 }
217
218 Ok(())
219 }
220
221 fn close(
222 &mut self,
223 _memory: &mut GuestMemory<'_>,
224 resp_handle: ResponseHandle,
225 ) -> Result<(), Error> {
226 self.take_response_parts(resp_handle)?;
229 Ok(())
230 }
231
232 fn http_keepalive_mode_set(
233 &mut self,
234 _memory: &mut GuestMemory<'_>,
235 _h: ResponseHandle,
236 mode: HttpKeepaliveMode,
237 ) -> Result<(), Error> {
238 match mode {
239 HttpKeepaliveMode::NoKeepalive => Err(Error::NotAvailable("No Keepalive")),
240 HttpKeepaliveMode::Automatic => Ok(()),
241 }
242 }
243
244 fn get_addr_dest_ip(
245 &mut self,
246 memory: &mut GuestMemory<'_>,
247 resp_handle: ResponseHandle,
248 addr_octets_ptr: GuestPtr<u8>,
249 ) -> Result<u32, Error> {
250 let resp = self.response_parts(resp_handle)?;
251 let md = resp
252 .extensions
253 .get::<upstream::ConnMetadata>()
254 .ok_or(Error::ValueAbsent)?;
255
256 if !md.direct_pass {
257 return Err(Error::ValueAbsent);
262 }
263
264 match md.remote_addr.ip() {
265 IpAddr::V4(addr) => {
266 let octets = addr.octets();
267 let octets_bytes = octets.len() as u32;
268 debug_assert_eq!(octets_bytes, 4);
269 memory.copy_from_slice(&octets, addr_octets_ptr.as_array(octets_bytes))?;
270 Ok(octets_bytes)
271 }
272 IpAddr::V6(addr) => {
273 let octets = addr.octets();
274 let octets_bytes = octets.len() as u32;
275 debug_assert_eq!(octets_bytes, 16);
276 memory.copy_from_slice(&octets, addr_octets_ptr.as_array(octets_bytes))?;
277 Ok(octets_bytes)
278 }
279 }
280 }
281
282 fn get_addr_dest_port(
283 &mut self,
284 _memory: &mut GuestMemory<'_>,
285 resp_handle: ResponseHandle,
286 ) -> Result<u16, Error> {
287 let resp = self.response_parts(resp_handle)?;
288 let md = resp
289 .extensions
290 .get::<upstream::ConnMetadata>()
291 .ok_or(Error::ValueAbsent)?;
292
293 if !md.direct_pass {
294 return Err(Error::ValueAbsent);
299 }
300
301 let port = md.remote_addr.port();
302 Ok(port)
303 }
304}