viceroy_lib/wiggle_abi/
log_impl.rs

1//! fastly_log` hostcall implementations.
2
3use {
4    crate::{
5        error::Error,
6        session::Session,
7        wiggle_abi::{fastly_log::FastlyLog, types::EndpointHandle},
8    },
9    lazy_static::lazy_static,
10    wiggle::{GuestMemory, GuestPtr},
11};
12
13fn is_reserved_endpoint(name: &[u8]) -> bool {
14    use regex::bytes::{RegexSet, RegexSetBuilder};
15    const RESERVED_ENDPOINTS: &[&str] = &["^stdout$", "^stderr$", "^fst_managed_"];
16    lazy_static! {
17        static ref RESERVED_ENDPOINT_RE: RegexSet = RegexSetBuilder::new(RESERVED_ENDPOINTS)
18            .case_insensitive(true)
19            .build()
20            .unwrap();
21    }
22    RESERVED_ENDPOINT_RE.is_match(name)
23}
24
25impl FastlyLog for Session {
26    fn endpoint_get(
27        &mut self,
28        memory: &mut GuestMemory<'_>,
29        name: GuestPtr<[u8]>,
30    ) -> Result<EndpointHandle, Error> {
31        let name = memory.as_slice(name)?.ok_or(Error::SharedMemory)?;
32
33        if is_reserved_endpoint(&name) {
34            return Err(Error::InvalidArgument);
35        }
36
37        Ok(self.log_endpoint_handle(&name))
38    }
39
40    fn write(
41        &mut self,
42        memory: &mut GuestMemory<'_>,
43        endpoint_handle: EndpointHandle,
44        msg: GuestPtr<[u8]>,
45    ) -> Result<u32, Error> {
46        let endpoint = self.log_endpoint(endpoint_handle)?;
47        let msg = memory.as_slice(msg)?.ok_or(Error::SharedMemory)?;
48
49        // The log API is infallible, so if we get an error, warn about it
50        // rather than bubbling it up through the log API.
51        match endpoint.write_entry(&msg) {
52            Ok(()) => {}
53            Err(err) => tracing::error!("Error writing log message: {:?}", err),
54        }
55
56        Ok(msg.len().try_into().unwrap())
57    }
58}