Rust静态文件服务库hyper-staticfile的使用,高性能Web静态资源托管解决方案

Rust静态文件服务库hyper-staticfile的使用,高性能Web静态资源托管解决方案

hyper-staticfile 是一个用于 Hyper 1.0 的静态文件服务库。

Build Status Crate Docs

安装

在项目目录中运行以下Cargo命令:

cargo add hyper-staticfile

或者在Cargo.toml中添加以下行:

hyper-staticfile = "0.10.1"

完整示例

以下是完整的静态文件服务器示例代码:

use std::path::Path;
use hyper::service::{make_service_fn, service_fn};
use hyper::{Body, Request, Response, Server};
use hyper_staticfile::Static;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    // 设置静态文件目录
    let static_ = Static::new(Path::new("./static"));
    
    // 创建服务函数
    let make_service = make_service_fn(|_| {
        let static_ = static_.clone();
        async move {
            Ok::<_, hyper::Error>(service_fn(move |req: Request<Body>| {
                // 处理静态文件请求
                static_.serve(req)
            }))
        }
    });

    // 绑定服务器端口
    let addr = ([127, 0, 0, 1], 3000).into();
    let server = Server::bind(&addr).serve(make_service);

    println!("Server running at http://{}", addr);

    // 运行服务器
    server.await?;

    Ok(())
}

代码说明

  1. 首先导入必要的模块
  2. 创建一个静态文件服务实例,指定静态文件目录(./static)
  3. 创建服务处理函数,使用hyper_staticfile::Static处理所有请求
  4. 绑定服务器到127.0.0.1:3000
  5. 启动服务器

使用方法

  1. 创建一个名为static的目录
  2. 将需要托管的静态文件放入该目录
  3. 运行服务器
  4. 访问http://localhost:3000查看静态文件

许可证

MIT License

完整示例demo

use std::path::Path;
use hyper::service::{make_service_fn, service_fn};
use hyper::{Body, Request, Response, Server};
use hyper_staticfile::Static;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    // 设置静态文件目录为当前目录下的public文件夹
    let static_ = Static::new(Path::new("./public"));
    
    // 创建服务处理函数
    let make_service = make_service_fn(|_conn| {
        // 克隆静态文件处理器
        let static_ = static_.clone();
        async {
            Ok::<_, hyper::Error>(service_fn(move |req: Request<Body>| {
                // 使用静态文件处理器处理请求
                static_.serve(req)
            }))
        }
    });

    // 绑定到本地8080端口
    let addr = ([127, 0, 0, 1], 8080).into();
    let server = Server::bind(&addr).serve(make_service);

    println!("静态文件服务器已启动,访问地址: http://{}", addr);

    // 运行服务器
    server.await?;

    Ok(())
}

1 回复

Rust静态文件服务库hyper-staticfile的使用

介绍

hyper-staticfile是一个用于hyper框架的Rust库,专门用于高效地提供静态文件服务。它非常适合构建高性能的Web静态资源托管解决方案,具有以下特点:

  • 专为hyper框架设计,与hyper生态无缝集成
  • 支持HTTP范围请求(partial content)
  • 自动处理MIME类型
  • 支持If-Modified-Since缓存头
  • 高性能文件服务,适合大文件传输
  • 简洁易用的API

安装

在Cargo.toml中添加依赖:

[dependencies]
hyper = "0.14"
hyper-staticfile = "0.9"
tokio = { version = "1.0", features = ["full"] }

完整示例代码

下面是一个结合了基本使用和高级配置的完整示例:

use hyper::service::{make_service_fn, service_fn};
use hyper::{Body, Method, Request, Response, Server, StatusCode};
use hyper_staticfile::{Static, MimeOverride};
use std::path::Path;
use std::time::Duration;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    let addr = ([127, 0, 0, 1], 8080).into();
    
    // 自定义MIME类型映射
    let mut mime_override = MimeOverride::new();
    mime_override.insert(".wasm", "application/wasm");
    mime_override.insert(".md", "text/markdown");
    
    // 创建静态文件服务实例,配置缓存和MIME类型
    let static_ = Static::new(Path::new("./static"))
        .with_mime_override(mime_override)
        .cache_headers(Some(Duration::from_secs(3600))); // 1小时缓存
    
    let make_service = make_service_fn(move |_| {
        let static_ = static_.clone();
        
        async move {
            Ok::<_, hyper::Error>(service_fn(move |req: Request<Body>| {
                let static_ = static_.clone();
                
                async move {
                    match (req.method(), req.uri().path()) {
                        // 自定义API端点
                        (&Method::GET, "/api/status") => {
                            Ok(Response::new(Body::from("Server is running")))
                        },
                        // 静态文件服务
                        (&Method::GET, _) => {
                            static_.serve(req).await.or_else(|_| {
                                // 文件不存在时返回404
                                Ok(Response::builder()
                                    .status(StatusCode::NOT_FOUND)
                                    .body(Body::from("404 Not Found"))
                                    .unwrap())
                            })
                        },
                        // 其他请求方法返回405
                        _ => {
                            Ok(Response::builder()
                                .status(StatusCode::METHOD_NOT_ALLOWED)
                                .body(Body::from("Method Not Allowed"))
                                .unwrap())
                        }
                    }
                }
            }))
        }
    });

    let server = Server::bind(&addr).serve(make_service);
    println!("Server running at http://{}", addr);
    
    if let Err(e) = server.await {
        eprintln!("server error: {}", e);
    }
    
    Ok(())
}

代码说明

  1. MIME类型配置

    • 使用MimeOverride自定义了.wasm和.md文件的MIME类型
    • 其他文件类型会自动检测
  2. 缓存配置

    • 设置了1小时的缓存时间
    • 会自动处理If-Modified-Since请求头
  3. 路由处理

    • 处理/api/status自定义API端点
    • 其他GET请求交给静态文件处理器
    • 返回适当的错误响应(404/405)
  4. 错误处理

    • 静态文件不存在时返回404
    • 不支持的HTTP方法返回405

使用建议

  1. 在生产环境使用绝对路径:

    Static::new(Path::new("/var/www/static"))
    
  2. 对于大量小文件服务,可以考虑添加内存缓存层

  3. 根据实际需求调整缓存时间:

    .cache_headers(Some(Duration::from_secs(86400))) // 24小时缓存
    
  4. 可以结合tower的中间件添加额外功能如:

    • 请求日志
    • 认证
    • 速率限制

这个完整示例展示了hyper-staticfile的主要功能,可以直接作为项目基础使用,也可以根据需要进行扩展。

回到顶部