# 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.

Canonical: https://protocol.diverge.network/2.3.0/endpoints/daemons-connect/response/
Specification revision: 2.3.0

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.

```text
[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](/2.3.0/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](/2.3.0/endpoints/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](/2.3.0/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`:

```rust
//! 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`:

```rust
//! 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,
        }
    }
}
```
