Module libunftp::storage

source ·
Expand description

Contains the StorageBackend trait that can be implemented to create virtual file systems for libunftp.

Pre-made implementations exists on crates.io (search for unftp-sbe-) and you can define your own implementation to integrate your FTP(S) server with whatever storage mechanism you prefer.

To create a new storage back-end:

  1. Declare a dependency on the async-trait crate
async-trait = "0.1.50"
  1. Implement the StorageBackend trait and optionally the Metadata trait:
use async_trait::async_trait;
use libunftp::storage::{Fileinfo, Metadata, Result, StorageBackend};
use std::fmt::Debug;
use std::path::{Path, PathBuf};
use libunftp::auth::DefaultUser;
use std::time::SystemTime;

#[derive(Debug)]
pub struct Vfs {}

#[derive(Debug)]
pub struct Meta {
    inner: std::fs::Metadata,
}

impl Vfs {
  fn new() -> Vfs { Vfs{} }
}

#[async_trait]
impl libunftp::storage::StorageBackend<DefaultUser> for Vfs {
    type Metadata = Meta;

    async fn metadata<P: AsRef<Path> + Send + Debug>(
        &self,
        user: &DefaultUser,
        path: P,
    ) -> Result<Self::Metadata> {
        unimplemented!()
    }

    async fn list<P: AsRef<Path> + Send + Debug>(
        &self,
        user: &DefaultUser,
        path: P,
    ) -> Result<Vec<Fileinfo<PathBuf, Self::Metadata>>>
    where
        <Self as StorageBackend<DefaultUser>>::Metadata: Metadata,
    {
        unimplemented!()
    }

    async fn get<P: AsRef<Path> + Send + Debug>(
        &self,
        user: &DefaultUser,
        path: P,
        start_pos: u64,
    ) -> Result<Box<dyn tokio::io::AsyncRead + Send + Sync + Unpin>> {
        unimplemented!()
    }

    async fn put<
        P: AsRef<Path> + Send + Debug,
        R: tokio::io::AsyncRead + Send + Sync + Unpin + 'static,
    >(
        &self,
        user: &DefaultUser,
        input: R,
        path: P,
        start_pos: u64,
    ) -> Result<u64> {
        unimplemented!()
    }

    async fn del<P: AsRef<Path> + Send + Debug>(
        &self,
        user: &DefaultUser,
        path: P,
    ) -> Result<()> {
        unimplemented!()
    }

    async fn mkd<P: AsRef<Path> + Send + Debug>(
        &self,
        user: &DefaultUser,
        path: P,
    ) -> Result<()> {
        unimplemented!()
    }

    async fn rename<P: AsRef<Path> + Send + Debug>(
        &self,
        user: &DefaultUser,
        from: P,
        to: P,
    ) -> Result<()> {
        unimplemented!()
    }

    async fn rmd<P: AsRef<Path> + Send + Debug>(
        &self,
        user: &DefaultUser,
        path: P,
    ) -> Result<()> {
        unimplemented!()
    }

    async fn cwd<P: AsRef<Path> + Send + Debug>(
        &self,
        user: &DefaultUser,
        path: P,
    ) -> Result<()> {
        unimplemented!()
    }
}

impl Metadata for Meta {
    fn len(&self) -> u64 {
        self.inner.len()
    }

    fn is_dir(&self) -> bool {
        self.inner.is_dir()
    }

    fn is_file(&self) -> bool {
        self.inner.is_file()
    }

    fn is_symlink(&self) -> bool {
       self.inner.file_type().is_symlink()
    }

    fn modified(&self) -> Result<SystemTime> {
        self.inner.modified().map_err(|e| e.into())
    }

    fn gid(&self) -> u32 {
        0
    }

    fn uid(&self) -> u32 {
        0
    }
}
  1. Initialize it with the Server:
let vfs_provider = Box::new(|| Vfs::new());
let server = libunftp::Server::new(vfs_provider);

Structs

  • The Error returned by storage backends. Storage backend implementations should choose the ErrorKind chosen for errors carefully since that will determine what is returned to the FTP client.
  • Fileinfo contains the path and Metadata of a file.
  • Represents the permissions of a FTP File

Enums

Constants

  • Tells if STOR/RETR restarts are supported by the storage back-end i.e. starting from a different byte offset.
  • Whether or not this storage backend supports the SITE MD5 command

Traits

  • Represents the metadata of a FTP File
  • The StorageBackend trait can be implemented to create custom FTP virtual file systems. Once implemented it needs to be registered with the Server on construction.

Type Aliases

  • Result type used by traits in this module