Response

The server sends the bytes of the file as responses of at most CHUNK_SIZE bytes each and the finish; a file of zero bytes is one empty response; an error is the last response.

[0][bytes …]         a piece of the file
[1][error JSON …]    the file was not read, or not all of it
  • The sequence. Zero or more responses whose first byte is 0, each a piece of the file in order, followed by the response finish; or the responses sent so far, exactly one response whose first byte is 1, and the response finish. A file of zero bytes is exactly one response whose first byte is 0 and nothing after it.
  • The piece. After the byte 0, the bytes of the piece, verbatim, running to the end of the payload. Each piece is at most CHUNK_SIZE bytes, 2 * 1024 * 1024, the constant diverge-sdk-rs/src/lib.rs defines; the pieces concatenated are the file, and a receiver measures none.
  • A finish with nothing. A response finish that no response precedes states that the server could not read the request.

The response is defined by diverge-sdk-rs/src/container_proxy/outside/endpoints/filesystem/read/server/response/frame.rs:

//! What a server's response frame carries for a read.

use std::fmt;

use crate::wire::decode::Decode;
use crate::wire::encode::{Encode, Writer};
use crate::shared::containers::read;
use crate::shared::error::Error;

/// A piece of the file, or the news that there will not be one.
///
/// A payload leads with one byte saying which — `0` for
/// [`Body`](Self::Body), `1` for [`Error`](Self::Error) — and the rest
/// is that variant's own bytes.
///
/// # How it ends
///
/// | the scope ends with | means |
/// |---------------------|-------|
/// | bodies, then a finish | the bytes are the file |
/// | an [`Error`](Self::Error), then a finish | the file was not read, or not all of it |
///
/// Only a finish ends it. A zero-byte file is one empty body, then
/// the finish, so that a finish with nothing before it keeps its
/// standing meaning: could not serve, with nothing to say.
///
/// # The failure is this scope's, the bytes are not
///
/// [`Body`](Self::Body) carries
/// [`read::response::Frame`](crate::shared::containers::read::response::Frame),
/// which means the same thing wherever the exchange happens. The
/// [`Error`](Self::Error) beside it is the exchange's own.
#[derive(Debug, Clone, PartialEq)]
pub enum Frame<'a> {
    /// A piece of the file. Tag `0`.
    ///
    /// Each at most [`CHUNK_SIZE`](crate::CHUNK_SIZE), in order, and
    /// every one appends to the file.
    Body(read::response::Frame<'a>),
    /// A failure. Tag `1`.
    ///
    /// See [`shared::error::Error`](crate::shared::error::Error) for
    /// why it says so little.
    Error(Error),
}

/// Tag for [`Frame::Body`].
const BODY: u8 = 0;

/// Tag for [`Frame::Error`].
const ERROR: u8 = 1;

impl Encode for Frame<'_> {
    /// The ordinary JSON failure, from the half that has one. The
    /// other cannot fail.
    type Error = serde_json::Error;

    // Spelled out rather than `Self::Error`: this enum has a variant
    // called `Error`, so the associated type is ambiguous by that name.
    fn encode(
        &self,
        out: &mut Writer<'_>,
    ) -> Result<(), serde_json::Error> {
        match self {
            Frame::Body(inner) => {
                out.extend_from_slice(&[BODY]);
                // Its error is `Infallible`, and an empty match on one
                // is how you say so: there is no value to handle.
                inner.encode(out).map_err(|error| match error {})
            }
            Frame::Error(error) => {
                out.extend_from_slice(&[ERROR]);
                error.encode(out)
            }
        }
    }
}

impl<'a> Decode<'a> for Frame<'a> {
    /// Three ways to fail, and only one of them is a parse.
    type Error = FrameError;

    // Spelled out for the same reason as `encode` above.
    fn decode(bytes: &'a [u8]) -> Result<Self, FrameError> {
        let (tag, rest) = bytes.split_first().ok_or(FrameError::Empty)?;
        match *tag {
            BODY => read::response::Frame::decode(rest)
                .map(Frame::Body)
                .map_err(|error| match error {}),
            ERROR => {
                Error::decode(rest).map(Frame::Error).map_err(FrameError::Error)
            }
            tag => Err(FrameError::UnknownTag(tag)),
        }
    }
}

/// A read response frame that could not be read.
#[derive(Debug)]
pub enum FrameError {
    /// No bytes at all, so not even a tag.
    ///
    /// Distinct from a zero-length body, which is a tag followed by
    /// nothing and is a file.
    Empty,
    /// A tag that is neither of this frame's two.
    UnknownTag(u8),
    /// The error did not parse.
    Error(serde_json::Error),
}

impl fmt::Display for FrameError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            FrameError::Empty => f.write_str("read response frame is empty"),
            FrameError::UnknownTag(tag) => {
                write!(f, "unknown read response frame tag {tag}")
            }
            FrameError::Error(error) => {
                write!(f, "read error did not parse: {error}")
            }
        }
    }
}

impl std::error::Error for FrameError {
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        match self {
            FrameError::Error(error) => Some(error),
            FrameError::Empty | FrameError::UnknownTag(_) => None,
        }
    }
}

and by diverge-sdk-rs/src/shared/containers/read/response/frame.rs:

//! What a response frame carries on a read channel.

use std::convert::Infallible;

use crate::wire::decode::Decode;
use crate::wire::encode::{Encode, Writer};

/// A piece of the file.
///
/// Bytes and nothing else — no tag, because there is nothing to
/// discriminate. A read channel carries one kind of traffic from the
/// first byte to the last, and the requester knew what it was when it
/// asked.
///
/// # How it ends
///
/// With a finish, and only with a finish. There is no `Complete` and
/// there is no failure: a read that finished cleanly is one whose
/// channel finished —
/// [`ChannelResponseFinish`](crate::wire::frame::server::ServerFrame::ChannelResponseFinish)
/// says so at the frame layer, and saying it again in the payload
/// would be two signals for one fact.
///
/// # A silent tear is possible here
///
/// A file being read can be written underneath the reader, and the
/// bytes already sent are then a mix: whatever was there before the
/// write, and whatever is there after.
///
/// A provider can DETECT it — `fstat` on its own descriptor before the
/// first byte and after the last, comparing size and mtime — and
/// cannot prevent it. Linux advisory locks bind only processes that
/// opt in, and mandatory locking was removed in 5.15. But there is no
/// frame here that means "here are the bytes, and they moved while I
/// sent them", so a provider that detects one has nowhere to say so.
///
/// # No length, anywhere
///
/// Not in a head, not in the request, not implied by anything. A file
/// being written to can change size in both directions after a sender
/// has looked at it, so any length stated up front is a promise made
/// about a number that has already moved. It is the commitment that
/// makes `tar` corrupt a whole archive when one entry shifts, and this
/// declines to make it.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub struct Frame<'a>(
    /// The bytes, borrowed from the frame they arrived in.
    ///
    /// Sent as they are read. A sender holds no more than one buffer's
    /// worth, so a file larger than memory crosses without either end
    /// ever holding it whole.
    pub &'a [u8],
);

/// Straight through, and identical to
/// [`write_bytes`](crate::shared::containers::write_bytes::response::Frame)
/// — which is what makes piping a read into a write cost nothing. One
/// frame out is one frame in, with no shape to translate between
/// them; whatever tag an endpoint puts in front is a byte, not a
/// copy.
impl Encode for Frame<'_> {
    /// [`Infallible`]: copying a slice into a buffer has no failure
    /// mode.
    type Error = Infallible;

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

impl<'a> Decode<'a> for Frame<'a> {
    /// [`Infallible`]: there is nothing to get wrong about a slice
    /// that is already the answer.
    type Error = Infallible;

    fn decode(bytes: &'a [u8]) -> Result<Self, Self::Error> {
        Ok(Frame(bytes))
    }
}