跳转至

rack: 一个简单且可扩展的 HTTP 服务器框架,用于 nginx-module-lua

安装

如果您尚未设置 RPM 仓库订阅,请 注册。然后您可以继续以下步骤。

CentOS/RHEL 7 或 Amazon Linux 2

yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install lua-resty-rack

CentOS/RHEL 8+、Fedora Linux、Amazon Linux 2023

dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install lua5.1-resty-rack

要在 NGINX 中使用此 Lua 库,请确保已安装 nginx-module-lua

本文档描述了 lua-resty-rack v0.3,于 2012 年 7 月 12 日发布。


这是一个简单且可扩展的 HTTP 服务器框架,用于 OpenResty,提供了一种干净的方法将 Lua HTTP 应用程序(“resty”模块)加载到 Nginx 中。

受到 RackConnect 的启发,lua-resty-rack 允许您将应用程序作为中间件的一部分加载,与其他中间件一起使用。您的应用程序可以选择忽略当前请求、以某种方式修改请求或响应并传递给其他中间件,或者通过生成响应来承担请求的责任。

使用中间件

要为给定的 location 安装中间件,您只需按希望模块运行的顺序调用 rack.use(middleware),然后最后调用 rack.run()

server {
    location / {
        content_by_lua '
            local rack = require "resty.rack"

            rack.use(rack.middleware.method_override)
            rack.use(require "my.module")
            rack.run()
        ';
    }
}

rack.use(...)

语法: rack.use(route?, middleware, options?)

如果提供了 route,则中间件仅在请求的路径中包含 route 时运行。如果中间件需要选择任何选项,可以作为第三个参数提供,通常是一个表。

rack.use('/some/path', app, { foo = 'bar' })

对于简单情况,middleware 参数也可以是一个简单的函数,而不是 Lua 模块。您的函数应接受 reqresnext 作为参数。有关编写中间件的说明,请参见下文。

rack.use(function(req, res, next)
    res.header["X-Homer"] = "Doh!"
    next()
end)

rack.run()

语法: rack.run()

按顺序运行每个中间件,直到其中一个选择处理响应。因此,调用 rack.use() 的顺序很重要。

捆绑的中间件

method_override

rack.use(rack.middleware.method_override, { key = "METHOD" })

使用查询字符串值覆盖 HTTP 方法。默认参数名称为 "_method",但可以通过设置选项 "key" 来覆盖。

read_request_headers

rack.use(rack.middleware.read_request_headers, { max = 50 })

仅在您希望遍历 HTTP 请求头时需要。它们将在通过 req.header 访问时懒加载。

您可以指定要读取的请求头的数量限制,默认为 100。通过指定最大值为 0 可以移除限制,但 强烈不建议

read_body

rack.use(rack.middleware.read_body)

显式读取请求体(原始)。

创建中间件

中间件应用程序只是使用 HTTP 请求和响应作为最小接口的 Lua 模块。它们必须实现函数 call(options),该函数返回一个函数。参数 (req, res, next) 定义如下。

module("resty.rack.method_override", package.seeall)

_VERSION = '0.01'

function call(options)
    return function(req, res, next)
        local key = options['key'] or '_method'
        req.method = string.upper(req.args[key] or req.method)
        next()
    end
end

API

req.method

HTTP 方法,例如 GET,由 ngx.var.request_method 设置。

req.scheme

协议方案 http|https,由 ngx.var.scheme 设置。

req.uri

例如 /my/uri,由 ngx.var.uri 设置。

req.host

主机名,例如 example.com,由 ngx.var.host 设置。

req.query

查询字符串,例如 var1=1&var2=2,由 ngx.var.query_string 设置。

req.args

查询参数,以 table 形式设置,来自 ngx.req.get_uri_args()

req.header

一个包含请求头的表。键不区分大小写,并且可以选择用下划线代替连字符。例如:

req.header["X-Foo"] = "bar"
res.body = req.header.x_foo
    --> "bar"

HTTP 请求头是按需读取的,因此除非使用 read_request_headers 中间件,否则无法遍历。

req.body

在使用 read_body 中间件读取之前为空字符串。

res.status

要返回的 HTTP 状态码。常见状态的 常量已定义

res.header

一个响应头的表,可以不区分大小写地匹配,并且可以选择用下划线代替连字符(见上面的 req.header)。

res.body

响应体。

next

此参数是提供给中间件的一个函数,可以调用它以指示 rack 应该尝试下一个中间件。如果您的应用程序不打算将响应发送到浏览器,则必须调用此函数。然而,如果您的应用程序负责响应,则只需返回而不调用 next。

示例仅修改请求。

function call(options)
    return function(req, res, next)
        local key = options['key'] or '_method'
        req.method = string.upper(req.args[key] or req.method)
        next()
    end
end

示例生成响应。

function call(options)
    return function(req, res)
        res.status = 200
        res.header['Content-Type'] = "text/plain"
        res.body = "Hello World"
    end
end

增强 req / res

您的应用程序可以在适当的情况下向 req / res 表添加新字段或甚至函数,这些字段或函数可以被其他中间件使用,只要依赖关系清晰(并且按正确的顺序调用 use())。

GitHub

您可以在 nginx-module-rack 的 GitHub 仓库 中找到有关此模块的其他配置提示和文档。