rust-web-server 17.104.0

A dependency-minimal Rust web platform: HTTP/1.1, HTTP/2, and HTTP/3 server, reverse proxy, and application framework with routing, middleware (auth, rate limiting, tracing), an MCP server, an async ORM, background jobs, object storage, and a mailer. Runs as a zero-code config-driven proxy or as a library crate. No third-party HTTP dependencies.
Documentation
use file_ext::FileExt;
use crate::controller::Controller;
use crate::mime_type::MimeType;
use crate::range::Range;
use crate::request::{METHOD, Request};
use crate::response::{Response, STATUS_CODE_REASON_PHRASE};
use crate::server::ConnectionInfo;

#[cfg(test)]
mod tests;

/// Serves the CSS/JS assets for the directory listing page generated by
/// [`crate::app::controller::static_resource::StaticResourceController`].
///
/// These are same-origin `<link>`/`<script src>` assets rather than inline
/// `<style>`/`<script>` blocks so the listing page renders correctly under
/// the framework's default `Content-Security-Policy: default-src 'self'` —
/// inline blocks would otherwise be silently blocked by that policy.
///
/// Mirrors [`StyleController`](crate::app::controller::style::StyleController) /
/// [`ScriptController`](crate::app::controller::script::ScriptController):
/// a file on disk at the same relative path overrides the compiled-in default,
/// so deployments can restyle the listing without recompiling.
pub struct DirectoryListingAssetsController;

impl DirectoryListingAssetsController {
    pub const CSS_FILEPATH: &'static str = "rws-directory-listing.css";
    pub const JS_FILEPATH: &'static str = "rws-directory-listing.js";

    fn css_path() -> String {
        format!("/{}", Self::CSS_FILEPATH)
    }

    fn js_path() -> String {
        format!("/{}", Self::JS_FILEPATH)
    }

    fn serve(filepath: &'static str, embedded: &'static [u8], mime_type: &str, mut response: Response) -> Response {
        response.status_code = *STATUS_CODE_REASON_PHRASE.n200_ok.status_code;
        response.reason_phrase = STATUS_CODE_REASON_PHRASE.n200_ok.reason_phrase.to_string();

        if FileExt::does_file_exist(filepath) {
            let boxed_content_range = Range::get_content_range_of_a_file(filepath);

            if boxed_content_range.is_ok() {
                response.content_range_list = vec![boxed_content_range.unwrap()];
            } else {
                let error = boxed_content_range.err().unwrap();
                let content_range = Range::get_content_range(
                    Vec::from(error.as_bytes()),
                    MimeType::TEXT_HTML.to_string(),
                );
                response.content_range_list = vec![content_range];
                response.status_code = *STATUS_CODE_REASON_PHRASE.n500_internal_server_error.status_code;
                response.reason_phrase = STATUS_CODE_REASON_PHRASE.n500_internal_server_error.reason_phrase.to_string();
            }
        } else {
            let content_range = Range::get_content_range(embedded.to_vec(), mime_type.to_string());
            response.content_range_list = vec![content_range];
        }

        response
    }
}

impl Controller for DirectoryListingAssetsController {
    fn is_matching(request: &Request, _connection: &ConnectionInfo) -> bool {
        request.method == METHOD.get
            && (request.request_uri == Self::css_path() || request.request_uri == Self::js_path())
    }

    fn process(request: &Request, response: Response, _connection: &ConnectionInfo) -> Response {
        if request.request_uri == Self::css_path() {
            let embedded = include_bytes!("directory_listing.css");
            Self::serve(Self::CSS_FILEPATH, embedded, MimeType::TEXT_CSS, response)
        } else {
            let embedded = include_bytes!("directory_listing.js");
            Self::serve(Self::JS_FILEPATH, embedded, MimeType::TEXT_JAVASCRIPT, response)
        }
    }
}