[nginx]lua读取请求体
前言
nginx默认不读取请求体的数据,但可以通过$request_body内置变量来获取。$request_body存在内存中,如果它的字节大小超过nginx配置的client_body_buffer_size的值,nginx就会把请求体存放到临时文件中。此时数据就不在内存中了,这会导致$request_body为空。
同步非阻塞方式获取请求体
ngx.req.read_body
含义:同步读取客户端请求体,且不会阻塞nginx的事件循环。使用此指令后,就可以通过ngx.req.get_body_data来获取请求体的数据了。但如果使用临时文件来存放请求体,就需要先使用函数ngx.req.get_body_file来获取临时文件名,再读取临时文件中的请求体数据。
环境:rewrite_by_lua*、access_by_lua*、content_by_lua*
ngx.req.get_body_data
含义:执行ngx.req.read_body指令后,可以使用本指令在内存中获取请求体数据,结果会返回一个lua的字符串类型的数据。如果要获取table类型的数据,则需要使用ngx.req.get_post_args。
环境:rewrite_by_lua*、access_by_lua*、content_by_lua*、log_by_lua*
ngx.req.get_post_args
含义:读取包含当前请求在内的所有post请求的查询参数,返回一个table类型的数据
环境:rewrite_by_lua*、access_by_lua*、content_by_lua*、log_by_lua*、header_filter_by_lua*、body_filter_by_lua*
ngx.req.get_body_file
含义:获取存放请求体的临时文件名。如果请求体被存放在内存中,获取的值就是nil。
示例
获取string类型的请求体
location /testlua {
client_max_body_size 10k;
client_body_buffer_size 1k;
content_by_lua_block {
local ngx = require "ngx";
ngx.req.read_body() -- 开启读取请求体模式
local data = ngx.req.get_body_data() -- 获取内存中的请求体
if data then
ngx.print(string.format("data: %s, type: %s",data,type(data)))
return
else
local file = ngx.req.get_body_file() -- 如果内存中没有, 则到临时文件中读取
if file then
ngx.say("body is in file ", file)
else
ngx.say("no body found")
end
end
}
}
请求测试
curl -i http://192.168.1.111/testlua -d 'test=123&a=qwe&b=zxc'
HTTP/1.1 200 OK
Server: openresty
Date: Sun, 28 May 2023 10:05:51 GMT
Content-Type: application/octet-stream
Transfer-Encoding: chunked
Connection: keep-alive
data: test=123&a=qwe&b=zxc, type: string
获取table类型的请求体
location /testlua {
client_max_body_size 10k;
client_body_buffer_size 1k;
content_by_lua_block {
local ngx = require "ngx";
ngx.req.read_body() -- 开启读取请求体模式
local args, err = ngx.req.get_post_args() -- 获取内存中的请求体
if args then
for k,v in pairs(args) do
if type(v) == "table" then
ngx.say(k, ": ", table.concat(v, ", "))
else
ngx.say(k, ": ", v)
end
end
else
local file = ngx.req.get_body_file() -- 如果内存中没有, 则到临时文件中读取
if file then
ngx.say("body is in file ", file)
else
ngx.say("no body found")
end
end
}
}
请求测试
curl -i http://192.168.1.111/testlua -d 'test=123&a=qwe&b=zxc'
HTTP/1.1 200 OK
Server: openresty
Date: Sun, 28 May 2023 10:37:48 GMT
Content-Type: application/octet-stream
Transfer-Encoding: chunked
Connection: keep-alive
a: qwe
b: zxc
test: 123
参考
- 《Nginx实战:基于lua语言的配置、开发与架构详解》
[nginx]lua读取请求体的更多相关文章
- nginx读取请求体
请求体的读取一般发生在nginx的content handler中,一些nginx内置的模块,比如proxy模块,fastcgi模块,uwsgi模块等,这些模块的行为必须将客户端过来的请求体(如果有的 ...
- nginx请求体读取
上节说到nginx核心本身不会主动读取请求体,这个工作是交给请求处理阶段的模块来做,但是nginx核心提供了ngx_http_read_client_request_body()接口来读取请求体,另外 ...
- 【精选】Nginx模块Lua-Nginx-Module学习笔记(一)Nginx Lua API 接口详解
源码地址:https://github.com/Tinywan/Lua-Nginx-Redis 一.介绍 各种* _by_lua,* _by_lua_block和* _by_lua_file配置指令用 ...
- post请求体过大导致ngx.req.get_post_args()取不到参数体的问题
http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size 该地址对于client_body_buf ...
- Nginx模块Lua-Nginx-Module学习笔记(一)Nginx Lua API 接口详解
源码地址:https://github.com/Tinywan/Lua-Nginx-Redis 一.介绍 各种* _by_lua,* _by_lua_block和* _by_lua_file配置指令用 ...
- openresty(nginx+lua)初识
1.新增项目配置文件: vim /usr/example/example1.conf --将以下内容加入example1.conf server { listen 80; server_name _; ...
- http 请求体数据--ngx
HTTP包体的长度有可能非常大,不同业务可能对包体读取 处理不相同, 比如waf, 也许会读取body内容或者只是读取很少的前几十字节.所以根据不同业务特性,对http body 数据包处理方式不同, ...
- 从Excel获取请求体
Excel文件 .py文件---------------------- import xlrdimport re def fetch_body(path,sheet,name,adict): ...
- Spring Cloud Gateway 之获取请求体(Request Body)的几种方式
Spring Cloud Gateway 获取请求体 一.直接在全局拦截器中获取,伪代码如下 private String resolveBodyFromRequest(ServerHttpReque ...
- Asp.Net Core上传大文件请求体限制设置
IIS进程内部署时 1. Web.Config的<system.webServer>节点下增加 <security> <requestFiltering> < ...
随机推荐
- Oracle 定时任务job实际应用
目录 一.Oracle定时任务简介 二.dbms_job涉及到的知识点 三.初始化相关参数job_queue_processes 四.实际创建一个定时任务(一分钟执行一次),实现定时一分钟往表中插入数 ...
- 2021-03-31:给定一个数组arr,给定一个值v。求子数组平均值小于等于v的最长子数组长度。
2021-03-31:给定一个数组arr,给定一个值v.求子数组平均值小于等于v的最长子数组长度. 福大大 答案2021-03-31: 这道题是昨天每日一题的变种.数组每个元素减v,然后求<=0 ...
- 2021-04-20:手写代码:最小生成树算法之Prim。
2021-04-20:手写代码:最小生成树算法之Prim. 福大大 答案2021-04-20: 解锁点,解锁边,解锁点,解锁边,一直解锁下去. 代码用golang编写.代码如下: package ma ...
- Selenium - 元素等待(2) - 显式等待/EC等待
Selenium - 元素等待 显式等待 显式等待是一种灵活的等待方式,需要声明等待的结束条件,当满足条件时会自动结束等待: 需要引入WebDriverWait包以及exception_conditi ...
- 17.AQS中的Condition是什么?
欢迎关注:王有志 期待你加入Java人的提桶跑路群:共同富裕的Java人 今天来和大家聊聊Condition,Condition为AQS"家族"提供了等待与唤醒的能力,使AQS&q ...
- 图数据库 NebulaGraph 的内存管理实践之 Memory Tracker
数据库的内存管理是数据库内核设计中的重要模块,内存的可度量.可管控是数据库稳定性的重要保障.同样的,内存管理对图数据库 NebulaGraph 也至关重要. 图数据库的多度关联查询特性,往往使图数据库 ...
- 在 Net Core 开发中如何解决 Cannot access a disposed object 这个问题
一.简介 Net Core跨平台项目开发多了,总会遇到各种各样的问题,我就遇到了一个这样的问题,不能访问 Cannot access a disposed object 错误,经过自己多方努力,查阅资 ...
- 解决NAT模式下SSH连接虚拟机
解决NAT模式下SSH连接虚拟机 简介: 用到的有软件:VirtualBox6.1,RetHat7.4 , SmartTTY 来由: 刚开始使用桥接模式(Bridged)网络连接,但是虚拟机没有网络. ...
- [ARM 汇编]进阶篇—存储访问指令—2.3.2 多数据传输指令
在 ARM 汇编中,多数据传输指令用于一次性从存储器中加载多个数据到寄存器组,或将寄存器组中的多个数据存储到存储器.这些指令通常用于高效地处理数组.结构体等数据结构.在本节中,我们将详细介绍 ARM ...
- To ChatGPT:让你更加随意地使用所有ChatGPT应用
现在其实已经有很多在线的llm服务了,当然也存在许多开源部署方案,但是不知道大家有没有发现一个问题,目前基于ChatGPT开发的应用,都是使用的OpenAI的接口.换句话说,如果没有OpenAI账号, ...