前言

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读取请求体的更多相关文章

  1. nginx读取请求体

    请求体的读取一般发生在nginx的content handler中,一些nginx内置的模块,比如proxy模块,fastcgi模块,uwsgi模块等,这些模块的行为必须将客户端过来的请求体(如果有的 ...

  2. nginx请求体读取

    上节说到nginx核心本身不会主动读取请求体,这个工作是交给请求处理阶段的模块来做,但是nginx核心提供了ngx_http_read_client_request_body()接口来读取请求体,另外 ...

  3. 【精选】Nginx模块Lua-Nginx-Module学习笔记(一)Nginx Lua API 接口详解

    源码地址:https://github.com/Tinywan/Lua-Nginx-Redis 一.介绍 各种* _by_lua,* _by_lua_block和* _by_lua_file配置指令用 ...

  4. post请求体过大导致ngx.req.get_post_args()取不到参数体的问题

    http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size 该地址对于client_body_buf ...

  5. Nginx模块Lua-Nginx-Module学习笔记(一)Nginx Lua API 接口详解

    源码地址:https://github.com/Tinywan/Lua-Nginx-Redis 一.介绍 各种* _by_lua,* _by_lua_block和* _by_lua_file配置指令用 ...

  6. openresty(nginx+lua)初识

    1.新增项目配置文件: vim /usr/example/example1.conf --将以下内容加入example1.conf server { listen 80; server_name _; ...

  7. http 请求体数据--ngx

    HTTP包体的长度有可能非常大,不同业务可能对包体读取 处理不相同, 比如waf, 也许会读取body内容或者只是读取很少的前几十字节.所以根据不同业务特性,对http body 数据包处理方式不同, ...

  8. 从Excel获取请求体

    Excel文件 .py文件---------------------- import xlrdimport re def fetch_body(path,sheet,name,adict):     ...

  9. Spring Cloud Gateway 之获取请求体(Request Body)的几种方式

    Spring Cloud Gateway 获取请求体 一.直接在全局拦截器中获取,伪代码如下 private String resolveBodyFromRequest(ServerHttpReque ...

  10. Asp.Net Core上传大文件请求体限制设置

    IIS进程内部署时 1. Web.Config的<system.webServer>节点下增加 <security> <requestFiltering> < ...

随机推荐

  1. 【Python基础】数据类型与类型转换

    五种基本数据类型 在 Python 中,基本数据类型是指不可变对象的数据类型.以下是 Python 中的基本数据类型: 整数类型(int):表示整数,例如 1.2.3 等等. 浮点数类型(float) ...

  2. 如何在 🤗 Space 上托管 Unity 游戏

    你知道吗?Hugging Face Space 可以托管自己开发的 Unity 游戏!惊不惊喜,意不意外?来了解一下吧! Hugging Face Space 是一个能够以简单的方式来构建.托管和分享 ...

  3. 修改mysql的密码时遇到问题ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corre

    先输入:flush privileges; 再输入:ALTER USER 'root'@'localhost' IDENTIFIED BY 'mysql'; 再输入:flush privileges刷 ...

  4. 2023-04-05:做甜点需要购买配料,目前共有n种基料和m种配料可供选购。 制作甜点需要遵循以下几条规则: 必须选择1种基料;可以添加0种、1种或多种配料,每种类型的配料最多添加2份, 给定长度为

    2023-04-05:做甜点需要购买配料,目前共有n种基料和m种配料可供选购. 制作甜点需要遵循以下几条规则: 必须选择1种基料:可以添加0种.1种或多种配料,每种类型的配料最多添加2份, 给定长度为 ...

  5. [HUBUCTF 2022 新生赛]help

    题目告诉我们要走迷宫了嘛,那么主要就是找地图: 查壳: 64位,进IDA: 创建地图?跟进去看看: 看看num里装了啥: emm挺长的,有能力的小伙伴可以手搓一个地图,反正我没手搓出来QWQ 再看看判 ...

  6. flutter系列之:使用AnimationController来控制动画效果

    目录 简介 构建一个要动画的widget 让图像动起来 总结 简介 之前我们提到了flutter提供了比较简单好用的AnimatedContainer和SlideTransition来进行一些简单的动 ...

  7. Cesium开发案例整理

    weigis近几年越来越被人们所关注,但是二三维开发难度也比普通web要高出许多,不管我们是在在开发或者是学习过程中,往往需要耗费大量的时间去查阅资料,和研究官方案例, 而大多二三维的包(openla ...

  8. 代码随想录算法训练营Day6 哈希表|242.有效的字母异位词 349.两个数组的交集 202.快乐数 1.两数之和

    哈希表理论基础 哈希表 哈希表(Hash tble)是根据关键码的值而进行直接访问的数据结构. 哈希表简单来说是数组,当我们遇到了要快速判断一个元素是否出现在集合里的时候,就要考虑哈希表. 哈希表中的 ...

  9. odoo开发教程五:高级视图

    树视图 tree视图表现出来是列表视图,列表中一行一纪录.可以根据每行纪录的某字段值不同而把每行以不同样式显示. decoration-{样式}="条件" 样式主要有: bf(fo ...

  10. 可视化生信分析利器 Galaxy 之 Docker 部署

    Galaxy Project(https://galaxyproject.org/)是很多年前在云计算背景下诞生的一个生物信息学可视化分析开源项目, 是目前生物医学研究领域最受欢迎的在线生物信息分析工 ...