Response

The server sends the byte 0 once when the acceptor takes the connection, then one response per server frame the acceptor sends, the byte 2 before each; or exactly one error, the byte 1, and the finish.

The server sends the byte 0 once, when the acceptor takes the connection, and from then on one response per frame the acceptor sends; or exactly one error and the response finish. No frame bearing the scope follows the finish.

[0]                  once, when the acceptor took the connection
[1][error JSON …]    once, when it did not, and the finish follows
[2][frame …]         per server frame of the acceptor's, after the byte 0
  • The sequence. The first response is the byte 0 or an error. An error is followed by the response finish, and the connection never opened. After the byte 0, the server sends zero or more frame responses, then the finish, and the finish carries no error: the acceptor hung up, the connector hung up, the accept scope ended, or the connector’s connection ended. A response finish that no response precedes states that the request was not served, as Endpoints provides.
  • The error. A payload whose first byte is 1 carries, after that byte, exactly one JSON value in the form defined on the volumes::list response page. The server sends {"kind":"missing"} for an identity no accept scope is open under and {"kind":"denied"} for an acceptor that declined the connection or whose accept scope ended before it took the connection.
  • The frame. A payload whose first byte is 2 carries, after that byte, exactly one server frame of the daemon protocol, laid out as Frames lays out a server frame, verbatim as the acceptor sent it: the type byte 2, a response; 3, a response finish; 4, a channel request the acceptor opened; 5, a channel response; 6, a channel response finish; never 0. The scope and the channel in it are the connector’s own, as it minted them.
  • Malformed. A payload with no byte, a payload whose first byte is none of 0, 1 and 2, and a payload whose bytes after the byte 1 do not parse as one JSON value are malformed.

The response is defined by diverge-sdk-rs/src/provider/endpoints/daemons/connect/server/response/frame.rs:

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

use std::fmt;

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

/// A connect's answer: the connection open, and then every server
/// frame the acceptor sends on it, one per response, for as long as
/// the scope lives — or a failure.
///
/// A payload leads with one byte saying which — `0` for
/// [`Connected`](Self::Connected), `1` for [`Error`](Self::Error),
/// `2` for [`Frame`](Self::Frame) — and the rest is that variant's
/// own bytes: nothing, the error's JSON, or one
/// [`daemon::server::Frame`](crate::shared::containers::daemon::server::Frame)
/// as the acceptor sent it, forwarded whole.
///
/// | the scope | means |
/// |-----------|-------|
/// | connected, then frames as they come, and stays open | the connection is open |
/// | an error, then a finish | it never was: no daemon accepts under the identity, or it declined |
/// | a finish, with no error | the acceptor hung up, or stopped accepting |
#[derive(Debug, Clone, PartialEq)]
pub enum Frame<'a> {
    /// The acceptor took the connection. Tag `0`, once, first.
    Connected,
    /// A failure. Tag `1`.
    ///
    /// The one variant that ends the scope rather than adding to it:
    /// `{"kind":"missing"}` for an identity no daemon accepts under
    /// here, `{"kind":"denied"}` for an acceptor that declined. See
    /// [`shared::error::Error`](crate::shared::error::Error) for why
    /// it says so little.
    Error(Error),
    /// One server frame of the acceptor's, after the connected. Tag
    /// `2`.
    Frame(&'a [u8]),
}

/// Tag for [`Frame::Connected`].
const CONNECTED: u8 = 0;

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

/// Tag for [`Frame::Frame`].
const FRAME: u8 = 2;

impl Encode for Frame<'_> {
    /// The ordinary JSON failure, of the error alone.
    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::Connected => {
                out.extend_from_slice(&[CONNECTED]);
                Ok(())
            }
            Frame::Error(error) => {
                out.extend_from_slice(&[ERROR]);
                error.encode(out)
            }
            Frame::Frame(bytes) => {
                out.extend_from_slice(&[FRAME]);
                out.extend_from_slice(bytes);
                Ok(())
            }
        }
    }
}

impl<'a> Decode<'a> for Frame<'a> {
    /// Three ways to fail.
    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 {
            CONNECTED => Ok(Frame::Connected),
            ERROR => Error::decode(rest).map(Frame::Error).map_err(FrameError::Error),
            FRAME => Ok(Frame::Frame(rest)),
            tag => Err(FrameError::UnknownTag(tag)),
        }
    }
}

/// A connect response frame that could not be read.
#[derive(Debug)]
pub enum FrameError {
    /// No bytes at all, so not even a tag.
    Empty,
    /// A tag that is none of this frame's three.
    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("daemons connect response frame is empty"),
            FrameError::UnknownTag(tag) => write!(f, "unknown daemons connect response frame tag {tag}"),
            FrameError::Error(error) => write!(f, "daemons connect 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/daemon/server/frame.rs:

//! One server frame of the daemon connection, as it crosses a wire.

use std::fmt;

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

/// One server frame of the daemon protocol, as the daemon sends it to
/// the program: a response on a scope, the scope's finish, a channel
/// request the daemon opens on a scope, a channel response or its
/// finish answering a channel the program opened. One channel response
/// of the provider's half per frame, in the order the daemon sent
/// them, and the proxy writes each to the program's socket as it is.
///
/// Every variant is the wire's own
/// [`ServerFrame`](crate::wire::frame::server::ServerFrame) variant of
/// the same name, with the same members; `Auth` is left out, as it is
/// of the [`client::Frame`](crate::shared::containers::daemon::client::Frame).
///
/// # On the wire
///
/// The server frame's own bytes, with no tag in front, so that a
/// bridge forwards bytes. An `Auth` frame, type `0`, does not decode.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Frame<'a> {
    /// One response on a scope.
    Response {
        /// The scope.
        scope: u32,
        /// The endpoint's response frame.
        payload: &'a [u8],
    },
    /// The scope's finish: no frame follows it on the scope.
    ResponseFinish {
        /// The scope.
        scope: u32,
    },
    /// A channel the daemon opens on a scope: a content ask.
    ChannelRequest {
        /// The scope.
        scope: u32,
        /// The channel the daemon minted.
        channel: u32,
        /// The channel request.
        payload: &'a [u8],
    },
    /// One response on a channel the program opened.
    ChannelResponse {
        /// The scope.
        scope: u32,
        /// The program's channel.
        channel: u32,
        /// The channel response.
        payload: &'a [u8],
    },
    /// The finish of a channel the program opened.
    ChannelResponseFinish {
        /// The scope.
        scope: u32,
        /// The program's channel.
        channel: u32,
    },
}

impl<'a> From<Frame<'a>> for ServerFrame<'a> {
    fn from(frame: Frame<'a>) -> Self {
        match frame {
            Frame::Response { scope, payload } => ServerFrame::Response { scope, payload },
            Frame::ResponseFinish { scope } => ServerFrame::ResponseFinish { scope },
            Frame::ChannelRequest { scope, channel, payload } => ServerFrame::ChannelRequest { scope, channel, payload },
            Frame::ChannelResponse { scope, channel, payload } => ServerFrame::ChannelResponse { scope, channel, payload },
            Frame::ChannelResponseFinish { scope, channel } => ServerFrame::ChannelResponseFinish { scope, channel },
        }
    }
}

impl<'a> TryFrom<ServerFrame<'a>> for Frame<'a> {
    /// The one frame that does not pass.
    type Error = Auth;

    fn try_from(frame: ServerFrame<'a>) -> Result<Self, Auth> {
        Ok(match frame {
            ServerFrame::Auth { .. } => return Err(Auth),
            ServerFrame::Response { scope, payload } => Frame::Response { scope, payload },
            ServerFrame::ResponseFinish { scope } => Frame::ResponseFinish { scope },
            ServerFrame::ChannelRequest { scope, channel, payload } => Frame::ChannelRequest { scope, channel, payload },
            ServerFrame::ChannelResponse { scope, channel, payload } => Frame::ChannelResponse { scope, channel, payload },
            ServerFrame::ChannelResponseFinish { scope, channel } => Frame::ChannelResponseFinish { scope, channel },
        })
    }
}

/// The server frame's own encoding, and nothing in front of it.
impl Encode for Frame<'_> {
    /// [`Infallible`](std::convert::Infallible): a frame is bytes
    /// copied.
    type Error = std::convert::Infallible;

    fn encode(&self, out: &mut Writer<'_>) -> Result<(), Self::Error> {
        ServerFrame::from(*self).encode(out)
    }
}

impl<'a> Decode<'a> for Frame<'a> {
    /// The frame that would not decode, or the one that does not pass.
    type Error = FrameError;

    fn decode(bytes: &'a [u8]) -> Result<Self, FrameError> {
        let frame = ServerFrame::decode(bytes).map_err(FrameError::Frame)?;
        Frame::try_from(frame).map_err(|Auth| FrameError::Auth)
    }
}

/// An `Auth` frame where a daemon connection's frame was expected.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Auth;

impl fmt::Display for Auth {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str("an auth frame does not pass on a daemon connection")
    }
}

impl std::error::Error for Auth {}

/// A server frame of a daemon connection that could not be read.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FrameError {
    /// Not a server frame: shorter than its header, or of a type the
    /// wire does not have.
    Frame(frame::FrameError),
    /// An `Auth` frame, which does not pass.
    Auth,
}

impl fmt::Display for FrameError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            FrameError::Frame(error) => write!(f, "daemon connection server frame did not decode: {error}"),
            FrameError::Auth => f.write_str("an auth frame does not pass on a daemon connection"),
        }
    }
}

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