1. 引言
nginx的rewrite模块提供了set配置指令,能够声明一个新的变量,并且给这个变量进行赋值,它只能进行简单的赋值,仅此而已,不能进行数学或者字符串运算。
而ngingx-let-module为我们提供了更加丰富的动态变量运算能力,它允许我们在赋值的时候进行数学加减乘除运算,和常见的字符串运算,这样在进行nginx配置的时候方便我们更加灵活地实现一些特殊的场景需求。
2. 指令介绍
nginx-let-module提供了一个let指令,可以在http/server/location块上下文中进行配置。格式如下:
let $Variable_Name Expression;
其中Variable_Name就是要定义的变量名字,而Expression则是运算的表达式。例如:
let $value ( $uid + 0x12 ) * $offset - 100 ;
let $remainer $number % 100 ;
let $welcome "Hi, " . $user . ", you have " . $num . " data items";
需要注意的是,写表达式的时候,需要在各个token之间添加空格。譬如:
let $value (1+2); # ERROR!
let $value ( 1 + 2 ); # OK
let $value 1 + (2 * $uid); # ERROR!
let $value 1 + ( 2 * $uid ); # OK
3. 支持的特性
-
数学运算符号:
+ - * / % -
按位运算符号:
| & -
字符串运算符号:
. (字符串连接)
-
括号:
-
内置函数:
md4 md5 sha1 sha224 sha256 sha384 sha512 ripemd160 (常用各种字符串哈希算法)
length substr (求字符串长度和字符串子串)
rand (随机值)
min max (求两个数字中的最小值和最大值)
譬如,下面计算一个字符串的md5哈希值:
location / {
let $x "Hello" . " " . "World";
let $y md5( $x );
echo $x--md5=$y;
}
然后进行curl请求,输出如下:
curl "http://127.0.0.1:8888/"
Hello World--md5=b10a8db164e0754105b7a99be72e3fe5
再如,生成一个随机值变量,并且对他求字符串长度:
location / {
let $z rand( );
let $zl length( $z );
echo $z length=$zl;
}
curl "http://127.0.0.1:8888/"
1802202033 length=10
4. 编译
从github上clone该模块:
git clone https://github.com/arut/nginx-let-module
并假设放在nginx源码目录的modules子目录中。
然后进行编译:
./configure --add-module=./modules/nginx-let-module
make
在编译的时候可能碰到下面的错误:
./modules/nginx-let-module/ngx_http_let_module.c:130:1: error: ‘MD4’ is deprecated: Since OpenSSL 3.0 [-Werror=deprecated-declarations]
130 | NGX_LET_HASHFUNC(MD4, md4, 16)
| ^~~~~~~~~~~~~~~~
In file included from ./modules/nginx-let-module/ngx_http_let_module.c:38:
/usr/include/openssl/md4.h:53:38: note: declared here
53 | OSSL_DEPRECATEDIN_3_0 unsigned char *MD4(const unsigned char *d, size_t n,
| ^~~
./modules/nginx-let-module/ngx_http_let_module.c: In function ‘ngx_let_func_md5’:
./modules/nginx-let-module/ngx_http_let_module.c:131:1: error: ‘MD5’ is deprecated: Since OpenSSL 3.0 [-Werror=deprecated-declarations]
可以通过在auto/cc/gcc文件中添加CFLAGS="$CFLAGS -Wno-deprecated-declarations"来解决。