Nginx Lua编程-简单案例 nginx+lua
liebian365 2024-11-14 18:02 23 浏览 0 评论
案例一:Lua脚本获取URL中的参数
- 通过ngx_lua模块的内置方法ngx.req.get_uri_args()获取URL后面的请求参数
- 通过Nginx内置变量$arg_PARAMETER获取请求参数的值
#ngx.req.get_uri_args()方法Lua脚本获取URL中的参数
location /add_params_demo {
set_by_lua $sum '
local args = ngx.req.get_uri_args();
local a = args["a"];
local b = args["b"];
return a + b;
';
echo "$arg_a + $arg_b = $sum";
}
#ngx.arg获取请求参数值
location /add_params_demo_2 {
set_by_lua $sum '
local a = tonumber(ngx.arg[1]);
local b = tonumber(ngx.arg[2]);
return a + b;
' $arg_a $arg_b;
echo "$arg_a + $arg_b = $sum";
}
Nginx Lua的内置方法
Nginx Lua的内置方法 | 方法说明 |
ngx.log(log_lever, ...) | 按照log_level设定的等级输出到error.log日志文件 |
Pring(...) | 输出到error.log日志文件,等价于ngx.log(ngx.NOTICE, ...) |
ngx.print(...) | 输出响应内容到客户端 |
ngx.say(...) | 输出响应内容到客户端,自动添加'\n'换行符 |
ngx.exit(status) | 如果status>=200,此方法就会结束当前请求处理,并且返回status状态码到客户端;若status==0,此方法就会结束请求处理的当前阶段,进入下一个请求处理阶段 |
ngx.send_header() | 显示地发送响应头 |
ngx.exec(uri, args?) | 内跳转URI地址 |
ngx.redirect(uri,status?) | 外部跳转URI地址 |
ngx.location.capture(uri, options?) | 发起一个子请求 |
ngx.location.capture_multi(uris) | 发起多个子请求。参数uris是一个table,格式为{{uri, options?},{uri, options?},...} |
ngx.is_subrequest() | 当前请求是不是子请求 |
ngx.sleep(seconds) | 无阻塞休眠秒数(定时器实现) |
ngx.get_phase() | 获取当前Lua脚本的执行阶段名称。 |
ngx.req.start_time() | 请求开始时间 |
ngx.req.http_version() | 请求的HTTP版本号 |
ngx.req.raw_header | 获取原始的请求头(包括请求行) |
ngx.req.get_method() | 获取请求方法 |
ngx.req.set_method(method) | 覆盖当前的请求方法 |
ngx.req.get_uri_args() | 获取请求参数 |
ngx.req.get_post_args() | 获取post请求内容,调用此方法之前必须调用ngx.req.read_body()来读取body体 |
ngx.req.get_headers() | 默认获取前100个请求头 |
ngx.resp.get_headers() | 获取响应头 |
ngx.req.read_body() | 获取当前请求的请求体 |
ngx.req.set_header(name, value) | 为当前请求设置请求头 |
ngx.req.clear_header(name) | 为当前请求删除名称为name的请求头 |
ngx.req.set_body_data(data) | 设置当前请求的请求体为data |
ngx.req.init_body(buffer_size?) | 为当前请求创建一个空的请求体。如果buffer_size参数不为空,那么新请求体的大小为buffer_size。若为空,那么新请求体的大小为client_body_buffer_size指令设置的请求体大小。若未设置,默认大小为8KB(32位系统、x86-64)或者16KB(其他的64位系统) |
ngx.escape_uri(str) | 对uri字符串进行编码 |
ngx.unescape_uri(str) | 对编码过的URL字符串进行解码 |
ngx.encode_args(table) | 将Lua table编码为一个参数字符串 |
ngx.decode_args(str) | 将参数字符串解码为一个Lua table |
ngx.encode_base64(str) | 将字符串str编码成base64摘要 |
ngx.decode_base64(str) | 将base64摘要解码成原始字符串 |
ngx.hmac_sha1(secret, str) | 将字符串str编码成二进制格式的hmac_sha1,并使用secret进行加密 |
ngx.md5(str) | 将字符串str编码成十六进制MD5摘要 |
ngx.md5_bin(str) | 将字符串str编码成二进制的MD5摘要 |
ngx.quote_sql_str(str) | SQL语句转译,按照MySQL的格式进行转义 |
ngx.today() | 获取当前日期 |
ngx.time() | 获取UNIX时间戳 |
ngx.now() | 获取当前时间 |
ngx.update_time() | 刷新时间后再返回 |
ngx.localtime() | 获取yyyy-mm-dd hh:mm:ss格式的本地时间 |
ngx.cookie_time() | 获取可用于cookie值的时间 |
ngx.http_time() | 获取可用于HTTP头的时间 |
ngx.parse_http_time() | 解析HTTP头的时间 |
ngx.config.nginx_version() | 获取Nginx版本号 |
ngx.config.ngx_lua_version() | 获取ngx_lua模块版本号 |
ngx.worker.pid() | 获取当前Worker进程的pid |
案例二:通过ngx.header设置HTTP响应头
ngx_lua模块可以通过内置变量ngx.header来访问和设置HTTP响应头字段,ngx.header的类型为table,可以通过ngx.header.HEADER形式应用某个响应头。
例如:使用ngx.header.set_cookie变量设置响应头set-cookie的值,使用table类型的对象可以一次设置多个set-cookie值。
#模拟上游服务
location /header_demo {
content_by_lua_block {
ngx.header["header1"] = "value1";
ngx.header.header2 = 2;
ngx.header.set_cookie = {'Foo=bar; test=ok; path=/','age=18; path=/'};
ngx.say("演示程序: ngx.header的使用");
}
}
#模拟网关反向代理
location /header_filter_demo {
proxy_pass http://127.0.0.1/header_demo;
header_filter_by_lua_block {
local cookies = ngx.header.set_cookie;
if cookies then
if type(cookies) == "table" then
local cookie = {}
for k, v in pairs(cookies) do
cookie[k]= v..";Secure;httponly"
end
ngx.header.set_cookie = cookie
else
ngx.header.set_cookie = cookies..";Secure;httponly"
end
end
}
}
响应结果如下
Cookie是通过请求的set-cookie响应头来保存的,HTTP响应内容中可以包含多个set-cookie响应头,一个set-cookie响应头的值通常为一个字符串。该字符串大致包含如下Cookie信息或属性
- Cookie名称:只能使用可以用于URL中的字符,一般为字母和数字,不能包含特殊字符,否则需要转码。
- Cookie值: 同Cookie名称。
- expires: Cookie过期日期。
- path: Cookie的访问路径。此属性设置指定路径下的页面才可以访问该Cookie。访问路径的值一般设为“/”。
- domain: Cookie的访问域名。此属性设置指定域名下的页面才可以访问该Cookie。
- Secure: Cookie的安全属性,此属性设置该Cookie是否只能通过HTTPS协议访问。只有值,没有名称。
- HttpOnly: 如果设置了该属性,那么通过程序将无法读取到Cookie信息。只有值,没有名称。
当设置了HttpOnly属性时,通过脚本将无法获取到Cookie信息,主要用于防止XSS攻击。
而一旦设置了Secure属性,前后端之间只能在HTTPS协议通信的情况下,浏览器才能访问Cookie,使用HTTP协议时,浏览器无法获取Cookie信息,同样是对Cookie信息的保护。通常都是在内网环境继续使用HTTP通信协议,然后通过Nginx网关完成外部HTTPS协议到内部HTTP协议的转换。此时,Nginx外部网关可以对Cookie属性进行修改,增加Secure安全属性。
案例三:Lua访问Nginx变量
无论是Nginx内部变量还是自定义变量,都可以在Lua代码中通过ngx.var进行访问。
#通过ngx.var访问Nginx变量
location /lua_var_demo {
#自定义Nginx变量,名为hello,值为world
set $hello world;
content_by_lua_block {
local basic = require("conf.luaScript.module.common.basic");
--定义一个Lua table,暂存需要输出的Nginx内置变量
local vars = {};
vars.remote_addr = ngx.var.remote_addr;
vars.request_uri = ngx.var.request_uri;
vars.query_string = ngx.var.query_string;
vars.uri = ngx.var.uri;
vars.nginx_version = ngx.var.nginx_version;
vars.server_protocol = ngx.var.server_protocol;
vars.request_method = ngx.var.request_method;
vars.request_filename = ngx.var.request_filename;
vars.document_root = ngx.var.document_root;
vars.body_bytes_sent = ngx.var.body_bytes_sent;
vars.binary_remote_addr = ngx.var.binary_remote_addr;
vars.args = ngx.var.args;
--通过内置变量访问请求参数
vars.foo = ngx.var.arg_foo;
ngx.say("演示程序: 将内置变量返回给客户端<br>");
--使用自定义函数将Lua table转换成字符串,然后输出
local str = basic.tableToStr(vars, ",<br>");
ngx.say(str);
ngx.say("<br>演示程序: 将普通变量返回给客户端<br>");
--访问自定义Nginx变量hello
local hello = ngx.var.hello;
ngx.say("hello = "..hello);
}
}
重启OpenResty后,浏览器访问http://localhost/lua_var_demo
案例四:Lua访问请求上下文变量
Nginx执行Lua脚本涉及很多阶段,每个阶段都可以嵌入不同的Lua脚本,不同阶段的Lua脚本可以通过ngx.ctx进行上下文变量共享。ngx.ctx上下文实质上是一个Lua table,其生存周期与当前请求相同,当前请求不同阶段嵌入的Lua脚本都可以读写ngx.ctx表中的属性。这些属性可以在请求处理的rewrite、access、content等各处理阶段进行共享。另外,在ngx_lua模块中,每个请求,包括子请求,都有一份独立的ngx.ctx表。
演示示例
#Lua访问请求上下文变量
location /ctx_demo {
rewrite_by_lua_block {
-- 在上下文设置属性var1
ngx.ctx.var1 = 1;
}
access_by_lua_block {
-- 在上下文设置属性var2
ngx.ctx.var2 = 10;
}
content_by_lua_block {
local basic = require("conf.luaScript.module.common.basic");
-- 在上下文设置属性var3
ngx.ctx.var3 = 100;
-- 3个上下文求和
local result = ngx.ctx.var1 + ngx.ctx.var2 + ngx.ctx.var3;
ngx.say(result);
ngx.ctx.sum = result;
-- 使用自定义函数将Lua table转换成字符串
local str = basic.tableToStr(ngx.ctx, ",<br>");
ngx.say("<br>");
ngx.say(str);
}
}
运行结果:
下一篇介绍复杂案例!
相关推荐
- go语言也可以做gui,go-fltk让你做出c++级别的桌面应用
-
大家都知道go语言生态并没有什么好的gui开发框架,“能用”的一个手就能数的清,好用的就更是少之又少。今天为大家推荐一个go的gui库go-fltk。它是通过cgo调用了c++的fltk库,性能非常高...
- 旧电脑的首选系统:TinyCore!体积小+精简+速度极快,你敢安装吗
-
这几天老毛桃整理了几个微型Linux发行版,准备分享给大家。要知道可供我们日常使用的Linux发行版有很多,但其中的一些发行版经常会被大家忽视。其实这些微型Linux发行版是一种非常强大的创新:在一台...
- codeblocks和VS2019下的fltk使用中文
-
在fltk中用中文有点问题。英文是这样。中文就成这个样子了。我查了查资料,说用UTF-8编码就行了。edit->Fileencoding->UTF-8然后保存文件。看下下边的编码指示确...
- FLTK(Fast Light Toolkit)一个轻量级的跨平台Python GUI库
-
FLTK(FastLightToolkit)是一个轻量级的跨平台GUI库,特别适用于开发需要快速、高效且简单界面的应用程序。本文将介绍Python中的FLTK库,包括其特性、应用场景以及如何通过代...
- 中科院开源 RISC-V 处理器“香山”流片,已成功运行 Linux
-
IT之家1月29日消息,去年6月份,中科院大学教授、中科院计算所研究员包云岗,发布了开源高性能RISC-V处理器核心——香山。近日,包云岗在社交平台晒出图片,香山芯片已流片,回片后...
- Linux 5.13内核有望合并对苹果M1处理器支持的初步代码
-
预计Linux5.13将初步支持苹果SiliconM1处理器,不过完整的支持工作可能还需要几年时间才能完全完成。虽然Linux已经可以在苹果SiliconM1上运行,但这需要通过一系列的补丁才能...
- Ubuntu系统下COM口测试教程(ubuntu port)
-
1、在待测试的板上下载minicom,下载minicom有两种方法:方法一:在Ubuntu软件中心里面搜索下载方法二:按“Ctrl+Alt+T”打开终端,打开终端后输入“sudosu”回车;在下...
- 湖北嵌入式软件工程师培训怎么选,让自己脱颖而出
-
很多年轻人毕业即失业、面试总是不如意、薪酬不满意、在家躺平。“就业难”该如何应对,参加培训是否能改变自己的职业走向,在湖北,有哪些嵌入式软件工程师培训怎么选值得推荐?粤嵌科技在嵌入式培训领域有十几年经...
- 新阁上位机开发---10年工程师的Modbus总结
-
前言我算了一下,今年是我跟Modbus相识的第10年,从最开始的简单应用到协议了解,从协议开发到协议讲解,这个陪伴了10年的协议,它一直没变,变的只是我对它的理解和认识。我一直认为Modbus协议的存...
- 创建你的第一个可运行的嵌入式Linux系统-5
-
@ZHangZMo在MicrochipBuildroot中配置QT5选择Graphic配置文件增加QT5的配置修改根文件系统支持QT5修改output/target/etc/profile配置文件...
- 如何在Linux下给zigbee CC2530实现上位机
-
0、前言网友提问如下:粉丝提问项目框架汇总下这个网友的问题,其实就是实现一个网关程序,内容分为几块:下位机,通过串口与上位机相连;下位机要能够接收上位机下发的命令,并解析这些命令;下位机能够根据这些命...
- Python实现串口助手 - 03串口功能实现
-
串口调试助手是最核心的当然是串口数据收发与显示的功能,pzh-py-com借助的是pySerial库实现串口收发功能,今天痞子衡为大家介绍pySerial是如何在pzh-py-com发挥功能的。一、...
- 为什么选择UART(串口)作为调试接口,而不是I2C、SPI等其他接口
-
UART(通用异步收发传输器)通常被选作调试接口有以下几个原因:简单性:协议简单:UART的协议非常简单,只需设置波特率、数据位、停止位和校验位就可以进行通信。相比之下,I2C和SPI需要处理更多的通...
- 同一个类,不同代码,Qt 串口类QSerialPort 与各种外设通讯处理
-
串口通讯在各种外设通讯中是常见接口,因为各种嵌入式CPU中串口标配,工业控制中如果不够还通过各种串口芯片进行扩展。比如spi接口的W25Q128FV.对于软件而言,因为驱动接口固定,软件也相对好写,因...
- 嵌入式linux为什么可以通过PC上的串口去执行命令?
-
1、uboot(负责初始化基本硬bai件,如串口,网卡,usb口等,然du后引导系统zhi运行)2、linux系统(真正的操作系统)3、你的应用程序(基于操作系统的软件应用)当你开发板上电时,u...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- go语言也可以做gui,go-fltk让你做出c++级别的桌面应用
- 旧电脑的首选系统:TinyCore!体积小+精简+速度极快,你敢安装吗
- codeblocks和VS2019下的fltk使用中文
- FLTK(Fast Light Toolkit)一个轻量级的跨平台Python GUI库
- 中科院开源 RISC-V 处理器“香山”流片,已成功运行 Linux
- Linux 5.13内核有望合并对苹果M1处理器支持的初步代码
- Ubuntu系统下COM口测试教程(ubuntu port)
- 湖北嵌入式软件工程师培训怎么选,让自己脱颖而出
- 新阁上位机开发---10年工程师的Modbus总结
- 创建你的第一个可运行的嵌入式Linux系统-5
- 标签列表
-
- wireshark怎么抓包 (75)
- qt sleep (64)
- cs1.6指令代码大全 (55)
- factory-method (60)
- sqlite3_bind_blob (52)
- hibernate update (63)
- c++ base64 (70)
- nc 命令 (52)
- wm_close (51)
- epollin (51)
- sqlca.sqlcode (57)
- lua ipairs (60)
- tv_usec (64)
- 命令行进入文件夹 (53)
- postgresql array (57)
- statfs函数 (57)
- .project文件 (54)
- lua require (56)
- for_each (67)
- c#工厂模式 (57)
- wxsqlite3 (66)
- dmesg -c (58)
- fopen参数 (53)
- tar -zxvf -c (55)
- 速递查询 (52)