#![cfg_attr(not(feature = "proxy_protocol"), allow(dead_code, unused_imports))]
use super::session::SharedSession;
use crate::{
auth::UserDetail,
server::controlchan::Reply,
server::session::TraceId,
storage::{self, StorageBackend},
};
use std::fmt;
use thiserror::Error;
use tokio::sync::mpsc::{Receiver, Sender};
use tokio::sync::oneshot;
#[derive(PartialEq, Eq, Debug)]
pub enum DataChanMsg {
ExternalCommand(DataChanCmd),
Abort,
}
#[derive(PartialEq, Eq, Debug)]
pub enum DataChanCmd {
Retr {
path: String,
},
Stor {
path: String,
},
Appe {
path: String,
},
List {
options: Option<String>,
path: Option<String>,
},
Nlst {
path: Option<String>,
},
Mlsd {
path: Option<String>,
},
}
impl DataChanCmd {
pub fn path(&self) -> Option<String> {
match self {
DataChanCmd::Retr { path, .. } => Some(path.clone()),
DataChanCmd::Stor { path, .. } => Some(path.clone()),
DataChanCmd::Appe { path, .. } => Some(path.clone()),
DataChanCmd::List { path, .. } => path.clone(),
DataChanCmd::Mlsd { path } => path.clone(),
DataChanCmd::Nlst { path } => path.clone(),
}
}
}
#[derive(Debug)]
#[allow(dead_code)]
pub enum ControlChanMsg {
PermissionDenied,
NotFound,
SentData {
path: String,
bytes: u64,
},
WrittenData {
path: String,
bytes: u64,
},
ConnectionReset,
DataConnectionClosedAfterStor,
WriteFailed,
DirectorySuccessfullyListed,
DirectoryListFailure,
CwdSuccess,
DelFileSuccess {
path: String,
},
RmDirSuccess {
path: String,
},
RenameSuccess {
old_path: String,
new_path: String,
},
DelFail,
ExitControlLoop,
MkDirSuccess { path: String },
MkdirFail,
AuthSuccess { username: String, trace_id: TraceId },
AuthFailed,
SecureControlChannel,
PlaintextControlChannel,
StorageError(storage::Error),
CommandChannelReply(Reply),
}
impl fmt::Display for ControlChanMsg {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(self, f)
}
}
#[derive(Error, Debug)]
#[error("Could not allocate port")]
pub struct PortAllocationError;
#[derive(Debug)]
pub(crate) enum SwitchboardMessage<Storage, User>
where
Storage: StorageBackend<User>,
User: UserDetail,
{
AssignDataPortCommand(SharedSession<Storage, User>, oneshot::Sender<Result<Reply, PortAllocationError>>),
CloseDataPortCommand(SharedSession<Storage, User>),
}
pub(crate) type SwitchboardSender<Storage, User> = Sender<SwitchboardMessage<Storage, User>>;
pub(crate) type SwitchboardReceiver<Storage, User> = Receiver<SwitchboardMessage<Storage, User>>;