StaticFileHandler

Struct StaticFileHandler 

Source
pub struct StaticFileHandler { /* private fields */ }
Expand description

Handler for serving static files from a directory.

StaticFileHandler provides secure, efficient static file serving with automatic MIME type detection and directory index support.

§Security Features

  • Path traversal protection: Prevents access to files outside the root directory
  • Canonicalization: All paths are resolved to their canonical form
  • Access validation: Only files under the configured root can be accessed

§Performance

  • Files are read asynchronously using tokio’s AsyncReadExt
  • No buffering overhead for small files
  • Efficient path resolution and validation

§Examples

§Basic Usage

use wsforge::static_files::StaticFileHandler;
use std::path::PathBuf;

let handler = StaticFileHandler::new(PathBuf::from("public"));

// Serve files from ./public directory
// Handler will automatically serve index.html for directories

§Custom Index File

use wsforge::static_files::StaticFileHandler;
use std::path::PathBuf;

let handler = StaticFileHandler::new(PathBuf::from("public"))
    .with_index("default.html");

// Now directories will serve default.html instead of index.html

§Serving Files

use wsforge::static_files::StaticFileHandler;
use std::path::PathBuf;

let handler = StaticFileHandler::new(PathBuf::from("public"));

// Serve a specific file
let (content, mime_type) = handler.serve("/app.js").await?;
println!("Served {} bytes of {}", content.len(), mime_type);

Implementations§

Source§

impl StaticFileHandler

Source

pub fn new(root: impl Into<PathBuf>) -> Self

Creates a new static file handler for the given root directory.

The root directory path should be relative to the current working directory or an absolute path. Files will only be served from within this directory and its subdirectories.

§Arguments
  • root - Path to the root directory containing static files
§Default Configuration
  • Index file: index.html
  • MIME detection: Automatic based on file extension
§Examples
§Relative Path
use wsforge::static_files::StaticFileHandler;

let handler = StaticFileHandler::new("public");
// Serves files from ./public
§Absolute Path
use wsforge::static_files::StaticFileHandler;
use std::path::PathBuf;

let handler = StaticFileHandler::new(PathBuf::from("/var/www/html"));
// Serves files from /var/www/html
§With PathBuf
use wsforge::static_files::StaticFileHandler;
use std::path::PathBuf;

let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
path.push("static");
let handler = StaticFileHandler::new(path);
Source

pub fn with_index(self, index: impl Into<String>) -> Self

Sets the name of the index file to serve for directory requests.

By default, this is index.html. Change this if your application uses a different default file name.

§Arguments
  • index - The name of the index file
§Examples
§Custom Index
use wsforge::static_files::StaticFileHandler;

let handler = StaticFileHandler::new("public")
    .with_index("default.html");
§Home Page
use wsforge::static_files::StaticFileHandler;

let handler = StaticFileHandler::new("public")
    .with_index("home.html");
Source

pub async fn serve(&self, path: &str) -> Result<(Vec<u8>, String)>

Serves a file at the given path.

This method:

  1. Decodes percent-encoded URLs
  2. Validates the path is within the root directory
  3. Checks if the path is a directory (serves index file if so)
  4. Reads the file contents
  5. Detects and returns the MIME type
§Arguments
  • path - The requested path (e.g., “/app.js”, “/images/logo.png”)
§Returns

Returns a tuple of (content, mime_type) where:

  • content is the raw file bytes
  • mime_type is the detected MIME type as a string
§Errors

Returns an error if:

  • The path is invalid or contains illegal characters
  • The path escapes the root directory (security violation)
  • The file does not exist
  • The file cannot be read (permissions, etc.)
§Security

This method prevents path traversal attacks by:

  • Canonicalizing both the requested path and root path
  • Ensuring the canonical file path starts with the canonical root path
  • Rejecting any path that would escape the root directory
§Examples
§Basic File Serving
use wsforge::static_files::StaticFileHandler;

let handler = StaticFileHandler::new("public");

let (content, mime_type) = handler.serve("/app.js").await?;
assert_eq!(mime_type, "application/javascript");
println!("Served {} bytes", content.len());
§Directory Request
use wsforge::static_files::StaticFileHandler;

let handler = StaticFileHandler::new("public");

// Request to "/" serves public/index.html
let (content, mime_type) = handler.serve("/").await?;
assert_eq!(mime_type, "text/html");
§Error Handling
use wsforge::static_files::StaticFileHandler;

let handler = StaticFileHandler::new("public");

match handler.serve("/nonexistent.html").await {
    Ok((content, mime_type)) => {
        println!("Served {}", mime_type);
    }
    Err(e) => {
        eprintln!("File not found: {}", e);
        // Send 404 response
    }
}
§Percent-Encoded Paths
use wsforge::static_files::StaticFileHandler;

let handler = StaticFileHandler::new("public");

// Handles percent-encoded characters
let (content, _) = handler.serve("/my%20file.html").await?;
// Serves "public/my file.html"

Trait Implementations§

Source§

impl Clone for StaticFileHandler

Source§

fn clone(&self) -> StaticFileHandler

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for StaticFileHandler

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more