# Response

> The sequence of channel responses that answers the channel, what ends it, and what a finish with nothing before it means.

Canonical: https://protocol.diverge.network/2.3.0/endpoints/containers-tools-run/client/daemon/response/
Specification revision: 2.3.0

```text
[type: u8][scope: u32][channel: u32][payload …]    zero or more, one client frame each
```

- **The sequence.** Zero or more channel responses, each one client
  frame of the daemon protocol with no tag in front, in the order the
  program sent them. The channel response finish follows when the
  program's socket ends, or when the program sends a frame that is
  not one — shorter than its header, of a type the wire does not have,
  or an auth frame — on which the server closes the socket. A channel
  response finish that no channel response precedes states that the
  id names no connection whose half is open.
- **The frame.** Each channel response is exactly one client frame of
  the daemon protocol, laid out as [Frames](/2.3.0/frames/) lays out a
  client frame: the type byte, the scope as a `u32` big-endian, the
  channel as a `u32` big-endian, and the payload, running to the end.
  The type is `1`, a request opening a scope; `4`, a channel request
  on a scope; `5`, a channel response on a channel the daemon opened;
  or `6`, the finish of such a channel. The type `0`, an auth frame,
  never passes: a daemon connection inside a container presents no
  credential, and the proxy closes a socket that sends one.
- **The numbers are the program's.** The scope and the channel in a
  frame are minted by the program as a client of the daemon mints
  them, and mean nothing on this wire: nothing between the program
  and the daemon reads them, and two connections of one program
  number independently.

The channel response is defined by `diverge-sdk-rs/src/provider/endpoints/containers/tools/run/server/channel_response/daemon/frame.rs`:

```rust
//! What a server's response frame carries on a daemon channel.

/// One client frame the program sent on the connection, on its way to
/// the daemon. See
/// [`daemon::client::Frame`](crate::shared::containers::daemon::client::Frame).
///
/// An alias rather than a re-export because this module is real: the
/// path says this scope's answer 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.
pub type Frame<'a> = crate::shared::containers::daemon::client::Frame<'a>;
```

and by `diverge-sdk-rs/src/shared/containers/daemon/client/frame.rs`:

```rust
//! One client 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::client::ClientFrame;

/// One client frame of the daemon protocol, as the program sent it on
/// the proxy's `/daemon`: a request opening a scope, a channel request
/// on one, a channel response or its finish answering a channel the
/// daemon opened on one. One channel response of the caller's half
/// per frame, in the order the program sent them.
///
/// Every variant is the wire's own
/// [`ClientFrame`](crate::wire::frame::client::ClientFrame) variant of
/// the same name, with the same members. The one the wire has and this
/// does not is `Auth`, which never passes: see
/// [`daemon`](crate::shared::containers::daemon).
///
/// # On the wire
///
/// The client frame's own bytes — its type byte, the scope, the
/// channel, the payload — exactly as the wire lays them out, 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> {
    /// Open a scope with a request: a daemon endpoint's request, tag
    /// and all.
    Request {
        /// The scope the program minted.
        scope: u32,
        /// The daemon's request frame, as the endpoint lays it out.
        payload: &'a [u8],
    },
    /// Open a channel on a scope: a cancel, a stop.
    ChannelRequest {
        /// The scope.
        scope: u32,
        /// The channel the program minted.
        channel: u32,
        /// The channel request, as the endpoint lays it out.
        payload: &'a [u8],
    },
    /// Answer a channel the daemon opened on a scope: a piece of an
    /// upload's content.
    ChannelResponse {
        /// The scope.
        scope: u32,
        /// The daemon's channel.
        channel: u32,
        /// The channel response, as the endpoint lays it out.
        payload: &'a [u8],
    },
    /// Finish a channel the daemon opened on a scope.
    ChannelResponseFinish {
        /// The scope.
        scope: u32,
        /// The daemon's channel.
        channel: u32,
    },
}

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

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

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

/// The client 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> {
        ClientFrame::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 = ClientFrame::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 client frame of a daemon connection that could not be read.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FrameError {
    /// Not a client 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 client 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,
        }
    }
}
```
