# Response

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

Canonical: https://protocol.diverge.network/2.3.0/endpoints/daemons-connect/server/frames/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
  connector sends them. The channel response finish is the connector
  hanging up: the server finishes the acceptor's half and sends the
  response finish of the scope. A channel response finish that no
  channel response precedes is the connector hanging up before it
  sent a frame, and the server does the same.
- **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 acceptor
  opened; or `6`, the finish of such a channel. A channel response
  that is not one — shorter than the header, of a type the wire does
  not have, or an auth frame — hangs up: the server finishes the
  acceptor's half and sends the response finish of the scope.
- **What the server does with it.** The server relays each channel
  response onto the acceptor's half of the connection as one channel
  response, verbatim.

The channel response is defined by `diverge-sdk-rs/src/provider/endpoints/daemons/connect/client/channel_response/frame.rs`:

```rust
//! What a client's channel response frame carries on the frames
//! channel of a connect.

/// One client frame the connector sends on the connection, on its
/// way to the acceptor. See
/// [`daemon::client::Frame`](crate::shared::containers::daemon::client::Frame):
/// the frame's own bytes, with no tag in front, so that the provider
/// forwards them as they are. The connector finishing the channel is
/// the connector hanging up.
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,
        }
    }
}
```
