首页 > 其他分享 >中间件

中间件

时间:2023-11-02 09:55:52浏览次数:337  
标签:extractor Firefox axum tracing 中间件 tower

中间件是一类提供系统软件和应用软件之间连接、便于软件各部件之间的沟通的软件,应用软件可以借助中间件在不同的技术架构之间共享信息与资源。 ——摘自维基百科;

在《axum 的状态共享》中,我们已经用到了中间件:用于添加共享数据的 AddExtension 中间件——它应用于AddExtensionLayerExtension

axum 直接使用了 tower 中间件的生态。

使用中间件

除了之前章节介绍的共享状态的中间件,我们再演示一个使用 tower 的 tower_http::trace::TraceLayer 中间件的示例。

定义处理函数

async fn foo() -> &'static str {
    "Welcome to axum.rs"
}

async fn bar() -> &'static str {
    "Powered by axum.rs"
}

定义路由并加上中间件

let app = Router::new()
        .route("/foo", get(foo))
        .route("/bar", get(bar))
        .layer(TraceLayer::new_for_http());

提示,为了能让该中间件正确地打印出日志,需要增加 tracingtracing-subscriber 依赖,并在代码中对其进行初始化:

if std::env::var_os("RUST_LOG").is_none() {
    std::env::set_var("RUST_LOG", "tower_http=debug,middleware=debug");
}
tracing_subscriber::fmt::init();

自定义中间件

你可以通过实现 tower::Service 来自定义中间件,但它非常复杂,有兴趣可以看看官方示例

好在 axum 提供了更简单的方法:通过extractor_middleware() 方法,将一个 extractor 转成中间件。

作为示例,我们将实现一个只能使用 Firefox 浏览器访问的中间件。如果用户使用 Firefox 浏览器访问,将展示正常信息,如果是用其它浏览器访问,将显示提示信息。

定义 extractor

pub struct UserAgentInfo;

#[async_trait]
impl<B> FromRequest<B> for UserAgentInfo
where
    B: Send,
{
    type Rejection = (StatusCode, String);
    async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
        let user_agent = req
            .headers()
            .and_then(|headers| headers.get(axum::http::header::USER_AGENT))
            .and_then(|value| value.to_str().ok())
            .unwrap_or("");
        tracing::debug!("该用户UserAgent是:{:?}", user_agent);
        if !user_agent.contains("Firefox") {
            tracing::error!("非Firefox浏览器,禁止访问");
            return Err((
                StatusCode::BAD_REQUEST,
                "You MUST use Firefox to visit this page.".to_string(),
            ));
        }
        Ok(UserAgentInfo {})
    }
}

作为中间件加到路由上

.layer(extractor_middleware::<user_agent::UserAgentInfo>());

本章讲解了 axum 的中间件的使用,以及如何自定义中间件。源码可以在我们的代码库中找到。

本章使用了多个第三方库,如果你对这些库暂时无法理解,可以先跳过。重点是理解如何使用及自定义中间件。

标签:extractor,Firefox,axum,tracing,中间件,tower
From: https://www.cnblogs.com/pythonClub/p/17804737.html

相关文章

  • 中间件【消息中间件选型】
    一、作用    异步化提升性能、系统间解耦、流量削峰。二、类型    ActiveMQ、RabbitMQ、Kafka以及RocketMQ这四大类。    2.1、ActivwMQ        目前不活跃,前几年用的比较多,故略去。    2.2、Kafka       【优......
  • Koa2 中后台返回字段由下划线改为驼峰的中间件
    //toHump.jsconsttoHump=async(ctx,next)=>{ctx.write=(obj)=>ctx.body=toHumpFun(obj)awaitnext()}functiontoHumpFun(obj){constresult=Array.isArray(obj)?[]:{}for(constkeyinobj){if(obj.hasOwnPr......
  • 如何使用中间件
    1.注册varbuilder=WebApplication.CreateBuilder(args);varapp=builder.Build();app.Map("/test",asyncappbuilder=>{appbuilder.Use(async(context,next)=>{context.Response.ContentType="text/html";......
  • 自定义中间件 middleware
    文件夹的创建1、在项目或者应用下创建一个任意名称的文件夹2、在该文件夹下创建一个任意名称的py文件3、在该py文件中写自定义的中间件(这个类必须继承MiddlewareMixin)然后在这个类里面就可以自定义五个方法了 (这五个方法并不是全部都需要书写,用几个写几个)中间件......
  • laravel:中间件给controller传递参数(10.27.0)
    一,相关文档https://learnku.com/docs/laravel/10.x/middleware/14846二,php代码1,middleware12345678910111213141516171819202122232425<?php namespaceApp\Http\Middleware; useClosure;useIlluminate\Http\Request;useS......
  • 【Django | 开发】中间件配置(记录响应耗时日志)
    ......
  • Java 常用中间件
    Java常用中间件1、网关Nginx、Kong、Zuul、Gateway2、缓存Redis、MemCached、OsCache、EhCache3、搜索ElasticSearch、Solr4、熔断Hystrix、resilience4j5、负载均衡DNS、F5、LVS、Nginx、OpenResty、HAproxy6、注册中心Nacos、Eureka、Zookeeper、Redis、Etcd、Cons......
  • 关于django中间件执行过程
    众所周知,django的中间件一般有五个方法,常用的仅三个,示例如下fromdjango.utils.deprecationimportMiddlewareMixinfromdjango.httpimportHttpResponse中间件示例classMyMiddleWare(MiddlewareMixin): defprocess_request(self,request): pass defprocess_view(se......
  • strapi系列-常用操作记录(创建中间件,创建关系型数据库,数据去掉attributes那一层)
    创建全局中间件创建关系型的数据https://docs.strapi.io/dev-docs/api/rest/relations{"product_types":{"connect":[10]},"product_tags":{"connect":[7,3,4]},"name":"TEST","......
  • 使用Hot Chocolate和.NET 6构建GraphQL应用 —— 创建Attribute中间件
    需求在部分接口添加一个机器人校验的功能思路读者们可以看下使用HotChocolate和.NET6构建GraphQL应用(5)——实现Query过滤功能,我们可以自定义创建一个类似的特性中间件来对接口进行管理.添加了该特性的接口即可实现机器人校验功能.实现输入对象///用户输入public......