Request

The payload of the channel request: the tag byte 5 and the request of the channel.

[5][path …]
  • The form. The bytes after the tag are exactly the bytes after the tag of the FUSE mkdir ask on a mount scope, and mean the same; that page states every field. The path is UTF-8, /-separated, with no leading /; empty is the root of the subtree.
  • Malformed. A channel request whose payload does not decode as stated is answered by a channel response finish that no channel response precedes, and the server does nothing else for it.

The channel request is defined by diverge-sdk-rs/src/container_proxy/outside/endpoints/filesystem/fuse_serve/client/channel_request/frame.rs:

//! What a client's channel request frame carries on a FUSE serve scope.

/// One of the nine asks, the stop, or the tree: the
/// [`volumes::fuse_serve`](crate::provider::endpoints::volumes::fuse_serve) scope's
/// channel request, byte for byte — `0`–`8` the mount's asks, `9`
/// the stop, `10` the tree — answered here by the proxy from the
/// container's filesystem. See
/// [`Frame`](crate::provider::endpoints::volumes::fuse_serve::client::channel_request::Frame)
/// for every tag.
///
/// An alias rather than a re-export because this module is real: the
/// path says this scope's channel request lives here, and it does,
/// rather than naming somewhere else and hoping a reader follows.
/// What the alias points at is right there in the signature. One
/// type rather than two because the whole point is that a relay
/// forwards bytes: the provider hands the proxy the caller's channel
/// request as it arrived, and nothing is re-encoded on the way.
pub type Frame<'a> = crate::provider::endpoints::volumes::fuse_serve::client::channel_request::Frame<'a>;

/// A FUSE serve channel request that could not be read: the volume
/// FUSE serve's own failures. See
/// [`FrameError`](crate::provider::endpoints::volumes::fuse_serve::client::channel_request::FrameError).
pub type FrameError = crate::provider::endpoints::volumes::fuse_serve::client::channel_request::FrameError;

and by diverge-sdk-rs/src/container_proxy/outside/endpoints/fuse/mount/server/channel_request/path.rs:

//! What an ask names when a path is all of it.

use std::str;

use super::FrameError;
use crate::wire::encode::{Encode, Writer};

/// One entry of the mount: its path relative to the mount root —
/// empty for a file mount, and for a directory mount's root.
///
/// ```text
/// [path: utf8…]
/// ```
///
/// The path runs to the end of the payload, so it needs no prefix and
/// takes any length. This is the whole ask for
/// [`List`](super::Frame::List), [`Remove`](super::Frame::Remove),
/// [`Mkdir`](super::Frame::Mkdir) and [`Stat`](super::Frame::Stat),
/// each of which is answered by its own frame. The mount itself is the scope the ask rides.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub struct Path<'a> {
    /// The entry's path inside the mount, `/`-separated, no leading
    /// slash; empty is the mount itself.
    pub path: &'a str,
}

impl Encode for Path<'_> {
    /// [`Infallible`](std::convert::Infallible): the path's bytes are
    /// already bytes.
    type Error = std::convert::Infallible;

    fn encode(&self, out: &mut Writer<'_>) -> Result<(), Self::Error> {
        out.extend_from_slice(self.path.as_bytes());
        Ok(())
    }
}

impl<'a> Path<'a> {
    /// Decode from the bytes after the ask's tag. The path borrows
    /// from `bytes`.
    pub fn decode(bytes: &'a [u8]) -> Result<Self, FrameError> {
        Ok(Path {
            path: str::from_utf8(bytes).map_err(|_| FrameError::PathUtf8)?,
        })
    }
}