Перейти к содержанию

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

Чтобы использовать эту библиотеку Lua с NGINX, убедитесь, что nginx-module-lua установлен.

Этот документ описывает lua-resty-rack v0.3, выпущенный 12 июля 2012 года.


Простой и расширяемый фреймворк HTTP-сервера для OpenResty, предоставляющий чистый метод загрузки Lua HTTP приложений ("resty" модули) в Nginx.

Вдохновленный Rack и Connect, 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 находится в пути (ngx.var.uri). Если промежуточное ПО требует выбора каких-либо опций, их можно предоставить, обычно в виде таблицы, как третий параметр.

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

Для простых случаев параметр middleware также может быть простой функцией, а не модулем Lua. Ваша функция должна принимать req, res и next в качестве параметров. См. ниже инструкции по написанию промежуточного ПО.

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)

Явно читает тело запроса (в сыром виде).

Создание промежуточного ПО

Приложения промежуточного ПО - это просто модули Lua, которые используют HTTP-запрос и ответ в качестве минимального интерфейса. Они должны реализовать функцию 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

Вы можете найти дополнительные советы по конфигурации и документацию для этого модуля в репозитории GitHub для nginx-module-rack.