Response
The sequence of channel responses the client answers with, what ends it, what a finish with nothing before it means, and what the server does with the answer.
- The sequence. Exactly one channel response, in the form the Container Proxy Endpoints layer defines, followed by the channel response finish.
- A finish with nothing. A channel response finish that no channel response precedes states that the client did not serve the ask. The server relays that to the proxy as a channel response finish that no channel response precedes, and does not ask again.
The channel response is defined by diverge-sdk-rs/src/shared/containers/fuse/list/response/frame.rs:
//! The answer to a listing.
use super::super::super::{Entry, ResponseEncodeError, ResponseError};
use crate::wire::encode::{Encode, Writer};
/// The one message that answers a listing.
///
/// ```text
/// [kind: u8][count: u32 BE][entry…]… | [kind: u8][message…]
/// ```
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Frame<'a> {
/// Kind `0`. The directory's entries, each an [`Entry`], in
/// whatever order the caller keeps them. Empty is an empty
/// directory.
Entries(Vec<Entry<'a>>),
/// Kind `1`. There is no such directory: the caller holds nothing
/// at the path, or a file there.
Missing,
/// Kind `2`. The listing was refused or failed, and this says why,
/// for a reader rather than a program.
Error(&'a str),
}
/// The bytes the count occupies.
const COUNT: usize = 4;
impl Encode for Frame<'_> {
/// One way to fail: an entry's name longer than its prefix holds.
type Error = ResponseEncodeError;
fn encode(&self, out: &mut Writer<'_>) -> Result<(), ResponseEncodeError> {
match self {
Frame::Entries(entries) => {
out.extend_from_slice(&[0]);
// A listing of more than four billion entries is not a
// message; the count saturates rather than wraps, and
// the entries after it are simply not written.
let count = u32::try_from(entries.len()).unwrap_or(u32::MAX);
out.extend_from_slice(&count.to_be_bytes());
for entry in entries.iter().take(count as usize) {
entry.encode(out)?;
}
}
Frame::Missing => out.extend_from_slice(&[1]),
Frame::Error(message) => {
out.extend_from_slice(&[2]);
out.extend_from_slice(message.as_bytes());
}
}
Ok(())
}
}
impl<'a> Frame<'a> {
/// Decode the one message. The entries' names, or the message,
/// borrow from `bytes`.
pub fn decode(bytes: &'a [u8]) -> Result<Self, ResponseError> {
let (kind, rest) = bytes.split_first().ok_or(ResponseError::Empty)?;
match *kind {
0 => {
let count: &[u8; COUNT] = rest
.get(..COUNT)
.and_then(|head| head.try_into().ok())
.ok_or(ResponseError::Truncated)?;
let count = u32::from_be_bytes(*count) as usize;
let mut rest = &rest[COUNT..];
// The shortest entry is four bytes: a kind, a prefix, one
// byte of name.
let mut entries = Vec::with_capacity(count.min(rest.len() / 4));
for _ in 0..count {
let (entry, after) = Entry::decode(rest)?;
entries.push(entry);
rest = after;
}
Ok(Frame::Entries(entries))
}
1 => Ok(Frame::Missing),
2 => std::str::from_utf8(rest)
.map(Frame::Error)
.map_err(|_| ResponseError::MessageUtf8),
other => Err(ResponseError::UnknownKind(other)),
}
}
}