ngx.req.get_body_data() 读请求体,会偶尔出现读取不到直接返回 nil 的情况。

如果请求体尚未被读取,请先调用 ngx.req.read_body (或打开 lua_need_request_body 选项强制本模块读取请求体,此方法不推荐)。

如果请求体已经被存入临时文件,请使用 ngx.req.get_body_file 函数代替。

如需要强制在内存中保存请求体,请设置 client_body_buffer_size 和 client_max_body_size 为同样大小。

1、ngx.req.read_body

语法: ngx.req.read_body()
作用域: rewrite_by_lua*, access_by_lua*, content_by_lua*

开启获取请求中的body内容。

结论:

1、lua_need_request_body 开启后,该函数不执行。
2、如果在该函数前执行 ngx.req.discard_body(),该函数不执行。

2、ngx.req.discard_body

语法: ngx.req.discard_body()
作用域: rewrite_by_lua*, access_by_lua*, content_by_lua*

禁止获取请求中的body内容。

3、ngx.req.get_body_data

语法: data = ngx.req.get_body_data()
作用域: rewrite_by_lua*, access_by_lua*, content_by_lua*, log_by_lua*

获取请求body的内容,返回字符串。

注意:如果使用 ngx.req.get_post_args(),则返回一个lua table。

以下三种情况返回 nil

  1. 未使用 ngx.req.read_body 读取请求 body,或未打开lua_need_request_body 。
  2. 请求 body 的内容已经写入临时文件;此时使用 ngx.req.get_body_file 获取,或设置 client_body_buffer_size  client_max_body_size同等大小,来避免请求body写入临时文件。
  3. 请求体的内容为空。

4、ngx.req.get_body_file

语法: file_name = ngx.req.get_body_file()
作用域: rewrite_by_lua*, access_by_lua*, content_by_lua*

返回请求body写入的临时文件。例如:返回

/usr/local/openresty/nginx/client_body_temp/0000000019

注意以下2种情况会写入临时文件:

1、请求body的长度超过nginx.conf定义的 client_body_buffer_size 大小。
2、nginx.conf开启 client_body_in_file_only on (请求body始终写入临时文件)

5、ngx.req.set_body_data

语法: ngx.req.set_body_data(data)
作用域: rewrite_by_lua*, access_by_lua*, content_by_lua*

设置请求body的内容,一般用于转发请求到子请求。

注意:

1、在使用该方法时,必需确保当前请求已经使用 ngx.req.read_body() 或者 lua_need_read_body on,否则,在使用该方法会报 500 错误。

例如:

ngx.req.read_body() --如果该行省略,将直接报错。
ngx.req.set_body_data("abc")
ngx.exec("/app/detail")

6、ngx.req.set_body_file

语法: ngx.req.set_body_file(file_name, auto_clean?)
作用域: rewrite_by_lua*, access_by_lua*, content_by_lua*

7、ngx.req.init_body

语法: ngx.req.init_body(buffer_size?)
作用域: set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*

8、ngx.req.append_body

语法: ngx.req.append_body(data_chunk)
作用域: set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*

9、ngx.req.finish_body

语法: ngx.req.finish_body()
作用域: set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*

Link: http://www.hangdaowangluo.com/archives/2746

OpenResty基Nginx,把Web服务的整个生命周期和请求处理流程分为如下几个阶段:

处理阶段

Web服务的生命周期分为三个阶段:

  • initing : 服务启动,通常是读取配置文件,初始化内部数据结构;
  • running : 服务运行,接收客户端的请求,返回响应结果;
  • exiting : 服务停止,做一些必要的清理工作。

OpenResty关注的是initing和running两个阶段,并做了更细致的划分。

initing阶段在OpenResty里分为三个子阶段:

  • configuration : 读取配置文件,解析配置指令,设置运行参数;
  • master-initing : 配置文件解析完毕,master进程初始化公用数据;
  • worker-initing : worker进程的初始化。

在running阶段,OpenResty会按照如下流程来处理:

  • ssl : SSL / TLS 安全通信和验证
  • preread : 在正式处理之前“预读”数据,接收 HTTP 请求头
  • rewrite : 检查、改写 URI,实现跳转/重定向
  • access : 访问权限控制:
  • content : 产生响应内容
  • filter : 对 content 阶段产生的内容进行过滤加工处理
  • log : 请求处理完毕,记录日志,或者其他的收尾工作

关系图如下:

OpenResty处理阶段

执行程序

对应于上述处理阶段,OpenResty提供了一系列的”xxx_by_lua”的指令:

  • init_by_lua : master-initing阶段,初始化全局配置或模块
  • init_work_by_lua : worker-initing阶段, 初始化进程专用功能
  • ssl_session_fetch_by_lua : ssl阶段,读取session
  • ssl_certificate_by_lua : ssl阶段,在“握手”时设置安全证书
  • ssl_session_store_by_lua : ssl阶段,存储session
  • set_by_lua : rewrite阶段,改写Nginx变量
  • rewrite_by_lua : rewrite阶段,改写URI,实现跳转或重定向
  • access_by_lua : access阶段,访问控制或限速
  • content_by_lua : content阶段,产生响应内容
  • balancer_by_lua : content阶段,反向代理时选择后端服务器
  • header_filter_by_lua : filter阶段,加工处理响应头
  • body_filter_by_lua : filter阶段,加工处理响应体
  • log_by_lua : log阶段,记录日志或其他收尾工作

流程图

参考文献:

  • 罗剑锋 《OpenResty完全开发指南-构建百万级别并发的Web应用》 电子工业出版社 ISBN 978-7-121-34896-9