脚本编写§
NGINX Unit 的 控制 API 支持 JavaScript 表达式,包括函数调用,形式为 模板文字,用 NGINX JavaScript ( njs ) 编写。它们可与这些 配置 选项一起使用
response_headers 值在 操作 中,用于处理响应头字段。
location 在 return 操作 中,用于启用 HTTP 重定向。
format 在 访问日志 中,用于自定义 Unit 的日志输出。
if 在 访问日志 中,用于动态地打开和关闭 Unit 的日志记录。
作为其 JavaScript 引擎,Unit 使用 njs 库,该库与 官方软件包 一起提供,或 从源代码构建。
警告
Unit 1.32.0 及更高版本需要 njs 0.8.2。
一些请求属性以 njs 对象或标量形式公开
名称 |
类型 |
说明 |
---|---|---|
参数 |
对象 |
查询字符串参数;颜色=蓝色是args.Color;可与Object.keys()一起使用。 |
cookies |
对象 |
请求 cookie;authID cookie 是cookies.authID;可与Object.keys()一起使用。 |
headers |
对象 |
请求标头字段;Accept 是headers.Accept,Content-Encoding 是headers[‘Content-Encoding’](连字符需要一个数组属性访问器);可与Object.keys()一起使用。 |
host |
标量 |
Host 标头字段,转换为小写并通过删除端口号和尾随句点(如果有)进行规范化。 |
remoteAddr |
标量 |
请求的远程 IP 地址。 |
uri |
标量 |
|
vars |
对象 |
Unit 变量;vars.method 是$method。 |
模板文字用反引号括起来。要在字符串中使用文字反引号,请转义它:\\`(转义反斜杠是JSON 要求)。njs 片段应括在大括号中:${…}。
接下来,您可以上传并使用自定义 JavaScript 模块和您的配置。考虑这个http.js脚本,它通过Authorization标头字段值区分请求
var http = {}
http.route = function(headers) {
var authorization = headers['Authorization'];
if (authorization) {
var user = atob(authorization.split(' ')[1]);
if (String(user) == 'user:password') {
return 'accept';
}
return 'forbidden';
}
return 'unauthorized';
}
export default http
要将其上传到 Unit 的 JavaScript 模块存储中,作为http
# curl -X PUT --data-binary @http.js --unix-socket /path/to/control.unit.sock \
https://127.0.0.1/js_modules/http
Unit 默认情况下不会启用上传的模块,因此将模块的名称添加到settings/js_module
# curl -X PUT -d '"http"' /path/to/control.unit.sock \
https://127.0.0.1/config/settings/js_module
注意
请注意,js_module选项可以是字符串或数组;选择适当的 HTTP 方法。
现在,http.route()函数可与 Unit 提供的标头字段值一起使用
{
"routes": {
"entry": [
{
"action": {
"pass": "`routes/${http.route(headers)}`"
}
}
],
"unauthorized": [
{
"action": {
"return": 401
}
}
],
"forbidden": [
{
"action": {
"return": 403
}
}
],
"accept": [
{
"action": {
"return": 204
}
}
]
}
}
示例§
此示例添加了简单的路由逻辑,该逻辑从User-Agent标头字段中提取代理名称,以拒绝由curl发出的请求
"routes": {
"parse": [
{
"action": {
"pass": "`routes/${ headers['User-Agent'].split('/')[0] == 'curl' ? 'reject' : 'default' }`"
}
}
],
"reject": [
{
"action": {
"return": 400
}
}
],
"default": [
{
"action": {
"return": 204
}
}
]
}
此示例使用一系列转换来记录请求的日期、IP、URI 及其所有标头
{
"path": "/var/log/unit/access_kv.log",
"format": "`@timestamp=${new Date().toISOString()} ip=${remoteAddr} uri=${uri} ${Object.keys(headers).map(k => 'req.' + k + '=\"' + headers[k] + '\"').join(' ')}\n`"
}
下一个示例将根据 HTTP 请求方法添加Cache-Control标头
{
"action": {
"pass": "applications/my_app",
"response_headers": {
"Cache-Control": "`${vars.method.startsWith('P') ? 'no-cache' : 'max-age=3600'}`"
}
}
}
如需进一步参考,请参阅njs 文档。