#web-framework #web #框架 #actix-web #http #async #actix

actix-cloud

Actix Cloud 是一个基于 Actix Web 的全功能 Web 框架。

2 个不稳定版本

0.2.0 2024 年 8 月 17 日
0.1.0 2024 年 8 月 13 日

#131 in HTTP 服务器

Download history 104/week @ 2024-08-10

104 每月下载量

MIT 许可证

100KB
2K SLoC

actix-cloud

Actix Cloud 是一个基于 Actix Web 的全功能 Web 框架。

特性

Actix Cloud 可高度配置。您可以仅启用需要的特性,实现自己的特性后端,甚至使用其他库。

指南

快速入门

您可以通过查看 Hello world 示例了解基本用法。

应用

由于应用配置可能相当动态,您需要自行构建。以下是一些有用的中间件:

App::new()
    .wrap(middleware::Compress::default()) // compress page
    .wrap(SecurityHeader::default().build()) // default security header
    .wrap(SessionMiddleware::builder(memorydb.clone(), Key::generate()).build()) // session
    ...
    .app_data(state_cloned.clone())

logger

我们使用 tracing 作为我们的日志记录器库。它是线程安全的。您可以在任何地方使用它。

启动日志记录器

LoggerBuilder::new().level(Level::DEBUG).start()        // colorful output
LoggerBuilder::new().json().start() // json output

您也可以使用 filtertransformer 等自定义日志记录器。

重新初始化日志记录器(例如,在插件中),或手动发送日志

logger.init(LoggerBuilder::new());
logger.sender().send(...);

保留字段

  • _time:微秒级的时间戳,覆盖日志记录的时间戳。

国际化

我们使用来自 rust-i18nrust-i18n-support 作为我们的国际化核心。

加载区域设置

let locale = Locale::new(String::from("en-US")).add_locale(i18n!("locale"));

翻译

t!(locale, "hello.world")
t!(locale, "hello.name", name = "MEME")

查看更多用法示例:示例

安全

添加安全头部的中间件

app.wrap(SecurityHeader::default().build())

默认头部

X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Cross-Origin-Opener-Policy: same-origin
Content-Security-Policy: default-src 'none'; script-src 'none'; object-src 'none'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'

使用HTTPS时启用HSTS

security_header.set_default_hsts();
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

memorydb-default

Actix Cloud有一个默认的内存数据库后端,用于会话。如果您实现了actix_cloud::memorydb::MemoryDB,也可以使用自己的后端。

注意:默认后端没有内存限制,如果未实施网关速率限制,则可能发生DDoS攻击

DefaultBackend::new()

memorydb-redis

Redis可以用作内存数据库的另一个后端。

RedisBackend::new("redis://user:[email protected]:6379/0").await.unwrap(),

认证

认证非常简单,您只需要实现提取器和检查器。

提取器用于从请求中提取自己的认证类型。例如,假设我们用0表示访客,用1表示管理员。我们的认证类型仅仅是Vec<u32>

fn perm_extractor(req: &mut ServiceRequest) -> Vec<u32> {
    let mut ret = Vec::new();
    ret.push(0); // guest permission is assigned by default.

    // test if query string has `admin=1`.
    let qs = QString::from(req.query_string());
    if qs.get("admin").is_some_and(|x| x == "1") {
        ret.push(1);
    }
    ret
}

检查器用于检查权限,如果返回值是false,则服务器将返回403

fn is_guest(p: Vec<u32>) -> bool {
    p.into_iter().find(|x| *x == 0).is_some()
}

然后使用build_router构建Router并在App中配置

app.service(scope("/api").configure(build_router(...)))

会话

大多数功能和用法都是基于actix-session。除了这些

  • MemoryDB是唯一支持的存储。
  • 错误使用actix-cloud::error::Error
  • 您可以在会话中设置_ttl来覆盖会话的TTL。
app.wrap(SessionMiddleware::builder(memorydb.clone(), Key::generate()).build())

配置

config-rs是底层库。

支持的功能

  • config-json:支持JSON文件。
  • config-yaml:支持YAML文件。
  • config-toml:支持TOML文件。

请求

提供每请求扩展。

内置中间件

  • 存储在extensions
  • 如果启用了i18n功能,语言将通过lang查询参数或GlobalState中的locale.default来识别。

启用内置中间件

app.wrap(request::Middleware::new())

用法

async fn handler(req: HttpRequest) -> impl Responder {
    let ext = req.extensions();
    let ext = ext.get::<actix_cloud::request::Extension>().unwrap();
    ...
}

响应

提供有用的响应类型。

如果启用了i18n功能,响应消息将自动翻译。

如果启用了response-json功能,响应消息将自动转换为JSON。

  1. 创建响应yml文件。
  2. 使用build.rs生成源文件。
  3. 使用include!包含生成的文件。

有关详细用法,请参阅示例

traceid

基于tracing-actix-web为每个请求添加跟踪ID。

app.wrap(request::Middleware::new())
   .wrap(TracingLogger::default())      // This should be after request::Middleware

如果您启用了request功能,请确保它在TracingLogger之前,因为trace_id字段基于它。

许可证

该项目受MIT许可证的许可。

依赖项

~16–35MB
~599K SLoC