首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >warp框架教程2-log模块,addr模块和header模块

warp框架教程2-log模块,addr模块和header模块

作者头像
zy010101
发布于 2023-07-11 05:52:21
发布于 2023-07-11 05:52:21
41700
代码可运行
举报
文章被收录于专栏:程序员程序员
运行总次数:0
代码可运行

log , addr 和 header

从本文开始,我们将介绍 warp 中 Filter 的核心模块。在文档中有 filter 相关模块的介绍, 本文来介绍其中的 addr,header 和 log

addr 模块

addr 模块非常简单,它是用来获取远程客户端的地址的。使用起来非常简单。文档中也只有一个 remote 方法。

文档中还给出了 remote 方法的示例。

我们来改造刚才的 hello world 程序,来获取远程访问地址。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
use warp::Filter;

#[tokio::main]
async fn main() {
    // GET /hello/warp => 200 OK with body "Hello, warp!"
    let hello = warp::path!("hello" / String)
        .and(warp::addr::remote())
        .map(|name: String, addr: Option<std::net::SocketAddr>|
            {
                format!("Hello, {}!\nClient IP: {}\n", name, addr.unwrap().to_string())
            });

    warp::serve(hello)
        .run(([0, 0, 0, 0], 3030))      // 监听 0.0.0.0
        .await;
}

这次,我们在代码中使用 and 加上了 remote 方法,并传入闭包中。另外一点是我们更改了 web 的监听地址为 0.0.0.0,来获取所有 IP 的访问。

  1. 在本地使用 curl 访问

可以看到打印的访问地址是 127.0.0.1:42260

  1. 在远程使用 postman 访问

通过远程Windows上的 postman 来访问,可以看到显示的 IP 地址是 221.218.142.126:17184

header 模块

header 模块是与请求 HTTP 标头交互,可以帮助我们提取请求头中的参数。该模块的文档如下所示:

所具备的方法并不是很多。这里不对每个函数进行说明。需要使用相关方法的,请查看相关文档。放在这里介绍 header 模块是因为上面 addr 方式获取到的 IP 在用反向代理的情况下,是不正确的。例如在使用 Nginx 作为代理的时候,我们需要配置 X-Forwarded-For ,然后读取请求头中的 X-Forwarded-For 或者 X-Real-IP 来确定客户端的真实 IP。我们使用 header 模块来读取相关的请求头。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
use warp::Filter;

#[tokio::main]
async fn main() {
    // GET /hello/warp => 200 OK with body "Hello, warp!"
    let hello = warp::path!("hello" / String)
        .and(warp::addr::remote())
        .and(warp::header("x-forwarded-for"))
        .and(warp::header("x-real-ip"))
        .map(|name: String, addr: Option<std::net::SocketAddr>, x_forward_for: String, x_real_ip: String|
            {
                format!("Hello, {}!\nClient IP: {}\nX-Forwarded-For: {}\nX-Real-IP: {}\n", 
                    name, addr.unwrap().to_string(), x_forward_for, x_real_ip)
            })
        .with(log);

    warp::serve(hello)
        .run(([127, 0, 0, 1], 3030))      // 监听 127.0.0.1
        .await;
}

和刚才一样,我们分别使用 curl 和 远程 postman 来进行访问。这次,我们访问的端口是 Nginx 的端口 80; 而不是监听的端口3030。

  1. 本地 curl 访问

可以看到,x-forwarded-for 和 x-real-ip 都显示的是 127.0.0.1,并且通过 addr 模块取得的 client IP 也是 127.0.0.1(实际上 addr 模块取得的地址是反向代理所在的IP地址)。

  1. 远程 postman 访问

可以看到 x-forwarded-for 和 x-real-ip 都显示的是 221.218.142.126,获取到了客户端的真实IP,而addr 此时获取的是 Nginx 所在的IP。也就是本机。

获取请求头中所有的字段

使用 header 模块的 headers_cloned 方法可以获取请求头中所有的字段,例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
use warp::{Filter, hyper::HeaderMap};

#[tokio::main]
async fn main() {
    // GET /hello/warp => 200 OK with body "Hello, warp!"
    let hello = warp::path!("hello" / String)
        .and(warp::addr::remote())
        .and(warp::header("x-forwarded-for"))
        .and(warp::header("x-real-ip"))
        .and(warp::header::headers_cloned())
        .map(|name: String, addr: Option<std::net::SocketAddr>, x_forward_for: String, x_real_ip: String, all_header: HeaderMap|
            {
                println!("{:?}", all_header);
                format!("Hello, {}!\nClient IP: {}\nX-Forwarded-For: {}\nX-Real-IP: {}\n", 
                    name, addr.unwrap().to_string(), x_forward_for, x_real_ip)
            });

    warp::serve(hello)
        .run(([127, 0, 0, 1], 3030))      // 监听 127.0.0.1
        .await;
}

现在,我们使用 postman 来进行访问,增加一个自定义的 Token 字段到 header 中

请求之后,我们来看一下控制台的输出结果。

log 模块

在第一篇文章的时候,我们引入了两个日志模块 log 和 pretty_env_logger 。现在是时候排上用场了。我们来配一下日志输出。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
use std::env;
use warp::{Filter, hyper::HeaderMap};

#[tokio::main]
async fn main() {
	// 日志输出相关配置
    env::set_var("MYAPP_LOG", "INFO");  
    pretty_env_logger::init_custom_env("MYAPP_LOG");
    let log = warp::log("MYAPP");

    // GET /hello/warp => 200 OK with body "Hello, warp!"
    let hello = warp::path!("hello" / String)
        .and(warp::addr::remote())
        .and(warp::header("x-forwarded-for"))
        .and(warp::header("x-real-ip"))
        .and(warp::header::headers_cloned())
        .map(|name: String, addr: Option<std::net::SocketAddr>, x_forward_for: String, x_real_ip: String, all_header: HeaderMap|
            {
                println!("{:?}", all_header);
                format!("Hello, {}!\nClient IP: {}\nX-Forwarded-For: {}\nX-Real-IP: {}\n", 
                    name, addr.unwrap().to_string(), x_forward_for, x_real_ip)
            })
        .with(log);		// 加入日志配置

    warp::serve(hello)
        .run(([127, 0, 0, 1], 3030))       // 监听 127.0.0.1
        .await;
}

log 模块的文档也是非常简单,只拥有两个结构体和两个方法。

我们来访问一下,看看输出的日志是什么样?

这个日志输出还是相当nice的。我们刚才是使用默认的访问日志记录格式,并生成日志记录。当然了,你也可以使用 custom 方法来定制日志格式和输出。例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    let log = warp::log::custom(|info| {
        log::info!(
            target: "MYAPP_LOG",
            "{} {} {}",
            info.method(),
            info.path(),
            info.status(),
        );
    });

此时日志输出如下所示:

这就是我们定制化之后的输出。不过这还缺少了最重要的东西,那就是日期。因此一般我们会这样使用。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
use std::env;
use warp::Filter;

#[tokio::main]
async fn main() {
    env::set_var("MYAPP_LOG", "INFO");
    // 初始化,默认带有时间,时间是带时区的
    pretty_env_logger::try_init_timed_custom_env("MYAPP_LOG").expect("logger init failed!");
    let log = warp::log("MYAPP_LOG");

    // GET /hello/warp => 200 OK with body "Hello, warp!"
    let hello = warp::path!("hello" / String)
        .and(warp::addr::remote())
        .and(warp::header("x-forwarded-for"))
        .and(warp::header("x-real-ip"))
        .map(|name: String, addr: Option<std::net::SocketAddr>, x_forward_for: String, x_real_ip: String|
            {
                format!("Hello, {}!\nClient IP: {}\nX-Forwarded-For: {}\nX-Real-IP: {}\n", 
                    name, addr.unwrap().to_string(), x_forward_for, x_real_ip)
            })
        .with(log);		// 加上日志输出

    warp::serve(hello)
        .run(([127, 0, 0, 1], 3030))       // 监听 127.0.0.1
        .await;
}

可以看到带有时区的访问时间被输出了。pretty_env_logger 的文档中还提供了其他初始化的方式,我们可以通过查看它的文档来使用其他的初始化方式。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-07-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
warp框架教程3-path, method和自定义请求方法
path 是 warp 中的路由系统, 一个 web 框架的灵魂所在, 一个优美的路由系统可以给我们带来非常良好的使用体验, 而 warp 的路由体验本身就是非常 nice 的。在本文中将展示一个 RESTful 风格的 API 设计。下面先来学习一下 path 模块。
zy010101
2023/07/11
6110
warp框架教程3-path, method和自定义请求方法
warp框架教程4-Filter系统中的方法介绍
过滤器可以选择性地从 request 中提取一些数据,将其与其他数据组合、修改,并将某个值作为 response 返回。过滤器的强大之处在于能够将其拆分为小的子集,然后在应用程序的各个部分中进行链式调用和重用。
zy010101
2023/07/24
5090
nginx获取请求真实IP
realip模块会修改remote_addr和remote_port,会用一个realip_remote_addr和realip_remote_port表示nginx原来的地址和端口
十毛
2021/07/14
3.4K0
Nginx 之 realip模块 使用详解
使用:realip 功能需要 Nginx 添加 ngx_http_realip_module 模块,默认情况下是不被编译,如果需要添加,请在编译时添加 --with-http_realip_module 选项开启它。
YP小站
2020/06/05
7.9K0
反向代理与 Real-IP 和 X-Forwarded-For
本文作者张开涛。为保障《亿级流量网站架构核心技术》一书内容的连续性,有些需要读者了解的内容,或者书的补充和引申内容,会通过二维码嵌入的方式引导读者阅读学习。大家可以关注作者公众号“开涛的博客”,并从菜单栏“我的新书”中查阅相关内容。
博文视点Broadview
2020/06/11
3.4K0
研发管理经验总结:3 私有化文件存储minio
橡树议会紧急召开。狐狸菲菲拍桌:"松鼠的存粮数据又丢了!我们需要私有化存储方案!"
李福春
2025/07/05
460
研发管理经验总结:3 私有化文件存储minio
rust warp框架教程1-helloworld
warp is a super-easy, composable, web server framework for warp speeds.
zy010101
2023/07/11
1.4K0
rust warp框架教程1-helloworld
Rust:axum学习笔记(4) 上传文件
接上一篇继续,上传文件是 web开发中的常用功能,本文将演示axum如何实现图片上传(注:其它类型的文件原理相同),一般来说要考虑以下几个因素:
菩提树下的杨过
2022/04/27
2.6K1
Rust:axum学习笔记(4) 上传文件
【大家的项目】RiteRaft - Raft 应用快速开发框架,160 行启动一个 Raft 服务
ritedb/riteraft 是一个实用 Raft 框架,用于快速开发和验证基于 Raft 共识算法的分布应用式。
MikeLoveRust
2021/06/16
6260
Nginx实现网站80端口和FRP共存
今日在阿里云服务器研究frp,因为备案了,所以打算实现将frp中的http端口改成80端口,但是服务器已经搭建有其他网站把80端口,于是打算通过nginx实现共用80端口。
Lcry
2022/11/29
1.3K0
「最佳实践」腾讯云CLB负载均衡通过TOA和XFF获取客户端真实IP:涵盖七层LB和NAT64 LB
随着互联网技术的飞速发展以及数字化转型的浪潮中,IPv6逐渐成为未来网络的主流协议,同时负载均衡也成为必不可少的组件,在使用过程中经常会遇到记录客户端真实IP地址的需求,本文将深入探讨NAT64 LB如何通过TOA(TCP Option Address)、以及七层LB如何通过XFF(X-Forwarded-For)机制获取客户端的真实IP地址,确保在复杂的网络环境和架构中也能精准地识别客户端身份。
RokasYang
2024/07/29
3K18
「最佳实践」腾讯云CLB负载均衡通过TOA和XFF获取客户端真实IP:涵盖七层LB和NAT64 LB
nginx反向代理中proxy_set_header 运维笔记
Nginx proxy_set_header:即允许重新定义或添加字段传递给代理服务器的请求头。该值可以包含文本、变量和它们的组合。在没有定义proxy_set_header时会继承之前定义的值。默认情况下,只有两个字段被重定义: proxy_set_header Host $proxy_host; proxy_set_header Connection close; 如果启用缓存,来自之前请求的头字段“If-Modified-Since”, “If-Unmodified-Since”, “If-None-
洗尽了浮华
2018/01/23
18.9K0
nginx反向代理中proxy_set_header 运维笔记
一文搞懂各种场景下的数据路由转发
可以看到 这里业务流程是这样的:服务端解析客户端上报的数据时,会同时解析客户端的IP信息,用于确认客户端的地域、运营商等信息,方便对数据进行分类和二次分析
粲然
2024/03/13
1.1K0
一文搞懂各种场景下的数据路由转发
【Nginx32】Nginx学习:随机索引、真实IP处理与来源处理模块
完成了代理这个大模块的学习,我们继续其它 Nginx 中 HTTP 相关的模块学习。今天的内容都比较简单,不过最后的来源处理非常有用,可以帮我们解决外链问题。另外两个其实大家了解一下就好。
硬核项目经理
2023/10/23
8410
【Nginx32】Nginx学习:随机索引、真实IP处理与来源处理模块
Nginx proxy_set_header 理解
用户认证接口:根据客户端IP和port,进行IP反查和端口范围确认,如符合则用户认证通过。 当前使用的是Nginx负载均衡,从客户端到Nginx端 ip和port都对,从Nginx到应有服务器上-port端口变成很奇怪的端口号。真是遇到的问题,登录页的ip和port在登录验证没有问题,但在登录完成后跳转的时候,端口号发生了变化。跟nginx服务器的监听端口相同了。(注:除了部署的Nginx服务器,应该还有一个前端的nginx,这是我没有接触到的部分。) 疑问:Nginx往应有服务器上 是如何 传递 客户端IP和port 参数的呢? 请看 Nginx proxy_set_header
用户5640963
2019/07/26
1.1K0
frp 供内网穿透服务的工具
frp 供内网穿透服务的工具 项目地址: https://github.com/fatedier/frp 修改配置文件: 1[common] 2server_addr = frp.yo1c.cc 3server_port = 7000 4#log_file = ./frpc.log 5log_level = info 6log_max_days = 3 7privilege_token = 30064E394C1C63766DA345EEFDA490EF 8 9[pay] 10type =
Tinywan
2019/07/16
1.6K0
nginx $remote_addr
remote_addr代表客户端的IP,但它的值不是由客户端提供的,而是服务端根据客户端的ip指定的,当你的浏览器访问某个网站时,假设中间没有任何代理,那么网站的web服务器(Nginx,Apache等)就会把remote_addr设为你的机器IP,如果你用了某个代理,那么你的浏览器会先访问这个代理,然后再由这个代理转发到网站,这样web服务器就会把remote_addr设为这台代理机器的IP。
随心助手
2020/09/08
2K0
nginx之配置proxy_set_header问题梳理
将左侧匹配到的/proxy_path/开头的url全部转发到后端服务器 192.168.223.137。
小勇DW3
2019/12/20
9.5K0
nginx之配置proxy_set_header问题梳理
用docker在本地搭建nginx实验环境
用docker搭建如下拓扑结构的实验环境。相关代码可以在 https://github.com/dhyuan/dockerEnv/tree/main/nginx 获得。
dhyuan
2022/05/30
6300
用docker在本地搭建nginx实验环境
nginx proxy_set_header设置、自定义header
允许重新定义或者添加发往后端服务器的请求头。value可以包含文本、变量或者它们的组合。 当且仅当当前配置级别中没有定义proxy_set_header指令时,会从上面的级别继承配置。 默认情况下,只有两个请求头会被重新定义:
用户5640963
2019/07/26
17.9K0
相关推荐
warp框架教程3-path, method和自定义请求方法
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档