1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/mirrors-lua-nginx-module

В этом репозитории не указан файл с открытой лицензией (LICENSE). При использовании обратитесь к конкретному описанию проекта и его зависимостям в коде.
Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.markdown

Имя

ngx_http_lua_module — Встраивает мощь языка Lua в сервера HTTP Nginx.

Этот модуль является основным компонентом OpenResty. Если вы используете этот модуль, то фактически используете OpenResty :)

Этот модуль не распространяется вместе с исходным кодом Nginx. См. инструкции по установке.

Содержание ==========* Имя

Версия

Этот документ описывает ngx_lua v0.10.25, который был выпущен 19 июня 2023 года.

Видео

Вы можете подписаться на наш официальный канал YouTube, OpenResty.

Назад к Оглавлению

Краткое описание

 lua_package_path '/foo/bar/?.lua;/blah/?.lua;;';

 # Установка путей поиска для внешних библиотек Lua, написанных на C (можно использовать ';;'):
 lua_package_cpath '/bar/baz/?.so;/blah/blah/?.so;;';

 server {
     location /lua_content {
         # MIME-тип определяется по умолчанию:
         default_type 'text/plain';

         content_by_lua_block {
             ngx.say('Привет,мир!')
         }
     }

     location /nginx_var {
         # MIME-тип определяется по умолчанию:
         default_type 'text/plain';

         # Попробуйте обратиться к /nginx_var?a=привет,мир
         content_by_lua_block {
             ngx.say(ngx.var.arg_a)
         }
     }
     
     location = /request_body {
         client_max_body_size 50k;
         client_body_buffer_size 50k;

         content_by_lua_block {
             ngx.req.read_body()  -- явно читаем тело запроса
             local data = ngx.req.get_body_data()
             if data then
                 ngx.say("тело данных:")
                 ngx.print(data)
                 return
             end

             -- тело может быть буферизировано в временном файле:
             local file = ngx.req.get_body_file()
             if file then
                 ngx.say("тело находится в файле ", file)
             else
                 ngx.say("тело не найдено")
             end
         }
     }

     # Прозрачное асинхронное ввод-вывод в Lua через подзапросы
     # (лучший способ использовать cosockets)
     location = /lua {
         # MIME тип определяется по default_type:
         default_type 'text/plain';

         content_by_lua_block {
             local res = ngx.location.capture("/some_other_location")
             if res then
                 ngx.say("статус: ", res.status)
                 ngx.say("тело:")
                 ngx.print(res.body)
             end
         }
     }     location = /foo {
         rewrite_by_lua_block {
             res = ngx.location.capture("/memc",
                 { args = { cmd = "incr", key = ngx.var.uri } }
             )
         }

         proxy_pass http://blah.blah.com;
     }

     location = /mixed {
         rewrite_by_lua_file /path/to/rewrite.lua;
         access_by_lua_file /path/to/access.lua;
         content_by_lua_file /path/to/content.lua;
     }

     # использование переменной nginx в пути кода
     # ВНИМАНИЕ: содержимое в переменной nginx должно быть тщательно отфильтровано,
     # иначе будет существовать большая угроза безопасности!
     location ~ ^/app/([-_a-zA-Z0-9/]+) {
         set $path $1;
         content_by_lua_file /path/to/lua/app/root/$path.lua;
     }

     location / {
        client_max_body_size 100k;
        client_body_buffer_size 100k;

        access_by_lua_block {
            -- проверяем, что адрес клиента находится в черном списке
            if ngx.var.remote_addr == "132.5.72.3" then
                ngx.exit(ngx.HTTP_FORBIDDEN)
            end

            -- проверяем, содержит ли URI плохие слова
            if ngx.var.uri and
                   string.match(ngx.var.request_body, "evil")
            then
                return ngx.redirect("/terms_of_use.html")
            end
        }
     }            -- тесты пройдены
        }

        # параметры proxy_pass/fastcgi_pass и т.д.
     }
 }

Описание

Этот модуль интегрирует LuaJIT 2.0/2.1 в Nginx. Это основной компонент OpenResty. Если вы используете этот модуль, то фактически используете OpenResty.

С версии v0.10.16 этого модуля стандартный интерпретатор Lua (также известный как "PUC-Rio Lua") больше не поддерживается. В этом документе используются термины "Lua" и "LuaJIT", которые относятся к интерпретатору LuaJIT.Используя подзапросы Nginx, этот модуль позволяет интегрировать мощные Lua потоки (известные как Lua "корутины") в модель событий Nginx.

В отличие от mod_lua Apache и mod_magnet Lighttpd, Lua-код, выполненный с помощью этого модуля, может быть 100% неблокирующим для сетевого трафика, если используется API Nginx для Lua, предоставляемый этим модулем, для обработки запросов к внешним службам, таким как MySQL, PostgreSQL, Memcached, Redis или внешним HTTP-веб-службам.

Следующие библиотеки Lua и модули Nginx могут использоваться с этим модулем:* lua-resty-memcached

Загруженные модули Lua сохраняются на уровне рабочего процесса Nginx, что приводит к небольшому потреблению памяти даже при высоких нагрузках.

Этот модуль подключается к "http" подсистеме Nginx, поэтому он может использовать только протоколы связи HTTP-семейства (HTTP 0.9/1.0/1.1/2.0, WebSockets и т.д.). Если вам нужно выполнять общие TCP-соединения с клиентами, то следует использовать модуль ngx_stream_lua, который предлагает совместимый API Lua.

Назад к Оглавлению

Примерные применения

Просто некоторые из них:* Обработка и объединение выходных данных различных модулей Nginx (прокси, drizzle, postgres, redis, memcached и т.д.) на Lua,

  • выполнение произвольно сложных проверок доступа и безопасности на Lua перед тем, как запросы достигнут серверных модулей,
  • манипуляция ответными заголовками произвольным образом (через Lua),
  • получение информации о серверах из внешних хранилищ (например, redis, memcached, mysql, postgresql) и использование этой информации для выбора серверных модулей в реальном времени,
  • создание произвольно сложных веб-приложений в обработчике контента с синхронным, но всё ещё асинхронным доступом к серверным базам данных и другим хранилищам,
  • выполнение очень сложной маршрутизации URL на Lua на этапе перезаписи,
  • использование Lua для реализации продвинутых кэшировочных механизмов для подзапросов Nginx и произвольных местоположений.Возможностей множество, поскольку модуль позволяет объединять различные элементы внутри Nginx и демонстрировать мощь языка Lua для пользователя. Модуль предоставляет полную гибкость скриптов, предлагая уровни производительности, сравнимые с нативными программами на языке C, как в плане времени работы процессора, так и в плане потребления памяти благодаря LuaJIT 2.x. Другие реализации скриптовых языков обычно испытывают трудности с достижением такого уровня производительности.

Назад к оглавлению

Совместимость с Nginx

Последняя версия этого модуля совместима со следующими версиями Nginx:

  • 1.25.x (последняя проверенная: 1.25.1)
  • 1.21.x (последняя проверенная: 1.21.4)
  • 1.19.x (последняя проверенная: 1.19.3)
  • 1.17.x (последняя проверенная: 1.17.8)
  • 1.15.x (последняя проверенная: 1.15.8)
  • 1.14.x
  • 1.13.x (последняя проверенная: 1.13.6)
  • 1.12.x
  • 1.11.x (последняя проверенная: 1.11.2)
  • 1.10.x
  • 1.9.x (последняя проверенная: 1.9.15)
  • 1.8.x
  • 1.7.x (последняя проверенная: 1.7.10)
  • 1.6.x

Конфигурации Nginx старше 1.6.0 (исключительно) не поддерживаются.

Назад к оглавлению

Установка

Рекомендуется использовать релизы OpenResty, которые включают Nginx, ngx_lua (этот модуль), LuaJIT, а также другие мощные дополнительные модули Nginx и библиотеки Lua.

Не рекомендуется компилировать этот модуль самостоятельно, так как это может быть сложной задачей.Обратите внимание, что официальные выпуски Nginx, LuaJIT и OpenSSL имеют различные ограничения и долгосрочные ошибки, которые могут привести к отключению некоторых функций этого модуля, некорректной работе или снижению производительности. Официальные релизы OpenResty рекомендуются, так как они включают оптимизированную вилку LuaJIT 2.1 от OpenResty и патчи для Nginx/OpenSSL.

В качестве альтернативы ngx_lua можно вручную скомпилировать в Nginx:

  1. LuaJIT можно скачать с последнего релиза вилки LuaJIT от OpenResty. Официальные релизы LuaJIT 2.x также поддерживаются, хотя производительность будет значительно ниже по причинам, подробно описанным выше.
  2. Скачайте последнюю версию модуля ngx_devel_kit (NDK) ЗДЕСЬ.
  3. Скачайте последнюю версию ngx_lua ЗДЕСЬ.
  4. Скачайте последнюю поддерживаемую версию Nginx ЗДЕСЬ (См. Совместимость с Nginx).
  5. Скачайте последнюю версию lua-resty-core ЗДЕСЬ.
  6. Скачайте последнюю версию lua-resty-lrucache ЗДЕСЬ.

Соберите исходники с этим модулем:

wget 'https://openresty.org/download/nginx-1.19.3.tar.gz'
tar -xzvf nginx-1.19.3.tar.gz
cd nginx-1.19.3/

# сообщите системе сборки Nginx, где находятся библиотеки LuaJIT 2.0:
export LUAJIT_LIB=/путь/к/luajit/lib
export LUAJIT_INC=/путь/к/luajit/include/luajit-2.0
``` # Укажите системе сборки Nginx, где находятся библиотеки LuaJIT 2.1:
 export LUAJIT_LIB=/путь/к/luajit/lib
 export LUAJIT_INC=/путь/к/luajit/include/luajit-2.1

 # Предполагается, что Nginx будет установлен в /opt/nginx/.
 ./configure --prefix=/opt/nginx \
         --with-ld-opt="-Wl,-rpath,/путь/к/luajit/lib" \
         --add-module=/путь/к/ngx_devel_kit \
         --add-module=/путь/к/lua-nginx-module

 # Обратите внимание, что вы можете также захотеть добавить опции `./configure`, используемые в вашем текущем сборке Nginx.
 # Вы можете получить эти опции, используя команду nginx -V

 # Вы можете изменить число параллелизма 2 ниже, чтобы соответствовать количеству свободных ядер процессора на вашем компьютере.
 make -j2
 make install

 # Обратите внимание, что эта версия модуля lua-nginx-module больше не позволяет установить `lua_load_resty_core off;`.
 # Поэтому вам придется установить `lua-resty-core` и `lua-resty-lrucache` вручную, как показано ниже.

 cd lua-resty-core
 make install PREFIX=/opt/nginx
 cd lua-resty-lrucache
 make install PREFIX=/opt/nginx

 # Добавьте необходимую директиву `lua_package_path` в `nginx.conf`, в контексте http
 lua_package_path "/opt/nginx/lib/lua/?.lua;;";

Назад к Оглавлению

Сборка как динамический модуль

Начиная с NGINX 1.9.11, вы также можете собрать этот модуль как динамический модуль, используя опцию --add-dynamic-module=ПУТЬ вместо --add-module=ПУТЬ на командной строке ./configure. Затем вы можете явно загрузить модуль в вашем nginx.conf с помощью директивы load_module, например,```nginx

load_module /путь/к/модулям/ndk_http_module.so; # предполагая, что NDK также собран как динамический модуль load_module /путь/к/модулям/ngx_http_lua_module.so;


[Назад к Оглавлению](#содержание)

Конфигурация макросов C
-----------------------

При сборке этого модуля как через OpenResty, так и с использованием ядра Nginx, вы можете определить следующие макросы C через опции компилятора C:

* `NGX_LUA_USE_ASSERT`
	При определении включает проверки условий в базе кода ngx_lua на языке C. Рекомендовано для отладки или тестирования сборок. Включение может привести к небольшому увеличению времени выполнения. Этот макрос был введен в версии `v0.9.10`.
* `NGX_LUA_ABORT_AT_PANIC`
	По умолчанию ngx_lua заставляет текущий процесс worker nginx завершиться грациозно при панике LuaJIT VM. Указание этого макроса на языке C заставляет ngx_lua немедленно прервать текущий процесс worker nginx (что обычно приводит к созданию файла core dump). Этот вариант полезен для отладки паник VM. Этот вариант был введен в версии `v0.9.8`.

Чтобы включить один или несколько этих макросов, просто передайте дополнительные опции компилятора C скрипту `./configure` для либо Nginx, либо OpenResty. Например,

    
    ./configure --with-cc-opt="-DNGX_LUA_USE_ASSERT -DNGX_LUA_ABORT_AT_PANIC"
    

[Назад к Оглавлению](#содержание)

Сообщество
==========

[Назад к Оглавлению](#содержание)

Англоязычная рассылка
---------------------Англоязычная рассылка [openresty-en](https://groups.google.com/group/openresty-en) предназначена для говорящих на английском языке.

[Назад к Оглавлению](#содержание)

Китайская рассылка
------------------

Китайская рассылка [openresty](https://groups.google.com/group/openresty) предназначена для говорящих на китайском языке.

[Назад к Оглавлению](#содержание)

Репозиторий кода
================

Репозиторий кода этого проекта расположен на GitHub по адресу
[openresty/lua-nginx-module](https://github.com/openresty/lua-nginx-module).

[Назад к Оглавлению](#содержание)

Ошибки и исправления
====================

Пожалуйста, отправляйте отчеты об ошибках, предложения или исправления через

1. создание тикета в [GitHub Issue Tracker](https://github.com/openresty/lua-nginx-module/issues),
1. или публикацию сообщения в [сообществе OpenResty](#сообщество).

[Назад к Оглавлению](#содержание)

Поддержка байткода LuaJIT
=========================

Смотрите видео YouTube "[Измерение времени выполнения Lua-кода в OpenResty правильно](https://youtu.be/VkRYW_qLoME)"

[![Предварительное компилирование Lua-модулей в байткод LuaJIT для ускорения запуска OpenResty](https://img.youtube.com/vi/EP7c0BM2yNo/0.jpg)](https://youtu.be/EP7c0BM2yNo)

С версии `v0.5.0rc32`, все конфигурационные директивы `*_by_lua_file` (например, [content_by_lua_file](#content_by_lua_file)) поддерживают прямую загрузку файлов с байткодом LuaJIT 2.0/2.1:

```bash
/path/to/luajit/bin/luajit -b /path/to/input_file.lua /path/to/output_file.ljbc

Параметр -bg можно использовать для включения отладочной информации в файл с байткодом LuaJIT:```bash

/path/to/luajit/bin/luajit -bg /path/to/input_file.lua /path/to/output_file.ljbc


Дополнительные сведения о параметре `-b` см. в официальной документации LuaJIT:

<https://luajit.org/running.html#opt_b>

Обратите внимание, что файлы байткода, сгенерированные LuaJIT 2.1, *не* совместимы с LuaJIT 2.0, и наоборот. Поддержка байткода LuaJIT 2.1 была впервые добавлена в ngx_lua v0.9.3.

Попытки загрузить стандартные файлы байткода Lua 5.1 в экземпляры ngx_lua, связанные с LuaJIT 2.0/2.1 (или наоборот), приведут к ошибке Nginx, такой как:

[ошибка] 13909#0: *1 не удалось загрузить Lua встроенный код: плохой заголовок байткода в /path/to/test_file.luac


Загрузка файлов байткода с помощью примитивов Lua, таких как `require` и `dofile`, должна работать так, как ожидалось.

[Назад к Оглавлению](#содержание)

Поддержка системной переменной окружения
========================================

Если вы хотите получить доступ к системной переменной окружения, скажем, `foo`, в Lua через стандартный API Lua [os.getenv](https://www.lua.org/manual/5.1/manual.html#pdf-os.getenv), то вам также следует указать это имя переменной окружения в вашем файле конфигурации `nginx.conf` через директиву [env](https://nginx.org/en/docs/ngx_core_module.html#env). Например,

```nginx

env foo;

Назад к Оглавлению

Поддержка HTTP 1.0 ===================Протокол HTTP 1.0 не поддерживает разбитое представление и требует явного заголовка Content-Length, когда тело ответа не пустое, чтобы поддерживать keep-alive HTTP 1.0. Поэтому при отправке запроса HTTP 1.0 и активации директивы lua_http10_buffering ngx_lua будет буферизировать вывод команд ngx.say и ngx.print и откладывать отправку заголовков ответа до тех пор, пока не будет получено все тело ответа. В этот момент ngx_lua сможет рассчитать общую длину тела и создать правильный заголовок Content-Length для возврата клиенту HTTP 1.0. Однако, если заголовок Content-Length ответа установлен в выполняющемся Lua-коде, буферизация будет отключена, даже если директива lua_http10_buffering активна. Для больших потоковых ответов важно отключить директиву lua_http10_buffering для минимизации использования памяти.Обратите внимание, что общие инструменты для тестирования HTTP, такие как ab и http_load, по умолчанию отправляют HTTP 1.0 запросы. Чтобы заставить curl отправлять HTTP 1.0 запросы, используйте опцию -0.

Назад к Оглавлению

Статическое связывание чистых модулей Lua

С LuaJIT 2.x возможно статически связывать байткод чистых модулей Lua с исполняемым файлом Nginx.

Вы можете использовать исполняемый файл luajit для компиляции файлов .lua модулей Lua в объектные файлы .o, содержащие экспортированный байткод данных, а затем связывать эти объектные файлы непосредственно при сборке Nginx.

Вот пример, демонстрирующий это. Предположим, что у нас есть следующий файл .lua с именем foo.lua:

-- foo.lua
local _M = {}

function _M.go()
    print("Привет от foo")
end

return _M

Затем мы компилируем этот файл .lua в файл foo.o:

/path/to/luajit/bin/luajit -bg foo.lua foo.o

Важно здесь имя файла .lua, которое определяет, как вы будете использовать этот модуль позже в Lua. Имя файла foo.o не имеет значения, кроме расширения файла .o (что указывает luajit на используемый формат выходных данных). Если вы хотите удалить информацию отладки Lua из полученного байткода, вы можете просто указать опцию -b вместо -bg.

Затем при сборке Nginx или OpenResty передайте опцию --with-лд-опт="foo.o" скрипту ./configure:```bash

./configure --with-ld-opt="/путь/к/foo.o" ...


Наконец, вы можете выполнить следующее в любом Lua-коде, запущенном ngx_lua:

```lua

local foo = require "foo"
foo.go()

И этот кусок кода больше не зависит от внешнего файла foo.lua, так как он уже был скомпилирован в исполняемый файл nginx.

Если вы хотите использовать точки в имени модуля Lua при вызове require, как в


local foo = require "resty.foo"

то вам потребуется переименовать файл foo.lua в resty_foo.lua перед компиляцией его в файл .o с помощью командной строки luajit.

Важно использовать точно ту же версию LuaJIT при компиляции файлов .lua в файлы .o, что и при сборке nginx + ngx_lua. Это связано с тем, что формат байткода LuaJIT может быть несовместим между различными версиями LuaJIT. Когда формат байткода несовместим, вы увидите ошибку времени выполнения Lua, говорящую о том, что модуль Lua не найден. При наличии нескольких файлов .lua, которые нужно скомпилировать и связать, просто укажите их файлы .o одновременно в значении опции --with-ld-opt. Например,


./configure --with-ld-opt="/путь/к/foo.o /путь/к/bar.o" ...

Если у вас слишком много файлов .o, то указание всех их в одной команде может быть нереалистичным. В этом случае вы можете создать статическую библиотеку (или архив) для ваших файлов .o, как показано ниже:


ar rcus libmyluafiles.a *.o

Затем вы можете связать архив myluafiles целиком с исполняемым файлом nginx:


./configure \
    --with-ld-opt="-L/путь/к/библиотеке -Wl,--whole-archive -lmyluafiles -Wl,--no-whole-archive"
```

где `/путь/к/библиотеке` — это путь к директории, содержащей файл `libmyluafiles.a`. Важно отметить, что здесь требуется опция компоновщика `--whole-archive`, так как в противном случае наш архив будет пропущен, поскольку ни один символ из нашего архива не упоминается в основной части исполняемого файла nginx.

[Назад к Оглавлению](#содержание)

Обмен данными внутри процесса Nginx
===================================

Для глобального обмена данными между всеми запросами, обрабатываемыми одним процессом Nginx, заключите общие данные в модуль Lua, используйте встроенный Lua `require`, чтобы импортировать модуль, а затем манипулируйте общими данными в Lua. Это работает потому, что требуемые модули Lua загружаются только один раз, и все корутины будут использовать одну и ту же копию модуля (как его кода, так и данных).

Обратите внимание, что использование глобальных переменных Lua *строго не рекомендуется*, так как это может привести к непредвиденным условиям гонки между конкурентными запросами.

Вот небольшой пример обмена данными внутри процесса Nginx через модуль Lua:

```lua

-- mydata.lua
local _M = {}

local data = {
    dog = OnClickListener(),
    cat = 4,
    pig = 5,
}

function _M.get_age(name)
    return data[name]
end

return _M
```

и затем доступ к нему из `nginx.conf`:

```nginx
``` location /lua {
     content_by_lua_block {
         local mydata = require "mydata"
         ngx.say(mydata.get_age("собака"))
     }
 }
```

Модуль `mydata` в этом примере будет загружен и запущен только при первом запросе к локации `/lua`, и все последующие запросы к тому же процессу Nginx будут использовать перезагруженную версию модуля, а также ту же копию данных, пока не будет отправлен сигнал `HUP` главному процессу Nginx для принудительной перезагрузки. Эта техника обмена данными является ключевой для высокопроизводительных приложений Lua на основе этого модуля. Обратите внимание, что эта передача данных осуществляется на основе каждого работника (*per-worker*) и не на основе каждого сервера (*per-server*). То есть, когда имеются несколько процессов-работников Nginx под управлением мастера Nginx, передача данных не может пересекать границу процесса между этими работниками.Обычно рекомендуется таким образом передавать только доступные для чтения данные. Вы также можете передавать изменяемые данные между всеми одновременными запросами каждого процесса-работника Nginx, если в середине ваших вычислений нет операций с неблокирующим вводом-выводом (включая [ngx.sleep](#ngxsleep)). В таком случае, пока вы не вернете управление обратно в цикл событий Nginx и планировщику легких потоков ngx_lua (даже неявно), никогда не будет расхождений в выполнении. По этой причине всегда будьте очень осторожны при передаче изменяемых данных на уровне работника. Ошибочные оптимизации могут легко привести к трудно отлаживаемым расхождениям при нагрузке.Если требуется передача данных на уровне всего сервера, то используйте один или более из следующих подходов:

1. Используйте API [ngx.shared.DICT](#ngxshareddict), предоставленное этим модулем.
1. Используйте только одного работника Nginx и один сервер (хотя это не рекомендуется при наличии многоядерного процессора или нескольких процессоров в одном компьютере).
1. Используйте механизмы хранения данных, такие как `memcached`, `redis`, `MySQL` или `PostgreSQL`. Официальные выпуски [OpenResty](https://openresty.org) включают набор сопутствующих модулей Nginx и библиотек Lua, предоставляющих интерфейсы с этими механизмами хранения данных.

[Назад к оглавлению](#table-of-contents)

Знаменитые проблемы
===================

[Назад к оглавлению](#table-of-contents)

Проблемы соединения TCP сокета
------------------------------

Метод [tcpsock:connect](#tcpsockconnect) может указывать на успех, несмотря на ошибки соединения, такие как ошибки Connection Refused.

Однако, последующие попытки манипулировать объектом cosocket завершатся неудачей и вернут фактическое сообщение об ошибке, сгенерированное неудачной операцией соединения.

Эта проблема связана с ограничениями модели событий Nginx и проявляется только на Mac OS X.

[Назад к оглавлению](#table-of-contents)Yielding/Resuming Lua Корутина
------------------------------
Поскольку встроенные функции Lua `dofile` и `require` в настоящее время реализованы как функции на C в LuaJIT 2.0/2.1, если Lua-файл, загружаемый с помощью `dofile` или `require`, вызывает [ngx.location.capture](#ngxlocationcapture), [ngx.exec](#ngxexec), [ngx.exit](#ngxexit) или другие API-функции, требующие передачи управления в верхнем уровне области Lua-файла, то будет возбуждена ошибка Lua "попытка передать управление через границу вызова C". Чтобы избежать этого, поместите эти вызовы, требующие передачи управления, в собственные Lua-функции в Lua-файле вместо верхнего уровня области файла.[Назад к оглавлению](#содержание)Область видимости переменных Lua
-------------------------------

Необходимо проявлять осторожность при импорте модулей, и следует использовать следующий формат:

```lua
local xxx = require('xxx')
```

вместо устаревшего старого формата:

```lua
require('xxx')
```

Причина этого такова: по дизайну глобальная среда имеет точно такой же срок службы, как и обработчик запроса Nginx, связанный с ней. Каждый обработчик запроса имеет свой набор глобальных переменных Lua, и это идея изоляции запросов. Модуль Lua фактически загружается первым обработчиком запроса Nginx и кэшируется в таблице `package.loaded` встроенным `require()`, а встроенный `module()`, используемый некоторыми модулями Lua, имеет побочный эффект установки глобальной переменной, указывающей на загруженную таблицу модуля. Однако эта глобальная переменная будет очищена в конце обработчика запроса, и каждый последующий обработчик запроса имеет свое (чистое) глобальное окружение. Поэтому при попытке доступа к значению `nil` будет выброшено исключение Lua.

Использование глобальных переменных Lua обычно нежелательно в контексте ngx\_lua по следующим причинам:1. Неправильное использование глобальных переменных Lua может привести к нежелательным побочным эффектам для одновременных запросов, когда такие переменные должны быть локальными по области видимости,
1. глобальные переменные Lua требуют поиска в глобальной среде, что является вычислительно затратным процессом, и
1. некоторые ссылки на глобальные переменные Lua могут содержать ошибки ввода, что затрудняет отладку.Поэтому **строго** рекомендуется всегда объявлять такие переменные в подходящей локальной области видимости.

```lua

 -- Избегайте
 foo = 123
 -- Рекомендуется
 local foo = 123

 -- Избегайте
 function foo() return 123 end
 -- Рекомендуется
 local function foo() return 123 end
```

Чтобы найти все экземпляры глобальных переменных Lua в вашем Lua коде, запустите [инструмент lua-releng](https://github.com/openresty/nginx-devel-utils/blob/master/lua-releng) по всем файлам исходного кода с расширением `.lua`:

    $ lua-releng
    Проверка использования глобальных переменных Lua в файле lib/foo/bar.lua ...
            1       [1489]  SETGLOBAL       7 -1    ; содержит
            55      [1506]  GETGLOBAL       7 -3    ; setvar
            3       [1545]  GETGLOBAL       3 -4    ; varexpand

Выходные данные говорят о том, что строка 1489 файла `lib/foo/bar.lua` записывает значение в глобальную переменную `содержит`, строка 1506 считывает значение из глобальной переменной `setvar`, а строка 1545 считывает значение глобальной переменной `varexpand`. Этот инструмент гарантирует, что локальные переменные в функциях модуля Lua объявлены с помощью ключевого слова `local`, в противном случае будет выброшено исключение во время выполнения. Это предотвращает нежелательные условия гонки при доступе к таким переменным. См. [Обмен данными внутри рабочего процесса Nginx](#data-sharing-within-an-nginx-worker) для причин этого.

[Назад к Оглавлению](#table-of-contents)

Локации, настроенные подзапросами других модулей
-------------------------------------------------Директивы [ngx.location.capture](#ngxlocationcapture) и [ngx.location.capture_multi](#ngxlocationcapture_multi) не могут захватывать локации, которые включают директивы [add_before_body](http://nginx.org/en/docs/http/ngx_http_addition_module.html#add_before_body), [add_after_body](http://nginx.org/en/docs/http/ngx_http_addition_module.html#add_after_body), [auth_request](https://nginx.org/en/docs/http/ngx_http_auth_request_module.html#auth_request), [echo_location](http://github.com/openresty/echo-nginx-module#echo_location), [echo_location_async](http://github.com/openresty/echo-nginx-module#echo_location_async), [echo_subrequest](http://github.com/openresty/echo-nginx-module#echo_subrequest), или [echo_subrequest_async](http://github.com/openresty/echo-nginx-module#echo_subrequest_async).

```nginx
location /foo {
    content_by_lua_block {
        res = ngx.location.capture("/bar")
    }
}
location /bar {
    echo_location /blah;
}
location /blah {
    echo "Success!";
}
```

```nginx
$ curl -i http://example.com/foo
```

не будут работать так, как ожидалось.

[Назад к Оглавлению](#table-of-contents)

Косокеты недоступны в некоторых контекстах
------------------------------------------

Из-за внутренних ограничений в ядре Nginx API косокеты отключены в следующих контекстах: [set_by_lua*](#set_by_lua), [log_by_lua*](#log_by_lua), [header_filter_by_lua*](#header_filter_by_lua), и [body_filter_by_lua](#body_filter_by_lua).Косокеты также отключены в контекстах директив [init_by_lua*](#init_by_lua) и [init_worker_by_lua*](#init_worker_by_lua), но мы можем добавить поддержку этих контекстов в будущем, поскольку нет ограничений в ядре Nginx (или ограничение может быть обойдено). Существует обходной путь, однако, когда исходный контекст *не* должен ждать результатов косокета. То есть, создание таймера с нулевой задержкой через API [ngx.timer.at](#ngxtimerat) и выполнение результатов косокета в обработчике таймера, который выполняется асинхронно относительно исходного контекста, создающего таймер.[Назад к оглавлению](#содержание)Особые последовательности экранирования
--------------------------

**ЗАМЕЧАНИЕ** После выпуска `v0.9.17` эта проблема может быть избежана с помощью конфигурационных директив `*_by_lua_block {}`.

Последовательности PCRE, такие как `\d`, `\s` или `\w`, требуют особого внимания, так как в строковых литералах символ обратной косой черты `\` удаляется как парсером Lua, так и парсером конфигурационного файла Nginx до выполнения, если не находится внутри директивы `*_by_lua_block {}`. Поэтому следующий фрагмент не будет работать так, как ожидалось:

```nginx

# nginx.conf
location /test {
    content_by_lua '
        local regex = "\d+"  -- ЭТО НЕВЕРНО ВНЕ ДИРЕКТИВЫ *_by_lua_block
        local m = ngx.re.match("hello, 1234", regex)
        if m then ngx.say(m[0]) else ngx.say("не найдено!") end
    ';
}
# выводится "не найдено!"
```

Чтобы избежать этой проблемы, удвойте экранирование обратной косой черты:

```nginx

# nginx.conf
location /test {
    content_by_lua '
        local regex = "\\\\d+"
        local m = ngx.re.match("hello, 1234", regex)
        if m then ngx.say(m[0]) else ngx.say("не найдено!") end
    ';
}
# выводится "1234"
```

Здесь `\\\\d+` удаляется до `\\d+` парсером конфигурационного файла Nginx, а затем до `\d+` парсером языка Lua перед выполнением.

В качестве альтернативы шаблон регулярного выражения может быть представлен как длиннобуквенная строковая литерал Lua, заключенная в "длинные скобки", `[[...]]`, в этом случае обратные косые черты должны быть экранированы только один раз для парсера конфигурационного файла Nginx.```nginx

# nginx.conf
location /test {
    content_by_lua '
        local regex = [[\d+]]
        local m = ngx.re.match("hello, 1234", regex)
        if m then ngx.say(m[0]) else ngx.say("не найдено!") end
    ';
}
# выводится "1234"
```

Здесь `[[\d+]]` удаляется до `[[\d+]]` парсером конфигурационного файла Nginx, а затем обрабатывается правильно.

Обратите внимание, что более длинная форма длинных скобок, `[=[...]=]`, может потребоваться, если шаблон регулярного выражения содержит последовательности `[...]`.
Форма `[=[...]=]` может использоваться по умолчанию, если это требуется.

```nginx

# nginx.conf
location /test {
    content_by_lua '
        local regex = [=[0-9]+=]
        local m = ngx.re.match("hello, 1234", regex)
        if m then ngx.say(m[0]) else ngx.say("не найдено!") end
    ';
}
# выводится "1234"
```

Альтернативный подход к экранированию последовательностей PCRE заключается в том, чтобы гарантировать, что код Lua размещается в внешних скриптовых файлах и выполняется с помощью различных директив `*_by_lua_file`.

С этим подходом обратные слэши удаляются только парсером языка Lua, поэтому их требуется экранировать только один раз.

```lua

-- test.lua
local regex = "\\d+"
local m = ngx.re.match("hello, 1234", regex)
if m then ngx.say(m[0]) else ngx.say("не найдено!") end
-- оценивается как "1234"
```

Внутри внешних скриптовых файлов последовательности PCRE, представленные как длинные квадратные скобочные литералы Lua, не требуют модификации.

```lua

-- test.lua
local regex = [[\d+]]
local m = ngx.re.match("hello, 1234", regex)
if m then ngx.say(m[0]) else ngx.say("не найдено!") end
-- оценивается как "1234"
```Как было отмечено ранее, последовательности PCRE, представленные внутри директив `*_by_lua_block {}` (доступны после выпуска `v0.9.17`), не требуют модификации.

```nginx

 # nginx.conf
 location /test {
     content_by_lua_block {
         local regex = [[\d+]]
         local m = ngx.re.match("hello, 1234", regex)
         if m then ngx.say(m[0]) else ngx.say("не найдено!") end
     }
 }
 # оценивается как "1234"
```

**Примечание:** рекомендуется использовать `by_lua_file`, когда код Lua очень длинный.

[Назад к Оглавлению](#содержание)

Отсутствие поддержки смешивания SSI
------------------------------------

Смешивание SSI с ngx_lua в одном запросе Nginx не поддерживается. Лучше использовать ngx_lua исключительно. Всё, что можно сделать с помощью SSI, можно выполнить с помощью ngx_lua, и это может быть более эффективным при использовании ngx_lua.

[Назад к Оглавлению](#содержание)

Не полная поддержка режима SPDY
--------------------------------

Некоторые API Lua, предоставляемые ngx_lua, ещё не работают в режиме SPDY Nginx: [ngx.location.capture](#ngxlocationcapture), [ngx.location.capture_multi](#ngxlocationcapture_multi), и [ngx.req.socket](#ngxreqsocket).

[Назад к Оглавлению](#содержание)

Отсутствие данных в случае раннего завершения запроса
------------------------------------------------------

Nginx может завершить запрос раньше с (по крайней мере):* 400 (Недопустимый запрос)
* 405 (Запрещенный метод)
* 408 (Запрос истек)
* 413 (Запрос слишком большой)
* 414 (URI запроса слишком длинный)
* 494 (Заголовки запроса слишком большие)
* 499 (Клиент прервал запрос)
* 500 (Ошибка сервера)
* 501 (Метод не реализован)

Это означает, что фазы, которые обычно выполняются, пропускаются, такие как фаза перезаписи или фаза доступа. Это также означает, что более поздние фазы, которые выполняются независимо, например [log_by_lua](#log_by_lua), не будут иметь доступа к информации, которая обычно устанавливается в этих фазах.[Назад к Оглавлению](#table-of-contents)

TODO
====

* cosocket: реализовать API несоединённого UDP LuaSocket.
* cosocket: добавить поддержку в контексте [init_by_lua*](#init_by_lua).
* cosocket: проверить и объединить патч aviramc для добавления метода `bsdrecv` ([патч](https://github.com/openresty/lua-nginx-module/pull/290)).
* cosocket: добавить опции конфигурации для различных стратегий управления соединением cosocket, превышающих лимит в пулах.
* использовать `ngx_hash_t` для оптимизации процесса поиска встроенных заголовков для [ngx.req.set_header](#ngxreqset_header) и т.д.
* добавить опции `ignore_resp_headers`, `ignore_resp_body` и `ignore_resp` для методов [ngx.location.capture](#ngxlocationcapture) и [ngx.location.capture_multi](#ngxlocationcapture_multi) для возможности микронастройки производительности с точки зрения пользователя.
* добавить автоматическую поддержку временного разбиения кода Lua путём активного переключения и возобновления Lua VM через дебаг-хуки Lua.
* добавить режим `stat`, аналогичный [mod_lua](https://httpd.apache.org/docs/trunk/mod/mod_lua.html).

[Назад к Оглавлению](#table-of-contents)

Изменения
=========

Изменения, сделанные в каждом выпуске этого модуля, перечислены в журналах изменений пакета OpenResty:

<https://openresty.org/#Changes>

[Назад к Оглавлению](#table-of-contents)

Тестовый набор
==============

Для запуска тестового набора требуются следующие зависимости:

* Версия Nginx >= 1.4.2* Perl модули:
	* Test::Nginx: <https://github.com/openresty/test-nginx>
* Модули Nginx:
	* [ngx_devel_kit](https://github.com/simplresty/ngx_devel_kit)
	* [ngx_set_misc](https://github.com/openresty/set-misc-nginx-module)
	* [ngx_auth_request](http://mdounin.ru/files/ngx_http_auth_request_module-0.2.tar.gz) (этот модуль не требуется, если вы используете Nginx 1.5.4+).
	* [ngx_echo](https://github.com/openresty/echo-nginx-module)
	* [ngx_memc](https://github.com/openresty/memc-nginx-module)
	* [ngx_srcache](https://github.com/openresty/srcache-nginx-module)
	* ngx_lua (то есть этот модуль)
	* [ngx_lua_upstream](https://github.com/openresty/lua-upstream-nginx-module)
	* [ngx_headers_more](https://github.com/openresty/headers-more-nginx-module)
	* [ngx_drizzle](https://github.com/openresty/drizzle-nginx-module)
	* [ngx_rds_json](https://github.com/openresty/rds-json-nginx-module)
	* [ngx_coolkit](https://github.com/FRiCKLE/ngx_coolkit)
	* [ngx_redis2](https://github.com/openresty/redis2-nginx-module)

Порядок добавления этих модулей во время конфигурации важен, так как положение любого модуля фильтра в цепочке фильтрации определяет окончательный вывод, например. Правильный порядок добавления показан выше.* 3rd-party Lua библиотеки:
	* [lua-cjson](https://www.kyne.au/~mark/software/lua-cjson.php)

* Приложения:
	* mysql: создайте базу данных 'ngx_test', предоставьте все привилегии пользователю 'ngx_test', пароль 'ngx_test'.
	* memcached: прослушивание по умолчанию порта 11211.
	* redis: прослушивание по умолчанию порта 6379.

Дополнительные сведения о настройке тестовой среды см. в [скрипте сборки разработчика](https://github.com/openresty/lua-nginx-module/blob/master/util/build.sh).

Чтобы запустить весь набор тестов в режиме тестирования по умолчанию:

    cd /путь/к/lua-nginx-module
    export PATH=/путь/к/вашему/nginx/sbin:$PATH
    prove -I/путь/к/test-nginx/lib -r t

Чтобы запустить конкретные файлы тестов:

    cd /путь/к/lua-nginx-module
    export PATH=/путь/к/вашему/nginx/sbin:$PATH
    prove -I/путь/к/test-nginx/lib t/002-content.t t/003-errors.t

Чтобы запустить конкретный блок теста в определенном файле теста, добавьте строку `--- ONLY` в блок теста, который вы хотите запустить, а затем используйте утилиту `prove`, чтобы запустить этот файл .t.

Также есть различные режимы тестирования на основе мока, valgrind и т.д. Подробнее см. в [документации Test::Nginx](https://search.cpan.org/perldoc?Test::Nginx). Также см. отчеты о тестах для тестового кластера Nginx, работающего на Amazon EC2: <https://qa.openresty.org>.

[Назад к Оглавлению](#содержание)

Авторское право и Лицензия
==========================

Этот модуль лицензирован под лицензией BSD.

Авторское право (C) 2009-2017, Xiaozhe Wang (chaoslawful) <chaoslawful@gmail.com>.Авторское право (C) 2009-2019, Yichun "agentzh" Zhang (Чжан Ичжун) <agentzh@gmail.com>, OpenResty Inc.

Все права защищены.

Распространение и использование в форме исходного кода и двоичных форм, с изменениями или без, разрешено при условии соблюдения следующих условий:

* Распространение исходного кода должно содержать вышеуказанное уведомление об авторском праве, этот список условий и нижеуказанное освобождение от ответственности.* Распространение в двоичной форме должно воспроизводить вышеуказанное уведомление об авторском праве, этот список условий и нижеуказанное освобождение от ответственности в документации и/или других материалах, предоставленных вместе с распределением. ЭТА ПРОГРАММА ПРЕДОСТАВЛЯЕТСЯ АВТОРСКИМИ ВЛАДЕЛЬЦАМИ И КОЛЛЕКТИВНЫМИ ВКЛАДЧИКАМИ «КАК ЕСТЬ» И ЛЮБЫЕ ЯВНЫЕ И НЕЯВНЫЕ ГАРАНТИИ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ЭТИМ, НЕЯВНЫЕ ГАРАНТИИ ТОРГОВЛЕЙ И ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ, ОТКАЗЫВАЮТСЯ. В НИКАКОМ СЛУЧАЕ АВТОРСКИЙ ВЛАДЕЛЬЦЕМ ИЛИ ВКЛАДЧИКАМИ НЕ БУДУТ УЧИТЫВАТЬСЯ ОТВЕТСТВЕННОСТЬ ЗА ЛЮБЫЕ ПРЯМЫЕ, КОСВЕННЫЕ, СЛУЧАЙНЫЕ, СПЕЦИАЛЬНЫЕ, ПРИМЕРНЫЕ ИЛИ СЛЕДСТВЕННЫЕ УЩЕРБЫ (ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ЭТИМ, ПОКУПКУ ЗАМЕЩАЮЩИХ ТОВАРОВ ИЛИ УСЛУГ; ПОТЕРЮ ИСПОЛЬЗОВАНИЯ, ДАННЫХ ИЛИ ПРИБЫЛЕЙ; ИЛИ ПРЕРЫВАНИЕ ДЕЯТЕЛЬНОСТИ) НЕЗАВИСИМО ОТ ПРИЧИНЫ, НЕЗАВИСИМО ОТ ТЕОРИИ ОТВЕТСТВЕННОСТИ, В КОНТРАКТЕ, СТРОГОЙ ОТВЕТСТВЕННОСТИ ИЛИ НЕДОСТОЙНОМУ ПОСТУПКУ (ВКЛЮЧАЯ НЕНАДЛЕЖАЩЕЕ ПОСТУПКИ ИЛИ ИНОЕ) ВОЗНИКШИХ В КАКИМ-ЛИБО ВИДЕ ИЗ ИСПОЛЬЗОВАНИЯ ЭТОЙ ПРОГРАММЫ, ДАЖЕ ЕСЛИ БЫЛО УЧИТЫВАНО ВОЗМОЖНОСТЬ ТАКОГО УЩЕРБА.[Назад к оглавлению](#содержание)

См. также
==========

Статьи блога:

* [Введение в CPU Flame Graphs Lua-Land](https://blog.openresty.com/en/lua-cpu-flame-graph/?src=gh_ngxlua)
* [Как OpenResty и Nginx распределяют и управляют памятью](https://blog.openresty.com/en/how-or-alloc-mem?src=gh_ngxlua)
* [Как OpenResty и Nginx используют общую память для зон](https://blog.openresty.com/en/how-nginx-shm-consume-ram/?src=gh_ngxlua)
* [Фрагментация памяти в общих зонах памяти OpenResty и Nginx](https://blog.openresty.com/en/nginx-shm-frag/?src=gh_ngxlua)Другие связанные модули и библиотеки:

* [ngx_stream_lua_module](https://github.com/openresty/stream-lua-nginx-module#readme) для официальной версии этого модуля для подсистемы Nginx "stream" (осуществляет общие downstream TCP-соединения).
* [lua-resty-memcached](https://github.com/openresty/lua-resty-memcached) — библиотека, основанная на ngx_lua cosocket.
* [lua-resty-redis](https://github.com/openresty/lua-resty-redis) — библиотека, основанная на ngx_lua cosocket.
* [lua-resty-mysql](https://github.com/openresty/lua-resty-mysql) — библиотека, основанная на ngx_lua cosocket.
* [lua-resty-upload](https://github.com/openresty/lua-resty-upload) — библиотека, основанная на ngx_lua cosocket.
* [lua-resty-dns](https://github.com/openresty/lua-resty-dns) — библиотека, основанная на ngx_lua cosocket.
* [lua-resty-websocket](https://github.com/openresty/lua-resty-websocket) — библиотека для WebSocket сервера и клиента, основанная на ngx_lua cosocket.
* [lua-resty-string](https://github.com/openresty/lua-resty-string) — библиотека, основанная на [LuaJIT FFI](https://luajit.org/ext_ffi.html).
* [lua-resty-lock](https://github.com/openresty/lua-resty-lock) — библиотека для простого API блокировки без блокировки.
* [lua-resty-cookie](https://github.com/cloudflare/lua-resty-cookie) — библиотека для манипулирования HTTP-куками.
* [Перенаправление запросов к различным MySQL-запросам в зависимости от аргументов URI](https://openresty.org/#RoutingMySQLQueriesBasedOnURIArgs)
* [Динамическое перенаправление на основе Redis и Lua](https://openresty.org/#DynamicRoutingBasedOnRedis)
* [Использование LuaRocks с ngx_lua](https://openresty.org/#UsingLuaRocks)
* [Введение в ngx_lua](https://github.com/openresty/lua-nginx-module/wiki/Introduction)
* [ngx_devel_kit](https://github.com/simplresty/ngx_devel_kit)
* [echo-nginx-module](http://github.com/openresty/echo-nginx-module)
* [drizzle-nginx-module](http://github.com/openresty/drizzle-nginx-module)
* [postgres-nginx-module](https://github.com/)com/FRiCKLE/ngx_postgres)
 * [memc-nginx-module](http://github.com/openresty/memc-nginx-module)
 * [The OpenResty bundle](https://openresty.org)
 * [Nginx Systemtap Toolkit](https://github.com/openresty/nginx-systemtap-toolkit)[Назад к оглавлению](#содержание)Руководства
===========

* [lua_load_resty_core](#lua_load_resty_core)
* [lua_capture_error_log](#lua_capture_error_log)
* [lua_use_default_type](#lua_use_default_type)
* [lua_malloc_trim](#lua_malloc_trim)
* [lua_code_cache](#lua_code_cache)
* [lua_thread_cache_max_entries](#lua_thread_cache_max_entries)
* [lua_regex_cache_max_entries](#lua_regex_cache_max_entries)
* [lua_regex_match_limit](#lua_regex_match_limit)
* [lua_package_path](#lua_package_path)
* [lua_package_cpath](#lua_package_cpath)
* [init_by_lua](#init_by_lua)
* [init_by_lua_block](#init_by_lua_block)
* [init_by_lua_file](#init_by_lua_file)
* [init_worker_by_lua](#init_worker_by_lua)
* [init_worker_by_lua_block](#init_worker_by_lua_block)
* [init_worker_by_lua_file](#init_worker_by_lua_file)
* [exit_worker_by_lua_block](#exit_worker_by_lua_block)
* [exit_worker_by_lua_file](#exit_worker_by_lua_file)
* [set_by_lua](#set_by_lua)
* [set_by_lua_block](#set_by_lua_block)
* [set_by_lua_file](#set_by_lua_file)
* [content_by_lua](#content_by_lua)
* [content_by_lua_block](#content_by_lua_block)
* [content_by_lua_file](#content_by_lua_file)
* [server_rewrite_by_lua_block](#server_rewrite_by_lua_block)
* [server_rewrite_by_lua_file](#server_rewrite_by_lua_file)
* [rewrite_by_lua](#rewrite_by_lua)
* [rewrite_by_lua_block](#rewrite_by_lua_block)
* [rewrite_by_lua_file](#rewrite_by_lua_file)
* [access_by_lua](#access_by_lua)
* [access_by_lua_block](#access_by_lua_block)
* [access_by_lua_file](#access_by_lua_file)
* [header_filter_by_lua](#header_filter_by_lua)
* [header_filter_by_lua_block](#header_filter_by_lua_block)
* [header_filter_by_lua_file](#header_filter_by_lua_file)
* [body_filter_by_lua](#body_filter_by_lua)
* [body_filter_by_lua_block](#body_filter_by_lua_block)
* [body_filter_by_lua_file](#body_filter_by_lua_file)
* [log_by_lua](#log_by_lua)
* [log_by_lua_block](#log_by_lua_block)
* [log_by_lua_file](#log_by_lua_file)
* [balancer_by_lua_block](#balancer_by_lua_block)
* [balancer_by_lua_file](#balancer_by_lua_file)
* [balancer_keepalive](#balancer_keepalive)
* [lua_need_request_body](#lua_need_request_body)
* [ssl_client_hello_by_lua_block](#ssl_client_hello_by_lua_block)
* [ssl_client_hello_by_lua_file](#ssl_client_hello_by_lua_file)
* [ssl_certificate_by_lua_block](#ssl_certificate_by_lua_block)
* [ssl_certificate_by_lua_file](#ssl_certificate_by_lua_file)* [ssl_session_fetch_by_lua_block](#ssl_session_fetch_by_lua_block)
* [ssl_session_fetch_by_lua_file](#ssl_session_fetch_by_lua_file)
  * [ssl_session_store_by_lua_block](#ssl_session_store_by_lua_block)
  * [ssl_session_store_by_lua_file](#ssl_session_store_by_lua_file)
  * [lua_shared_dict](#lua_shared_dict)
  * [lua_socket_connect_timeout](#lua_socket_connect_timeout)
  * [lua_socket_send_timeout](#lua_socket_send_timeout)
  * [lua_socket_send_lowat](#lua_socket_send_lowat)
  * [lua_socket_read_timeout](#lua_socket_read_timeout)
  * [lua_socket_buffer_size](#lua_socket_buffer_size)
  * [lua_socket_pool_size](#lua_socket_pool_size)
  * [lua_socket_keepalive_timeout](#lua_socket_keepalive_timeout)
  * [lua_socket_log_errors](#lua_socket_log_errors)
  * [lua_ssl_ciphers](#lua_ssl_ciphers)
  * [lua_ssl_crl](#lua_ssl_crl)
  * [lua_ssl_protocols](#lua_ssl_protocols)
  * [lua_ssl_certificate](#lua_ssl_certificate)
  * [lua_ssl_certificate_key](#lua_ssl_certificate_key)
  * [lua_ssl_trusted_certificate](#lua_ssl_trusted_certificate)
  * [lua_ssl_verify_depth](#lua_ssl_verify_depth)
  * [lua_ssl_conf_command](#lua_ssl_conf_command)
  * [lua_http10_buffering](#lua_http10_buffering)
  * [rewrite_by_lua_no_postpone](#rewrite_by_lua_no_postpone)
  * [access_by_lua_no_postpone](#access_by_lua_no_postpone)
  * [lua_transform_underscores_in_response_headers](#lua_transform_underscores_in_response_headers)
  * [lua_check_client_abort](#lua_check_client_abort)
  * [lua_max_pending_timers](#lua_max_pending_timers)
  * [lua_max_running_timers](#lua_max_running_timers)
  * [lua_sa_restart](#lua_sa_restart)
  * [lua_worker_thread_vm_pool_size](#lua_worker_thread_vm_pool_size)

Основные строительные блоки скриптового программирования Nginx с использованием Lua — это директивы. Директивы используются для указания того, когда будет выполнен пользовательский Lua-код, и как будут использоваться результаты его выполнения.Ниже приведена диаграмма, показывающая порядок выполнения директив.

![Lua Nginx Modules Directives](./doc/images/lua_nginx_modules_directives.drawio.png)

[Назад к Оглавлению](#содержание)

lua_load_resty_core
-------------------

**синтаксис:** *lua_load_resty_core on|off*

**по умолчанию:** *lua_load_resty_core on*

**контекст:** *http*

Эта директива устарела начиная с выпуска модуля `v0.10.16`. Модуль `resty.core` из библиотеки [lua-resty-core](https://github.com/openresty/lua-resty-core) теперь обязательно загружается при инициализации Lua виртуальной машины. Указание этой директивы больше не имеет эффекта.

Эта директива была введена впервые в выпуске `v0.10.15` и использовалась для опциональной загрузки модуля `resty.core`.

[Назад к Оглавлению](#директивы)

lua_capture_error_log
---------------------

**синтаксис:** *lua_capture_error_log размер*

**по умолчанию:** *никакое*

**контекст:** *http*

Включает буфер указанного `размера` для захвата всех данных сообщений ошибок Nginx (не только тех, которые производятся этим модулем или подсистемой Nginx HTTP, но и всего остального) без использования файлов или дисков.

Вы можете использовать единицы измерения, такие как `k` и `m`, в значении `размера`, как в следующем примере:

```nginx

 lua_capture_error_log 100k;
```

Как правило, буфер размером 4КБ обычно может содержать около 20 типичных сообщений ошибок. Так что сделайте вычисления!

Этот буфер никогда не увеличивается. Если он заполнен, новые сообщения ошибок заменят самые старые в буфере.Размер буфера должен быть больше максимальной длины одного сообщения об ошибке (что составляет 4К в OpenResty и 2К в стандартном NGINX).

Вы можете прочитать сообщения в буфере на стороне Lua с помощью функции [get_logs()](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/errlog.md#get_logs) модуля [ngx.errlog](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/errlog.md#readme) библиотеки [lua-resty-core](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/errlog.md#readme). Эта функция Lua API вернет захваченные сообщения об ошибках и также удалит уже прочитанные из глобального буфера захвата, освобождая место для новых данных об ошибках. По этой причине пользователю следует не настраивать этот буфер слишком большим, если пользователь быстро читает данные из буфера захвата ошибок. Примечание: Уровень журналирования, указанный в стандартной [error_log](https://nginx.org/r/error_log) директиве, имеет влияние на эту возможность захвата. Он захватывает только сообщения журнала уровня, не ниже указанного уровня журналирования в [error_log](https://nginx.org/r/error_log) директиве. Пользователь все еще может выбрать установить даже более высокий уровень фильтрации журнала в режиме реального времени с помощью функции Lua API [errlog.set_filter_level](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/errlog.md#set_filter_level). Поэтому это более гибко, чем статическая [error_log](https://nginx.org/r/error_log) директива.Стоит отметить, что нет способа захвата журналов отладки
без сборки OpenResty или Nginx с опцией `./configure --with-debug`.
И включение журналов отладки строго не рекомендуется для производственных сборок из-за высокой накладной стоимости.Эта директива была введена впервые в выпуске `v0.10.9`.

[Назад к Оглавлению](#directives)

lua_use_default_type
--------------------

**синтаксис:** *lua_use_default_type on | off*

**по умолчанию:** *lua_use_default_type on*

**контекст:** *http, server, location, location if*

Указывает, следует ли использовать MIME-тип, указанный в [default_type](https://nginx.org/en/docs/http/ngx_http_core_module.html#default_type) директиве, как значение по умолчанию для заголовка ответа `Content-Type`. Отключите эту директиву, если не требуется значение по умолчанию для заголовка ответа `Content-Type` для обработчиков запросов Lua.

Эта директива по умолчанию включена.

Эта директива была введена впервые в выпуске `v0.9.1`.

[Назад к Оглавлению](#directives)

lua_malloc_trim
---------------

**синтаксис:** *lua_malloc_trim &lt;request-count&gt;*

**по умолчанию:** *lua_malloc_trim 1000*

**контекст:** *http*Запрашивает библиотеку времени выполнения `libc`, чтобы она освобождала закэшированные свободные блоки памяти обратно в операционную систему каждые
`N` запросов, обрабатываемых ядром Nginx. По умолчанию, `N` равно 1000. Вы можете настроить количество запросов
с помощью своих собственных значений. Меньшие значения означают более частое освобождение памяти, что может привести к увеличению потребления процессора и
меньшему объему используемой памяти, в то время как большие значения обычно приводят к меньшей накладной стоимости процессора и относительно большему объему используемой памяти.
Просто настройте число для ваших собственных случаев использования.Настройка аргумента на `0` фактически отключает периодическое обрезание памяти полностью.

```nginx
lua_malloc_trim 0;  # полностью отключает обрезку памяти
```

Текущая реализация использует обработчик фаз журналирования Nginx для подсчета запросов. Поэтому наличие директив
[log_subrequest on](https://nginx.org/en/docs/http/ngx_http_core_module.html#log_subrequest) в `nginx.conf`
может ускорить подсчет, когда используются подзапросы. По умолчанию, подсчет производится только для "основных запросов".

Обратите внимание, что эта директива не влияет на память, выделенную LuaJIT своим собственным аллокатором на основе системного вызова `mmap`.

Эта директива была введена впервые в выпуске `v0.10.7`.

[Назад к Оглавлению](#directives)

lua_code_cache
--------------
**синтаксис:** *lua_code_cache on | off*

**по умолчанию:** *lua_code_cache on*

**контекст:** *http, server, location, location if*

Включает или отключает кэширование кода Lua для Lua-кода в директивах `*_by_lua_file` (например, [set_by_lua_file](#set_by_lua_file) и
[content_by_lua_file](#content_by_lua_file)) и Lua-модулей.

При отключении каждый запрос, обслуживаемый ngx_lua, будет выполняться в отдельном экземпляре Lua-машины, начиная с версии `0.9.3`. Таким образом, файлы Lua, указанные в [set_by_lua_file](#set_by_lua_file),
[content_by_lua_file](#content_by_lua_file), [access_by_lua_file](#access_by_lua_file),
и т.д., не будут кэшироваться, а все используемые Lua-модули будут загружаться заново. В этом случае разработчики могут использовать подход "редактирование и перезагрузка".Однако обратите внимание, что Lua-код, написанный встроенным в `nginx.conf`, такие как те, которые указаны в [set_by_lua](#set_by_lua), [content_by_lua](#content_by_lua),
[access_by_lua](#access_by_lua), и [rewrite_by_lua](#rewrite_by_lua), не будет обновлен при редактировании этого встроенного Lua-кода в вашем файле `nginx.conf`, так как только парсер конфигурационного файла Nginx может правильно обрабатывать файл `nginx.conf`.
Единственный способ — перезагрузить конфигурационный файл, отправив сигнал `HUP` или просто перезапустив Nginx.

Даже при включенном кэшировании Lua-файлы, загруженные с помощью `dofile` или `loadfile` в `*_by_lua_file`, не будут кэшироваться (если вы сами не будете кэшировать результаты). Обычно вы можете использовать директивы [init_by_lua](#init_by_lua)
или [init_by_lua_file](#init-by_lua_file) для загрузки всех таких файлов или просто сделать эти Lua-файлы настоящими Lua-модулями и загружать их через `require`. Модуль ngx_lua не поддерживает режим `stat`, доступный в модуле `mod_lua` Apache (в настоящее время).

Отключение кэша Lua-кода строго не рекомендуется для использования в продакшне и следует использовать только во время разработки, так как это значительно снижает общую производительность. Например, производительность примера Lua "Hello World" может снизиться в десятки раз после отключения кэша Lua-кода.

[Назад к Оглавлению](#directions)

lua_thread_cache_max_entries
----------------------------**синтаксис:** *lua_thread_cache_max_entries &lt;число&gt;*

**по умолчанию:** *lua_thread_cache_max_entries 1024*

**контекст:** *http*

Задает максимальное количество записей, разрешённых в кеше объектов lua-потока уровня рабочего процесса.

Этот кеш перезапускает объекты сборки мусора lua-потока между всеми нашими "лёгкими потоками".

Значение `<число>` равное нулю отключает кеш.

Обратите внимание, что эта функция требует LuaJIT OpenResty с новым C API `lua_resetthread`.

Эта функция была введена впервые в версии `v0.10.9`.

[Назад к Оглавлению](#directions)

lua_regex_cache_max_entries
----------------------------

**синтаксис:** *lua_regex_cache_max_entries &lt;число&gt;*

**по умолчанию:** *lua_regex_cache_max_entries 1024*

**контекст:** *http*

Задает максимальное количество записей, разрешённых в кеше скомпилированных регулярных выражений уровня рабочего процесса.

Регулярные выражения, используемые в [ngx.re.match](#ngxrematch), [ngx.re.gmatch](#ngxregmatch), [ngx.re.sub](#ngxresub), и [ngx.re.gsub](#ngxregsub), будут кэшироваться в этом кеше, если опция регулярного выражения `o` (то есть, флаг компиляции один раз) указана.

По умолчанию разрешено 1024 записи, и когда этот лимит достигнут, новые регулярные выражения не будут кэшироваться (как если бы опция `o` не была указана), и будет выдано одно предупреждение в файле `error.log`:

```
2011/08/27 23:18:26 [warn] 31997#0: *1 lua превышение лимита записей кеша регулярных выражений (1024), ...
```Если вы используете реализацию `ngx.re.*` модуля [lua-resty-core](https://github.com/openresty/lua-resty-core) путём загрузки модуля `resty.core.regex` (или просто модуля `resty.core`), то используется кеш LRU для кеша регулярных выражений, используемого здесь.

Не активируйте опцию `o` для регулярных выражений (и/или аргументов строки `replace` для [ngx.re.sub](#ngxresub) и [ngx.re.gsub](#ngxregsub)), которые генерируются "на лету" и могут вызвать бесконечное количество вариаций, чтобы избежать достижения указанного лимита. [Назад к оглавлению](#directives)

lua_regex_match_limit
---------------------

**синтаксис:** *lua_regex_match_limit &lt;число&gt;*

**по умолчанию:** *lua_regex_match_limit 0*

**контекст:** *http*

Задает "лимит совпадений", используемый библиотекой PCRE при выполнении [API ngx.re](#ngxrematch). Как указано в руководстве по PCRE, "лимит ... имеет эффект ограничения количества обратной проверки, которая может произойти".

При достижении лимита будет возвращена ошибка "pcre_exec() failed: -8" функциями [API ngx.re](#ngxrematch) на стороне Lua.

При установке лимита в 0 используется значение "лимита совпадений" по умолчанию при компиляции библиотеки PCRE. Это значение по умолчанию для этой директивы.

Эта директива была введена впервые в выпуске `v0.8.5`.

[Назад к оглавлению](#directives)

lua_package_path
----------------

**синтаксис:** *lua_package_path &lt;строка-пути-в-стиле-Lua&gt;*

**по умолчанию:** *Содержимое переменной окружения LUA_PATH или встроенные значения по умолчанию Lua.***Контекст:** *http*

Задает путь поиска модулей Lua, используемый скриптами, заданными с помощью [set_by_lua](#set_by_lua),
[content_by_lua](#content_by_lua) и других. Строка пути находится в стандартной форме пути Lua, и `;;`
может использоваться для указания оригинальных путей поиска.

С версии `v0.5.0rc29` специальная нотация `$prefix` или `${prefix}` может использоваться в строке пути поиска для указания пути префикса сервера, обычно определяемого опцией командной строки `-p PATH` при запуске сервера Nginx.

[Назад к оглавлению](#directives)

lua_package_cpath
-----------------

**синтаксис:** *lua_package_cpath &lt;строка-пути-C-модулей-в-стиле-Lua&gt;*

**по умолчанию:** *Содержимое переменной окружения LUA_CPATH или встроенные значения по умолчанию Lua.*

**контекст:** *http*

Задает путь поиска C-модулей Lua, используемый скриптами, заданными с помощью [set_by_lua](#set_by_lua),
[content_by_lua](#content_by_lua) и других. Строка пути C-модулей находится в стандартной форме пути Lua, и `;;`
может использоваться для указания оригинальных путей C-модулей.

С версии `v0.5.0rc29` специальная нотация `$prefix` или `${prefix}` может использоваться в строке пути поиска для указания пути префикса сервера, обычно определяемого опцией командной строки `-p PATH` при запуске сервера Nginx.

[Назад к оглавлению](#directives)

init_by_lua
-----------

**синтаксис:** *init_by_lua &lt;lua-скрипт-строка&gt;*

**контекст:** *http***фаза:** *загрузка-конфигурации*

**ЗАМЕЧАНИЕ** Использование этой директивы **не рекомендуется** после выпуска `v0.9.17`. Вместо неё используйте директиву [init_by_lua_block](#init_by_lua_block).

Похожа на директиву [init_by_lua_block](#init_by_lua_block), но принимает Lua-код напрямую в строковом литерале Nginx (что требует специального экранирования символов).

Например,

```nginx

 init_by_lua '
     print("Я не нуждаюсь в дополнительном экранировании здесь, например: \r\nblah")
 '
```

Эта директива была введена впервые в выпуске `v0.5.5`.

[Назад к Оглавлению](#директивы)

init_by_lua_block
-----------------

**синтаксис:** *init_by_lua_block { lua-скрипт }*

**контекст:** *http*

**фаза:** *загрузка-конфигурации*

Когда Nginx получает сигнал `HUP` и начинает перезагрузку конфигурационного файла, Lua виртуальная машина также будет пересоздана, и `init_by_lua_block` снова запустится на новой Lua виртуальной машине. В случае, если директива [lua_code_cache](#lua_code_cache) отключена (по умолчанию включена), обработчик `init_by_lua_block` будет запускаться при каждом запросе, так как в этом специальном режиме всегда создаётся отдельная Lua виртуальная машина для каждого запроса.

Обычно вы можете заранее загрузить Lua модули при запуске сервера с помощью этой вставки и воспользоваться современной оптимизацией операционной системы "копирование при записи" (COW). Вот пример заранее загруженных Lua модулей:```nginx

# Это выполняется до форка Nginx рабочих процессов:
init_by_lua_block { require "cjson" }

server {
    location = /api {
        content_by_lua_block {
            -- Следующий require() вернёт уже загруженный модуль из package.loaded:
            ngx.say(require "cjson".encode{dog = 5, cat = 6})
        }
    }
}
```

Вы также можете инициализировать [lua_shared_dict](#lua_shared_dict) памяти на этой фазе. Вот пример для этого:

```nginx

lua_shared_dict dogs 1m;

init_by_lua_block {
    local dogs = ngx.shared.dogs
    dogs:set("Tom", 56)
}

server {
    location = /api {
        content_by_lua_block {
            local dogs = ngx.shared.dogs
            ngx.say(dogs:get("Tom"))
        }
    }
}
```

Обратите внимание, что хранилище shm в [lua_shared_dict](#lua_shared_dict) не будет очищено при перезагрузке конфигурации (например, с помощью сигнала `HUP`). Поэтому, если вы *не хотите* заново инициализировать хранилище shm в вашем `init_by_lua_block` коде в этом случае, вам просто нужно установить пользовательский флаг в хранилище shm и всегда проверять этот флаг в вашем `init_by_lua_block` коде. Поскольку Lua-код в данном контексте выполняется до того, как Nginx создаст свои рабочие процессы (если они есть), данные или код, загруженные здесь, смогут воспользоваться возможностью [Copy-on-write (COW)](https://ru.wikipedia.org/wiki/Copy-on-write), предоставляемой многими операционными системами для всех рабочих процессов, что позволяет значительно сэкономить память.
```Не следует инициализировать собственные глобальные переменные Lua в этом контексте, так как использование глобальных переменных Lua может привести к снижению производительности и загрязнению глобального пространства имен (см. раздел [Область видимости переменных Lua](#lua-variable-scope) для более подробной информации). Рекомендуемым способом является использование правильных [файлов модулей Lua](https://www.lua.org/manual/5.1/manual.html#5.3) (но не используйте стандартную функцию Lua [module()](https://www.lua.org/manual/5.1/manual.html#pdf-module) для определения модулей Lua, так как она также загрязняет глобальное пространство имен) и вызов [require()](https://www.lua.org/manual/5.1/manual.html#pdf-require) для загрузки своих файлов модулей в `init_by_lua_block` или других контекстах ([require()](https://www.lua.org/manual/5.1/manual.html#pdf-require) кэширует загруженные модули Lua в глобальной таблице `package.loaded` в реестре Lua, поэтому ваши модули будут загружены только один раз для всего экземпляра Lua VM).В данном контексте поддерживаются только некоторые части [API Nginx для Lua](#nginx-api-for-lua):

* API логирования: [ngx.log](#ngxlog) и [print](#print),
* API общего словаря: [ngx.shared.dict](#ngxshareddict).

Более широкий набор API Nginx для Lua может быть поддержан в этом контексте по запросам пользователей.

Основным образом вы можете безопасно использовать библиотеки Lua, которые выполняют блокирующее ввод-вывод, в данном контексте, поскольку блокировка основного процесса во время запуска сервера полностью допустима. Даже ядро Nginx выполняет блокирующее ввод-вывод (по крайней мере при разрешении доменных имён для верхних уровней) на этапе загрузки конфигурации.

Вы должны быть очень осторожны с потенциальными уязвимостями безопасности в вашем Lua-коде, зарегистрированном в этом контексте, так как основной процесс Nginx часто запускается под учётной записью `root`.

Эта директива была введена впервые в выпуске `v0.9.17`.

Дополнительную информацию о OpenResty и общих областях памяти Nginx можно найти в следующих блог-постах:

* [Как OpenResty и общие области памяти Nginx расходуют RAM](https://blog.openresty.com/en/how-nginx-shm-consume-ram/?src=gh_ngxlua)
* [Фрагментация памяти в OpenResty и общих областях памяти Nginx](https://blog.openresty.com/en/nginx-shm-frag/?src=gh_ngxlua)[Назад к оглавлению](#directives)

init_by_lua_file
----------------

**синтаксис:** *init_by_lua_file &lt;путь-к-файлу-с-скриптом-lua&gt;***Контекст:** *http*

**Фаза:** *загрузка-конфигурации*

Аналогично [init_by_lua_block](#init_by_lua_block), за исключением того, что указанный файл `<путь-к-файлу-с-скриптом-lua>` содержит Lua-код или [LuaJIT-байткод](#luajit-bytecode-support), который будет выполнен.

При использовании относительного пути, такого как `foo/bar.lua`, он будет преобразован в абсолютный путь, относительно пути `server prefix`, определенного командной строкой `-p PATH` при запуске сервера Nginx.

Эта директива была введена впервые в выпуске `v0.5.5`.

[Назад к оглавлению](#directives)

init_worker_by_lua
------------------

**Синтаксис:** *init_worker_by_lua &lt;lua-скрипт-строка&gt;*

**Контекст:** *http*

**Фаза:** *начало-работника*

**ЗАМЕЧАНИЕ** Использование этой директивы *не рекомендуется* начиная с выпуска `v0.9.17`. Вместо этого используйте директиву [init_worker_by_lua_block](#init_worker_by_lua_block).

Похоже на директиву [init_worker_by_lua_block](#init_worker_by_lua_block), но принимает Lua-код напрямую в строковом литерале Nginx (что требует специального экранирования символов).

Например,

```nginx

 init_worker_by_lua '
     print("Я не требую дополнительного экранирования здесь, например: \r\nblah")
 ';
```

Эта директива была введена впервые в выпуске `v0.9.5`.

Этот хук больше не выполняется в процессах управления кэшем и загрузки кэша начиная с выпуска `v0.10.12`.

[Назад к оглавлению](#directives)

init_worker_by_lua_block
------------------------

**Синтаксис:** *init_worker_by_lua_block { lua-скрипт }***контекст:** *http*

**фаза:** *начала-работника*

Выполняет указанный Lua-код при каждом запуске рабочего процесса Nginx, если процесс-мастер включен. Когда процесс-мастер отключен, этот хук будет выполняться после [init_by_lua*](#init_by_lua_block).

Этот хук часто используется для создания повторяющихся таймеров для каждого рабочего процесса (через Lua API [ngx.timer.at](#ngxtimerat)), либо для проверки состояния бэкендов или других задач, выполняемых по расписанию. Пример:

```nginx

 init_worker_by_lua_block {
     local задержка = 3  -- в секундах
     local новый_таймер = ngx.timer.at
     local лог = ngx.log
     local ОШИБКА = ngx.ERR
     local проверка = function(premature)
        if not premature then
            -- выполнение проверки состояния или других регулярных задач
            local ok, err = новый_таймер(задержка, проверка)
            if not ok then
                лог(ОШИБКА, "не удалось создать таймер: ", err)
                return
            end
        end
     end

     local hdl, err = новый_таймер(задержка, проверка)
     if not hdl then
         лог(ОШИБКА, "не удалось создать таймер: ", err)
         return
     end

     -- другая работа в init_worker_by_lua
 }

Эта директива была введена впервые в выпуске `v0.9.17`.

Этот хук больше не выполняется в процессах менеджера кэша и загрузчика кэша с выпуска `v0.10.12`.

[Назад к Оглавлению](#директивы)

init_worker_by_lua_file
-----------------------

**синтаксис:** *init_worker_by_lua_file &lt;путь-к-файлу-источника-lua&gt;***контекст:** *http*

**фаза:** *начало-работы-работника*

Аналогично [init_worker_by_lua_block](#init_worker_by_lua_block), но принимает путь к файлу с исходным кодом Lua или байт-кодом Lua.

Эта директива была введена впервые в выпуске `v0.9.5`.

Этот хук больше не выполняется в процессах менеджера кэша и загрузчика кэша с выпуска `v0.10.12`.

[Назад к Оглавлению](#директивы)

exit_worker_by_lua_block
------------------------

**синтаксис:** *exit_worker_by_lua_block { lua-скрипт }*

**контекст:** *http*

**фаза:** *выход-из-работника*

Выполняет указанный Lua-код при каждом выходе каждого процесса работника Nginx, когда включен основной процесс. Когда основной процесс отключен, этот хук будет выполнен перед тем, как завершится процесс Nginx.

Этот хук часто используется для освобождения ресурсов, выделенных каждым работником (например, ресурсы, выделенные [init_worker_by_lua*](#init_worker_by_lua_block)), или для предотвращения аномального завершения работы работников.

Например,

```nginx
exit_worker_by_lua_block {
    print("Лог из exit_worker_by_lua_block")
}
```

Создание таймера (даже таймера с нулевой задержкой) здесь запрещено, так как он выполняется после того, как все таймеры были обработаны.

Эта директива была введена впервые в выпуске `v0.10.18`.

[Назад к Оглавлению](#директивы)

exit_worker_by_lua_file
-----------------------

**синтаксис:** *exit_worker_by_lua_file &lt;путь-к-файлу-скрипта-lua&gt;*

**контекст:** *http***фаза:** *выход-из-работника*

Аналогично [exit_worker_by_lua_block](#exit_worker_by_lua_block), но принимает путь к файлу с исходным кодом Lua или байт-кодом Lua.

Эта директива была введена впервые в выпуске `v0.10.18`.

[Назад к Оглавлению](#директивы)

set_by_lua
-----------

**синтаксис:** *set_by_lua $res &lt;lua-скрипт-строка&gt; [рг1 рг2 ...]*

**context:** *сервер, сервер if, расположение, расположение if*

**фаза:** *перезапись*

**ЗАМЕЧАНИЕ** Использование этого директивы **не рекомендуется** после выпуска `v0.9.17`. Вместо него используйте директиву [set_by_lua_block](#set_by_lua_block).

Похоже на директиву [set_by_lua_block](#set_by_lua_block), но принимает Lua-источник напрямую в строковом литерале Nginx (что требует специальной последовательности экранирования символов), и
1. эта директива поддерживает дополнительные аргументы после Lua-скрипта.

Например,

```nginx

 set_by_lua $res ' return 32 + math.cos(32) ';
 # $res теперь имеет значение "32.834223360507" или подобное.
```

С версии `v0.5.0rc29` интерполяция переменных Nginx отключена в аргументе `<lua-script-str>` этой директивы, поэтому знак доллара (`$`) можно использовать напрямую.

Эта директива требует модуля [ngx_devel_kit](https://github.com/simplresty/ngx_devel_kit).

[Назад к Оглавлению](#директивы)

set_by_lua_block
----------------

**синтаксис:** *set_by_lua_block $res { lua-скрипт }*

**context:** *сервер, сервер if, расположение, расположение if*

**фаза:** *перезапись*Выполняет код, указанный внутри пары фигурных скобок (`{}`), и возвращает строковый вывод в `$res`.
Код внутри пары фигурных скобок (`{}`) может выполнять [вызовы API](#nginx-api-for-lua) и получать входные аргументы из таблицы `ngx.arg` (индекс начинается с `1` и увеличивается последовательно).Эта директива предназначена для выполнения коротких, быстро выполняемых блоков кода, так как цикл событий Nginx блокируется во время выполнения кода. Поэтому следует избегать долгих операций.

Эта директива реализуется путём внедрения пользовательских команд в стандартный список команд модуля [ngx_http_rewrite_module](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html). Поскольку [ngx_http_rewrite_module](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html) не поддерживает неблокирующее ввод-вывод в своих командах, Lua-интерфейсы, требующие передачи текущего Lua "лёгкого потока", не могут работать в этой директиве.

В контексте `set_by_lua_block` по крайней мере следующие API-функции отключены:
* Функции API вывода (например, [ngx.say](#ngxsay) и [ngx.send_headers](#ngxsend_headers))
* Функции API управления (например, [ngx.exit](#ngxexit))
* Функции API подзапроса (например, [ngx.location.capture](#ngxlocationcapture) и [ngx.location.capture_multi](#ngxlocationcapture_multi))
* Функции API сокета (например, [ngx.socket.tcp](#ngxsockettcp) и [ngx.req.socket](#ngxreqsocket))
* Функция API задержки [ngx.sleep](#ngxsleep)

Кроме того, обратите внимание на то, что этот директивный элемент может записывать значение в одну переменную Nginx за один раз. Однако существует возможность обойти это ограничение с помощью интерфейса [ngx.var.VARIABLE](#ngxvarvariable).

```nginx

location /foo {
    set $diff ''; # нам нужно предопределить переменную $diff здесь

    set_by_lua_block $sum {
        local a = 32
        local b = 56
```         ngx.var.diff = a - b  -- запись значения в $diff напрямую
         return a + b          -- возврат значения $sum обычно
     }

     echo "sum = $sum, diff = $diff";
 }
```

Эта директива может свободно использоваться вместе со всеми директивами модулей [ngx_http_rewrite_module](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html), [set-misc-nginx-module](http://github.com/openresty/set-misc-nginx-module) и [array-var-nginx-module](http://github.com/openresty/array-var-nginx-module). Все эти директивы будут выполняться в том же порядке, в котором они указаны в конфигурационном файле.

```nginx

 set $foo 32;
 set_by_lua_block $bar { return tonumber(ngx.var.foo) + 1 }
 set $baz "bar: $bar";  # $baz == "bar: 33"
```

В блоке Lua-кода специальное экранирование не требуется.

Для использования этой директивы необходим модуль [ngx_devel_kit](https://github.com/simplresty/ngx_devel_kit).

Эта директива была введена в версии `v0.9.17`.

[Назад к Оглавлению](#directives)

set_by_lua_file
---------------

**синтаксис:** *set_by_lua_file $res &lt;путь-к-файлу-с-lua-кодом&gt; [$arg1 $arg2 ...]*

**контекст:** *server, server if, location, location if*

**фаза:** *rewrite*

Аналогична [set_by_lua_block](#set_by_lua_block), за исключением того, что файл, указанный как `<путь-к-файлу-с-lua-кодом>`, содержит Lua-код, или, начиная с версии `v0.5.0rc32`, байт-код LuaJIT для выполнения.

Интерполяция переменных Nginx поддерживается в строке аргумента этого директивного элемента `<путь-к-файлу-с-lua-кодом>`. Однако следует проявлять особую осторожность при защите от атак инъекции.При указании относительного пути, такого как `foo/bar.lua`, он будет преобразован в абсолютный путь относительно пути сервера `server prefix`, определённого опцией командной строки `-p PATH` при запуске сервера Nginx.Когда кэширование Lua-кода включено (по умолчанию), пользовательский код загружается один раз при первом запросе и кэшируется. Конфигурация Nginx должна быть перезагружена каждый раз, когда исходный Lua-файл изменяется. Кэширование Lua-кода можно временно отключить во время разработки, переключив [lua_code_cache](#lua_code_cache) на `off` в `nginx.conf`, чтобы избежать перезагрузки Nginx. Этот директивный модуль требует наличия модуля [ngx_devel_kit](https://github.com/simplresty/ngx_devel_kit).

[Назад к Оглавлению](#директивы)

content_by_lua
---------------

**синтаксис:** *content_by_lua &lt;строка-скрипта-lua&gt;*

**контекст:** *локация, локация if*

**фаза:** *content*

**ЗАМЕЧАНИЕ** Использование этой директивы *не рекомендуется* начиная с версии `v0.9.17`. Вместо неё следует использовать директиву [content_by_lua_block](#content_by_lua_block).

Похожа на директиву [content_by_lua_block](#content_by_lua_block), но принимает Lua-скрипт напрямую в строковом литерале Nginx (что требует специального экранирования символов).

Например,

```nginx

 content_by_lua '
     ngx.say("Я не нуждаюсь в дополнительном экранировании здесь, например: \r\nblah")
 ';
```

[Назад к Оглавлению](#директивы)

content_by_lua_block
--------------------

**синтаксис:** *content_by_lua_block { lua-скрипт }*

**контекст:** *локация, локация if*

**фаза:** *content*

Например,

```nginx

 content_by_lua_block {
     ngx.say("Я не нуждаюсь в дополнительном экранировании здесь, например: \r\nblah")
 }
```Функционирует как "обработчик контента" и выполняет строковый Lua-скрипт, указанный в `{ lua-скрипт }`, для каждого запроса.
Lua-скрипт может выполнять [вызовы API](#nginx-api-for-lua) и выполняется как новая запущенная корутина в независимой глобальной среде (то есть в песочнице).

Не используйте эту директиву и другие директивы обработчиков контента в одной и той же локации. Например, эту директиву и директиву [proxy_pass](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass) следует использовать отдельно в разных локациях.

Эта директива была введена впервые в версии `v0.9.17`.

[Назад к Оглавлению](#директивы)

content_by_lua_file
-------------------

**синтаксис:** *content_by_lua_file &lt;путь-к-файлу-скрипта-lua&gt;*

**контекст:** *локация, локация if*

**фаза:** *content*

Эквивалентна директиве [content_by_lua_block](#content_by_lua_block), за исключением того, что файл, указанный в `<путь-к-файлу-скрипта-lua>`, содержит Lua-скрипт, или, начиная с версии `v0.5.0rc32`, байт-код LuaJIT для выполнения.

Если файл не найден, будет возвращён статус-код `404 Not Found`, а в случае ошибок при чтении других файлов — статус-код `503 Service Temporarily Unavailable`.Переменные Nginx могут использоваться в строке `<путь-к-файлу-скрипта-lua>` для повышения гибкости. Однако это не рекомендуется из-за связанных с этим рисков. Когда указывается относительный путь, такой как `foo/bar.lua`, он преобразуется в абсолютный путь относительно пути с префиксом `server prefix`, определяемого параметром командной строки `-p PATH` при запуске сервера Nginx.Когда кэширование Lua-кода включено (по умолчанию), пользовательский код загружается один раз при первом запросе и кэшируется,
а конфигурация Nginx должна перезагружаться каждый раз, когда исходный файл Lua изменяется.
Кэширование Lua-кода можно временно отключить во время разработки, установив ключ `off` для параметра [lua_code_cache](#lua_code_cache) в файле `nginx.conf`, чтобы избежать перезагрузки Nginx.

Переменные Nginx поддерживаются в пути к файлу для динамического маршрутизирования, например:

```nginx

 # ВНИМАНИЕ: содержимое в переменных Nginx должно быть тщательно фильтровано,
 # иначе это создаст значительную угрозу безопасности!
 location ~ ^/app/([-_a-zA-Z0-9/]+)$ {
     set $path $1;
     content_by_lua_file /path/to/lua/app/root/$path.lua;
 }
```

Но будьте очень осторожны с вредоносными входными данными пользователей и всегда тщательно проверяйте или фильтруйте предоставленные пользователем компоненты пути.

[Назад к Оглавлению](#directives)

server_rewrite_by_lua_block
----------------------------

**синтаксис:** *server_rewrite_by_lua_block { lua-скрипт }*

**контекст:** *http, server*

**фаза:** *server rewrite*

Функционирует как обработчик фазы перезаписи сервера и выполняет строку Lua-кода, указанную в `{ lua-скрипт }`, для каждого запроса.
Lua-код может выполнять [вызовы API](#nginx-api-for-lua) и выполняется как новая запущенная корутина в независимой глобальной среде (то есть в песочнице).```nginx

 server {
     ...

     server_rewrite_by_lua_block {
         ngx.ctx.a = "server_rewrite_by_lua_block в http"
     }

     location /lua {
         content_by_lua_block {
             ngx.say(ngx.ctx.a)
             ngx.log(ngx.INFO, ngx.ctx.a)
         }
     }
 }
```

Как и любой другой обработчик фазы перезаписи, [server_rewrite_by_lua_block](#server_rewrite_by_lua_block) также выполняется в подзапросах.

```nginx

 server {
     server_rewrite_by_lua_block {
         ngx.log(ngx.INFO, "является подзапросом:", ngx.is_subrequest)
     }

     location /lua {
         content_by_lua_block {
             local res = ngx.location.capture("/sub")
             ngx.print(res.body)
         }
     }

     location /sub {
         content_by_lua_block {
             ngx.say("OK")
         }
     }
 }
```

Примечание: при вызове `ngx.exit(ngx.OK)` внутри обработчика [server_rewrite_by_lua_block](#server_rewrite_by_lua_block), поток управления обработкой запроса Nginx продолжит выполнение до обработчика контента. Чтобы завершить текущий запрос изнутри обработчика [server_rewrite_by_lua_block](#server_rewrite_by_lua_block), следует вызвать [ngx.exit](#ngxexit) с состоянием >= 200 (`ngx.HTTP_OK`) и состоянием < 300 (`ngx.HTTP_SPECIAL_RESPONSE`) для успешного завершения и `ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)` (или его аналоги) для ошибок.

```nginx

 server_rewrite_by_lua_block {
     ngx.exit(503)
 }

 location /bar {
     ...
     # никогда не выполняется
 }
```

[Назад к Оглавлению](#directives)

server_rewrite_by_lua_file
---------------------------

**синтаксис:** *server_rewrite_by_lua_file &lt;путь-к-файлу-с-кодом-lua&gt;*

**контекст:** *http, server*

**фаза:** *server rewrite*

Аналогичен [server_rewrite_by_lua_block](#server_rewrite_by_lua_block), за исключением того, что указанный файл `<путь-к-файлу-с-кодом-lua>` содержит код Lua, или, начиная с версии `v0.10.22`, байт-код LuaJIT для выполнения.
Переменные Nginx могут использоваться в строке `<путь-к-файлу-с-кодом-lua>`, чтобы обеспечить гибкость. Однако это не рекомендуется по умолчанию из-за некоторых рисков.

При указании относительного пути, такого как `foo/bar.lua`, он будет преобразован в абсолютный путь относительно директории сервера, определенной опцией командной строки `-p PATH` при запуске сервера Nginx.

Когда кэширование кода Lua включено (по умолчанию), пользовательский код загружается один раз при первом запросе и кэшируется, а конфигурация Nginx должна быть перезагружена каждый раз, когда исходный файл Lua изменяется. Кэширование кода Lua можно временно отключить во время разработки, переключив [lua_code_cache](#lua_code_cache) на `off` в `nginx.conf`, чтобы избежать перезагрузки Nginx.

[Назад к Оглавлению](#directives)

rewrite_by_lua
--------------

**синтаксис:** *rewrite_by_lua &lt;строка-с-кодом-lua&gt;*

**контекст:** *http, server, location, location if*

**фаза:** *rewrite tail*

**ЗАМЕЧАНИЕ** Использование этой директивы *не рекомендуется* начиная с версии `v0.9.17`. Вместо этого используйте директиву [rewrite_by_lua_block](#rewrite_by_lua_block).

Похоже на директиву [rewrite_by_lua_block](#rewrite_by_lua_block), но принимает прямой код Lua в строке Nginx (что требует специального экранирования символов). Например,

```nginx

 rewrite_by_lua '
     do_something("hello, world!\nhiya\n")
 ';
'
```

[Назад к Оглавлению](#directions)

rewrite_by_lua_block
---------------------**синтаксис:** *rewrite_by_lua_block { lua-скрипт }*

**контекст:** *http, server, location, location if*

**фаза:** *конец фазы rewrite*

Выполняет Lua-код, указанный в `{ lua-скрипт }`, для каждого запроса. Lua-код может выполнять [API-вызовы](#nginx-api-for-lua) и выполняется как новая запущенная корутина в независимой глобальной среде (то есть в песочнице).

Обратите внимание, что этот обработчик всегда выполняется *после* стандартного [ngx_http_rewrite_module](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html). Поэтому следующее будет работать так, как ожидалось:

```nginx

location /foo {
    set $a 12; # создает и инициализирует $a
    set $b ""; # создает и инициализирует $b
    rewrite_by_lua_block {
        ngx.var.b = tonumber(ngx.var.a) + 1
    }
    echo "res = $b";
}
```

потому что `set $a 12` и `set $b ""` выполняются *до* [rewrite_by_lua_block](#rewrite_by_lua_block).

С другой стороны, следующее не будет работать так, как ожидалось:

```nginx

location /foo {
    set $a 12; # создает и инициализирует $a
    set $b ''; # создает и инициализирует $b
    rewrite_by_lua_block {
        ngx.var.b = tonumber(ngx.var.a) + 1
    }
    if ($b = '13') {
        rewrite ^ /bar redirect;
        break;
    }

    echo "res = $b";
}
```

потому что `if` выполняется *до* [rewrite_by_lua_block](#rewrite_by_lua_block), даже если он указан после [rewrite_by_lua_block](#rewrite_by_lua_block) в конфигурации.

Правильный способ выполнения этого следующий:

```nginx

location /foo {
    set $a 12; # создает и инициализирует $a
    set $b ''; # создает и инициализирует $b
    rewrite_by_lua_block {
        ngx.var.b = tonumber(ngx.var.a) + 1
        if tonumber(ngx.var.b) == 13 then
            return ngx.redirect("/bar")
        end
    }
```     echo "res = $b";
 }
```

Обратите внимание, что модуль [ngx_eval](http://www.grid.net.ru/nginx/eval.en.html) можно приблизительно заменить с помощью [rewrite_by_lua_block](#rewrite_by_lua_block). Например,

```nginx

 location / {
     eval $res {
         proxy_pass http://foo.com/check-spam;
     }

     if ($res = 'spam') {
         rewrite ^ /terms-of-use.html redirect;
     }
 }
```

Можно реализовать в ngx_lua следующим образом:

```nginx

 location = /check-spam {
     internal;
     proxy_pass http://foo.com/check-spam;
 }

 location / {
     rewrite_by_lua_block {
         local res = ngx.location.capture("/check-spam")
         if res.body == "spam" then
             return ngx.redirect("/terms-of-use.html")
         end
     }

     fastcgi_pass ...;
 }
```

Как и любой другой обработчик фазы перезаписи, [rewrite_by_lua_block](#rewrite_by_lua_block) также выполняется в подзапросах.

Обратите внимание, что при вызове `ngx.exit(ngx.OK)` внутри обработчика [rewrite_by_lua_block](#rewrite_by_lua_block), поток управления обработкой запроса Nginx продолжит выполнение до обработчика контента. Чтобы завершить текущий запрос изнутри обработчика [rewrite_by_lua_block](#rewrite_by_lua_block), следует вызвать [ngx.exit](#ngxexit) с состоянием >= 200 (`ngx.HTTP_OK`) и состоянием < 300 (`ngx.HTTP_SPECIAL_RESPONSE`) для успешного завершения и `ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)` (или его аналоги) для ошибок.Если используется директива [rewrite](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite) модуля [ngx_http_rewrite_module](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html) для изменения URI и инициализации внутренней переадресации местоположений, то любые последовательности кода [rewrite_by_lua_block](#rewrite_by_lua_block) или [rewrite_by_lua_file_block](#rewrite_by_lua_file_block) внутри текущего местоположения не будут выполнены. Например,```nginx

 location /foo {
     rewrite ^ /bar;
     rewrite_by_lua_block {
         ngx.exit(503)
     }
 }
 location /bar {
     ...
 }
```

Здесь код Lua `ngx.exit(503)` никогда не будет выполнен. Это будет так, если используется `rewrite ^ /bar last`, так как это также инициирует внутреннюю переадресацию. Если используется модификатор `break` вместо этого, внутренняя переадресация не будет происходить, и код `rewrite_by_lua_block` будет выполнен.

Код `rewrite_by_lua_block` всегда выполняется в конце фазы обработки запроса `rewrite`, за исключением случаев, когда [rewrite_by_lua_no_postpone](#rewrite_by_lua_no_postpone) включен.

Эта директива была введена впервые в выпуске `v0.9.17`.

[Назад к Оглавлению](#directives)

rewrite_by_lua_file
-------------------

**синтаксис:** *rewrite_by_lua_file &lt;путь-к-файлу-скрипта-lua&gt;***

**контекст:** *http, server, location, location if*

**фаза:** *перезапись хвост*

Эквивалент [rewrite_by_lua_block](#rewrite_by_lua_block), за исключением того, что файл, указанный по пути `<path-to-lua-script-file>`, содержит Lua-код, или, начиная с выпуска `v0.5.0rc32`, [LuaJIT байткод](#luajit-bytecode-support) для выполнения.

Переменные Nginx могут использоваться в строке `<path-to-lua-script-file>` для предоставления гибкости. Однако это не рекомендуется по умолчанию из-за некоторых рисков.

Когда указан относительный путь, такой как `foo/bar.lua`, он преобразуется в абсолютный путь относительно пути `server prefix`, определенного опцией командной строки `-p PATH` при запуске сервера Nginx.Когда кэширование Lua-кода включено (по умолчанию), пользовательский код загружается один раз при первом запросе и кэшируется, а конфигурация Nginx должна быть перезагружена каждый раз, когда исходный Lua-файл изменяется. Кэширование Lua-кода может быть временно отключено во время разработки путём переключения [lua_code_cache](#lua_code_cache) на `off` в `nginx.conf` для избежания перезагрузки Nginx.

Код `rewrite_by_lua_file` всегда выполняется в конце фазы обработки запроса `перезапись`, если [rewrite_by_lua_no_postpone](#rewrite_by_lua_no_postpone) не включен.

Переменные Nginx поддерживаются в пути к файлу для динамического вызова, как и в [content_by_lua_file](#content_by_lua_file).

[Назад к Оглавлению](#directives)

access_by_lua
-------------

**синтаксис:** *access_by_lua &lt;lua-script-str&gt;*

**context:** *http, server, location, location if*

**phase:** *доступ хвост*

**ЗАМЕЧАНИЕ** Использование этой директивы *не рекомендуется* после выпуска `v0.9.17`. Вместо неё используйте [access_by_lua_block](#access_by_lua_block).

Похожа на директиву [access_by_lua_block](#access_by_lua_block), но принимает Lua-источник напрямую в строковом литерале Nginx (что требует специального экранирования символов).

Например,

```nginx

 access_by_lua '
     do_something("hello, world!\nhiya\n")
 ';
```

[Назад к Оглавлению](#directives)

access_by_lua_block
-------------------

**синтаксис:** *access_by_lua_block { lua-script }*

**context:** *http, server, location, location if*

**phase:** *доступ хвост*Выполняет Lua-код, указанный в `{<lua-script>}`, для каждого запроса в качестве обработчика фазы доступа.
Lua-код может выполнять [API-вызовы](#nginx-api-for-lua) и выполняется как новая запущенная корутина в независимой глобальной среде (то есть в песочнице).

Примечание: этот обработчик всегда выполняется *после* стандартного [ngx_http_access_module](http://nginx.org/en/docs/http/ngx_http_access_module.html). Поэтому следующее будет работать так, как ожидается:```nginx

location / {
    deny    192.168.1.1;
    allow   192.168.1.0/24;
    allow   10.1.1.0/16;
    deny    all;

    access_by_lua_block {
        local res = ngx.location.capture("/mysql", { ... })
        ...
    }

    # proxy_pass/fastcgi_pass/...
}
```

То есть, если адрес клиента находится в черном списке, он будет заблокирован до выполнения запроса к MySQL для более сложной аутентификации, выполненной блоком [access_by_lua_block](#access_by_lua_block).

Примечание: модуль [ngx_auth_request](http://mdounin.ru/hg/ngx_http_auth_request_module/) можно приблизительно реализовать с помощью блока [access_by_lua_block](#access_by_lua_block):

```nginx

location / {
    auth_request /auth;

    # proxy_pass/fastcgi_pass/postgres_pass/...
}
```

может быть реализован в ngx_lua следующим образом:

```nginx

location / {
    access_by_lua_block {
        local res = ngx.location.capture("/auth")

        if res.status == ngx.HTTP_OK then
            return
        end

        if res.status == ngx.HTTP_FORBIDDEN then
            ngx.exit(res.status)
        end

        ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
    }

    # proxy_pass/fastcgi_pass/postgres_pass/...
}
```

Как и другие обработчики фазы доступа, [access_by_lua_block](#access_by_lua_block) не будет запущен в подзапросах.

Примечание: при вызове `ngx.exit(ngx.OK)` внутри блока [access_by_lua_block](#access_by_lua_block), поток управления обработкой запроса Nginx продолжит работу до обработчика контента. Для завершения текущего запроса изнутри блока [access_by_lua_block](#access_by_lua_block) следует вызвать [ngx.exit](#ngxexit) с статусом >= 200 (`ngx.HTTP_OK`) и статусом < 300 (`ngx.HTTP_SPECIAL_RESPONSE`) для успешного завершения и `ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)` (или его аналоги) для ошибок.Начиная с версии `v0.9.20`, вы можете использовать директиву [access_by_lua_no_postpone](#access_by_lua_no_postpone)
для контроля времени выполнения этого обработчика в фазе "access" обработки запроса Nginx.

Эта директива была введена впервые в версии `v0.9.17`.

[Назад к Оглавлению](#directives)access_by_lua_file
------------------

**синтаксис:** *access_by_lua_file &lt;путь-к-файлу-с-скриптом-lua&gt;*

**контекст:** *http, server, location, location if*

**фаза:** *access tail*

Эквивалентен [access_by_lua_block](#access_by_lua_block), за исключением того, что файл, указанный как `<путь-к-файлу-с-скриптом-lua>`, содержит Lua-код или, начиная с версии `v0.5.0rc32`, байт-код LuaJIT для выполнения.

Переменные Nginx могут использоваться в строке `<путь-к-файлу-с-скриптом-lua>` для обеспечения гибкости. Однако это не рекомендуется по умолчанию из-за некоторых рисков.

Когда используется относительный путь, такой как `foo/bar.lua`, он преобразуется в абсолютный путь относительно пути `server prefix`, определенного опцией командной строки `-p PATH` при запуске сервера Nginx.

Когда кэширование Lua-кода включено (по умолчанию), пользовательский код загружается один раз при первом запросе и кэшируется. Конфигурация Nginx должна быть перезагружена каждый раз, когда Lua-источник изменяется.

Кэширование Lua-кода можно временно отключить во время разработки, установив параметр [lua_code_cache](#lua_code_cache) в `off` в конфигурационном файле `nginx.conf`.Переменные Nginx поддерживаются в пути к файлу для динамического вызова, как и в [content_by_lua_file](#content_by_lua_file).

[Назад к Оглавлению](#directives)

header_filter_by_lua
---------------------

**синтаксис:** *header_filter_by_lua &lt;lua-скрипт-строка&gt;*

**контекст:** *http, server, location, location if*

**фаза:** *output-header-filter*

**ЗАМЕЧАНИЕ** Использование этой директивы *не рекомендуется* начиная с версии `v0.9.17`. Вместо неё следует использовать директиву [header_filter_by_lua_block](#header_filter_by_lua_block).

Похожа на директиву [header_filter_by_lua_block](#header_filter_by_lua_block), но принимает Lua-источник напрямую в строковом литерале Nginx (что требует специального экранирования символов).

Например,

```nginx

 header_filter_by_lua '
     ngx.header["content-length"] = nil
 ';
```

Эта директива была введена впервые в версии `v0.2.1rc20`.

[Назад к Оглавлению](#directives)

header_filter_by_lua_block
--------------------------

**синтаксис:** *header_filter_by_lua_block { lua-скрипт }*

**контекст:** *http, server, location, location if*

**фаза:** *output-header-filter*

Использует Lua-код, указанный в `{ lua-скрипт }`, для определения фильтра заголовка выходных данных.

Обратите внимание, что следующие API-функции в настоящее время отключены в этом контексте:

* Функции API выходных данных (например, [ngx.say](#ngxsay) и [ngx.send_headers](#ngxsend_headers))
* Функции API управления (например, [ngx.redirect](#ngxredirect) и [ngx.exec](#ngxexec))
* Функции API подзапросов (например, [ngx.location.capture](#ngxlocationcapture) и [ngx.location.capture_multi](#ngxlocationcapture_multi))
* Функции API сокетов (например, [ngx.socket.tcp](#ngxsockettcp) и [ngx.req.socket](#ngxreqsocket)).Вот пример переопределения заголовка ответа (или добавления его, если он отсутствует) в нашем фильтре заголовков Lua:

```nginx

location / {
    proxy_pass http://mybackend;
    header_filter_by_lua_block {
        ngx.header.Foo = "blah"
    }
}
```

Эта директива была введена впервые в выпуске `v0.9.17`.

[Назад к Оглавлению](#directives)

header_filter_by_lua_file
-------------------------
**синтаксис:** *header_filter_by_lua_file &lt;путь-к-файлу-lua-скрипта&gt;*

**контекст:** *http, server, location, location if*

**фаза:** *фильтр заголовка выходных данных*

Аналогично [header_filter_by_lua_block](#header_filter_by_lua_block), за исключением того, что указанный файл `<путь-к-файлу-lua-скрипта>` содержит Lua-код, или как с версии `v0.5.0rc32`, [LuaJIT-байткод](#luajit-bytecode-support) для выполнения.

Когда указан относительный путь, такой как `foo/bar.lua`, он преобразуется в абсолютный путь относительно пути `server prefix`, определенного командной строкой `-p PATH` при запуске сервера Nginx.

Эта директива была введена впервые в выпуске `v0.2.1rc20`.

[Назад к Оглавлению](#directives)

body_filter_by_lua
------------------
**синтаксис:** *body_filter_by_lua &lt;lua-скрипт-строка&gt;*

**контекст:** *http, server, location, location if*

**фаза:** *фильтр тела выходных данных*

**ЗАМЕЧАНИЕ** Использование этой директивы *не рекомендуется* начиная с выпуска `v0.9.17`. Вместо этого используйте директиву [body_filter_by_lua_block](#body_filter_by_lua_block).

Аналогично директиве [body_filter_by_lua_block](#body_filter_by_lua_block), но принимает Lua-источник напрямую в строковом литерале Nginx (что требует специального экранирования символов).Например,

```nginx
```markdown
body_filter_by_lua '
    local data, eof = ngx.arg[1], ngx.arg[2]
';
```

Эта директива была введена впервые в выпуске `v0.5.0rc32`.

[Назад к Оглавлению](#директивы)

body_filter_by_lua_block
-------------------------

**синтаксис:** *body_filter_by_lua_block { lua-скрипт }*

**контекст:** *http, server, location, location if*

**фаза:** *output-body-filter*

Использует Lua-код, указанный в `{ lua-скрипт }`, чтобы определить фильтр выходных данных тела ответа.

Блок входных данных передается через [ngx.arg](#ngxarg)[1] (в виде строки Lua) и флаг окончания "eof", указывающий на конец потока данных тела ответа, передается через [ngx.arg](#ngxarg)[2] (в виде логического значения Lua).

Под капотом, флаг "eof" представляет собой флаг `last_buf` (для основных запросов) или `last_in_chain` (для подзапросов) буферов цепочки Nginx. (До выпуска `v0.7.14` флаг "eof" вообще не работал в подзапросах.)

Поток выходных данных можно немедленно прервать выполнением следующего Lua-выражения:

```lua

return ngx.ERROR

```

Это отрежет тело ответа и обычно приведет к некорректному ответу.

Lua-код может передать свое модифицированное версию блока входных данных в нижележащие фильтры выходных данных Nginx, переопределяя [ngx.arg](#ngxarg)[1] строкой Lua или таблицей строк Lua. Например, чтобы преобразовать все строчные буквы в теле ответа, можно просто написать:

```nginx

location / {
    proxy_pass http://mybackend;
    body_filter_by_lua_block {
        ngx.arg[1] = string.upper(ngx.arg[1])
    }
}
```Установка `nil` или пустой строки Lua в `ngx.arg[1]` не передаст блок данных в нижележащие фильтры выходных данных Nginx.

Аналогично, новый флаг "eof" также можно указать, установив логическое значение в [ngx.arg](#ngxarg)[2]. Например,

```nginx

location /t {
    echo hello world;
    echo hiya globe;

    body_filter_by_lua_block {
        local chunk = ngx.arg[1]
        if string.match(chunk, "hello") then
            ngx.arg[2] = true  -- новый флаг "eof"
            return
        end

        -- просто выбрасываем оставшиеся данные
        ngx.arg[1] = nil
    }
}
```

Тогда `GET /t` вернет вывод


    hello world


То есть, когда фильтр тела видит блок данных, содержащий слово "hello", он немедленно устанавливает флаг "eof" в true, что приводит к отрезанию, но все еще корректному ответу. Когда Lua-код может изменять длину тела ответа, то требуется всегда очищать заголовок `Content-Length` ответа (если он есть) в фильтре заголовков, чтобы обеспечить потоковое отображение выходных данных, как в

```nginx

location /foo {
    # fastcgi_pass/proxy_pass/...

    header_filter_by_lua_block {
        ngx.header.content_length = nil
    }
    body_filter_by_lua_block {
        ngx.arg[1] = string.len(ngx.arg[1]) .. "\n"
    }
}
```

Обратите внимание, что следующие API-функции в настоящее время отключены в этом контексте из-за ограничений в реализации фильтров вывода Nginx:* Функции API вывода (например, [ngx.say](#ngxsay) и [ngx.send_headers](#ngxsend_headers))
* Функции API управления (например, [ngx.exit](#ngxexit) и [ngx.exec](#ngxexec))
* Функции API подзапросов (например, [ngx.location.capture](#ngxlocationcapture) и [ngx.location.capture_multi](#ngxlocationcapture_multi))
* Функции API сокетов (например, [ngx.socket.tcp](#ngxsockettcp) и [ngx.req.socket](#ngxreqsocket))Фильтры вывода Nginx могут вызываться несколько раз для одного запроса, так как тело ответа может передаваться частями. Таким образом, указанный Lua-код также может выполняться несколько раз в течение жизни одного HTTP-запроса.

Эта директива была введена впервые в выпуске `v0.9.17`.

[Назад к Оглавлению](#directives)

body_filter_by_lua_file
------------------------

**синтаксис:** *body_filter_by_lua_file &lt;путь-к-файлу-lua-скрипта&gt;*

**контекст:** *http, server, location, location if*

**фаза:** *output-body-filter*

Аналогична [body_filter_by_lua_block](#body_filter_by_lua_block), за исключением того, что указанный файл `<path-to-lua-script-file>` содержит Lua-код, или, начиная с выпуска `v0.5.0rc32`, [LuaJIT-байткод](#luajit-bytecode-support) для выполнения.

При использовании относительного пути, такого как `foo/bar.lua`, они преобразуются в абсолютный путь, относительный к пути `server prefix`, определенному опцией командной строки `-p PATH` при запуске сервера Nginx.

Эта директива была введена впервые в выпуске `v0.5.0rc32`.

[Назад к Оглавлению](#directives)

log_by_lua
----------

**синтаксис:** *log_by_lua &lt;lua-script-str&gt;*

**контекст:** *http, server, location, location if*

**фаза:** *log*

**ЗАМЕЧАНИЕ** Использование этой директивы **не рекомендуется** после выпуска `v0.9.17`. Вместо неё следует использовать директиву [log_by_lua_block](#log_by_lua_block).

Похоже на директиву [log_by_lua_block](#log_by_lua_block), но принимает Lua-код напрямую в строковом литерале Nginx (что требует специального экранирования символов).Например,

```nginx

 log_by_lua '
     print("Я не нуждаюсь в дополнительном экранировании здесь, например: \r\nblah")
 ';
```

Эта директива была введена впервые в выпуске `v0.5.0rc31`.

[Назад к Оглавлению](#directives)

log_by_lua_block
----------------

**синтаксис:** *log_by_lua_block { lua-скрипт }*

**контекст:** *http, server, location, location if*

**фаза:** *log*

Выполняет встроенный Lua-код, представленный как `{ lua-скрипт }`, на этапе обработки запроса **log**. Это не заменяет текущие журналы доступа, но выполняется до них.

Обратите внимание, что следующие API-функции в настоящее время отключены в этом контексте:

* Функции API вывода (например, [ngx.say](#ngxsay) и [ngx.send_headers](#ngxsend_headers))
* Функции API управления (например, [ngx.exit](#ngxexit))
* Функции API подзапроса (например, [ngx.location.capture](#ngxlocationcapture) и [ngx.location.capture_multi](#ngxlocationcapture_multi))
* Функции API сокета (например, [ngx.socket.tcp](#ngxsockettcp) и [ngx.req.socket](#ngxreqsocket)).

Вот пример сбора средних данных для [$upstream_response_time](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#var_upstream_response_time):

```nginx

 lua_shared_dict log_dict 5M;

 server {
     location / {
         proxy_pass http://mybackend;

         log_by_lua_block {
             local log_dict = ngx.shared.log_dict
             local upstream_time = tonumber(ngx.var.upstream_response_time)

             local sum = log_dict:get("upstream_time-sum") or 0
             sum = sum + upstream_time
             log_dict:set("upstream_time-sum", sum)

             local newval, err = log_dict:incr("upstream_time-nb", 1)
             if not newval and err == "not found" then
                 log_dict:add("upstream_time-nb", 0)
                 log_dict:incr("upstream_time-nb", 1)
             end
         }
     }
 ```     location = /status {
         content_by_lua_block {
             local log_dict = ngx.shared.log_dict
             local sum = log_dict:get("upstream_time-sum")
             local nb = log_dict:get("upstream_time-nb")
             если nb и sum существуют
                 ngx.say("среднее время ответа на входящий запрос: ", sum / nb,
                         " (", nb, " запросов)")
             иначе
                 ngx.say("еще нет данных")
             конец
         }
     }
 }
```

Эта директива была введена впервые в выпуске `v0.9.17`.

[Назад к Оглавлению](#директивы)

log_by_lua_file
---------------

**синтаксис:** *log_by_lua_file &lt;путь-к-файлу-с-lua-кодом&gt;*

**контекст:** *http, server, location, location if*

**фаза:** *лог*

Эквивалентна [log_by_lua_block](#log_by_lua_block), за исключением того, что файл, указанный как `<путь-к-файлу-с-lua-кодом>`, содержит Lua-код, или, начиная с выпуска `v0.5.0rc32`, [LuaJIT-байткода](#поддержка-luajit-байткода).

Когда указан относительный путь, например `foo/bar.lua`, он преобразуется в абсолютный путь относительно пути `server prefix`, определенного командной строкой `-p PATH` при запуске сервера Nginx.

Эта директива была введена впервые в выпуске `v0.5.0rc31`.

[Назад к Оглавлению](#директивы)

balancer_by_lua_block
---------------------

**синтаксис:** *balancer_by_lua_block { lua-код }*

**контекст:** *upstream*

**фаза:** *контент*

Эта директива выполняет Lua-код в качестве балансера для любого определенного в блоке конфигурации `upstream {}` источника.

Например,

```nginx

 upstream foo {
     сервер 127.0.0.1;
     balancer_by_lua_block {
         -- используйте Lua для выполнения чего-то интересного здесь
         -- как динамический балансер
     }
 }
``````nginx
сервер {
    местоположение / {
        proxy_pass http://foo;
    }
}
```

Результирующий Lua-балансер может работать с любыми существующими модулями Nginx для upstream, такими как [ngx_proxy](https://nginx.org/en/docs/http/ngx_http_proxy_module.html) и
[ngx_fastcgi](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html).

Кроме того, Lua-балансер может работать с стандартным механизмом пула соединений для upstream, то есть с стандартной [keepalive](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive) директивой.
Просто убедитесь, что [keepalive](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive) директива используется *после* этой `balancer_by_lua_block` директивы в одном блоке конфигурации `upstream {}`. Балансировщик Lua может полностью игнорировать список серверов, определенный в блоке `upstream {}`, 
и выбирать пару из полностью динамического списка серверов (даже меняющегося по запросу) с помощью
модуля [ngx.balancer](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/balancer.md)
из библиотеки [lua-resty-core](https://github.com/openresty/lua-resty-core).

Обработчик Lua-кода, зарегистрированный этим директивой, может быть вызван более одного раза в одном
нижестоящем запросе, когда механизм upstream Nginx повторяет запрос при выполнении условий,
указанных директивами, такими как [proxy_next_upstream](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_next_upstream).
```Этот контекст выполнения кода на Lua не поддерживает отдачу управления, поэтому API Lua, которые могут вызвать отдачу управления (например, cosockets и "легкие потоки"), отключены в этом контексте. Обычно можно обойти это ограничение, выполняя такие операции в обработчике ранней фазы (например, [access_by_lua*](#access_by_lua*)) и передавая результат в этот контекст через таблицу [ngx.ctx](#ngxctx).Эта директива была введена впервые в выпуске `v0.10.0`.

[Назад к Оглавлению](#directives)

balancer_by_lua_file
--------------------

**синтаксис:** *balancer_by_lua_file &lt;путь-к-файлу-с-кодом-Lua&gt;*

**контекст:** *upstream*

**фаза:** *content*

Аналогична [balancer_by_lua_block](#balancer_by_lua_block), за исключением того, что указанный файл `<path-to-lua-script-file>` содержит Lua-код, или, начиная с выпуска `v0.5.0rc32`, байт-код LuaJIT для выполнения.

Когда указан относительный путь, такой как `foo/bar.lua`, он преобразуется в абсолютный путь, относительно пути `server prefix`, определенного командной строкой `-p PATH` при запуске сервера Nginx.

Эта директива была введена впервые в выпуске `v0.10.0`.

[Назад к Оглавлению](#directives)

balancer_keepalive
------------------

**синтаксис:** *balancer_keepalive &lt;общее-количество-соединений&gt;*

**контекст:** *upstream*

**фаза:** *loading-config*

Параметр `общее-количество-соединений` устанавливает максимальное количество простоящих keepalive соединений с серверами upstream, сохраняемых в кэше каждого рабочего процесса. Когда это число превышено, наименее недавно использованные соединения закрываются. Должно быть особо отмечено, что директива keepalive не ограничивает общее количество соединений с серверами-получателями, которые может открыть рабочий процесс nginx. Параметр `connections` следует установить таким образом, чтобы он был достаточно малым, чтобы позволить серверам-получателям обрабатывать новые входящие соединения.Эта директива была введена впервые в выпуске `v0.10.21`.

[Назад к Оглавлению](#directives)

lua_need_request_body
----------------------

**синтаксис:** *lua_need_request_body &lt;on|off&gt;*

**по умолчанию:** *off*

**контекст:** *http, server, location, location if*

**фаза:** *зависит от использования*

Определяет, следует ли заставить данные тела запроса быть прочитанными до выполнения команд rewrite/access/content_by_lua* или нет. Ядро nginx по умолчанию не читает тело запроса клиента, и если требуется чтение данных тела запроса, то эту директиву следует включить (`on`) или вызвать функцию [ngx.req.read_body](#ngxreqread_body) внутри Lua-кода.

Чтобы прочитать данные тела запроса внутри переменной [$request_body](http://nginx.org/en/docs/http/ngx_http_core_module.html#var_request_body),
[client_body_buffer_size](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size) должна иметь ту же величину, что и [client_max_body_size](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size). Поскольку при превышении размера содержимого [client_body_buffer_size](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size), но меньшего, чем [client_max_body_size](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size), nginx будет буферизировать данные в временном файле на диске, что приведёт к пустому значению в переменной [$request_body](http://nginx.org/en/docs/http/ngx_http_core_module.html#var_request_body).Если текущее расположение включает директивы [rewrite_by_lua*](#rewrite_by_lua*), то тело запроса будет прочитано сразу перед выполнением кода [rewrite_by_lua*](#rewrite_by_lua*) (и также на этапе `rewrite`). Аналогично, если указано только [content_by_lua](#content_by_lua), тело запроса не будет прочитано до тех пор, пока Lua-код обработчика контента не будет готов к выполнению (то есть, тело запроса будет прочитано на этапе контента).Однако рекомендуется использовать функции [ngx.req.read_body](#ngxreqread_body) и [ngx.req.discard_body](#ngxreqdiscard_body) для более тонкого управления процессом чтения тела запроса. Это также относится к [access_by_lua*](#access_by_lua).

[Назад к Оглавлению](#directives)

ssl_client_hello_by_lua_block
-----------------------------

**синтаксис:** *ssl_client_hello_by_lua_block { lua-скрипт }*

**контекст:** *http, server*

**фаза:** *немедленно после обработки сообщения SSL Client Hello*

Эта директива запускает пользовательский Lua-код при обработке SSL-клиента сообщения "Client Hello" перед построением соединения SSL (HTTPS).

Она особенно полезна для динамического установления SSL-протоколов в соответствии с SNI.

Также полезно выполнять некоторые специальные операции в зависимости от информации о соединении в сообщении "Client Hello".

Например, можно распарсить пользовательское расширение "Client Hello" и выполнить соответствующую обработку на чистом Lua.

Этот Lua-обработчик всегда выполняется независимо от того, возобновляется ли SSL-сессия (через SSL-идентификаторы сессий или TLS-билеты сессий) или нет.
В то время как обработчик Lua `ssl_certificate_by_lua*` выполняется только при инициализации полной SSL-рукопожатки.

Модули Lua [ngx.ssl.clienthello](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/clienthello.md),
предоставляемые библиотекой [lua-resty-core](https://github.com/openresty/lua-resty-core/#readme),
особенно полезны в этом контексте.Обратите внимание, что этот обработчик выполняется на очень ранней стадии SSL-рукопожатия, до парсинга расширений "Client Hello".

Поэтому вы не можете использовать некоторые API Lua, такие как `ssl.server_name()`, которые зависят от обработки поздних стадий.

Также обратите внимание, что директива в сервере по умолчанию действует для нескольких виртуальных серверов с одинаковым IP-адресом и портом.

Пример ниже демонстрирует простое использование модуля
[ngx.ssl.clienthello](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/clienthello.md):

```nginx
сервер {
     слушать 443 ssl;
     сервер_имя   test.com;
     ssl_certificate /path/to/cert.crt;
     ssl_certificate_key /path/to/key.key;
     ssl_client_hello_by_lua_block {
         местный ssl_clt = требовать "ngx.ssl.clienthello"
         местный host, err = ssl_clt.get_client_hello_server_name()
         если host == "test.com" то
             ssl_clt.set_protocols({"TLSv1", "TLSv1.1"})
         elseif host == "test2.com" then
             ssl_clt.set_protocols({"TLSv1.2", "TLSv1.3"})
         elseif нет host then
             ngx.log(ngx.ERR, "failed to get the SNI name: ", err)
             ngx.exit(ngx.ERROR)
         иначе
             ngx.log(ngx.ERR, "unknown SNI name: ", host)
             ngx.exit(ngx.ERROR)
         конец
     }
     ...
 }
сервер {
     слушать 443 ssl;
     сервер_имя   test2.com;
     ssl_certificate /path/to/cert.crt;
     ssl_certificate_key /path/to/key.key;
     ...
 }
```

См. больше информации в [ngx.ssl.clienthello](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/clienthello.md) официальной документации модулей Lua.

Несоблюдённые исключения Lua в пользовательском Lua коде немедленно прерывают текущую сессию SSL, так же как и вызов [ngx.exit](#ngxexit) с кодом ошибки, таким как `ngx.ERROR`.Этот контекст выполнения Lua кода поддерживает перехват, поэтому API Lua, которые могут перехватывать (например, cosockets, сон и "лёгкие потоки") активированы в этом контексте.

Примечание: вам потребуется настроить [ssl_certificate](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate)
и [ssl_certificate_key](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate_key),
чтобы избежать следующей ошибки при запуске NGINX:

```
nginx: [emerg] no ssl configured for the server
```

Эта директива требует OpenSSL версии 1.1.1 или выше.

Если вы используете [официально собранные пакеты](https://openresty.org/en/linux-packages.html)
для OpenResty 1.21.4.1 или более поздней версии, то всё должно работать сразу после установки.

Если вы не используете ядро Nginx, которое поставляется вместе с OpenResty 1.21.4.1 или более поздней версией, вам потребуется применить патчи к стандартному ядру Nginx:

<https://openresty.org/en/nginx-ssl-patches.html>

Эта директива была введена впервые в выпуске `v0.10.21`.

[Назад к Оглавлению](#directives)

ssl_client_hello_by_lua_file
-----------------------------

**синтаксис:** *ssl_client_hello_by_lua_file <путь-к-файлу-lua-скрипта>*

**контекст:** *http, server*

**фаза:** *немедленно после обработки сообщения client hello*

Аналогична [ssl_client_hello_by_lua_block](#ssl_client_hello_by_lua_block), за исключением того, что указанный файл `<path-to-lua-script-file>` содержит Lua код, или, начиная с выпуска `v0.5.0rc32`, [LuaJIT байткод](#luajit-bytecode-support) для выполнения.Когда указан относительный путь, такой как `foo/bar.lua`, он преобразуется в абсолютный путь относительно пути `server prefix`, определённого командной строкой `-p PATH` при запуске сервера Nginx.

Эта директива была введена впервые в выпуске `v0.10.21`.

[Назад к Оглавлению](#directives)

ssl_certificate_by_lua_block
----------------------------

**синтаксис:** *ssl_certificate_by_lua_block { lua-скрипт }***

**контекст:** *сервер*

**фаза:** *перед-SSL-рукопожатием*

Эта директива запускает пользовательский Lua-код, когда Nginx собирается начать SSL-рукопожатие для нижестоящих SSL (https) соединений.

Она особенно полезна для установки цепочки SSL-сертификатов и соответствующего приватного ключа на основе каждого запроса. Также полезно загружать такие конфигурации рукопожатия SSL асинхронно с удалённого сервера (например, с помощью [cosocket](#ngxsockettcp) API). Можно также выполнять обработку OCSP stapling на основе каждого запроса чисто на Lua.

Ещё один типичный случай использования — это управление трафиком SSL-рукопожатия асинхронно в этом контексте, с помощью библиотеки [lua-resty-limit-traffic#readme](https://github.com/openresty/lua-resty-limit-traffic), например.

Также можно выполнять интересные вещи с запросами SSL-рукопожатия от стороны клиента, например отклонять старых клиентов SSL, использующих протокол SSLv3 или даже ниже, выборочно.Lua-модули [ngx.ssl](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md)
и [ngx.ocsp](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ocsp.md), предоставляемые библиотекой
[lua-resty-core](https://github.com/openresty/lua-resty-core/#readme), особенно полезны в этом контексте. Вы можете использовать Lua-API, предлагаемое этими двумя модулями Lua, чтобы манипулировать цепочкой SSL-сертификатов и приватным ключом для текущего SSL-соединения, которое инициируется.Однако этот Lua-обработчик вообще не запускается, когда Nginx/OpenSSL успешно возобновляет SSL-сеанс через SSL-идентификаторы сессий или TLS-билеты сессий для текущего SSL-соединения. Другими словами, этот Lua-обработчик запускается только тогда, когда Nginx должен инициировать полное SSL-рукопожатие.

Ниже приведен простой пример использования
[ngx.ssl](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md) модуля
в то же время:

```nginx
server {
    listen 443 ssl;
    server_name test.com;

    ssl_certificate_by_lua_block {
        print("Готовится к началу нового SSL-рукопожатия!")
    }

    location / {
        root html;
    }
}
```

Для более сложных примеров см. официальную документацию по Lua-модулям [ngx.ssl](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md)
и [ngx.ocsp](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ocsp.md). Необработанные исключения Lua в пользовательском Lua коде немедленно прерывают текущую сессию SSL, так же как вызов функции [ngx.exit](#ngxexit) с кодом ошибки, например `ngx.ERROR`.

Этот контекст выполнения Lua кода поддерживает переключение (yielding), поэтому Lua API, которые могут вызвать переключение (например, cosockets, задержка выполнения и "лёгкие потоки"), активированы в этом контексте.Однако, стоит отметить, что вам всё равно нужно настроить директивы [ssl_certificate](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate) и
[ssl_certificate_key](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate_key),
хотя вы и не будете использовать этот статический сертификат и приватный ключ. Это связано с тем, что ядро NGINX требует их наличия; иначе при запуске NGINX вы получите следующую ошибку:```
nginx: [emerg] нет конфигурации SSL для сервера
```

Данная директива требует OpenSSL версии 1.0.2e или выше.

Если вы используете [официальные предварительно скомпилированные пакеты](https://openresty.org/en/linux-packages.html) для
[OpenResty](https://openresty.org/) версии 1.9.7.2 или выше, то всё должно работать корректно из коробки.

Если вы не используете ядро Nginx, поставляемое вместе с
[OpenResty](https://openresty.org) версии 1.9.7.2 или выше, вам потребуется применить патчи к стандартному ядру Nginx:

<https://openresty.org/en/nginx-ssl-patches.html>

Данная директива была введена впервые в выпуске `v0.10.0`.

[Назад к Оглавлению](#directives)

ssl_certificate_by_lua_file
----------------------------

**синтаксис:** *ssl_certificate_by_lua_file &lt;путь-к-файлу-с-lua-кодом&gt;*

**контекст:** *server*

**фаза:** *перед SSL-рукопожатием*

Аналогична директиве [ssl_certificate_by_lua_block](#ssl_certificate_by_lua_block), за исключением того, что файл, указанный по пути `<path-to-lua-script-file>`, содержит Lua код, или, начиная с выпуска `v0.5.0rc32`, байт-код LuaJIT для выполнения.

Когда указан относительный путь, например `foo/bar.lua`, он преобразуется в абсолютный путь относительно пути сервера, определённого опцией командной строки `-p PATH` при запуске сервера Nginx.

Данная директива была введена впервые в выпуске `v0.10.0`.

[Назад к Оглавлению](#directives)

ssl_session_fetch_by_lua_block
-------------------------------

**синтаксис:** *ssl_session_fetch_by_lua_block { lua-скрипт }*

**контекст:** *http*

**фаза:** *перед SSL-рукопожатием*Этот директивный блок запускает Lua-код для поиска и загрузки SSL-сессии (если таковая имеется) в соответствии с идентификатором сессии, предоставленным текущим запросом SSL-рукопожатия для нижестоящего соединения.

API Lua для получения текущего идентификатора сессии и загрузки закэшированных данных SSL-сессии предоставляются в модуле Lua [ngx.ssl.session](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/session.md), который поставляется вместе с библиотекой [lua-resty-core](https://github.com/openresty/lua-resty-core#readme).

API Lua, которые могут привести к временной приостановке выполнения, такие как [ngx.sleep](#ngxsleep) и [cosockets](#ngxsockettcp), активированы в этом контексте.

Эта вставка кода, вместе с вставкой кода [ssl_session_store_by_lua*](#ssl_session_store_by_lua_block), может использоваться для реализации распределённой системы кэширования на чистом Lua (например, на основе API [cosocket](#ngxsockettcp)). Если закэшированная SSL-сессия найдена и загружена в контекст текущего SSL-соединения, процесс восстановления SSL-сессии может немедленно начаться, минуя полный процесс SSL-рукопожатия, который очень затратен в плане использования процессора.Пожалуйста, обратите внимание, что TLS-сессионные билеты очень отличаются, и это является обязанностью клиентов кэшировать состояние SSL-сессии при использовании сессионных билетов. Восстановление SSL-сессий на основе TLS-сессионных билетов происходит автоматически без прохождения этой вставки кода (или вставки кода [ssl_session_store_by_lua*](#ssl_session_store_by_lua_block)). Эта вставка кода主要用于支持旧版或功能较弱的仅使用会话ID进行SSL会话的SSL客户端。

Пожалуйста, обратите внимание, что TLS-сессионные билеты очень отличаются, и это является обязанностью клиентов кэшировать состояние SSL-сессии при использовании сессионных билетов. Восстановление SSL-сессий на основе TLS-сессионных билетов происходит автоматически без прохождения этой вставки кода (или вставки кода [ssl_session_store_by_lua*](#ssl_session_store_by_lua_block)). Эта вставка кода主要用于支持旧版或功能较弱的仅使用会话ID进行SSL会话的SSL客户端.

Пожалуйста, обратите внимание, что TLS-сессионные билеты очень отличаются, и это является обязанностью клиентов кэшировать состояние SSL-сессии при использовании сессионных билетов. Восстановление SSL-сессий на основе TLS-сессионных билетов происходит автоматически без прохождения этой вставки кода (или вставки кода [ssl_session_store_by_lua*](#ssl_session_store_by_lua_block)). Эта вставка кода主要用于支持旧版或功能较弱的仅使用会话ID进行SSL会话的SSL客户端。

Пожалуйста, обратите внимание, что TLS-сессионные билеты очень отличаются, и это является обязанностью клиентов кэшировать состояние SSL-сессии при использовании сессионных билетов. Восстановление SSL-сессий на основе TLS-сессионных билетов происходит автоматически без прохождения этой вставки кода (или вставки кода [ssl_session_store_by_lua*](#ssl_session_store_by_lua_block)). Эта вставка кода主要用于支持旧版或功能较弱的仅使用会话ID进行SSL会话的SSL客户端。

Пожалуйста, обратите внимание, что TLS-сессионные билеты очень отличаются, и это является обязанностью клиентов кэшировать состояние SSL-сессии при использовании сессионных билетов. Восстановление SSL-сессий на основе TLS-сессионных билетов происходит автоматически без прохождения этой вставки кода (или вставки кода [ssl_session_store_by_lua*](#ssl_session_store_by_lua_block)). Эта вставка кода主要用于支持旧版或功能较弱的仅使用会话ID进行SSL会话的SSL客户端。

Пожалуйста, обратите внимание, что TLS-сессионные билеты очень отличаются, и это является обязанностью клиентов кэшировать состояние SSL-сессии при использовании сессионных билетов. Восстановление SSL-сессий на основе TLS-сессионных билетов происходит автоматически без прохождения этой вставки кода (или вставки кода [ssl_session_store_by_lua*](#ssl_session_store_by_lua_block)). Эта вставка кода主要用于支持旧版或功能较弱的仅使用会话ID进行SSL会话的SSL客户端。

Пожалуйста, обратите внимание, что TLS-сессионные билеты очень отличаются, и это является обязанностью клиентов кэшировать состояние SSL-сессии при использовании сессионных билетов. Восстановление SSL-сессий на основе TLS-сессионных билетов происходит автоматически без прохождения этой вставки кода (или вставки кода [ssl_session_store_by_lua*](#ssl_session_store_by_lua_block)). Эта вставка кода主要用于支持旧版或功能较弱的仅使用会话ID进行SSL会话的SSL客户端。

Пожалуйста, обратите внимание, что TLS-сессионные билеты очень отличаются, и это является обязанностью клиентов кэшировать состояние SSL-сессии при использовании сессионных билетов. Восстановление SSL-сессий на основе TLS-сессионных билетов происходит автоматически без прохождения этой вставки кода (или вставки кода [ssl_session_store_by_lua*](#ssl_session_store_by_lua_block)). Эта вставка кода主要用于支持旧版或功能较弱的仅使用会话ID进行SSL会话的SSL客户端。

Пожалуйста, обратите внимание, что TLS-сессионные билеты очень отличаются, и это является обязанностью клиентов кэшировать состояние SSL-сессии при использовании сессионных билетов. Восстановление SSL-сессий на основе TLS-сессионных билетов происходит автоматически без прохождения этой вставки кода (или вставки кода [ssl_session_store_by_lua*](#ssl_session_store_by_lua_block)). Эта вставка кода主要用于支持旧版或功能较弱的仅使用会话ID进行SSL会话的SSL客户端。

Пожалуйста, обратите внимание, что TLS-сессионные билеты очень отличаются, и это является обязанностью клиентов кэшировать состояние SSL-сессии при использовании сессионных билетов. Восстановление SSL-сессий на основе TLS-сессионных билетов происходит автоматически без прохождения этой вставки кода (или вставки кода [ssl_session_store_by_lua*](#ssl_session_store_by_lua_block)). Эта вставка кода主要用于支持旧版或功能较弱的仅使用会话ID进行SSL会话的SSL客户端。

Пожалуйста, обратите внимание, что TLS-сессионные билеты очень отличаются, и это является обязанностью клиентов кэшировать состояние SSL-сессии при использовании сессионных билетов. Восстановление SSL-сессий на основе TLS-сессионных билетов происходит автоматически без прохождения этой вставки кода (или вставки кода [ssl_session_store_by_lua*](#ssl_session_store_by_lua_block)). Эта вставка кода主要用于支持旧版或功能较弱的仅使用会话ID进行SSL会话的SSL客户端。

Пожалуйста, обратите внимание, что TLS-сессионные билеты очень отличаются, и это является обязанностью клиентов кэшировать состояние SSL-сессии при использовании сессионных билетов. Восстановление SSL-сессий на основе TLS-сессионных билетов происходит автоматически без прохождения этой вставки кода (или вставки кода [ssl_session_store_by_lua*](#ssl_session_store_by_lua_block)). Эта вставка кода主要用于支持旧版或功能较弱的仅使用会话ID进行SSL会话的SSL客户端。

Пожалуйста, обратите внимание, что TLS-сессионные билеты очень отличаются, и это является обязанностью клиентов кэшировать состояние SSL-сессии при использовании сессионных билетов. Восстановление SSL-сессий на основе TLS-сессионных билетов происходит автоматически без прохождения этой вставки кода (или вставки кода [ssl_session_store_by_lua*](#ssl_session_store_by_lua_block)). Эта вставка кода主要用于支持旧版或功能较弱的仅使用会话ID进行SSL会话的SSL客户端。

Пожалуйста, обратите внимание, что TLS-сессионные билеты очень отличаются, и это является обязанностью клиентов кэшировать состояние SSL-сессии при использовании сессионных билетов. Восстановление SSL-сессий на основе TLS-сессионных билетов происходит автоматически без прохождения этой вставки кода (или вставки кода [ssl_session_store_by_lua*](#ssl_session_store_by_lua_block)). Эта вставка кода主要用于支持旧版或功能较弱的仅使用会话ID进行SSL会话的SSL客户端。

Пожалуйста, обратите внимание, что TLS-сессионные билеты очень отличаются, и это является обязанностью клиентов кэшировать состояние SSL-сессии при использовании сессионных билетов. Восстановление SSL-сессий на основе TLS-сессионных билетов происходит автоматически без прохождения этой вставки кода (или вставки кода [ssl_session_store_by_lua*](#ssl_session_store_by_lua_block)). Эта вставка кода主要用于支持旧版或功能较弱的仅使用会话ID进行SSL会话的SSL客户端。

Пожалуйста, обратите внимание, что TLS-сессионные билеты очень отличаются, и это является обязанностью клиентов кэшировать состояние SSL-сессии при использовании сессионных билетов. Восстановление SSL-сессий на основе TLS-сессионных билетов происходит автоматически без прохождения этой вставки кода (или вставки кода [ssl_session_store_by_lua*](#ssl_session_store_by_lua_block)). Эта вставка кода主要用于支持旧版或功能较弱的仅使用会话ID进行SSL会话的SSL客户端。

Пожалуйста, обратите внимание, что TLS-сессионные билеты очень отличаются, и это является обязанностью клиентов кэшировать состояние SSL-сессии при использовании сессионных билетов. Восстановление SSL-сессий на основе TLS-сессионных билетов происходит автоматически без прохождения этой вставки кода (или вставки кода [ssl_session_store_by_lua*](#ssl_session_store_by_lua_block)). Эта вставка кода主要用于支持旧版或功能较弱的仅使用会话ID进行SSL会话的SSL客户端。

Пожалуйста, обратите внимание, что TLS-сессионные билеты очень отличаются, и это является обязанностью клиентов кэшировать состояние SSL-сессии при использовании сессионных билетов. Восстановление SSL-сессий на основе TLS-сессионных билетов происходит автоматически без прохождения этой вставки кода (или вставки кода [ssl_session_store_by_lua*](#ssl_session_store_by_lua_block)). Эта вставка кода主要用于支持旧版或功能较弱的仅使用会话ID进行SSL会话的SSL客户端。

Пожалуйста, обратите внимание, что TLS-сессиКогда одновременно заданы [ssl_certificate_by_lua*](#ssl_certificate_by_lua_block), этот хук обычно выполняется до [ssl_certificate_by_lua*](#ssl_certificate_by_lua_block). Когда текущий SSL-соединение и SSL-сессия успешно загружены, происходит восстановление SSL-сессии, полностью обходя хук [ssl_certificate_by_lua*](#ssl_certificate_by_lua_block). В этом случае Nginx также явно обходит хук [ssl_session_store_by_lua*](#ssl_session_store_by_lua_block).

Для удобства локального тестирования этого хука вы можете временно добавить следующую строку в ваш блок конфигурации HTTPS-сервера, чтобы отключить поддержку TLS-сессионных билетов:
    ssl_session_tickets off;

Но не забудьте закомментировать эту строку перед публикацией вашего сайта в Интернете.

Если вы используете официально собранные пакеты для [OpenResty](https://openresty.org/) версии 1.11.2.1 или выше, то всё должно работать корректно из коробки.

Если вы не используете один из [пакетов OpenSSL](https://openresty.org/en/linux-packages.html), предоставленных [OpenResty](https://openresty.org), вам потребуется применить патчи к OpenSSL для использования этой директивы:

<https://openresty.org/en/openssl-patches.html>

Аналогично, если вы не используете ядро Nginx, поставляемое с [OpenResty](https://openresty.org) версии 1.11.2.1 или выше, вам потребуется применить патчи к стандартному ядру Nginx:

<https://openresty.org/en/nginx-ssl-patches.html>

Эта директива была введена впервые в выпуске `v0.10.6`.

Обратите внимание, что эта директива может использоваться только в контексте **http**, начиная с выпуска `v0.10.7`, поскольку восстановление SSL-сессии происходит до распределения запросов по серверам.

[Назад к Оглавлению](#directives)

ssl_session_fetch_by_lua_file
------------------------------**синтаксис:** *ssl_session_fetch_by_lua_file &lt;путь-к-файлу-скрипта-lua&gt;*

**контекст:** *http*

**фаза:** *перед SSL-рукопожатием*

Аналогична [ssl_session_fetch_by_lua_block](#ssl_session_fetch_by_lua_block), за исключением того, что указанный файл `<путь-к-файлу-скрипта-lua>` содержит скрипт Lua или, другими словами, [байт-код LuaJIT](#luajit-bytecode-support) для выполнения.

Когда указан относительный путь, такой как `foo/bar.lua`, он преобразуется в абсолютный путь относительно пути сервера, определённого опцией командной строки `-p PATH` при запуске сервера Nginx.

Эта директива была введена впервые в выпуске `v0.10.6`.

Обратите внимание, что: эта директива может использоваться только в контексте **http** начиная с выпуска `v0.10.7` (потому что восстановление SSL-сеанса происходит до распределения запросов по серверам).

[Назад к Оглавлению](#directives)

**синтаксис:** *ssl_session_store_by_lua_block { lua-скрипт }*

**контекст:** *http***Фаза:** *после SSL-рукопожатия* Эта директива выполняет Lua-код для получения и сохранения SSL-сеанса (если он есть) в соответствии с идентификатором сессии, предоставленным текущим запросом SSL-рукопожатия для downstream. Сохраненные или кэшированные данные SSL-сеанса могут использоваться для будущих SSL-соединений для возобновления SSL-сеансов без прохождения полного процесса SSL-рукопожатия (что очень дорого с точки зрения времени работы ЦПУ).

API Lua, такие как [ngx.sleep](#ngxsleep) и [cosockets](#ngxsockettcp), которые могут вызвать отдачу, в данном контексте *отключены*. Однако вы всё ещё можете использовать API [ngx.timer.at](#ngxtimerat) для создания таймеров с нулевой задержкой, чтобы асинхронно сохранять данные SSL-сеанса в внешние службы (например, `redis` или `memcached`).API Lua для получения текущего идентификатора сессии и связанной с ним информации о состоянии сессии предоставляется в модуле Lua [ngx.ssl.session](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/session.md#readme), который поставляется вместе с библиотекой [lua-resty-core](https://github.com/openresty/lua-resty-core#readme).

Для удобного локального тестирования этого хука с помощью современного веб-браузера вы можете временно добавить следующую строку в блок вашего сервера HTTPS для отключения поддержки TLS-тикетов сессии:

    ssl_session_tickets off;

Но не забудьте закомментировать эту строку перед публикацией вашего сайта в интернете.

Эта директива была введена в версии `v0.10.6`.

Примечание: данная директива разрешена только для использования в **контексте HTTP** начиная с версии `v0.10.7` (поскольку восстановление SSL-сеанса происходит до маршрутизации по имени сервера).

[Назад к Оглавлению](#directives)

ssl_session_store_by_lua_file
-----------------------------

**синтаксис:** *ssl_session_store_by_lua_file &lt;путь-к-файлу-скрипта-lua&gt;*

**контекст:** *http*

**фаза:** *немедленно после SSL-рукопожатия*

Аналогична [ssl_session_store_by_lua_block](#ssl_session_store_by_lua_block), за исключением того, что указанный файл `<путь-к-файлу-скрипта-lua>` содержит Lua-код или, другими словами, [LuaJIT-байткод](#luajit-bytecode-support), который будет выполнен.Когда указан относительный путь, такой как `foo/bar.lua`, он преобразуется в абсолютный путь относительно пути префикса сервера, определённого опцией командной строки `-p PATH` при запуске сервера Nginx.Эта директива была введена в версии `v0.10.6`.

Примечание: данная директива разрешена только для использования в **контексте HTTP** начиная с версии `v0.10.7` (поскольку восстановление SSL-сеанса происходит до маршрутизации по имени сервера).

[Назад к Оглавлению](#directives)

lua_shared_dict
---------------

**синтаксис:** *lua_shared_dict &lt;имя&gt; &lt;размер&gt;*

**по умолчанию:** *нет*

**контекст:** *http*

**фаза:** *зависит от использования*

Объявляет зону совместного доступа памяти `<имя>`, которая служит хранилищем для словаря Lua на основе shm `ngx.shared.<имя>`. Зоны совместного использования памяти всегда используются всеми рабочими процессами Nginx в текущем экземпляре сервера Nginx.

Аргумент `<size>` принимает единицы измерения размера, такие как `k` и `m`:

```nginx
http {
    lua_shared_dict собаки 10m;
    ...
}
```

Жестко заданный минимальный размер составляет 8КБ, а практический минимальный размер зависит от фактического набора данных пользователя (некоторые люди начинают с 12КБ).

Дополнительные сведения см. в разделе [ngx.shared.DICT](#ngxshareddict).

Эта директива была введена впервые в выпуске `v0.3.1rc22`.

[Назад к Оглавлению](#directives)

lua_socket_connect_timeout
--------------------------

**синтаксис:** *lua_socket_connect_timeout &lt;время&gt;*

**по умолчанию:** *lua_socket_connect_timeout 60с*

**контекст:** *http, server, location*Эта директива управляет значением по умолчанию для тайм-аута, используемого в методе [connect](#tcpsockconnect) объекта TCP/Unix-доменного сокета, и может быть переопределена методами [settimeout](#tcpsocksettimeout) или [settimeouts](#tcpsocksettimeouts).Аргумент `<time>` может быть целым числом с опциональной единицей времени, такой как `с` (секунда), `мс` (миллисекунда), `м` (минута). По умолчанию единица времени — это `с`, то есть "секунда". Значение по умолчанию — `60с`.

Эта директива была введена впервые в выпуске `v0.5.0rc1`.

[Назад к Оглавлению](#directives)

lua_socket_send_timeout
-----------------------

**синтаксис:** *lua_socket_send_timeout &lt;время&gt;*

**по умолчанию:** *lua_socket_send_timeout 60с*

**контекст:** *http, server, location*

Управляет значением по умолчанию для тайм-аута, используемого в методе [send](#tcpsocksend) объекта TCP/Unix-доменного сокета, и может быть переопределена методами [settimeout](#tcpsocksettimeout) или [settimeouts](#tcpsocksettimeouts).

Аргумент `<time>` может быть целым числом с опциональной единицей времени, такой как `с` (секунда), `мс` (миллисекунда), `м` (минута). По умолчанию единица времени — это `с`, то есть "секунда". Значение по умолчанию — `60с`.

Эта директива была введена впервые в выпуске `v0.5.0rc1`.

[Назад к Оглавлению](#directives)

lua_socket_send_lowat
---------------------

**синтаксис:** *lua_socket_send_lowat &lt;размер&gt;*

**по умолчанию:** *lua_socket_send_lowat 0*

**контекст:** *http, server, location*

Управляет значением `lowat` (низкий уровень воды) для буфера отправки cosocket.

[Назад к Оглавлению](#directives)

lua_socket_read_timeout
-----------------------

**по умолчанию:** *lua_socket_read_timeout 60с*

**контекст:** *http, server, location*

**фаза:** *зависит от использования*Эта директива управляет значением по умолчанию таймаута, используемого в методе [receive](#tcpsockreceive) объекта TCP/Unix-domain сокета и функциях-итераторах, возвращаемых методом [receiveuntil](#tcpsockreceiveuntil). Это значение можно переопределить с помощью методов [settimeout](#tcpsocksettimeout) или [settimeouts](#tcpsocksettimeouts).

Аргумент `<время>` может быть целым числом с опциональной единицей времени, такой как `с` (секунда), `мс` (миллисекунда), `м` (минута). По умолчанию единица времени — это `с`, то есть "секунда". Значение по умолчанию — `60с`.

Эта директива была введена впервые в выпуске `v0.5.0rc1`.

[Назад к Оглавлению](#directives)

lua_socket_buffer_size
----------------------

**синтаксис:** *lua_socket_buffer_size &lt;размер&gt;*

**по умолчанию:** *lua_socket_buffer_size 4к/8к*

**контекст:** *http, сервер, локация*

Задает размер буфера, используемый при чтении данных с использованием cosocket.

Этот буфер не обязан быть таким большим, чтобы уместить всё одновременно, так как cosocket поддерживает 100%-ное небуферизированное чтение и парсинг. Поэтому даже размер буфера в `1` байт должен работать везде, но производительность может быть ужасной.

Эта директива была введена впервые в выпуске `v0.5.0rc1`.

[Назад к Оглавлению](#directives)

lua_socket_pool_size
--------------------

**синтаксис:** *lua_socket_pool_size &lt;размер&gt;*

**по умолчанию:** *lua_socket_pool_size 30*

**контекст:** *http, сервер, локация*Задаёт ограничение по размеру (в терминах количества соединений) для каждого пула соединений cosocket, связанного с каждым удалённым сервером (то есть, определяемым либо парой хост-порт, либо путём файла unix-domain сокета).

По умолчанию ограничение составляет 30 соединений для каждого пула.

Когда пул соединений превышает доступное ограничение по размеру, самое недавно использованное (неактивное) соединение, уже находящееся в пуле, будет закрыто, чтобы освободить место для текущего соединения.

Обратите внимание, что пул соединений cosocket относится к каждому процессу рабочего узла Nginx, а не к каждому экземпляру сервера Nginx, поэтому указанное здесь ограничение по размеру также применяется ко всем процессам рабочих узлов Nginx.

Эта директива была введена впервые в выпуске `v0.5.0rc1`.

[Назад к Оглавлению](#directives)

lua_socket_keepalive_timeout
-------------------------------
**синтаксис:** *lua_socket_keepalive_timeout &lt;время&gt;*

**по умолчанию:** *lua_socket_keepalive_timeout 60с*

**контекст:** *http, server, location*

Эта директива управляет максимальным временем бездействия соединений в встроенной пуле соединений cosocket. Когда этот таймаут достигает своего значения, бездействующие соединения закрываются и удаляются из пула. Это значение можно переопределить методом [setkeepalive](#tcpsocksetkeepalive) объектов cosocket.Аргумент `<время>` может быть целым числом с опциональной единицей времени, такой как `с` (секунда), `мс` (миллисекунда), `м` (минута). По умолчанию единица времени — `с`, то есть "секунда". Значение по умолчанию — `60с`.Эта директива была введена в версии `v0.5.0rc1`.

[Назад к Оглавлению](#directives)

lua_socket_log_errors
----------------------

**синтаксис:** *lua_socket_log_errors on|off*

**по умолчанию:** *lua_socket_log_errors on*

**контекст:** *http, server, location*

Эта директива используется для переключения записи ошибок при возникновении ошибок для TCP или UDP cosockets. Если вы уже правильно обрабатываете ошибки и записываете их в Lua-коде, рекомендуется отключить эту директиву, чтобы предотвратить запись данных в журнал ошибок Nginx (что обычно является дорогостоящим процессом).

Эта директива была введена в версии `v0.5.13`.

[Назад к Оглавлению](#directives)

lua_ssl_ciphers
---------------

**синтаксис:** *lua_ssl_ciphers &lt;шифры&gt;*

**по умолчанию:** *lua_ssl_ciphers DEFAULT*

**контекст:** *http, server, location*

Указывает активные шифры для запросов к SSL/TLS серверу в методе [tcpsock:sslhandshake](#tcpsocksslhandshake). Шифры указываются в формате, понятном библиотеке OpenSSL.

Полный список можно просмотреть с помощью команды `openssl ciphers`.

Эта директива была введена в версии `v0.9.11`.

[Назад к Оглавлению](#directives)

lua_ssl_crl
-----------

**синтаксис:** *lua_ssl_crl &lt;файл&gt;*

**по умолчанию:** *нет*

**контекст:** *http, server, location*

Указывает файл с аннулированными сертификатами (CRL) в формате PEM для проверки сертификата SSL/TLS сервера в методе [tcpsock:sslhandshake](#tcpsocksslhandshake).

Эта директива была введена в версии `v0.9.11`.

[Назад к Оглавлению](#directives)lua_ssl_protocols
-----------------
**синтаксис:** *lua_ssl_protocols \[SSLv2\] \[SSLv3\] \[TLSv1\] [TLSv1.1] [TLSv1.2] [TLSv1.3]*

**по умолчанию:** *lua_ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3*

**контекст:** *http, server, location*

Включает указанные протоколы для запросов к SSL/TLS серверу в методе [tcpsock:sslhandshake](#tcpsocksslhandshake).

Поддержка параметра `TLSv1.3` требует версии `v0.10.12` *и* OpenSSL 1.1.1.
С версии v0.10.25 значение по умолчанию изменено с `SSLv3 TLSv1 TLSv1.1 TLSv1.2` на `TLSv1 TLSv1.1 TLSv1.2 TLSv1.3`.

Эта директива была введена впервые в выпуске `v0.9.11`.

[Назад к Оглавлению](#directives)

lua_ssl_certificate
-------------------
**синтаксис:** *lua_ssl_certificate &lt;file&gt;*

**по умолчанию:** *никакое*

**контекст:** *http, server, location*

Указывает путь к файлу SSL/TLS сертификата в формате PEM, используемому в методе [tcpsock:sslhandshake](#tcpsocksslhandshake).

Эта директива позволяет указать SSL/TLS сертификат, который будет представлен серверу во время процесса SSL/TLS аутентификации.

Эта директива была введена впервые в выпуске `v0.10.26`.

См. также [lua_ssl_certificate_key](#lua_ssl_certificate_key) и [lua_ssl_verify_depth](#lua_ssl_verify_depth).

[Назад к Оглавлению](#directives)

lua_ssl_certificate_key
-----------------------
**синтаксис:** *lua_ssl_certificate_key &lt;file&gt;*

**по умолчанию:** *никакое*

**контекст:** *http, server, location*

Указывает путь к файлу приватного ключа, связанного с SSL/TLS сертификатом, используемого в методе [tcpsock:sslhandshake](#tcpsocksslhandshake).Эта директива позволяет указать файл приватного ключа, соответствующий SSL/TLS сертификату, указанному в `lua_ssl_certificate`. Приватный ключ должен быть в формате PEM и должен соответствовать сертификату.Эта директива была введена впервые в выпуске `v0.10.26`.

См. также [lua_ssl_certificate](#lua_ssl_certificate) и [lua_ssl_verify_depth](#lua_ssl_verify_depth).

[Назад к Оглавлению](#directives)

lua_ssl_trusted_certificate
----------------------------

**синтаксис:** *lua_ssl_trusted_certificate &lt;file&gt;*

**по умолчанию:** *никакое*

**контекст:** *http, server, location*

Указывает путь к файлу доверенных CA сертификатов в формате PEM, используемых для проверки сертификата SSL/TLS сервера в методе [tcpsock:sslhandshake](#tcpsocksslhandshake). Эта директива была введена впервые в выпуске `v0.9.11`.

См. также [lua_ssl_verify_depth](#lua_ssl_verify_depth).

[Назад к Оглавлению](#directives)

lua_ssl_verify_depth
--------------------

**синтаксис:** *lua_ssl_verify_depth &lt;число&gt;*

**по умолчанию:** *1*

**контекст:** *http, server, location*

Устанавливает глубину проверки в цепочке сертификатов сервера.

Эта директива была введена впервые в выпуске `v0.9.11`.

См. также [lua_ssl_certificate](#lua_ssl_certificate), [lua_ssl_certificate_key](#lua_ssl_certificate_key) и [lua_ssl_trusted_certificate](#lua_ssl_trusted_certificate).

[Назад к Оглавлению](#directives)

lua_ssl_conf_command
--------------------

**синтаксис:** *lua_ssl_conf_command &lt;команда&gt;*

**по умолчанию:** *нет*

**контекст:** *http, server, location*

Устанавливает произвольные команды конфигурации OpenSSL [commands](https://www.openssl.org/docs/man1.1.1/man3/SSL_CONF_cmd.html).

Директива поддерживается при использовании OpenSSL 1.0.2 или выше и nginx 1.19.4 или выше. В зависимости от конкретной команды может потребоваться более высокая версия OpenSSL.Можно указать несколько директив `lua_ssl_conf_command` на одном уровне:

```nginx

lua_ssl_conf_command Options PrioritizeChaCha;
lua_ssl_conf_command Ciphersuites TLS_CHACHA20_POLY1305_SHA256;
```

Команды конфигурации применяются после собственной конфигурации OpenResty для SSL, поэтому они могут использоваться для переопределения любого значения, установленного OpenResty.

Обратите внимание, однако, что прямое конфигурирование OpenSSL с помощью `lua_ssl_conf_command` может привести к поведению, которого OpenResty не ожидал, и должно выполняться с осторожностью.

Эта директива была введена впервые в выпуске `v0.10.21`.


[Назад к Оглавлению](#directives)

lua_http10_buffering
--------------------

**синтаксис:** *lua_http10_buffering on|off*

**по умолчанию:** *lua_http10_buffering on*

**контекст:** *http, сервер, расположение, расположение-if*

Включает или отключает автоматическое буферизирование ответа для HTTP  Yöntem 1.0 (или более старых) запросов. Этот механизм буферизации主要用于HTTP 1.0保持活动,它依赖于适当的`Content-Length`响应头。

Если Lua-код явно задает заголовок `Content-Length` в ответе перед отправкой (как через [ngx.send_headers](#ngxsend_headers) явно, так и через первый вызов [ngx.say](#ngxsay) или [ngx.print](#ngxprint) неявно), то даже при активации этого указания, буферизация ответа для HTTP 1.0 будет отключена. Для вывода очень больших данных ответа в потоковом режиме (например, с помощью вызова [ngx.flush](#ngxflush)), это указание ДОЛЖНО быть отключено для минимизации использования памяти.

Это указание по умолчанию установлено в `on`.

---

Внесены изменения в текст, чтобы он был более понятен и соответствовал правилам русского языка.Это указание было введено впервые в выпуске `v0.5.0rc19`.

[Назад к TOC](#directives)

rewrite_by_lua_no_postpone
---------------------------

**синтаксис:** *rewrite_by_lua_no_postpone on|off*

**по умолчанию:** *rewrite_by_lua_no_postpone off*

**контекст:** *http*

Управляет тем, следует ли отключать откладывание выполнения директив [rewrite_by_lua*](#rewrite_by_lua*) до конца фазы обработки запроса `rewrite`. По умолчанию это указание отключено, и Lua-код откладывается для выполнения в конце фазы `rewrite`.

Это указание было введено впервые в выпуске `v0.5.0rc29`.

[Назад к TOC](#directives)

access_by_lua_no_postpone
--------------------------

**синтаксис:** *access_by_lua_no_postpone on|off*

**по умолчанию:** *access_by_lua_no_postpone off*

**контекст:** *http*

Управляет тем, следует ли отключать откладывание выполнения директив [access_by_lua*](#access_by_lua*) до конца фазы обработки запроса `access`. По умолчанию это указание отключено, и Lua-код откладывается для выполнения в конце фазы `access`.

Это указание было введено впервые в выпуске `v0.9.20`.

[Назад к TOC](#directives)

lua_transform_underscores_in_response_headers
----------------------------------------------

**синтаксис:** *lua_transform_underscores_in_response_headers on|off*

**по умолчанию:** *lua_transform_underscores_in_response_headers on*

**контекст:** *http, server, location, location-if*

Управляет тем, следует ли преобразовывать подчеркивания (`_`) в названиях заголовков ответа, указанных в API [ngx.header.HEADER](#ngxheaderheader), в дефисы (`-`).

Это указание было введено впервые в выпуске `v0.5.0rc32`.[Назад к TOC](#directives)

lua_check_client_abort
-----------------------

**синтаксис:** *lua_check_client_abort on|off*

**по умолчанию:** *lua_check_client_abort off*

**контекст:** *http, server, location, location-if*

Это указание управляет тем, следует ли проверять наличие преждевременного прерывания соединения клиентом. Когда эта директива включена, модуль ngx_lua будет отслеживать событие преждевременного закрытия соединения на соединениях с клиентом. В случае наличия такого события модуль будет вызывать пользовательскую Lua-функцию, зарегистрированную через [ngx.on_abort](#ngxon_abort), или, если такая функция не зарегистрирована, прекратит выполнение всех Lua "лёгких потоков", работающих в текущем обработчике запроса.

[Назад к TOC](#directives)

lua_check_client_abort
-----------------------

**syntax:** *lua_check_client_abort on|off*

**default:** *lua_check_client_abort off*

**context:** *http, server, location, location-if*

This directive controls whether to check for premature client connection aborts. When this directive is enabled, the ngx_lua module will track premature connection closure events on client connections. In the event of such an occurrence, the module will call the user's registered Lua function callback (registered via [ngx.on_abort](#ngxon_abort)) or, if no user callback function is registered, terminate and clean up all running Lua "lightweight threads" in the current request handler.Когда эта директива включена, модуль ngx_lua будет отслеживать событие преждевременного закрытия соединения на соединениях с сервером. При возникновении такого события модуль вызовет зарезервированную пользователем Lua-функцию обратного вызова (зарегистрированную через [ngx.on_abort](#ngxon_abort)), либо, если такой функции нет, завершит выполнение и освободит все Lua "легковесные потоки", выполняющиеся в текущем обработчике запроса. Согласно текущей реализации, если клиент закрывает соединение до того, как Lua-код завершит чтение данных тела запроса через [ngx.req.socket](#ngxreqsocket), то ngx_lua ни при каких условиях не остановит все запущенные "легкие потоки" и не вызовет пользовательский обратный вызов (если был вызван [ngx.on_abort](#ngxon_abort)). Вместо этого операция чтения на [ngx.req.socket](#ngxreqsocket) вернёт сообщение об ошибке "клиент прервал соединение" как второй возвращаемый аргумент (первый возвращаемый аргумент наверняка будет `nil`).Когда поддержка TCP keepalive отключена, она полагается на сторону клиента для грациозного закрытия сокета (отправкой пакета `FIN` или чем-то подобным). Для (мягких) реальных времени веб-приложений настоятельно рекомендуется настроить поддержку [TCP keepalive](http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html) в реализации TCP-стека вашей системы для своевременного обнаружения "полуоткрытых" TCP-соединений.

Например, на Linux вы можете настроить стандартную [listen](http://nginx.org/en/docs/http/ngx_http_core_module.html#listen) директиву в вашем файле конфигурации `nginx.conf` следующим образом:

```nginx
listen 80 so_keepalive=2s:2s:8;
```

На FreeBSD вы можете только настроить системную конфигурацию для TCP keepalive, например:

    # sysctl net.inet.tcp.keepintvl=2000
    # sysctl net.inet.tcp.keepidle=2000

Эта директива была введена впервые в выпуске `v0.7.4`.

См. также [ngx.on_abort](#ngxon_abort).

[Назад к Оглавлению](#directives)

lua_max_pending_timers
-----------------------

**синтаксис:** *lua_max_pending_timers &lt;число&gt;*

**по умолчанию:** *lua_max_pending_timers 1024*

**контекст:** *http*

Управляет максимальным количеством ожидающих таймеров.

Ожидаемые таймеры — это те таймеры, которые ещё не истекли.

При превышении этого лимита вызов [ngx.timer.at](#ngxtimerat) немедленно вернёт `nil` и строку ошибки "слишком много ожидающих таймеров".

Эта директива была введена впервые в выпуске `v0.8.0`.

[Назад к Оглавлению](#directives)

lua_max_running_timers
-----------------------**синтаксис:** *lua_max_running_timers &lt;число&gt;*

**по умолчанию:** *lua_max_running_timers 256*

**контекст:** *http*

Управляет максимальным количеством запущенных таймеров.

Запущенные таймеры — это те таймеры, чьи пользовательские обратные вызовы всё ещё выполняются или `lightthreads`, созданные в обратных вызовах, всё ещё выполняются. При превышении этого лимита, Nginx прекратит выполнение обратных вызовов новых истёкших таймеров и выведет сообщение об ошибке "N lua_max_running_timers недостаточно", где "N" — текущее значение этой директивы.

Эта директива была введена впервые в выпуске `v0.8.0`.

[Назад к Оглавлению](#directives)

lua_sa_restart
--------------

**синтаксис:** *lua_sa_restart on|off*

**по умолчанию:** *lua_sa_restart on*

**контекст:** *http*

При включении этого модуля будет установлен флаг `SA_RESTART` для сигналов рабочих процессов Nginx.

Это позволяет Lua I/O примитивам не прерываться при обработке различных сигналов Nginx.

Эта директива была введена впервые в выпуске `v0.10.14`.

[Назад к Оглавлению](#directives)

lua_worker_thread_vm_pool_size
------------------------------

**синтаксис:** *lua_worker_thread_vm_pool_size &lt;размер&gt;*

**по умолчанию:** *lua_worker_thread_vm_pool_size 10*

**контекст:** *http*

Задает ограничение размера пула Lua VM (по умолчанию 100), который будет использоваться в API [ngx.run_worker_thread](#ngxrun_worker_thread).

Кроме того, создание Lua VM, превышающих лимит размера пула, не допускается.Lua VM в пуле используется для выполнения Lua кода в отдельном потоке.

Пул является глобальным на уровне рабочего процесса Nginx и используется для повторного использования Lua VM между запросами.

**Внимание:** Каждый рабочий поток использует отдельную Lua VM и кэширует Lua VM для повторного использования в последующих операциях. Настройка слишком большого количества рабочих потоков может привести к значительному потреблению памяти.

[Назад к Оглавлению](#directives)API Nginx для Lua
=================

* [Введение](#введение)
* [ngx.arg](#ngxarg)
* [ngx.var.VARIABLE](#ngxvarvariable)
* [Основные константы](#основные-константы)
* [Константы методов HTTP](#константы-методов-http)
* [Константы статусов HTTP](#конstantы-статусов-http)
* [Константы уровней логирования Nginx](#константы-уровней-логирования-nginx)
* [print](#print)
* [ngx.ctx](#ngxctx)
* [ngx.location.capture](#ngxlocationcapture)
* [ngx.location.capture_multi](#ngxlocationcapture_multi)
* [ngx.status](#ngxstatus)
* [ngx.header.HEADER](#ngxheaderheader)
* [ngx.resp.get_headers](#ngxrespget_headers)
* [ngx.req.is_internal](#ngxreqis_internal)
* [ngx.req.start_time](#ngxreqstart_time)
* [ngx.req.http_version](#ngxreqhttp_version)
* [ngx.req.raw_header](#ngxreqraw_header)
* [ngx.req.get_method](#ngxreqget_method)
* [ngx.req.set_method](#ngxreqset_method)
* [ngx.req.set_uri](#ngxreqset_uri)
* [ngx.req.set_uri_args](#ngxreqset_uri_args)
* [ngx.req.get_uri_args](#ngxreqget_uri_args)
* [ngx.req.get_post_args](#ngxreqget_post_args)
* [ngx.req.get_headers](#ngxreqget_headers)
* [ngx.req.set_header](#ngxreqset_header)
* [ngx.req.clear_header](#ngxreqclear_header)
* [ngx.req.read_body](#ngxreqread_body)
* [ngx.req.discard_body](#ngxreqdiscard_body)
* [ngx.req.get_body_data](#ngxreqget_body_data)
* [ngx.req.get_body_file](#ngxreqget_body_file)
* [ngx.req.set_body_data](#ngxreqset_body_data)
* [ngx.req.set_body_file](#ngxreqset_body_file)
* [ngx.req.init_body](#ngxreqinit_body)
* [ngx.req.append_body](#ngxreqappend_body)
* [ngx.req.finish_body](#ngxreqfinish_body)
* [ngx.req.socket](#ngxreqsocket)
* [ngx.exec](#ngxexec)
* [ngx.redirect](#ngxredirect)
* [ngx.send_headers](#ngxsend_headers)
* [ngx.headers_sent](#ngxheaders_sent)
* [ngx.print](#ngxprint)
* [ngx.say](#ngxsay)
* [ngx.log](#ngxlog)
* [ngx.flush](#ngxflush)
* [ngx.exit](#ngxexit)
* [ngx.eof](#ngxeof)
* [ngx.sleep](#ngxsleep)
* [ngx.escape_uri](#ngxescape_uri)
* [ngx.unescape_uri](#ngxunescape_uri)
* [ngx.encode_args](#ngxencode_args)
* [ngx.decode_args](#ngxdecode_args)
* [ngx.encode_base64](#ngxencode_base64)
* [ngx.decode_base64](#ngxdecode_base64)decode_base64mime](#ngxdecode_base64mime)
  * [ngx.crc32_short](#ngxcrc32_short)
  * [ngx.crc32_long](#ngxcrc32_long)
  * [ngx.hmac_sha1](#ngxhmac_sha1)
  * [ngx.md5](#ngxmd5)
  * [ngx.md5_bin](#ngxmd5_bin)
  * [ngx.sha1_bin](#ngxsha1_bin)
  * [ngx.quote_sql_str](#ngxquote_sql_str)
  * [ngx.today](#ngxtoday)
  * [ngx.time](#ngxtime)
  * [ngx.now](#ngxnow)
  * [ngx.update_time](#ngxupdate_time)
  * [ngx.localtime](#ngxlocaltime)
  * [ngx.utctime](#ngxutctime)
  * [ngx.cookie_time](#ngxcookie_time)
  * [ngx.http_time](#ngxhttp_time)
  * [ngx.parse_http_time](#ngxparse_http_time)
  * [ngx.is_subrequest](#ngxis_subrequest)
  * [ngx.re.match](#ngxrematch)
  * [ngx.re.find](#ngxrefind)
  * [ngx.re.gmatch](#ngxregmatch)
  * [ngx.re.sub](#ngxresub)
  * [ngx.re.gsub](#ngxregsub)
  * [ngx.shared.DICT](#ngxshareddict)
  * [ngx.shared.DICT.get](#ngxshareddictget)
  * [ngx.shared.DICT.get_stale](#ngxshareddictget_stale)
  * [ngx.shared.DICT.set](#ngxshareddictset)
  * [ngx.shared.DICT.safe_set](#ngxshareddictsafe_set)
  * [ngx.shared.DICT.add](#ngxshareddictadd)
  * [ngx.shared.DICT.safe_add](#ngxshareddictsafe_add)
  * [ngx.shared.DICT.replace](#ngxshareddictreplace)
  * [ngx.shared.DICT.delete](#ngxshareddictdelete)
  * [ngx.shared.DICT.incr](#ngxshareddictincr)
  * [ngx.shared.DICT.lpush](#ngxshareddictlpush)
  * [ngx.shared.DICT.rpush](#ngxshareddictrpush)
  * [ngx.shared.DICT.lpop](#ngxshareddictlpop)
  * [ngx.shared.DICT.rpop](#ngxshareddictrpop)
  * [ngx.shared.DICT.llen](#ngxshareddictllen)
  * [ngx.shared.DICT.ttl](#ngxshareddictttl)
  * [ngx.shared.DICT.expire](#ngxshareddictexpire)
  * [ngx.shared.DICT.flush_all](#ngxshareddictflush_all)
  * [ngx.shared.DICT.flush_expired](#ngxshareddictflush_expired)
  * [ngx.shared.DICT.get_keys](#ngxshareddictget_keys)
  * [ngx.shared.DICT.capacity](#ngxshareddictcapacity)
  * [ngx.shared.DICT.free_space](#ngxshareddictfree_space)
  * [ngx.socket.udp](#ngxsocketudp)
  * [udpsock.bind](#udpsockbind)
  * [udpsock.setpeername](#udpsocksetpeername)
  * [udpsock.send](#udpsocksend)
  * [udpsock.receive](#udpsockreceive)
  * [udpsock.close](#udpsockclose)
  * [udpsock.settimeout](#udpsocksettimeout)
  * [ngx.socket.stream](#ngxsocketstream)
  * [ngx.socket.tcp](#ngxsockettcp)
  * [tcpsock.bind](#tcpsockbind)
  * [tcpsock.connect](#tcpsockconnect)
  * [tcpsock.getfd](#tcpsockgetfd) * [tcpsock:setclientcert](#tcpsocksetclientcert)
  * [tcpsock:sslhandshake](#tcpsocksslhandshake)
  * [tcpsock:send](#tcpsocksend)
  * [tcpsock:receive](#tcpsockreceive)
  * [tcpsock:receiveany](#tcpsockreceiveany)
  * [tcpsock:receiveuntil](#tcpsockreceiveuntil)
  * [tcpsock:close](#tcpsockclose)
  * [tcpsock:settimeout](#tcpsocksettimeout)
  * [tcpsock:settimeouts](#tcpsocksettimeouts)
  * [tcpsock:setoption](#tcpsocksetoption)
 * [tcpsock:setkeepalive](#tcpsocksetkeepalive)
 * [tcpsock:getreusedtimes](#tcpsockgetreusedtimes)
 * [ngx.socket.connect](#ngxsocketconnect)
 * [ngx.get_phase](#ngxget_phase)
 * [ngx.thread.spawn](#ngxthreadspawn)
 * [ngx.thread.wait](#ngxthreadwait)
 * [ngx.thread.kill](#ngxthreadkill)
 * [ngx.on_abort](#ngxon_abort)
 * [ngx.timer.at](#ngxtimerat)
 * [ngx.timer.every](#ngxtimerevery)
 * [ngx.timer.running_count](#ngxtimerrunning_count)
 * [ngx.timer.pending_count](#ngxtimerpending_count)
 * [ngx.config.subsystem](#ngxconfigsubsystem)
 * [ngx.config.debug](#ngxconfigdebug)
 * [ngx.config.prefix](#ngxconfigprefix)
 * [ngx.config.nginx_version](#ngxconfignginx_version)
 * [ngx.config.nginx_configure](#ngxconfignginx_configure)
 * [ngx.config.nginx_lua_version](#ngxconfigngx_lua_version)
 * [ngx.worker.exiting](#ngxworkerexiting)
 * [ngx.worker.pid](#ngxworkerpid)
 * [ngx.worker.pids](#ngxworkerpids)
 * [ngx.worker.count](#ngxworkercount)
 * [ngx.worker.id](#ngxworkerid)
 * [ngx.semaphore](#ngxsemaphore)
 * [ngx.balancer](#ngxbalancer)
 * [ngx.ssl](#ngxssl)
 * [ngx.ocsp](#ngxocsp)
 * [ndk.set_var.DIRECTIVE](#ndkset_vardirective)
 * [coroutine.create](#coroutinecreate)
 * [coroutine.resume](#coroutineresume)
 * [coroutine.yield](#coroutineyield)
 * [coroutine.wrap](#coroutinewrap)
 * [coroutine.running](#coroutinerunning)
 * [coroutine.status](#coroutinestatus)
 * [ngx.run_worker_thread](#ngxrun_worker_thread)[Возврат к оглавлению](#table-of-contents)Введение
------------

Различные конфигурационные директивы `*_by_lua`, `*_by_lua_block` и `*_by_lua_file` служат в качестве шлюзов к API Lua внутри файла конфигурации `nginx.conf`. Описанное ниже API Lua может быть вызвано только внутри пользовательского кода Lua, выполняющегося в контексте этих конфигурационных директив.

API предоставляется Lua в виде двух стандартных пакетов `ngx` и `ndk`. Эти пакеты находятся в глобальной области по умолчанию в ngx_lua и всегда доступны в директивах ngx_lua.

Пакеты могут быть введены в внешние модули Lua следующим образом:

```lua

local say = ngx.say

local _M = {}

function _M.foo(a)
    say(a)
end

return _M
```

Использование флага [package.seeall](https://www.lua.org/manual/5.1/manual.html#pdf-package.seeall) строго не рекомендуется из-за его различных негативных побочных эффектов.

Также возможно прямое требование этих пакетов в внешних модулях Lua:

```lua

local ngx = require "ngx"
local ndk = require "ndk"
```

Возможность требовать этих пакетов была введена в выпуске `v0.2.1rc19`.Операции ввода-вывода через сеть в пользовательском коде должны выполняться только через вызовы API Lua Nginx, так как цикл событий Nginx может быть заблокирован, что приведет к значительному снижению производительности. Операции с диском с относительно небольшим объемом данных можно выполнять с помощью стандартной библиотеки Lua `io`, но чтение и запись больших файлов следует избегать по возможности, так как они могут значительно заблокировать процесс Nginx. Делегирование всех операций ввода-вывода через сеть и диск к подзапросам Nginx (через метод [ngx.location.capture](#ngxlocationcapture) и подобные) строго рекомендуется для максимальной производительности.[Возврат к оглавлению](#nginx-api-for-lua)

ngx.arg
-------

**синтаксис:** *val = ngx.arg\[index\]*

**контекст:** *set_by_lua*, *body_filter_by_lua*

Когда это используется в контексте директив [set_by_lua*](#set_by_lua), этот массив является только для чтения и содержит входные аргументы для конфигурационных директив:

```lua

value = ngx.arg[n]
```

Пример:

```nginx

location /foo {
    set $a 32;
    set $b 56;

    set_by_lua $sum
        'return tonumber(ngx.arg[1]) + tonumber(ngx.arg[2])'
        $a $b;

    echo $sum;
}
```

этот пример выводит `88`, сумму `32` и `56`. Когда эта таблица используется в контексте [body_filter_by_lua*](#body_filter_by_lua), первый элемент содержит блок входных данных для кода фильтра вывода, а второй элемент содержит булево значение флага "eof", указывающее на конец всего потока выводных данных.

Блок данных и флаг "eof" могут быть переопределены путем прямого присвоения значений соответствующим элементам таблицы. Установка значения `nil` или пустой строки Lua для `ngx.arg[1]` приведет к тому, что блок данных вообще не будет передан нижестоящим фильтрам вывода Nginx.

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.var.VARIABLE
----------------

**синтаксис:** *ngx.var.VAR_NAME*

**контекст:** *set_by_lua*, *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *header_filter_by_lua*, *body_filter_by_lua*, *log_by_lua*, *balancer_by_lua*

Чтение и запись значений переменных Nginx.

```nginx

value = ngx.var.some_nginx_variable_name
ngx.var.some_nginx_variable_name = value
```

Обратите внимание, что только уже определенные переменные Nginx могут быть записаны.
Например:```nginx

 location /foo {
     set $my_var ''; # эта строка необходима для создания переменной $my_var на этапе конфигурирования
     content_by_lua_block {
         ngx.var.my_var = 123
         ...
     }
 }
```

То есть переменные Nginx не могут создаваться на лету. Вот список заранее определённых
[переменных Nginx](http://nginx.org/en/docs/varindex.html).

Некоторые специальные переменные Nginx, такие как `$args` и `$limit_rate`, могут принимать значения, многие другие — нет, например, `$query_string`, `$arg_PARAMETER`, и `$http_NAME`.

Переменные Nginx для захвата групп регулярных выражений `$1`, `$2`, `$3`, и т.д., также могут быть прочитаны через этот интерфейс, записывая `ngx.var[1]`, `ngx.var[2]`, `ngx.var[3]`, и т.д.

Установка `ngx.var.Foo` в значение `nil` удалит переменную Nginx `$Foo`.

```lua

 ngx.var.args = nil
```

**ВНИМАНИЕ** При чтении из переменной Nginx, Nginx выделяет память в пуле памяти запроса, который освобождается только при завершении запроса. Поэтому, когда вам нужно многократно читать из переменной Nginx в вашем коде Lua, кэшируйте значение переменной Nginx в собственную переменную Lua, например,

```lua

 local val = ngx.var.some_var
 --- используйте val повторно позже
```

чтобы предотвратить временное утечку памяти в течение жизни текущего запроса. Другой способ кэширования результата — использование таблицы [ngx.ctx](#ngxctx). Неопределённые переменные Nginx оцениваются как `nil`, в то время как неинициализированные (но определённые) переменные Nginx оцениваются как пустую строку Lua.
Этот API требует относительно дорогостоящего вызова метаметода, поэтому рекомендуется избегать его использования на горячих путях выполнения кода.

[Назад к Оглавлению](#nginx-api-for-lua)

Основные константы
-------------------

**контекст:** *init_by_lua*, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer.*, balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, ssl_client_hello_by_lua*

```lua

   ngx.OK (0)
   ngx.ERROR (-1)
   ngx.AGAIN (-2)
   ngx.DONE (-4)
   ngx.DECLINED (-5)
```

Обратите внимание, что только три из этих констант используются в [API Nginx для Lua](#nginx-api-for-lua) (то есть [ngx.exit](#ngxexit) принимает `ngx.OK`, `ngx.ERROR` и `ngx.DECLINED` в качестве входных данных).

```lua

   ngx.null
```

Константа `ngx.null` является `NULL` легким userdata, обычно используемым для представления `nil` значений в таблицах Lua и т.д., и аналогична константе `cjson.null` библиотеки [lua-cjson](http://www.kyne.com.au/~mark/software/lua-cjson.php). Эта константа была введена в версии `v0.5.0rc5`.

Константа `ngx.DECLINED` была введена в версии `v0.5.0rc19`.

[Назад к Оглавлению](#nginx-api-for-lua)

Константы методов HTTP
-----------------------

**контекст:** *init_by_lua*, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer.*, balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, ssl_client_hello_by_lua*

```lua   ngx.HTTP_GET
   ngx.HTTP_HEAD
   ngx.HTTP_PUT
   ngx.HTTP_POST
   ngx.HTTP_DELETE
   ngx.HTTP_OPTIONS   (добавлено в версии v0.5.0rc24)
   ngx.HTTP_MKCOL     (добавлено в версии v0.8.2)
   ngx.HTTP_COPY      (добавлено в версии v0.8.2)
   ngx.HTTP_MOVE      (добавлено в версии v0.8.2)
   ngx.HTTP_PROPFIND  (добавлено в версии v0.8.2)
   ngx.HTTP_PROPPATCH (добавлено в версии v0.8.2)
   ngx.HTTP_LOCK      (добавлено в версии v0.8.2)
   ngx.HTTP_UNLOCK    (добавлено в версии v0.8.2)
   ngx.HTTP_PATCH     (добавлено в версии v0.8.2)
   ngx.HTTP_TRACE     (добавлено в версии v0.8.2)

```Эти константы обычно используются в вызовах методов [ngx.location.capture](#ngxlocationcapture) и [ngx.location.capture_multi](#ngxlocationcapture_multi).```[Назад к Оглавлению](#nginx-api-for-lua)

Константы HTTP-статуса
-----------------------

**контекст:** *init_by_lua*, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer.*, balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, ssl_client_hello_by_lua*```nginx```   значение = ngx. HTTP_CONTINUE (100) (впервые добавлено в выпуске v0. 9. 20)
    значение = ngx. HTTP_SWITCHING_PROTOCOLS (101) (впервые добавлено в выпуске v0. 9. 20)
    значение = ngx. HTTP_OK (200)
    значение = ngx. HTTP_CREATED (201)
    значение = ngx. HTTP_ACCEPTED (202) (впервые добавлено в выпуске v0. 9. 20)
    значение = ngx. HTTP_NO_CONTENT (204) (впервые добавлено в выпуске v0. 9. 20)
    значение = ngx. HTTP_PARTIAL_CONTENT (206) (впервые добавлено в выпуске v0. 9. 20)
    значение = ngx. HTTP_SPECIAL_RESPONSE (300)
    значение = ngx. HTTP_MOVED_PERMANENTLY (301)
    значение = ngx. HTTP_MOVED_TEMPORARILY (302)
    значение = ngx. HTTP_SEE_OTHER (303)
    значение = ngx. HTTP_NOT_MODIFIED (304)
    значение = ngx. HTTP_TEMPORARY_REDIRECT (307) (впервые добавлено в выпуске v0. 9. 20)
    значение = ngx. HTTP_PERMANENT_REDIRECT (308)
    значение = ngx. HTTP_BAD_REQUEST (400)
    значение = ngx. HTTP_UNAUTHORIZED (401)
    значение = ngx. HTTP_PAYMENT_REQUIRED (402) (впервые добавлено в выпуске v0. 9. 20)
    значение = ngx. HTTP_FORBIDDEN (403)
    значение = ngx. HTTP_NOT_FOUND (404)
    значение = ngx. HTTP_NOT_ALLOWED (405)
    значение = ngx. HTTP_NOT_ACCEPTABLE (406) (впервые добавлено в выпуске v0. 9. 20)
    значение = ngx. HTTP_REQUEST_TIMEOUT (408) (впервые добавлено в выпуске v0. 9. 20)
    значение = ngx. HTTP_CONFLICT (409) (впервые добавлено в выпуске v0. 9. 20)
    значение = ngx. HTTP_GONE (410)
    значение = ngx. HTTP_UPGRADE_REQUIRED (426) (впервые добавлено в выпуске v0. 9. 20)
    значение = ngx. HTTP_TOO_MANY_REQUESTS (429) (впервые добавлено в выпуске v0. 9. 20)
    значение = ngx. HTTP_CLOSE (444) (впервые добавлено в выпуске v0. 9. 20)
    значение = ngx. HTTP_ILLEGAL (451) (впервые добавлено в выпуске v0. 9. 20)
    значение = ngx. HTTP_INTERNAL_SERVER_ERROR (500)
    значение = ngx. HTTP_NOT_IMPLEMENTED (501)
    значение = ngx. HTTP_METHOD_NOT_IMPLEMENTED (501) (сохранено для обратной совместимости)
    значение = ngx. HTTP_BAD_GATEWAY (502) (впервые добавлено в выпуске v0. 9. 20)
    значение = ngx. HTTP_SERVICE_UNAVAILABLE (503)
    значение = ngx.HTTP_GATEWAY_TIMEOUT (504) (впервые добавлено в выпуске v0. 3. 1rc38)
    значение = ngx. HTTP_VERSION_NOT_SUPPORTED (505) (впервые добавлено в выпуске v0. 9. 20)
    значение = ngx. HTTP_INSUFFICIENT_STORAGE (507) (впервые добавлено в выпуске v0. 9. 20)[Назад к оглавлению](#nginx-api-for-lua)Константы уровней логирования Nginx
-----------------------------------

**Контекст:** *init_by_lua*, init_worker_by_lua, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer.*, balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, exit_worker_by_lua, ssl_client_hello_by_lua*

```lua

   ngx.STDERR
   ngx.EMERG
   ngx.ALERT
   ngx.CRIT
   ngx.ERR
   ngx.WARN
   ngx.NOTICE
   ngx.INFO
   ngx.DEBUG
```

Эти константы обычно используются в методе [ngx.log](#ngxlog).

[Назад к оглавлению](#nginx-api-for-lua)

print
-----

**Синтаксис:** *print(...)*

**Контекст:** *init_by_lua*, init_worker_by_lua, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer.*, balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, exit_worker_by_lua, ssl_client_hello_by_lua*

Записывает значения аргументов в файл логирования Nginx `error.log` с уровнем логирования `ngx.NOTICE`.

Это эквивалентно

```lua

 ngx.log(ngx.NOTICE, ...)
```

Аргументы Lua типа `nil` принимаются и приводят к строкам `"nil"`, а логические значения Lua приводят к строкам `"true"` или `"false"`. Константа `ngx.null` приводит к выводу строки `"null"`.

В ядре Nginx есть жёстко заданный лимит в 2048 байтов на длину сообщений об ошибках. Этот лимит включает завершающие символы новой строки и начальные отметки времени. Если размер сообщения превышает этот лимит, Nginx будет обрезать текст сообщения соответственно. Этот лимит можно вручную изменить, отредактировав определение макроса `NGX_MAX_ERROR_STR` в файле `src/core/ngx_log.h` дерева исходных кодов Nginx.[Назад к оглавлению](#nginx-api-for-lua)

ngx.ctx
-------

**контекст:** *init_worker_by_lua*, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer.*, balancer_by_lua, exit_worker_by_lua*

Эта таблица может использоваться для хранения данных контекста Lua для каждого запроса, и её срок службы совпадает со сроком службы текущего запроса (как и у переменных Nginx). Рассмотрим следующий пример:

```nginx

location /test {
    rewrite_by_lua_block {
        ngx.ctx.foo = 76
    }
    access_by_lua_block {
        ngx.ctx.foo = ngx.ctx.foo + 3
    }
    content_by_lua_block {
        ngx.say(ngx.ctx.foo)
    }
}
```

Тогда выполнение запроса `GET /test` приведёт к выводу:

```bash

79
```

То есть, запись `ngx.ctx.foo` сохраняется на протяжении всех фаз запроса: rewrite, access и content.

Каждый запрос, включая подзапросы, имеет свою копию таблицы. Например:

```nginx

location /sub {
    content_by_lua_block {
        ngx.say("sub pre: ", ngx.ctx.blah)
        ngx.ctx.blah = 32
        ngx.say("sub post: ", ngx.ctx.blah)
    }
}

location /main {
    content_by_lua_block {
        ngx.ctx.blah = 73
        ngx.say("main pre: ", ngx.ctx.blah)
        local res = ngx.location.capture("/sub")
        ngx.print(res.body)
        ngx.say("main post: ", ngx.ctx.blah)
    }
}
```

Тогда выполнение запроса `GET /main` приведёт к выводу:

```bash

main pre: 73
sub pre: nil
sub post: 32
main post: 73
```

Здесь изменение записи `ngx.ctx.blah` в подзапросе не влияет на запись в родительском запросе. Это происходит потому, что они имеют две отдельные версии `ngx.ctx.blah`.Внутренние переадресации (вызванные директивами конфигурации nginx, такими как `error_page`, `try_files`, `index` и т.д.) уничтожают данные запроса `ngx.ctx` (если такие имеются), и новый запрос будет иметь пустую таблицу `ngx.ctx`. Например:```nginx

 location /new {
     content_by_lua_block {
         ngx.say(ngx.ctx.foo)
     }
 }

 location /orig {
     content_by_lua_block {
         ngx.ctx.foo = "hello"
         ngx.exec("/new")
     }
 }
```

Тогда выполнение запроса `GET /orig` приведет к выводу:

```bash

 nil
```

вместо исходного значения `"hello"`.

Поскольку HTTP-запрос создается после SSL-рукопожатия, `ngx.ctx`, созданный в [ssl_certificate_by_lua*](#ssl_certificate_by_lua), [ssl_session_store_by_lua*](#ssl_session_store_by_lua), [ssl_session_fetch_by_lua*](#ssl_session_fetch_by_lua) и [ssl_client_hello_by_lua*](#ssl_client_hello_by_lua), недоступен в последующих фазах, таких как [rewrite_by_lua*](#rewrite_by_lua).

С версии `v0.10.18` `ngx.ctx`, созданный во время SSL-рукопожатия, будет наследоваться запросами, использующими ту же TCP-соединение, созданное рукопожатием. Обратите внимание, что перезапись значений в `ngx.ctx` в фазах HTTP-запроса (например, `rewrite_by_lua*`) будут влиять только на текущий HTTP-запрос. Арбитрные значения данных, включая замыкания Lua и вложенные таблицы, могут быть вставлены в эту "волшебную" таблицу. Она также позволяет регистрировать пользовательские мета-методы.

Перезапись `ngx.ctx` новой таблицей Lua также поддерживается, например,

```lua

 ngx.ctx = { foo = 32, bar = 54 }
```

Когда используется в контексте [init_worker_by_lua*](#init_worker_by_lua), эта таблица имеет ту же продолжительность жизни, что и текущий обработчик Lua.
Поиск по `ngx.ctx` требует относительно дорогостоящих вызовов мета-методов и значительно медленнее, чем явное передача данных на уровне запроса через аргументы функции. Поэтому не злоупотребляйте этим API для хранения своих аргументов функций, так как это обычно оказывает значительное влияние на производительность.Из-за магии мета-методов никогда не "локализуйте" таблицу `ngx.ctx` вне области видимости вашей функции Lua на уровне модуля Lua из-за [обмена данными между рабочими процессами Nginx](#data-sharing-within-an-nginx-worker). Например, следующее является плохим:

```lua

 -- mymodule.lua
 local _M = {}

 -- следующая строка является плохой, так как ngx.ctx — это данные на уровне запроса,
 -- в то время как эта переменная ctx находится на уровне модуля Lua
 -- и поэтому является на уровне рабочего процесса Nginx.
 local ctx = ngx.ctx

 function _M.main()
     ctx.foo = "bar"
 end

 return _M
```

Используйте следующее вместо этого:

```lua

 -- mymodule.lua
 local _M = {}

 function _M.main(ctx)
     ctx.foo = "bar"
 end

 return _M
```

То есть, пусть вызывающий код передает таблицу `ctx` явно через аргумент функции.

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.location.capture
--------------------

**синтаксис:** *res = ngx.location.capture(uri, options?)*

**контекст:** *rewrite_by_lua*, *access_by_lua*, *content_by_lua*

Выполняет синхронный, но все еще неблокирующий *Nginx Subrequest* с использованием `uri`.

Подзапросы Nginx предоставляют мощный способ для выполнения неблокирующих внутренних запросов к другим местам, конфигурируемым с помощью директорий файловой системы или *любых* других модулей C Nginx, таких как `ngx_proxy`, `ngx_fastcgi`, `ngx_memc`, `ngx_postgres`, `ngx_drizzle`, и даже `ngx_lua` и т.д.

Также обратите внимание, что подзапросы имитируют интерфейс HTTP, но нет дополнительной HTTP/TCP-трафики *ни* IPC. Все работает внутренне, эффективно, на уровне C.Подзапросы полностью отличаются от HTTP 301/302 переадресации (через [ngx.redirect](#ngxredirect)) и внутренней переадресации (через [ngx.exec](#ngxexec)). Вы всегда должны прочитать тело запроса (вызовом либо [ngx.req.read_body](#ngxreqread_body) или настройкой [lua_need_request_body](#lua_need_request_body)) до инициализации подзапроса.

Эта функция API (а также [ngx.location.capture_multi](#ngxlocationcapture_multi)) всегда буферизирует весь ответ подзапроса в памяти. Поэтому вы должны использовать [cosockets](#ngxsockettcp) и потоковое обработание, если вам нужно обрабатывать большие ответы подзапросов.

Вот базовый пример:

```lua
res = ngx.location.capture(uri)
```

Возвращает Lua таблицу с четырьмя слотами: `res.status`, `res.header`, `res.body`, и `res.truncated`.

`res.status` содержит код состояния ответа для ответа подзапроса.

`res.header` содержит все заголовки ответа подзапроса и является обычной Lua таблицей. Для многозначных заголовков ответа значение является Lua (массивной) таблицей, которая хранит все значения в порядке их появления. Например, если заголовки ответа подзапроса содержат следующие строки:

```bash
Set-Cookie: a=3
Set-Cookie: foo=bar
Set-Cookie: baz=blah
```

Тогда `res.header["Set-Cookie"]` будет оцениваться как таблицное значение `{"a=3", "foo=bar", "baz=blah"}`.`res.body` содержит данные тела ответа подзапроса, которые могут быть усечены. Вы всегда должны проверять булево значение `res.truncated`, чтобы узнать, содержит ли `res.body` усеченные данные. Усечение данных здесь может быть вызвано только непоправимыми ошибками в ваших подзапросах, такими как случаи, когда удалённый конец прерывает соединение слишком рано во время потока данных тела ответа или происходит таймаут при чтении, когда ваш подзапрос получает данные тела ответа от удалённого источника.Строки запроса URI могут быть объединены с URI самим, например,

```lua
res = ngx.location.capture('/foo/bar?a=3&b=4')
```

Именованные локации, такие как `@foo`, не допускаются из-за ограничения в ядре Nginx. Используйте обычные локации, объединённые с директивой `internal`, чтобы подготовить локации только для внутреннего использования.Необязательная опция таблица может быть передана как второй аргумент, поддерживающие опции:

* `method` — укажите метод запроса подзапроса, который принимает только константы, такие как `ngx.HTTP_POST`.
* `body` — укажите тело запроса подзапроса (только строковое значение).
* `args` — укажите параметры запроса URI подзапроса (как строковое значение, так и таблицы Lua допустимы).
* `headers` — укажите заголовки запроса подзапроса (только таблицы Lua). Эти заголовки заменят оригинальные заголовки подзапроса.
* `ctx` — укажите таблицу Lua, которая будет таблицей [ngx.ctx](#ngxctx) для подзапроса. Это может быть текущая таблица [ngx.ctx](#ngxctx) запроса, что фактически делает родительский запрос и его подзапросы совместно использующими одну и ту же таблицу контекста. Эта опция была введена в выпуске `v0.3.1rc25`.
* `vars` — укажите таблицу Lua, содержащую значения для установки указанных переменных Nginx в подзапросе. Эта опция была введена в выпуске `v0.3.1rc31`.
* `copy_all_vars` — укажите, следует ли копировать все значения переменных Nginx текущего запроса в подзапрос. Изменения переменных Nginx в подзапросе не будут влиять на текущий (родительский) запрос. Эта опция была введена в выпуске `v0.3.1rc31`.
* `share_all_vars` — укажите, следует ли делиться всеми переменными Nginx подзапроса с текущим (родительским) запросом. Изменения переменных Nginx в подзапросе будут влиять на текущий (родительский) запрос.Включение этой опции может привести к трудно отлаживаемым проблемам из-за побочных эффектов и считается нежелательным и вредным. Включайте эту опцию только тогда, когда вы полностью понимаете, что делаете.
* `always_forward_body`
	если установлено значение `true`, тело запроса текущего (родительского) запроса всегда будет передаваться в создаваемый подзапрос, если опция `body` не указана. Тело запроса, прочитанное с помощью [ngx.req.read_body()](#ngxreqread_body) или [lua_need_request_body on](#lua_need_request_body), будет передаваться в подзапрос без копирования всего содержимого тела запроса при создании подзапроса (независимо от того, находится ли тело запроса в буферах памяти или временных файлах). По умолчанию эта опция имеет значение `false`, и если опция `body` не указана, тело запроса текущего (родительского) запроса передается только при использовании методов запроса `PUT` или `POST`. Выполнение POST-подзапроса, например, можно выполнить следующим образом.```lua

res = ngx.location.capture(
    '/foo/bar',
    { method = ngx.HTTP_POST, body = 'hello, world' }
)
```

См. константы методов HTTP, отличные от POST.
Параметр `method` по умолчанию равен `ngx.HTTP_GET`.

Параметр `args` может указывать дополнительные аргументы URI, например,

```lua

ngx.location.capture('/foo?a=1',
    { args = { b = 3, c = ':' } }
)
```

эквивалентен

```lua

ngx.location.capture('/foo?a=1&b=3&c=%3a')
```

то есть этот метод экранирует ключи и значения аргументов в соответствии с правилами URI и объединяет их в полную строку запроса. Формат таблицы Lua, передаваемой как аргумент `args`, аналогичен формату, используемому в методе [ngx.encode_args](#ngxencode_args).

Параметр `args` также может принимать обычные строки запроса:

```lua

ngx.location.capture('/foo?a=1',
    { args = 'b=3&c=%3a' }
)
```

Это функционально эквивалентно предыдущим примерам.

Параметр `share_all_vars` контролирует, будут ли переменные Nginx делиться между текущим запросом и его подзапросами.
Если этот параметр установлен в `true`, то текущий запрос и связанные с ним подзапросы будут использовать одинаковый диапазон переменных Nginx. Таким образом, изменения переменных Nginx, сделанные подзапросом, повлияют на текущий запрос.

Необходимо проявлять осторожность при использовании этого параметра, так как разделение области переменных может привести к непредвиденным побочным эффектам. Обычно предпочтительнее использовать параметры `args`, `vars` или `copy_all_vars`.
```Этот параметр по умолчанию установлен в `false`.

```nginx

 location /other {
     set $dog "$dog мир";
     echo "$uri собака: $dog";
 }

 location /lua {
     set $dog 'привет';
     content_by_lua_block {
         res = ngx.location.capture("/other",
             { share_all_vars = true })

         ngx.print(res.body)
         ngx.say(ngx.var.uri, ": ", ngx.var.dog)
     }
 }
```

Доступ к локации `/lua` дает


    /other собака: привет мир
    /lua: привет мир


Параметр `copy_all_vars` обеспечивает копию переменных родительского запроса Nginx для подзапросов при их выполнении. Изменения, сделанные этими подзапросами, не повлияют на родительский запрос или любые другие подзапросы, использующие переменные родительского запроса.

```nginx
 location /other {
     set $dog "$dog мир";
     echo "$uri собака: $dog";
 }

 location /lua {
     set $dog 'привет';
     content_by_lua_block {
         res = ngx.location.capture("/other",
             { copy_all_vars = true })

         ngx.print(res.body)
         ngx.say(ngx.var.uri, ": ", ngx.var.dog)
     }
 }
```

Запрос `GET /lua` вернет вывод


    /other собака: привет мир
    /lua: привет


Обратите внимание, что если оба `share_all_vars` и `copy_all_vars` установлены в true, то `share_all_vars` имеет приоритет.

Кроме двух настроек выше, возможно указать значения переменных в подзапросе с помощью опции `vars`. Эти переменные устанавливаются после того, как были учтены операции совместного использования или копирования переменных, и предоставляют более эффективный метод передачи конкретных значений в подзапрос, чем закодирование их как аргументы URL и декодирование в конфигурационном файле Nginx.```nginx

 location /other {
     content_by_lua_block {
         ngx.say("собака = ", ngx.var.dog)
         ngx.say("кошка = ", ngx.var.cat)
     }
 }

 location /lua {
     set $dog '';
     set $cat '';
     content_by_lua_block {
         res = ngx.location.capture("/other",
             { vars = { dog = "привет", cat = 32 } })

         ngx.print(res.body)
     }
 }
```

Доступ к `/lua` даст вывод


    собака = привет
    кошка = 32

Опция `headers` может использоваться для указания заголовков запроса для подзапроса. Значение этой опции должно быть Lua таблицей, где ключи — это названия заголовков, а значения — это сами заголовки. Например,

```lua

location /foo {
    content_by_lua_block {
        ngx.print(ngx.var.http_x_test)
    }
}

location /lua {
    content_by_lua_block {
        local res = ngx.location.capture("/foo", {
            headers = {
                ["X-Test"] = "aa",
            }
        })
        ngx.print(res.body)
    }
}
```

Доступ к `/lua` даст вывод


    aa


Опция `ctx` может использоваться для указания пользовательской Lua таблицы, которая будет служить таблицей [ngx.ctx](#ngxctx) для подзапроса.

```nginx

 location /sub {
     content_by_lua_block {
         ngx.ctx.foo = "bar";
     }
 }
 location /lua {
     content_by_lua_block {
         local ctx = {}
         res = ngx.location.capture("/sub", { ctx = ctx })
```         ngx.say(ctx.foo)
         ngx.say(ngx.ctx.foo)
     }
 }
```

Затем запрос `GET /lua` дает ответ


    bar
    nil


Использование этого параметра `ctx` позволяет разделить одну и ту же таблицу [ngx.ctx](#ngxctx) между текущим (родительским) запросом и подзапросом:

```nginx

 location /sub {
     content_by_lua_block {
         ngx.ctx.foo = "bar"
     }
 }
 location /lua {
     content_by_lua_block {
         res = ngx.location.capture("/sub", { ctx = ngx.ctx })
         ngx.say(ngx.ctx.foo)
     }
 }
```Запрос `GET /lua` дает выходные данные


    bar


Обратите внимание, что подзапросы, инициированные с помощью [ngx.location.capture](#ngxlocationcapture), по умолчанию наследуют все заголовки запроса текущего запроса, что может привести к непредвиденным последствиям для ответов подзапросов. Например, при использовании стандартного модуля `ngx_proxy` для обслуживания подзапросов заголовок "Accept-Encoding: gzip" в основном запросе может привести к сжатым ответам, которые не могут быть правильно обработаны в Lua-коде. Оригинальные заголовки запроса должны игнорироваться путем установки параметра [proxy_pass_request_headers](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass_request_headers) в значение `off` в местах конфигурации подзапросов.

Когда параметр `body` не указан и параметр `always_forward_body` имеет значение `false` (значение по умолчанию), POST и PUT подзапросы наследуют тела запросов родительского запроса (если они есть).

Существует жестко закодированное верхнее ограничение на количество возможных подзапросов для каждого основного запроса. В более старых версиях Nginx это ограничение было равно `50` одновременных подзапросов, а в более новых версиях, начиная с Nginx `1.9.5`, это ограничение изменено на ограничение глубины рекурсивных подзапросов. Когда это ограничение превышено, следующее сообщение об ошибке добавляется в файл `error.log`:    [ошибка] 13983#0: *1 подзапросы циклически повторяются при обработке "/uri"


Это ограничение можно вручную изменить, отредактировав определение макроса `NGX_HTTP_MAX_SUBREQUESTS` в файле `nginx/src/http/ngx_http_request.h` в дереве исходных файлов Nginx.

Пожалуйста, обратите внимание также на ограничения на захват мест, настроенных с помощью [подзапросных директив других модулей](#locations-configured-by-subrequest-directives-of-other-modules).

[Назад к TOC](#nginx-api-for-lua)

ngx.location.capture_multi
--------------------------

**синтаксис:** *res1, res2, ... = ngx.location.capture_multi({ {uri, options?}, {uri, options?}, ... })*

**контекст:** *rewrite_by_lua*, *access_by_lua*, *content_by_lua*

Как и [ngx.location.capture](#ngxlocationcapture), но поддерживает несколько параллельных подзапросов.

Эта функция отправляет несколько параллельных подзапросов, указанных входной таблицей, и возвращает их результаты в том же порядке. Например,

```lua

 res1, res2, res3 = ngx.location.capture_multi{
     { "/foo", { args = "a=3&b=4" } },
     { "/bar" },
     { "/baz", { method = ngx.HTTP_POST, body = "hello" } },
 }

 if res1.status == ngx.HTTP_OK then
     ...
 end

 if res2.body == "BLAH" then
     ...
 end
```

Эта функция не вернётся до тех пор, пока все подзапросы не завершатся.
Общее время задержки — это самое длинное время задержки отдельных подзапросов, а не их сумма.

Таблицы Lua могут использоваться как для запросов, так и для ответов, когда количество подзапросов, которое нужно отправить, заранее не известно:

```lua

 -- создание таблицы запросов
 local reqs = {}
 table.insert(reqs, { "/mysql" })
 table.insert(reqs, { "/postgres" })
 table.insert(reqs, { "/redis" })
 table.insert(reqs, { "/memcached" })
``` -- одновременная отправка всех запросов и ожидание их завершения
 local resps = {
     ngx.location.capture_multi(reqs)
 }

 -- цикл по таблице ответов
 for i, resp in ipairs(resps) do
     -- обработка таблицы ответа resp
 end
```

Функция `ngx.location.capture` является просто специальным случаем этой функции. Логически говоря, `ngx.location.capture` может быть реализована следующим образом

```lua

 ngx.location.capture =
     function (uri, args)
         return ngx.location.capture_multi({ {uri, args} })
     end
```

Пожалуйста, обратитесь также к ограничениям на захват мест, настроенными с помощью подзапросных директив других модулей.

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.status
----------

**контекст:** *set_by_lua*, *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *header_filter_by_lua*, *body_filter_by_lua*, *log_by_lua*

Чтение и запись текущего статуса ответа запроса. Это следует вызывать до отправки заголовков ответа.

```lua

 ngx.status = ngx.HTTP_CREATED
 status = ngx.status
```

Установка `ngx.status` после отправки заголовков ответа не имеет эффекта, но оставляет сообщение об ошибке в файле журнала ошибок Nginx:

```
попытка установить ngx.status после отправки заголовков ответа
```

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.header.HEADER
-----------------

**синтаксис:** *ngx.header.HEADER = ЗНАЧЕНИЕ*

**синтаксис:** *значение = ngx.header.HEADER*

**контекст:** *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *header_filter_by_lua*, *body_filter_by_lua*, *log_by_lua*Устанавливает, добавляет или очищает текущий заголовок запроса `HEADER`, который будет отправлен.

Подчеркивания (`_`) в названиях заголовков по умолчанию заменяются дефисами (`-`). Это преобразование можно отключить с помощью директивы [lua_transform_underscores_in_response_headers](#lua_transform_underscores_in_response_headers).

Названия заголовков совпадают без учета регистра.

```lua

 -- эквивалентно ngx.header["Content-Type"] = 'text/plain'
 ngx.header.content_type = 'text/plain'

 ngx.header["X-My-Header"] = 'blah blah'
```

Множественные значения заголовков могут быть установлены следующим образом:

```lua

 ngx.header['Set-Cookie'] = {'a=32; path=/', 'b=4; path=/'}
```

что приведет к следующему:

```bash

 Set-Cookie: a=32; path=/
 Set-Cookie: b=4; path=/
```

в заголовках ответа.

Только таблицы Lua принимаются (только последний элемент в таблице будет иметь эффект для стандартных заголовков, таких как `Content-Type`, которые принимают только одно значение).

```lua

 ngx.header.content_type = {'a', 'b'}
```

эквивалентно

```lua

 ngx.header.content_type = 'b'
```

Установка слота в `nil` фактически удаляет его из заголовков ответа:

```lua

 ngx.header["X-My-Header"] = nil
```

То же самое применимо к присваиванию пустой таблицы:

```lua

 ngx.header["X-My-Header"] = {}
```

Установка `ngx.header.HEADER` после отправки заголовков ответа (явно с помощью [ngx.send_headers](#ngxsend_headers) или неявно с помощью [ngx.print](#ngxprint) и подобных) приведет к записи сообщения об ошибке.

Чтение `ngx.header.HEADER` вернет значение заголовка ответа с названием `HEADER`.Подчеркивания (`_`) в названиях заголовков также будут заменены дефисами (`-`) и названия заголовков будут совпадать без учета регистра. Если заголовок ответа вообще отсутствует, будет возвращено `nil`. Это особенно полезно в контексте [header_filter_by_lua*](#header_filter_by_lua), например,

```nginx
location /test {
    set $footer '';

    proxy_pass http://some-backend;

    header_filter_by_lua_block {
        if ngx.header["X-My-Header"] == "blah" then
            ngx.var.footer = "some value"
        end
    }

    echo_after_body $footer;
}
```

Для многострочных заголовков все значения заголовка будут собраны в порядке и возвращены как Lua-таблица. Например, ответные заголовки


    Foo: bar
    Foo: baz


будут приведены к виду

```lua
{"bar", "baz"}
```

при чтении `ngx.header.Foo`.

Обратите внимание, что `ngx.header` не является обычной Lua-таблицей, поэтому невозможно итерировать через неё с помощью Lua-функции `ipairs`.

Примечание: эта функция выбрасывает Lua-ошибку, если `HEADER` или `VALUE` содержат небезопасные символы (контрольные символы).

Для чтения заголовков запроса используйте функцию [ngx.req.get_headers](#ngxreqget_headers).

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.resp.get_headers
---------------------

**синтаксис:** *headers, err = ngx.resp.get_headers(max_headers?, raw?)*

**контекст:** *set_by_lua*, *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *header_filter_by_lua*, *body_filter_by_lua*, *log_by_lua*, *balancer_by_lua*

Возвращает Lua-таблицу, содержащую все текущие заголовки ответа для текущего запроса.```lua

local h, err = ngx.resp.get_headers()

if err == "truncated" then
    -- можно выбрать игнорирование или отклонение текущего ответа здесь
end

for k, v in pairs(h) do
    ...
end
```

Эта функция имеет ту же сигнатуру, что и [ngx.req.get_headers](#ngxreqget_headers), за исключением того, что она получает заголовки ответа вместо заголовков запроса.

Обратите внимание, что по умолчанию максимальное количество заголовков ответа, которое парсится, составляет OnClickListener 100 (включая те, у которых одинаковое имя), и что дополнительные заголовки ответа тихо игнорируются для защиты от потенциальных атак отказа в обслуживании. С версии `v0.10.13`, когда лимит превышается, она возвращает второе значение, которое является строкой `"truncated"`.

Этот API был вперваки введен в выпуске `v0.9.5`.

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.req.is_internal
-------------------

**синтаксис:** *is_internal = ngx.req.is_internal()***

**контекст:** *set_by_lua*, *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *header_filter_by_lua*, *body_filter_by_lua*, *log_by_lua*

Возвращает логическое значение, указывающее, является ли текущий запрос "внутренним запросом", то есть,
запросом, инициированным внутри текущего сервера Nginx, а не с клиентской стороны.

Подзапросы являются всеми внутренними запросами, такими же являются запросы после внутренних переадресаций.

Этот API был вперваки введен в выпуске `v0.9.20`.

[Назад к Оглавлению](#nginx-api-for-lua)
```ngx.req.start_time
------------------

**синтаксис:** *secs = ngx.req.start_time()*

**контекст:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*

Возвращает десятичное число, представляющее метку времени (включая миллисекунды как десятичную часть) момента создания текущего запроса.

В следующем примере эмулируется значение переменной `$request_time` (предоставленное модулем [ngx_http_log_module](http://nginx.org/en/docs/http/ngx_http_log_module.html)) чистым Lua:

```lua

local request_time = ngx.now() - ngx.req.start_time()
```

Эта функция была введена впервые в выпуске `v0.7.7`.

См. также [ngx.now](#ngxnow) и [ngx.update_time](#ngxupdate_time).

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.req.http_version
--------------------

**синтаксис:** *num = ngx.req.http_version()*

**контекст:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*

Возвращает номер версии протокола HTTP для текущего запроса как число Lua.

Текущие возможные значения —  Yöntem 3.0, 2.0, 1.0, 1.1 и 0.9. Возвращает `nil` для неизвестных значений.

Этот метод был введен впервые в выпуске `v0.7.17`.

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.req.raw_header
------------------

**синтаксис:** *str = ngx.req.raw_header(no_request_line?)*

**контекст:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*

Возвращает исходный сырой HTTP-заголовок, полученный сервером Nginx.

По умолчанию строка запроса и завершающий `CR LF` терминатор также будут включены. Например,

```lua

ngx.print(ngx.req.raw_header())
```

дает что-то вроде этого:    GET /t HTTP/1.1
    Host: localhost
    Connection: close
    Foo: barВы можете указать опциональный
`no_request_line` аргумент как значение `true`, чтобы исключить строку запроса из результата. Например,

```lua

ngx.print(ngx.req.raw_header(true))
```

выведет что-то вроде этого:

    Host: localhost
    Connection: close
    Foo: bar



Этот метод был впервые введен в выпуске `v0.7.17`.

Этот метод еще не работает с запросами HTTP/2.

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.req.get_method
------------------

**синтаксис:** *method_name = ngx.req.get_method()*

**контекст:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, balancer_by_lua*, log_by_lua*

Получает имя метода запроса текущего запроса. Возвращаются строки вроде `"GET"` и `"POST"` вместо числовых [констант метода](#http-method-constants).

Если текущий запрос является подзапросом Nginx, то возвращается имя метода подзапроса.

Этот метод был впервые введен в выпуске `v0.5.6`.

См. также [ngx.req.set_method](#ngxreqset_method).

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.req.set_method
------------------

**синтаксис:** *ngx.req.set_method(method_id)*

**контекст:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*

Заменяет метод запроса текущего запроса аргументом `method_id`. В настоящее время поддерживаются только числовые [константы метода](#http-method-constants), такие как `ngx.HTTP_POST` и `ngx.HTTP_GET`.

Если текущий запрос является подзапросом Nginx, то метод подзапроса будет заменен.

Этот метод был впервые введен в выпуске `v0.5.6`.

См. также [ngx.req.get_method](#ngxreqget_method).[Назад к Оглавлению](#nginx-api-for-lua)

ngx.req.set_uri
---------------

**синтаксис:** *ngx.req.set_uri(uri, jump?, binary?)*

**контекст:** *set_by_lua*, *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *header_filter_by_lua*, *body_filter_by_lua*

Перезаписывает (парсированное) URI текущего запроса аргументом `uri`. Аргумент `uri` должен быть строкой Lua и не может быть пустым, иначе будет выброшено исключение Lua. Необязательный булев аргумент `jump` может активировать перезапрос локации (или прыжок локации) как директива [rewrite](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite) модуля [ngx_http_rewrite_module](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html). То есть, когда `jump` равен `true` (по умолчанию `false`), эта функция никогда не вернётся и скажет Nginx попробовать заново найти локации с новым значением URI в последующей фазе `post-rewrite` и перейти к новой локации. Перемещение по местоположению не будет запущено в противном случае, и будет изменена только URI текущего запроса, что является также стандартным поведением. Эта функция вернётся, но без возвращаемых значений, если аргумент `jump` равен `false` или отсутствует вовсе.

Например, следующий фрагмент конфигурации Nginx

```nginx

rewrite ^ /foo last;
```

может быть записан на Lua следующим образом:

```lua

ngx.req.set_uri("/foo", true)
```

Аналогично, конфигурация Nginx

```nginx

rewrite ^ /foo break;
```

может быть записана на Lua следующим образом:

```lua

ngx.req.set_uri("/foo", false)
```или эквивалентно:

```lua

ngx.req.set_uri("/foo")
```

Аргумент `jump` может быть установлен только на `true` в [rewrite_by_lua*](#rewrite_by_lua). Использование `jump` в других контекстах запрещено и приведёт к выбросу исключения Lua.

Более сложный пример, включающий замены с использованием регулярных выражений, представлен ниже:

```nginx

location /test {
    rewrite_by_lua_block {
        local uri = ngx.re.sub(ngx.var.uri, "^/test/(.*)", "/$1", "o")
        ngx.req.set_uri(uri)
    }
    proxy_pass http://my_backend;
}
```

что функционально эквивалентно:

```nginx

location /test {
    rewrite ^/test/(.*) /$1 break;
    proxy_pass http://my_backend;
}
```

Примечание: эта функция выбрасывает исключение Lua, если аргумент `uri` содержит небезопасные символы (управляющие символы).

Примечание: использование этого интерфейса для изменения URI-параметров невозможно, и вместо него следует использовать [ngx.req.set_uri_args](#ngxreqset_uri_args). Например, конфигурация Nginx

```nginx

rewrite ^ /foo?a=3? last;
```

может быть записана следующим образом:

```lua

ngx.req.set_uri_args("a=3")
ngx.req.set_uri("/foo", true)
```

или

```lua

ngx.req.set_uri_args({a = 3})
ngx.req.set_uri("/foo", true)
```

С версии `0.10.16` этого модуля, эта функция принимает необязательный булевый аргумент `binary`, чтобы позволить произвольные двоичные данные URI. По умолчанию, этот аргумент `binary` равен `false`, и эта функция выбросит исключение Lua, если аргумент `uri` содержит какие-либо управляющие символы (код ASCII 0 ~ 0x08, 0x0A ~ 0x1F и 0x7F).    [ошибка] 23430#23430: *1 lua entry thread aborted: runtime error:
    content_by_lua(nginx.conf:44):3: ngx.req.set_uri unsafe byte "0x00"
    in "\x00foo" (может быть, вам стоит установить аргумент 'binary'?). Этот интерфейс был впервые введен в выпуске `v0.3.1rc14`.

[Назад к оглавлению](#nginx-api-for-lua)

ngx.req.set_uri_args
--------------------

**синтаксис:** *ngx.req.set_uri_args(args)*

**контекст:** *set_by_lua*, *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *header_filter_by_lua*, *body_filter_by_lua*

Перезаписывает URI-параметры запроса текущего запроса аргументом `args`. Аргумент `args` может быть как строкой Lua, так и таблицей Lua, содержащей пары ключ-значение параметров запроса. Например,

```lua

 ngx.req.set_uri_args("a=3&b=hello%20world")
```

или таблицей Lua, содержащей ключ-значение пары параметров запроса, как в следующем примере:

```lua

 ngx.req.set_uri_args({ a = 3, b = "hello world" })
```

В первом случае, когда вся строка запроса предоставляется напрямую, входная строка Lua должна уже быть правильно сформированной с URI-кодированием. По соображениям безопасности, этот метод автоматически экранирует любые контрольные и пробельные символы (код ASCII 0x00 ~ 0x20 и 0x7F) в строке Lua.

Во втором случае, этот метод экранирует ключи и значения параметров запроса согласно правилам URI-экранирования.

Поддержка многозначных параметров также предусмотрена:

```lua

 ngx.req.set_uri_args({ a = 3, b = {5, 6} })
```

что приведет к формированию строки запроса вида `a=3&b=5&b=6` или `b=5&b=6&a=3`.**Обратите внимание, что при использовании таблицы Lua в качестве аргумента `args`, порядок параметров в результирующей строке запроса может меняться от времени до времени. Если вам требуется упорядоченный результат, вам следует использовать строку Lua в качестве аргумента `args`.**Этот интерфейс был впервые введен в выпуске `v0.3.1rc13`.

См. также [ngx.req.set_uri](#ngxreqset_uri).

[Назад к оглавлению](#nginx-api-for-lua)

ngx.req.get_uri_args
---------------------

**синтаксис:** *args, err = ngx.req.get_uri_args(max_args?, tab?)*

**контекст:** *set_by_lua*, *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *header_filter_by_lua*, *body_filter_by_lua*, *log_by_lua*, *balancer_by_lua*

Возвращает таблицу Lua, содержащую все параметры запроса текущего URL. Опциональный аргумент `tab` может быть использован для переиспользования таблицы, возвращаемой этим методом.

```nginx

 location = /test {
     content_by_lua_block {
         local args, err = ngx.req.get_uri_args()

         if err == "truncated" then
             -- можно выбрать игнорирование или отклонение текущего запроса здесь
         end
     }
 }
```

Для каждого ключа и значения в парах(args) выполните следующее:

```lua

 for key, val in pairs(args) do
     if type(val) == "table" then
         ngx.say(key, ": ", table.concat(val, ", "))
     else
         ngx.say(key, ": ", val)
     end
 end
```

Тогда `GET /test?foo=bar&bar=baz&bar=blah` вернет ответ с телом:

```bash

 foo: bar
 bar: baz, blah
```

Множественные вхождения ключа аргумента приведут к значению таблицы, содержащему все значения для этого ключа в порядке.

Ключи и значения раскодируются согласно правилам экранирования URI. В настройках выше, `GET /test?a%20b=1%61+2` вернет:

```bash

 a b: 1a 2
```

Аргументы без части `=<значение>` рассматриваются как булевые аргументы. `GET /test?foo&bar` вернет:

```bash

 foo: true
 bar: true
```

То есть они будут иметь логические значения Lua `true`. Однако, они отличаются от аргументов, имеющих пустые строковые значения. `GET /test?foo=&bar=` вернет что-то вроде```bash

 foo:
 bar:
```

Пустые ключи аргументов игнорируются. `GET /test?=hello&=world` вернет пустой вывод, например.

Обновление аргументов запроса через переменную Nginx `$args` (или `ngx.var.args` в Lua) в реальном времени также поддерживается:

```lua

 ngx.var.args = "a=3&b=42"
 local args, err = ngx.req.get_uri_args()
```

Здесь таблица `args` всегда будет выглядеть так

```lua

 {a = 3, b = 42}
```

независимо от фактической строки запроса.

Обратите внимание, что по умолчанию парсинг аргументов запроса ограничен 100 аргументами (включая те с одинаковым именем) и что дополнительные аргументы запроса тихо игнорируются для защиты от потенциальных атак отказа в обслуживании. С версии `v0.10.13`, когда лимит превышается, вторым значением будет строка `"truncated"`.

Однако, опциональный аргумент функции `max_args` может использоваться для изменения этого лимита:

```lua

 local args, err = ngx.req.get_uri_args(10)
 if err == "truncated" then
     -- можно выбрать игнорировать или отклонить текущий запрос здесь
 end
```

Этот аргумент может быть установлен в ноль для удаления лимита и обработки всех полученных аргументов запроса:

```lua

 local args, err = ngx.req.get_uri_args(0)
```

Удаление ограничения `max_args` строго не рекомендуется.

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.req.get_post_args
----------------------**синтаксис:** *args, err = ngx.req.get_post_args(max_args?)*

**контекст:** *rewrite_by_lua\*, access_by_lua\*, content_by_lua\*, header_filter_by_lua\*, body_filter_by_lua\*, log_by_lua\***
Возвращает Lua-таблицу, содержащую все текущие аргументы запроса POST (типа MIME `application/x-www-form-urlencoded`). Вызовите [ngx.req.read_body](#ngxreqread_body), чтобы сначала прочитать тело запроса, или включите директиву [lua_need_request_body](#lua_need_request_body), чтобы избежать ошибок.

```nginx

location = /test {
    content_by_lua_block {
        ngx.req.read_body()
        local args, err = ngx.req.get_post_args()

        if err == "truncated" then
            -- можно выбрать игнорирование или отклонение текущего запроса здесь
        end

        if not args then
            ngx.say("не удалось получить POST аргументы: ", err)
            return
        end
        for key, val in pairs(args) do
            if type(val) == "table" then
                ngx.say(key, ": ", table.concat(val, ", "))
            else
                ngx.say(key, ": ", val)
            end
        end
    }
}
```

Затем

```bash

# POST-запрос с телом 'foo=bar&bar=baz&bar=blah'
$ curl --data 'foo=bar&bar=baz&bar=blah' localhost/test
```

вернет ответное тело, например

```bash

foo: bar
bar: baz, blah
```

Множественные вхождения ключа аргумента приведут к значению таблицы, содержащему все значения для этого ключа в порядке.

Ключи и значения будут декодированы согласно правилам экранирования URI.

С указанными выше настройками,

```bash

# POST-запрос с телом 'a%20b=1%61+2'
$ curl -d 'a%20b=1%61+2' localhost/test
```

вернет

```bash

a b: 1a 2
```

Аргументы без части `=<значение>` считаются логическими аргументами. `POST /test` с телом запроса `foo&bar` вернет

```bash

foo: true
bar: true
```

То есть они принимают логические значения Lua `true`. Однако, они отличаются от аргументов, принимающих пустые строки. `POST /test` с телом запроса `foo=&bar=` вернет что-то вроде```bash

 foo:
 bar:
```

Пустые ключи аргументов игнорируются. `POST /test` с телом `=hello&=world` вернет пустые выходные данные, например. Примечание: по умолчанию максимум  Yöntem: 100 аргументов запроса парсятся (включая те, у которых одинаковое имя), и дополнительные аргументы запроса тихо отбрасываются для защиты от потенциальных атак отказа в обслуживании. С версии `v0.10.13`, когда лимит превышается, будет возвращено второе значение, которое является строкой `"truncated"`. Однако опциональный аргумент функции `max_args` может использоваться для переопределения этого ограничения:

```lua

local args, err = ngx.req.get_post_args(10)
if err == "truncated" then
    -- можно выбрать игнорирование или отклонение текущего запроса здесь
end
```

Этот аргумент можно установить в ноль для удаления ограничения и обработки всех полученных аргументов запроса:

```lua

local args, err = ngx.req.get_post_args(0)
```

Удаление ограничения `max_args` строго не рекомендуется.

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.req.get_headers
-------------------

**синтаксис:** *headers, err = ngx.req.get_headers(max_headers?, raw?)*

**контекст:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*

Возвращает Lua-таблицу, содержащую все текущие заголовки запроса.

```lua

local h, err = ngx.req.get_headers()

if err == "truncated" then
    -- можно выбрать игнорирование или отклонение текущего запроса здесь
end

for k, v in pairs(h) do
    ...
end
```Чтобы прочитать отдельный заголовок:

```lua

ngx.say("Host: ", ngx.req.get_headers()["Host"])
```

Обратите внимание, что вызов API [ngx.var.HEADER](#ngxvarvariable), использующий ядро [$http_HEADER](http://nginx.org/en/docs/http/ngx_http_core_module.html#var_http_) переменные, может быть более предпочтителен для чтения отдельных заголовков запроса.

Для нескольких экземпляров заголовков запроса, таких как:

```bash

Foo: foo
Foo: bar
Foo: baz
```

значение `ngx.req.get_headers()["Foo"]` будет Lua (массивной) таблицей, такой как:

```lua

{"foo", "bar", "baz"}
```

Обратите внимание, что по умолчанию парсится максимум 100 заголовков запроса (включая те с одинаковым именем), и что дополнительные заголовки запроса тихо игнорируются для защиты от потенциальных атак отказа в обслуживании. С версии `v0.10.13`, когда лимит превышается, возвращается второе значение, которое является строкой `"truncated"`.

Однако опциональный аргумент функции `max_headers` может использоваться для переопределения этого ограничения:

```lua

local headers, err = ngx.req.get_headers(10)

if err == "truncated" then
    -- можно выбрать игнорирование или отклонение текущего запроса здесь
end
```

Этот аргумент можно установить в ноль для удаления ограничения и обработки всех полученных заголовков запроса:

```lua

local headers, err = ngx.req.get_headers(0)
```

Удаление ограничения `max_headers` настоятельно не рекомендуется.С момента выпуска версии `0.6.9` все имена заголовков в возвращаемой Lua-таблице преобразуются в полностью нижний регистр по умолчанию, если аргумент `raw` не установлен в `true` (по умолчанию `false`).Кроме того, по умолчанию в результирующую Lua-таблицу добавляется мета-метод `__index`, который нормализует ключи до чисто нижнего регистра с заменой всех подчеркиваний на дефисы при отсутствии совпадений. Например, если присутствует заголовок запроса `My-Foo-Header`, то следующие вызовы будут корректно выбирать значение этого заголовка:

```lua
ngx.say(headers.my_foo_header)
ngx.say(headers["My-Foo-Header"])
ngx.say(headers["my-foo-header"])
```

Мета-метод `__index` не будет добавлен, если аргумент `raw` установлен в `true`.

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.req.set_header
------------------

**синтаксис:** *ngx.req.set_header(имя_заголовка, значение_заголовка)*

**контекст:** *set_by_lua*, *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *header_filter_by_lua*, *body_filter_by_lua*

Устанавливает текущий заголовок запроса `имя_заголовка` значением `значение_заголовка`, переопределяя любые существующие значения.

Входная Lua-строка `имя_заголовка` и `значение_заголовка` должны уже быть правильно сформированы с учетом URI-кодирования. По соображениям безопасности этот метод автоматически экранирует `" ", """", "(", ")", ",", "/", ":", ";", "?", "<", "=", ">", "?", "@", "[", "]", "\", "{" и "}"` в диапазоне `0x00-0x1F, 0x7F-0xFF` для `имя_заголовка` и автоматически экранирует `0x00-0x08, 0x0A-0x0F, 0x7F` для `значение_заголовка`.

По умолчанию все подзапросы, последующие за [ngx.location.capture](#ngxlocationcapture) и [ngx.location.capture_multi](#ngxlocationcapture_multi), будут наследовать новый заголовок.Это не эквивалент Lua директивы Nginx `proxy_set_header` (так же верно для [ngx.req.clear_header](#ngxreqclear_header)). `proxy_set_header` влияет только на запрос к upstream, в то время как `ngx.req.set_header` изменяет входящий запрос. Запись HTTP-заголовков в файл журнала доступа покажет различия. Но вы всё равно можете использовать его как альтернативу директиве Nginx `proxy_set_header`, если знаете эти различия.

Вот пример установки заголовка `Content-Type`:

```lua
ngx.req.set_header("Content-Type", "text/css")
```

Значение заголовка `header_value` может быть списком значений в виде массива,
например,

```lua
ngx.req.set_header("Foo", {"a", "abc"})
```

что приведёт к созданию двух новых заголовков запроса:

```bash
Foo: a
Foo: abc
```

и старые заголовки `Foo` будут переопределены, если они существуют.

Когда аргумент `header_value` равен `nil`, заголовок запроса будет удалён. То есть

```lua
ngx.req.set_header("X-Foo", nil)
```

эквивалентно

```lua
ngx.req.clear_header("X-Foo")
```

Примечание: эта функция выбрасывает ошибку Lua, если `header_name` или
`header_value` содержат недопустимые символы (контрольные символы).

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.req.clear_header
---------------------

**синтаксис:** `ngx.req.clear_header(header_name)`

**контекст:** `set_by_lua`, `rewrite_by_lua*`, `access_by_lua*`, `content_by_lua*`, `header_filter_by_lua*`, `body_filter_by_lua*`

Удаляет текущий заголовок запроса с именем `header_name`. Никакие из существующих подзапросов текущего запроса не будут затронуты, но последующие инициированные подзапросы будут наследовать изменения по умолчанию.[Назад к Оглавлению](#nginx-api-for-lua)

ngx.req.read_body
-----------------

**синтаксис:** *ngx.req.read_body()*

**контекст:** *rewrite_by_lua*, *access_by_lua*, *content_by_lua*

Чтение тела запроса клиента синхронно без блокировки цикла событий Nginx.

```lua

 ngx.req.read_body()
 local args = ngx.req.get_post_args()
```

Если тело запроса уже было прочитано ранее путём включения [lua_need_request_body](#lua_need_request_body) или использованием других модулей, то эта функция не выполнится и вернётся немедленно.

Если тело запроса было явно отброшено, как это делается с помощью функции [ngx.req.discard_body](#ngxreqdiscard_body) или других модулей, эта функция не выполнится и вернётся немедленно.

В случае ошибок, таких как ошибки соединения при чтении данных, этот метод выбросит исключение Lua *или* завершит текущий запрос с кодом состояния 500 немедленно.

Данные тела запроса, прочитанные с помощью этой функции, могут быть получены позднее через [ngx.req.get_body_data](#ngxreqget_body_data) или, альтернативно, имя временного файла для данных тела, закэшированных на диск с помощью [ngx.req.get_body_file](#ngxreqget_body_file). Это зависит от:

1. проверяет, превышает ли текущее тело запроса размер [client_body_buffer_size](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size),
1. а также проверяет, включен ли параметр [client_body_in_file_only](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_in_file_only).В случаях, когда текущий запрос может содержать тело запроса, но данные тела запроса не требуются, необходимо использовать функцию [ngx.req.discard_body](#ngxreqdiscard_body) для явного отбрасывания тела запроса, чтобы избежать сбоев при использовании HTTP 1.1 keepalive или HTTP 1.1 pipelining.Эта функция была введена впервые в выпуске `v0.3.1rc17`.

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.req.discard_body
--------------------

**синтаксис:** *ngx.req.discard_body()*

**контекст:** *rewrite_by_lua*, *access_by_lua*, *content_by_lua*

Явно отбрасывает тело запроса, то есть читает данные соединения и немедленно отбрасывает их (не используя тело запроса никаким образом).

Эта функция является асинхронной и возвращает управление сразу.

Если тело запроса уже было прочитано, эта функция ничего не делает и немедленно возвращает управление.

Эта функция была введена впервые в выпуске `v0.3.1rc17`.

См. также [ngx.req.read_body](#ngxreqread_body).

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.req.get_body_data
----------------------

**синтаксис:** *data = ngx.req.get_body_data(max_bytes?)*

**контекст:** *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *log_by_lua*

Получает данные тела запроса, хранящиеся в памяти. Возвращает Lua-строку вместо Lua-таблицы, содержащей все распарсенные параметры запроса. Если требуется Lua-таблица, используйте функцию [ngx.req.get_post_args](#ngxreqget_post_args).

Необязательный параметр `max_bytes` можно использовать, если вам не требуется полное тело запроса.

Эта функция возвращает `nil`, если

1. тело запроса еще не было прочитано,
1. тело запроса было прочитано в временные файлы на диске,
1. или размер тела запроса равен нулю.Если тело запроса ещё не было прочитано, сначала вызовите функцию [ngx.req.read_body](#ngxreqread_body) (или включите параметр [lua_need_request_body](#lua_need_request_body) для принудительного чтения тела запроса этим модулем. Однако это не рекомендуется).Если тело запроса было прочитано в файлы на диске, попробуйте вызвать функцию [ngx.req.get_body_file](#ngxreqget_body_file). Чтобы заставить Nginx использовать встроенные в память тела запросов, попробуйте установить [client_body_buffer_size](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size) на ту же размерную величину, что и [client_max_body_size](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size).

Обратите внимание, что использование этой функции вместо `ngx.var.request_body` или `ngx.var.echo_request_body` более эффективно, так как это может сэкономить одну динамическую выделение памяти и одно копирование данных.

Эта функция была введена впервые в выпуске `v0.3.1rc17`.

См. также [ngx.req.get_body_file](#ngxreqget_body_file).

ngx.req.get_body_file
----------------------

**синтаксис:** *file_name = ngx.req.get_body_file()*

**контекст:** *rewrite_by_lua*, *access_by_lua*, *content_by_lua*

Получает имя файла для данных тела запроса, хранящихся в файле. Возвращает `nil`, если тело запроса ещё не было прочитано или было прочитано в память.

Возвращаемый файл является только для чтения и обычно очищается пулом памяти Nginx. Его не следует изменять, переименовывать или удалять в Lua-коде.

Если тело запроса ещё не было прочитано, сначала вызовите [ngx.req.read_body](#ngxreqread_body) (или включите [lua_need_request_body](#lua_need_request_body), чтобы заставить этот модуль прочитать тело запроса. Это не рекомендуется, однако).

Если тело запроса было прочитано в память, попробуйте вызвать функцию [ngx.req.get_body_data](#ngxreqget_body_data).Чтобы заставить Nginx использовать тела запросов, хранящиеся в файлах, попробуйте включить [client_body_in_file_only](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_in_file_only).

Обратите внимание, что эта функция также работает на этапе балансировки, но ей требуется вызов [balancer.recreate_request](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/balancer.md#recreate_request), чтобы изменения вступили в силу после установки данных тела запроса или заголовков.

Эта функция была введена впервые в выпуске `v0.3.1rc17`.

См. также [ngx.req.get_body_data](#ngxreqget_body_data).

[Назад к TOC](#nginx-api-for-lua)

ngx.req.set_body_data
----------------------

**синтаксис:** *ngx.req.set_body_data(data)*

**контекст:** *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *balancer_by_lua*

Устанавливает текущее тело запроса, используя данные, хранящиеся в памяти, указанные аргументом `data`. Если тело запроса ещё не было прочитано, сначала вызовите [ngx.req.read_body](#ngxreqread_body) (или включите [lua_need_request_body](#lua_need_request_body) для принудительного чтения тела запроса этим модулем. Однако это не рекомендуется). Кроме того, тело запроса не должно было быть ранее отброшено с помощью [ngx.req.discard_body](#ngxreqdiscard_body).

Независимо от того, был ли предыдущий запрос прочитан в память или буферизирован в файл на диске, он будет освобожден или файл на диске будет удален соответственно.Обратите внимание, что эта функция также работает на этапе балансировки, но ей требуется вызвать [balancer.recreate_request](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/balancer.md#recreate_request), чтобы изменения вступили в силу после установки данных или заголовков тела запроса.Эта функция была введена впервые в выпуске `v0.3.1rc18`.

См. также [ngx.req.set_body_file](#ngxreqset_body_file).

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.req.set_body_file
----------------------

**синтаксис:** *ngx.req.set_body_file(имя\_файла, auto\_clean?)*

**контекст:** *rewrite\_by\_lua*, *access\_by\_lua*, *content\_by\_lua*, *balancer\_by\_lua*

Устанавливает текущее тело запроса, используя данные из указанного файла `имя_файла`.

Если тело запроса еще не было прочитано, сначала вызовите [ngx.req.read_body](#ngxreqread_body) (или включите [lua\_need\_request\_body](#lua\_need\_request\_body) для принудительного чтения тела запроса этим модулем. Однако это не рекомендуется). Кроме того, тело запроса не должно было быть ранее отброшено с помощью [ngx.req.discard_body](#ngxreqdiscard_body).

Если опциональный аргумент `auto_clean` имеет значение `true`, этот файл будет удален при завершении запроса или при следующем вызове этой функции или [ngx.req.set_body_data](#ngxreqset_body_data) в том же запросе. Значение `auto_clean` по умолчанию равно `false`.

Убедитесь, что файл, указанный аргументом `имя_файла`, существует и доступен для чтения процессом рабочего узла Nginx, чтобы избежать ошибок исключения Lua.

Независимо от того, был ли предыдущий запрос прочитан в память или буферизирован в файл на диске, он будет освобожден или файл на диске будет удален соответственно.

Эта функция была введена впервые в выпуске `v0.3.1rc18`. См. также [ngx.req.set_body_data](#ngxreqset_body_data).[Назад к Оглавлению](#nginx-api-for-lua)

ngx.req.init_body
-----------------

**синтаксис:** *ngx.req.init_body(buffer_size?)*

**контекст:** *set_by_lua*, *rewrite_by_lua*, *access_by_lua*, *content_by_lua*

Создает новый пустой объект тела запроса для текущего запроса и инициализирует буфер для последующей записи данных тела запроса с помощью API [ngx.req.append_body](#ngxreqappend_body) и [ngx.req.finish_body](#ngxreqfinish_body).

Если указан аргумент `buffer_size`, то его значение будет использоваться для размера памяти буфера для записи тела запроса с помощью [ngx.req.append_body](#ngxreqappend_body). Если аргумент не указан, то вместо него будет использоваться значение, указанное стандартной директивой [client_body_buffer_size](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size).

Когда данные больше не могут быть сохранены в памяти буфера для тела запроса, они будут выгружены в временный файл, как это происходит с стандартным читателем тела запроса в ядре Nginx.

Важно всегда вызывать [ngx.req.finish_body](#ngxreqfinish_body) после того, как все данные были добавлены в текущее тело запроса. Также, когда эта функция используется вместе с [ngx.req.socket](#ngxreqsocket), требуется вызвать [ngx.req.socket](#ngxreqsocket) *до* этой функции, чтобы избежать ошибки "тело запроса уже существует".

Использование этой функции часто выглядит следующим образом:

```lua

 ngx.req.init_body(128 * 1024)  -- буфер 128КБ
 for chunk in next_data_chunk() do
     ngx.req.append_body(chunk) -- каждый кусок может быть 4КБ
 end
 ngx.req.finish_body()
```Эта функция может использоваться вместе с [ngx.req.append_body](#ngxreqappend_body), [ngx.req.finish_body](#ngxreqfinish_body) и [ngx.req.socket](#ngxreqsocket) для реализации эффективных фильтров ввода на чистом Lua (в контексте [rewrite_by_lua*](#rewrite_by_lua*) или [access_by_lua*](#access_by_lua*)), которые могут использоваться вместе с другими модулями содержимого Nginx или модулями-источниками, такими как [ngx_http_proxy_module](http://nginx.org/en/docs/http/ngx_http_proxy_module.html) и [ngx_http_fastcgi_module](http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html).

Эта функция была введена впервые в выпуске `v0.5.11`. [Назад к оглавлению](#nginx-api-for-lua)

ngx.req.append_body
-------------------

**синтаксис:** *ngx.req.append_body(data_chunk)*

**контекст:** *set_by_lua*, *rewrite_by_lua*, *access_by_lua*, *content_by_lua*

Добавляет новый фрагмент данных, указанный аргументом `data_chunk`, к существующему телу запроса, созданному с помощью вызова [ngx.req.init_body](#ngxreqinit_body).

Когда данные больше не могут быть сохранены в буфере памяти для тела запроса, они будут выгружены в временный файл, как это происходит с обычным читателем тела запроса в ядре Nginx.

Важно всегда вызывать [ngx.req.finish_body](#ngxreqfinish_body) после того, как все данные были добавлены к текущему телу запроса.Эта функция может использоваться вместе с [ngx.req.init_body](#ngxreqinit_body), [ngx.req.finish_body](#ngxreqfinish_body) и [ngx.req.socket](#ngxreqsocket) для реализации эффективных фильтров входных данных на чистом Lua (в контексте [rewrite_by_lua*](#rewrite_by_lua) или [access_by_lua*](#access_by_lua)), которые могут использоваться с другими модулями обработки содержимого или upstream Nginx, такими как [ngx_http_proxy_module](http://nginx.org/en/docs/http/ngx_http_proxy_module.html) и [ngx_http_fastcgi_module](http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html).Эта функция была введена впервые в выпуске `v0.5.11`.

См. также [ngx.req.init_body](#ngxreqinit_body).

[Назад к оглавлению](#nginx-api-for-lua)

ngx.req.finish_body
-------------------

**синтаксис:** *ngx.req.finish_body()*

**контекст:** *set_by_lua*, *rewrite_by_lua*, *access_by_lua*, *content_by_lua*

Завершает процесс построения нового тела запроса, созданного с помощью вызовов [ngx.req.init_body](#ngxreqinit_body) и [ngx.req.append_body](#ngxreqappend_body).

Эта функция может использоваться вместе с [ngx.req.init_body](#ngxreqinit_body), [ngx.req.append_body](#ngxreqappend_body) и [ngx.req.socket](#ngxreqsocket) для реализации эффективных фильтров входных данных на чистом Lua (в контексте [rewrite_by_lua*](#rewrite_by_lua) или [access_by_lua*](#access_by_lua)), которые могут использоваться с другими модулями обработки содержимого или upstream Nginx, такими как [ngx_http_proxy_module](http://nginx.org/en/docs/http/ngx_http_proxy_module.html) и [ngx_http_fastcgi_module](http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html). Эта функция была введена в выпуске `v0.5.11`.

См. также [ngx.req.init_body](#ngxreqinit_body).

[Назад к оглавлению](#nginx-api-for-lua)

ngx.req.socket
--------------

**синтаксис:** *tcpsock, err = ngx.req.socket()*

**синтаксис:** *tcpsock, err = ngx.req.socket(raw)*

**контекст:** *rewrite_by_lua*, *access_by_lua*, *content_by_lua*

Возвращает объект только для чтения cosocket, который обертывает соединение с клиентом. Поддерживаются только методы [receive](#tcpsockreceive), [receiveany](#tcpsockreceiveany) и [receiveuntil](#tcpsockreceiveuntil).

В случае ошибки будет возвращено значение `nil` вместе со строкой, описывающей ошибку.**Примечание:** Этот метод блокирует выполнение до полной загрузки тела запроса от клиента. Время блокировки зависит от директивы [client_body_timeout](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_timeout) и максимального размера тела запроса, указанного директивой [client_max_body_size](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size). Если происходит таймаут при чтении или размер тела запроса превышает заданный лимит, эта функция не вернёт управление и вместо этого будет возвращён ответ с кодом ошибки `408 Request Time-out` или `413 Request Entity Too Large`.

Объект сокета, возвращаемый этой функцией, обычно используется для чтения тела текущего запроса в потоковом режиме. Не активируйте директиву [lua_need_request_body](#lua_need_request_body), и не смешивайте этот вызов с [ngx.req.read_body](#ngxreqread_body) и [ngx.req.discard_body](#ngxreqdiscard_body).

Если какие-либо данные тела запроса были предварительно прочитаны в буфер заголовка запроса в ядре Nginx, созданный объект cosocket будет учитывать это, чтобы избежать потери данных вследствие предварительного чтения.

Разделенные блоками тела запроса ещё не поддерживаются в этой API.С версии `v0.9.0` эта функция принимает необязательный булев аргумент `raw`. Когда этот аргумент равен `true`, эта функция возвращает объект full-duplex cosocket, обёрнутый вокруг чистого сокета соединения с клиентом, на котором можно вызвать методы [receive](#tcpsockreceive), [receiveany](#tcpsockreceiveany), [receiveuntil](#tcpsockreceiveuntil) и [send](#tcpsocksend). Когда аргумент `raw` равен `true`, требуется, чтобы не было непереданных данных от любых предыдущих вызовов [ngx.say](#ngxsay), [ngx.print](#ngxprint) или [ngx.send_headers](#ngxsend_headers). Поэтому, если у вас есть эти вызовы вывода вниз по потоку ранее, вы должны вызвать [ngx.flush(true)](#ngxflush) перед вызовом `ngx.req.socket(true)`, чтобы гарантировать, что нет непереданных данных вывода. Если тело запроса ещё не было прочитано, то этот "сырой сокет" также можно использовать для чтения тела запроса. Вы можете использовать «сырой запросовый сокет», возвращаемый функцией `ngx.req.socket(true)`, чтобы реализовать сложные протоколы, такие как [WebSocket](https://ru.wikipedia.org/wiki/WebSocket), или просто отправить свои собственные сырые HTTP-заголовки или данные тела. Вы можете обратиться к библиотеке [lua-resty-websocket](https://github.com/openresty/lua-resty-websocket) для реального примера.Эта функция была введена впервые в выпуске `v0.5.0rc1`.

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.exec
--------

**синтаксис:** *ngx.exec(uri, args?)*

**контекст:** *rewrite_by_lua*, *access_by_lua*, *content_by_lua*

Выполняет внутреннее перенаправление на `uri` с `args` и аналогичен директиве [echo_exec](http://github.com/openresty/echo-nginx-module#echo_exec) модуля [echo-nginx-module](http://github.com/openresty/echo-nginx-module).

```lua

 ngx.exec('/some-location')
 ngx.exec('/some-location', 'a=3&b=5&c=6')
 ngx.exec('/some-location?a=3&b=5', 'c=6')
```

Необязательный второй аргумент `args` можно использовать для указания дополнительных параметров запроса URI, например:

```lua

 ngx.exec("/foo", "a=3&b=hello%20world")
```

Альтернативно, таблицу Lua можно передать в качестве аргумента `args` для выполнения URI-экранирования и конкатенации строк.

```lua

 ngx.exec("/foo", { a = 3, b = "hello world" })
```

Результат будет точно таким же, как и в предыдущем примере.

Формат таблицы Lua, передаваемой в качестве аргумента `args`, идентичен формату, используемому в методе [ngx.encode_args](#ngxencode_args).

Поддержка именованных локаций также предусмотрена, но второй аргумент `args` будет проигнорирован, если он присутствует, и строка запроса нового цели будет наследована от направляющей локации (если таковая имеется).

`GET /foo/file.php?a=hello` вернет "hello" и не "goodbye" в следующем примере

```nginx

 location /foo {
     content_by_lua_block {
         ngx.exec("@bar", "a=goodbye")
     }
 }

 location @bar {
     content_by_lua_block {
         local args = ngx.req.get_uri_args()
         for key, val in pairs(args) do
             if key == "a" then
                 ngx.say(val)
             end
         end
     }
 }
```Обратите внимание, что метод `ngx.exec` отличается от [ngx.redirect](#ngxredirect) тем, что это чисто внутреннее перенаправление, и что нет новых внешних HTTP-соединений. Также обратите внимание, что вызов этого метода завершает обработку текущего запроса, и он **должен** вызываться до [ngx.send_headers](#ngxsend_headers) или явного вывода тела ответа с помощью [ngx.print](#ngxprint) или [ngx.say](#ngxsay).

Рекомендуется использовать стиль программирования, который объединяет этот вызов метода со значением `return`, то есть `return ngx.exec(...)` при использовании этого метода в контекстах, отличных от [header_filter_by_lua*](#header_filter_by_lua), чтобы подчеркнуть тот факт, что обработка запроса завершается.

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.redirect
------------

**синтаксис:** *ngx.redirect(uri, status?)*

**контекст:** *rewrite_by_lua*, *access_by_lua*, *content_by_lua*

Выпустить `HTTP  Yöntem ngx.redirect, ngx.redirect'in [ngx.redirect](#ngxredirect) ile farklılık gösterir. Bu, tamamen iç periyodur ve yeni dış HTTP bağlantıları yoktur. Ayrıca, bu yöntem çağrıldığında mevcut isteğin işleme son verildiğini unutmamak gerekir. Bu nedenle, ngx.send_headers ([ngxsend_headers](#ngxsend_headers)) veya ngx.print ([ngxprint](#ngxprint)) veya ngx.say ([ngxsay](#ngxsay)) kullanılarak açıkça yanıt gövdesinin çıktısı verilmeden önce bu yöntem çağrılması gerekmektedir.

Bu yöntem, header_filter_by_lua* ([header_filter_by_lua](#header_filter_by_lua)) dışında kullanılacaksa, return anahtar kelimesiyle birlikte kullanmak önerilir. Örneğin, return ngx.exec(...) şeklinde kullanılması, isteğin işleme son verildiğini vurgulamaktadır.

[Ana Menü'ye Geri Dönüş](#nginx-api-for-lua)

ngx.redirect
------------

**Sintaksis:** *ngx.redirect(uri, status?)*

**Konteks:** *rewrite_by_lua*, *access_by_lua*, *content_by_lua*

`HTTP 301` veya `302` yönlendirme `uri`'ye gönderir.

Not: Bu fonksiyon, `uri` argümanı güvenli olmayan karakterler içeriyorsa (kontrol karakterleri), Lua hata fırlatır.

Opsiyonel `status` parametresi, kullanılacak HTTP durum kodunu belirtir. Şu anki desteklenen durum kodları şunlardır:

* `301`
* `302` (varsayılan olarak)
* `303`
* `307`
* `308`

Varsayılan olarak, `302` durum kodu (`ngx.HTTP_MOVED_TEMPORARILY`) kullanılır.

Aşağıda, şu varsayılan senaryo için örnek verilmiştir: mevcut sunucu adı `localhost` ve 1984 portunu dinliyor:

```lua
server {
    listen 1984;
    server_name localhost;

    location / {
        rewrite_by_lua_block {
            if ngx.var.uri == "/old" then
                ngx.redirect("/new")
            end
        }
        ...
    }
}
```

---

Обратите внимание, что метод `ngx.exec` отличается от [ngx.redirect](#ngxredirect) тем, что это чисто внутреннее перенаправление, и что нет новых внешних HTTP-соединений. Также обратите внимание, что вызов этого метода завершает обработку текущего запроса, и он **должен** вызываться до [ngx.send_headers](#ngxsend_headers) или явного вывода тела ответа с помощью [ngx.print](#ngxprint) или [ngx.say](#ngxsay).

Рекомендуется использовать стиль программирования, который объединяет этот вызов метода со значением `return`, то есть `return ngx.exec(...)` при использовании этого метода в контекстах, отличных от [header_filter_by_lua*](#header_filter_by_lua), чтобы подчеркнуть тот факт, что обработка запроса завершается.

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.redirect
------------

**синтаксис:** *ngx.redirect(uri, status?)*

**контекст:** *rewrite_by_lua*, *access_by_lua*, *content_by_lua*

Выпустить `HTTP 301` или `302` перенаправление на `uri`.

Примечание: эта функция выбрасывает ошибку Lua, если аргумент `uri` содержит небезопасные символы (управляющие символы).

Необязательный параметр `status` указывает HTTP-статус, который будет использоваться. В настоящее время поддерживаются следующие статусы:

* `301`
* `302` (по умолчанию)
* `303`
* `307`
* `308`

По умолчанию используется статус `302` (`ngx.HTTP_MOVED_TEMPORARILY`).

Вот пример, предполагающий, что текущее имя сервера — `localhost`, и он прослушивает порт 1984:

```lua
server {
    listen 1984;
    server_name localhost;

    location / {
        rewrite_by_lua_block {
            if ngx.var.uri == "/old" then
                ngx.redirect("/new")
            end
        }
        ...
    }
}
``` return ngx.redirect("/foo")
```

что эквивалентно

```lua

 return ngx.redirect("/foo", ngx.HTTP_MOVED_TEMPORARILY)
```

Поддерживается перенаправление произвольных внешних URL-адресов, например:

```lua

 return ngx.redirect("http://www.google.com")
```

Можно также использовать числовое значение кода напрямую как второй аргумент `status`:

```lua

 return ngx.redirect("/foo", gstauts.HTTTP_301)
```

Этот метод аналогичен директиве [rewrite](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite) с модификатором `redirect` в стандартном
[ngx_http_rewrite_module](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html), например, этот фрагмент конфигурации `nginx.conf`

```nginx

 rewrite ^ /foo? redirect;  # nginx config
```

эквивалентен следующему коду Lua

```lua

 return ngx.redirect('/foo')  -- Lua code
```

в то время как

```nginx

 rewrite ^ /foo? permanent;  # nginx config
```

эквивалентен

```lua

 return ngx.redirect('/foo', ngx.HTTP_MOVED_PERMANENTLY)  -- Lua code
```

Также можно указывать аргументы URI, например:

```lua

 return ngx.redirect('/foo?a=3&b=4')
```

Примечание: этот метод завершает обработку текущего запроса, и он **должен** вызываться до [ngx.send_headers](#ngxsend_headers) или явного вывода тела ответа с помощью [ngx.print](#ngxprint) или [ngx.say](#ngxsay).

Рекомендуется использовать стиль программирования, который объединяет этот метод с оператором `return`, то есть `return ngx.redirect(...)`, когда этот метод используется в контекстах, отличных от [header_filter_by_lua*](#header_filter_by_lua), чтобы подчеркнуть, что обработка запроса завершается.

[Назад к Оглавлению](#nginx-api-for-lua)ngx.send_headers
-----------------

**синтаксис:** *ok, err = ngx.send_headers()*

**контекст:** *rewrite_by_lua*, *access_by_lua*, *content_by_lua*

Явное отправление заголовков ответа.

С версии `v0.8.3` эта функция возвращает `1` при успешном выполнении, или `nil` и строку, описывающую ошибку, в противном случае.

Примечание: обычно нет необходимости вручную отправлять заголовки ответа, так как ngx_lua автоматически отправляет заголовки перед выводом содержимого с помощью [ngx.say](#ngxsay) или [ngx.print](#ngxprint) или при нормальном завершении работы [content_by_lua*](#content_by_lua).

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.headers_sent
-----------------

**синтаксис:** *value = ngx.headers_sent*

**контекст:** *set_by_lua*, *rewrite_by_lua*, *access_by_lua*, *content_by_lua*

Возвращает `true`, если заголовки ответа были отправлены (ngx_lua), и `false` в противном случае.

Этот API был впервые введен в ngx_lua v0.3.1rc6.

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.print
---------

**синтаксис:** *ok, err = ngx.print(...)*

**контекст:** *rewrite_by_lua*, *access_by_lua*, *content_by_lua*

Вывод аргументов, склеенных в HTTP-клиент (как тело ответа). Если заголовки ответа еще не были отправлены, эта функция сначала отправит заголовки, а затем выведет данные тела.

С версии `v0.8.3` эта функция возвращает `1` при успешном выполнении, или `nil` и строку, описывающую ошибку, в противном случае.

Значения `nil` Lua будут выводиться как строки `"nil"`, а логические значения Lua будут выводиться как литеральные строки `"true"` и `"false"` соответственно.Разрешены вложенные массивы строк, и элементы этих массивов будут отправлены по одному за раз:

```lua
local table = {
    "привет, ",
    {"мир: ", true, " или ", false,
        {": ", ngx.null}}
}
ngx.print(table)
```

выдаст вывод

```bash
привет, мир: true или false: null
```

Неассоциированные массивные аргументы таблицы вызовут выброс исключения Lua.

Константа `ngx.null` выдаст строковый вывод `"null"`.

Это асинхронный вызов и он вернётся немедленно без ожидания завершения записи всех данных в буфер отправки системы. Чтобы запустить в синхронном режиме, вызовите `ngx.flush(true)` после вызова `ngx.print`. Это может быть особенно полезно для потоковой передачи вывода. См. [ngx.flush](#ngxflush) для получения дополнительной информации.

Обратите внимание, что как `ngx.print`, так и [ngx.say](#ngxsay) всегда вызывают цепочку фильтровирования выходных данных Nginx, что является дорогостоящей операцией. Поэтому будьте осторожны при вызове одного из этих двух методов в плотно расположенных циклах; буфферизуйте данные самостоятельно в Lua и экономьте вызовы.

[Назад к Оглавлению](#nginx-api_for_lua)

ngx.say
-------

**синтаксис:** *ok, err = ngx.say(...)*

**контекст:** *rewrite_by_lua*, *access_by_lua*, *content_by_lua*

Как [ngx.print](#ngxprint), но также выводит завершающую новую строку.

[Назад к Оглавлению](#nginx_api_for_lua)

ngx.log
-------

**синтаксис:** *ngx.log(log_level, ...)***контекст:** init_by_lua, init_worker_by_lua, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer.*, balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, exit_worker_by_lua, ssl_client_hello_by_luaЛогирует аргументы, склеенные в error.log с указанным уровнем логирования.

Аргументы Lua `nil` принимаются и приводят к строке `"nil"`, а логические значения Lua приводят к строкам `"true"` или `"false"`. Константа `ngx.null` выдаёт строковый вывод `"null"`.

Аргумент `log_level` может принимать константы, такие как `ngx.ERR` и `ngx.WARN`. Подробнее см. [Константы уровня логирования Nginx](#nginx_log_level_constants).

В ядре Nginx жёстко задана ограничение на длину сообщений ошибок в 2048 байтов. Это ограничение включает завершающие новые строки и начальные отметки времени. Если размер сообщения превышает это ограничение, Nginx обрежет текст сообщения соответственно. Это ограничение можно вручную изменить, отредактировав определение макроса `NGX_MAX_ERROR_STR` в файле `src/core/ngx_log.h` дерева исходного кода Nginx.[Назад к оглавлению](#nginx-api-for-lua)

ngx.flush
---------

**синтаксис:** *ok, err = ngx.flush(ожидание?)*

**контекст:** *rewrite_by_lua*, *access_by_lua*, *content_by_lua*

Осуществляет сброс выходных данных ответа клиенту.

Функция `ngx.flush` принимает необязательный булевый аргумент `ожидание` (по умолчанию: `false`), введенный в версии `v0.3.1rc34`. При вызове с аргументом по умолчанию функция выполняет асинхронный вызов (возвращает управление сразу же, не дожидаясь записи данных в системный буфер отправки). Вызов функции с аргументом `ожидание`, установленным в `true`, переключает режим на синхронный.В синхронном режиме функция не вернет управление до тех пор, пока все данные не будут записаны в системный буфер отправки или пока не истечет настройка [send_timeout](http://nginx.org/en/docs/http/ngx_http_core_module.html#send_timeout). Обратите внимание, что использование механизма корутин Lua означает, что эта функция не блокирует цикл событий Nginx даже в синхронном режиме.

Когда `ngx.flush(true)` вызывается сразу после [ngx.print](#ngxprint) или [ngx.say](#ngxsay), это заставляет последнюю функцию работать в синхронном режиме. Это может быть особенно полезно для потокового вывода данных.

Обратите внимание, что `ngx.flush` не работает при использовании режима буферизации HTTP 1.0. См. [Поддержка HTTP 1.0](#http-10-support).

С версии `v0.8.3` эта функция возвращает `1` при успешном выполнении, или `nil` и строку, описывающую ошибку, в противном случае.

[Назад к оглавлению](#nginx-api-for-lua)

ngx.exit
--------

**синтаксис:** *ngx.exit(статус)*

**контекст:** *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *header_filter_by_lua*, *ngx.timer.*, *balancer_by_lua*, *ssl_certificate_by_lua*, *ssl_session_fetch_by_lua*, *ssl_session_store_by_lua*, *ssl_client_hello_by_lua*

При `статус >= 200` (то есть, `ngx.HTTP_OK` и выше), он прерывает выполнение текущего запроса и возвращает код состояния Nginx.

При `статус == 0` (то есть, `ngx.OK`), он завершает текущий обработчик фазы (или обработчик контента, если используется директива [content_by_lua*](#content_by_lua)) и продолжает выполнение следующих фаз (если они есть) для текущего запроса.Аргумент `status` может быть `ngx.OK`, `ngx.ERROR`, `ngx.HTTP_NOT_FOUND`, `ngx.HTTP_MOVED_TEMPORARILY` или другими [константами состояния HTTP](#http-status-constants). Чтобы вернуть страницу с ошибкой с пользовательским содержимым, используйте код, подобный этому:

```lua

 ngx.status = ngx.HTTP_GONE
 ngx.say("Это наше собственное содержимое")
 -- чтобы завершить обработку всего запроса, а не только текущей фазы
 ngx.exit(ngx.HTTP_OK)
```

Эффект в действии:

```bash

 $ curl -i http://localhost/test
 HTTP/1.1 410 Gone
 Server: nginx/1.0.6
 Date: Thu, 15 Sep 2011 00:51:48 GMT
 Content-Type: text/plain
 Transfer-Encoding: chunked
 Connection: keep-alive

 Это наше собственное содержимое
```

Числовые литералы могут использоваться напрямую в качестве аргумента, например,

```lua

 ngx.exit(501)
```

Обратите внимание, что этот метод принимает все [константы HTTP-статуса](#http-status-constants) в качестве входных данных, но принимает только `ngx.OK` и `ngx.ERROR` из [основных констант](#core-constants).

Также обратите внимание, что вызов этого метода завершает обработку текущего запроса, и рекомендуется использовать стиль программирования, который объединяет этот метод с оператором `return`, то есть `return ngx.exit(...)`, чтобы подчеркнуть, что обработка запроса завершена.Когда используется в контексте [header_filter_by_lua*](#header_filter_by_lua), [balancer_by_lua*](#balancer_by_lua_block) и [ssl_session_store_by_lua*](#ssl_session_store_by_lua_block), `ngx.exit()` является асинхронной операцией и немедленно возвращает управление. Это поведение может измениться в будущем, и рекомендуется всегда использовать `return` в сочетании с этим методом, как указано выше.[Назад к Оглавлению](#nginx-api-for-lua)

ngx.eof
-------

**синтаксис:** *ok, err = ngx.eof()*

**контекст:** *rewrite_by_lua*, *access_by_lua*, *content_by_lua*

Указывает явно конец потока вывода ответа. В случае HTTP 1.1 с чанками, это просто активирует отправку последнего чанка в ядре Nginx.

Когда отключено использование HTTP 1.1 keep-alive для ваших прокси-соединений, вы можете полагаться на правильно написанные HTTP-клиенты, чтобы они закрывали соединение активно при вызове этого метода. Этот трюк можно использовать для выполнения фоновых задач без того, чтобы HTTP-клиенты ждали завершения соединения, как показано в следующем примере:

```nginx location = /async {
     keepalive_timeout 0;
     content_by_lua_block {
         ngx.say("получил задачу!")
         ngx.eof()  -- правильно написанные HTTP-клиенты закроют соединение на этом этапе
         -- доступ к MySQL, PostgreSQL, Redis, Memcached и т.д. здесь...
     }
 }
```Но если вы создаете подзапросы для доступа к другим местоположениям, настроенными с помощью модулей upstream Nginx, то вам следует настроить эти модули upstream для игнорирования прерываний соединения клиентов, если они не игнорируются по умолчанию. Например, по умолчанию стандартный [ngx_http_proxy_module](http://nginx.org/en/docs/http/ngx_http_proxy_module.html) завершит как подзапрос, так и основной запрос сразу после того, как клиент закроет соединение, поэтому важно включить директиву [proxy_ignore_client_abort](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ignore_client_abort) в блок конфигурации location, настроенном с помощью [ngx_http_proxy_module](http://nginx.org/en/docs/http/ngx_http_proxy_module.html):```nginx

proxy_ignore_client_abort on;
```

Лучший способ выполнения фоновых задач — использовать API [ngx.timer.at](#ngxtimerat).

С версии `v0.8.3` эта функция возвращает `1` при успешном выполнении или `nil` и строку, описывающую ошибку в противном случае.

[Назад к оглавлению](#nginx-api-for-lua)

ngx.sleep
---------
**синтаксис:** *ngx.sleep(секунды)*

**контекст:** *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *ngx.timer.*, *ssl_certificate_by_lua*, *ssl_session_fetch_by_lua*, *ssl_client_hello_by_lua*

Засыпает на указанное количество секунд без блокировки. Можно указывать время с разрешением до 0.001 секунды (то есть одна миллисекунда).

За кулисами этот метод использует таймеры Nginx.

С версии `0.7.20` можно также указывать время `0`.

Эта функция была введена в версии `0.5.0rc30`.

[Назад к оглавлению](#nginx-api-for-lua)

ngx.escape_uri
--------------
**синтаксис:** *новая_строка = ngx.escape_uri(строка, тип?)*

**контекст:** *init_by_lua*, *init_worker_by_lua*, *set_by_lua*, *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *header_filter_by_lua*, *body_filter_by_lua*, *log_by_lua*, *ngx.timer.*, *balancer_by_lua*, *ssl_certificate_by_lua*, *ssl_session_fetch_by_lua*, *ssl_session_store_by_lua*, *exit_worker_by_lua*, *ssl_client_hello_by_lua*

С версии `v0.10.16` эта функция принимает необязательный аргумент `тип`.
Она принимает следующие значения (по умолчанию `2`):

* `0`: экранирует `строка` как полный URI. И символы
` ` (пробел), `#`, `%`,
`?`, 0x00 ~ 0x1F, 0x7F ~ 0xFF будут экранированы.
* `2`: экранирует `строка` как компонент URI. Все символы, кроме
алфавитных символов, цифр, `-`, `.`, `_`,
`~` будут закодированы как `%XX`.

[Назад к оглавлению](#nginx-api-for-lua)ngx.unescape_uri
-----------------

**синтаксис:** *newstr = ngx.unescape_uri(str)*

**контекст:** *init_by_lua\*, init_worker_by_lua\*, set_by_lua\*, rewrite_by_lua\*, access_by_lua\*, content_by_lua\*, header_filter_by_lua\*, body_filter_by_lua\*, log_by_lua\*, ngx.timer.\*, balancer_by_lua\*, ssl_certificate_by_lua\*, exit_worker_by_lua\*, ssl_client_hello_by_lua\***

Раскодирует `str` как заэкранированный компонент URI.

Например,

```lua

 ngx.say(ngx.unescape_uri("b%20r56+7"))
```

дает вывод


    b r56 7


Недействительные последовательности экранирования обрабатываются традиционным образом: `%` остаются без изменений. Также, символы, которые не должны появляться в заэкранированной строке, просто остаются без изменений.

Например,

```lua

 ngx.say(ngx.unescape_uri("try %search%%20%again%"))
```

дает вывод


    try %search% %again%


(Обратите внимание, что `%20` после `%` раскодировалось, даже если это можно считать частью недействительной последовательности.)

[Назад к оглавлению](#api-nginx-для-lua)

ngx.encode_args
---------------

**синтаксис:** *str = ngx.encode_args(table)*

**контекст:** *set_by_lua\*, rewrite_by_lua\*, access_by_lua\*, content_by_lua\*, header_filter_by_lua\*, body_filter_by_lua\*, log_by_lua\*, ngx.timer.\*, balancer_by_lua\*, ssl_certificate_by_lua\*, ssl_client_hello_by_lua\***

Кодирует Lua таблицу в строку запроса аргументов согласно правилам URI-кодирования.

Например,

```lua

 ngx.encode_args({foo = 3, ["b r"] = "hello world"})
```

дает


    foo=3&b%20r=hello%20world


Ключи таблицы должны быть Lua строками.

Поддерживаются многозначные аргументы запроса. Просто используйте Lua таблицу для значения аргумента, например:```lua

 ngx.encode_args({baz = {32, "hello"}})
```

дает


    baz=32&baz=hello


Если значение таблицы пустое, эффект эквивалентен значению `nil`.

Поддерживаются логические значения аргументов, например,

```lua

 ngx.encode_args({a = true, b = 1})
```

дает


    a&b=1


Если значение аргумента `false`, то эффект эквивалентен значению `nil`.

Этот метод был введен впервые в выпуске `v0.3.1rc27`.

[Назад к оглавлению](#api-nginx-для-lua)

ngx.decode_args
---------------

**синтаксис:** *table, err = ngx.decode_args(str, max_args?)*  
**контекст:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, ngx.timer.*, balancer_by_lua*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_session_store_by_lua*, ssl_client_hello_by_lua*

Разбирает URI-кодированную строку запроса в таблицу Lua. Это обратная функция для [ngx.encode_args](#ngxencode_args).

Необязательный аргумент `max_args` можно использовать для указания максимального количества аргументов, которые будут распарсены из аргумента `str`. По умолчанию из 100 аргументов запроса (включая те с одинаковым именем) парсятся только первые 100, а дополнительные URI-аргументы игнорируются для защиты от потенциальных атак отказа в обслуживании. С версии `v0.10.13`, если лимит превышается, функция вернет второй аргумент, который будет строкой `"truncated"`.

Этот аргумент можно установить в ноль для удаления ограничения и обработки всех полученных аргументов запроса:

```lua
```local args = ngx.decode_args(str, 0)
```

Удаление ограничения `max_args` строго не рекомендуется.

Метод был введен в версии `v0.5.0rc29`.

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.encode_base64
------------------

**синтаксис:** *newstr = ngx.encode_base64(str, no_padding?)*

**контекст:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, ngx.timer.*, balancer_by_lua*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_session_store_by_lua*, ssl_client_hello_by_lua*

Кодирует `str` в base64-строку. Для кодирования base64url используйте [`base64.encode_base64url`](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/base64.md#encode_base64url).

С версии `0.9.16` можно указать необязательный булевый аргумент `no_padding` для управления тем, будет ли добавлено заполнение base64 к конечной строке (по умолчанию `false`, то есть с заполнением).

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.decode_base64
------------------

**синтаксис:** *newstr = ngx.decode_base64(str)*

**контекст:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, ngx.timer.*, balancer_by_lua*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_session_store_by_lua*, ssl_client_hello_by_lua*

Декодирует аргумент `str` как base64-строку в исходную форму. Для декодирования base64url используйте [`base64.decode_base64url`](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/base64.md#decode_base64url).

Аргумент `str` должен быть стандартным 'base64' кодированием для RFC 3548 или RFC 4648, и будет возвращать `nil`, если он не является правильной формой или содержит символы, не входящие в алфавит базовой кодировки. Заполнение может быть опущено из входных данных.[Назад к Оглавлению](#nginx-api-for-lua)

ngx.decode_base64mime
----------------------
**синтаксис:** *newstr = ngx.decode_base64mime(str)*

**контекст:** *set_by_lua*, *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *header_filter_by_lua*, *body_filter_by_lua*, *log_by_lua*, *ngx.timer.*, *balancer_by_lua*, *ssl_certificate_by_lua*, *ssl_session_fetch_by_lua*, *ssl_session_store_by_lua*

**требования:** `resty.core.base64` или `resty.core`

Декодирует аргумент `str` как базовый шестнадцатеричный дайджест в исходную форму. Аргумент `str` следует базовой кодировке передачи для MIME (RFC 2045) и будет игнорировать символы, выходящие за рамки алфавита базовой кодировки. Возвращает `nil`, если `str` не является правильной формой.

 '''Примечание:''' Этот метод требует модулей <code>resty.core.base64</code> или <code>resty.core</code> из библиотеки [lua-resty-core](https://github.com/openresty/lua-resty-core).

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.crc32_short
---------------
**синтаксис:** *intval = ngx.crc32_short(str)*

**контекст:** *set_by_lua*, *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *header_filter_by_lua*, *body_filter_by_lua*, *log_by_lua*, *ngx.timer.*, *balancer_by_lua*, *ssl_certificate_by_lua*, *ssl_session_fetch_by_lua*, *ssl_session_store_by_lua*, *ssl_client_hello_by_lua*

Вычисляет CRC-32 (циклический код избыточности) дайджест для аргумента `str`. Этот метод работает лучше для относительно коротких входных данных `str` (т. е., менее 30 ~ 60 байтов), по сравнению с [ngx.crc32_long](#ngxcrc32_long). Результат точно такой же, как [ngx.crc32_long](#ngxcrc32_long).

За кулисами это просто тонкая обертка вокруг функции `ngx_crc32_short`, определенной в ядре Nginx.Эта API была введена впервые в выпуске `v0.3.1rc8`.

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.crc32_long
--------------
**синтаксис:** *intval = ngx.crc32_long(str)*

**контекст:** *set_by_lua*, *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *header_filter_by_lua*, *body_filter_by_lua*, *log_by_lua*, *ngx.timer.*, *balancer_by_lua*, *ssl_certificate_by_lua*, *ssl_session_fetch_by_lua*, *ssl_session_store_by_lua*, *ssl_client_hello_by_lua*

Вычисляет контрольную сумму CRC-32 (Cyclic Redundancy Check) для аргумента `str`.

Этот метод работает лучше всего на относительно длинных входных данных `str` (то есть длиннее 30 ~ 60 байт), по сравнению с [ngx.crc32_short](#ngxcrc32_short). Результат точно такой же, как [ngx.crc32_short](#ngxcrc32_short).

За кулисами это просто тонкая обёртка вокруг функции `ngx_crc32_long`, определённой в ядре Nginx.

Эта API была введена впервые в выпуске `v0.3.1rc8`.

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.hmac_sha1
-------------
**синтаксис:** *digest = ngx.hmac_sha1(secret_key, str)*

**контекст:** *set_by_lua*, *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *header_filter_by_lua*, *body_filter_by_lua*, *log_by_lua*, *ngx.timer.*, *balancer_by_lua*, *ssl_certificate_by_lua*, *ssl_session_fetch_by_lua*, *ssl_session_store_by_lua*, *ssl_client_hello_by_lua*

Вычисляет [HMAC-SHA1](https://en.wikipedia.org/wiki/HMAC) хэш аргумента `str` и преобразует результат с использованием секретного ключа `<secret_key>`.

Возвращает сырую двоичную форму хэша HMAC-SHA1. Для получения текстового представления используйте [ngx.encode_base64](#ngxencode_base64), например.

Пример:

```lua

local key = "thisisverysecretstuff"
local src = "some string we want to sign"
local digest = ngx.hmac_sha1(key, src)
ngx.say(ngx.encode_base64(digest))
```дает вывод


    R/pvxzHC4NLtj7S+kXFg/NePTmk=


Эта API требует наличия библиотеки OpenSSL в сборке Nginx (обычно передается опция `--with-http_ssl_module` скрипту `./configure`).

Эта функция была введена впервые в выпуске `v0.3.1rc29`.

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.md5
-------

**синтаксис:** *digest = ngx.md5(str)*

**контекст:** *set_by_lua*, *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *header_filter_by_lua*, *body_filter_by_lua*, *log_by_lua*, *ngx.timer.*, *balancer_by_lua*, *ssl_certificate_by_lua*, *ssl_session_fetch_by_lua*, *ssl_session_store_by_lua*, *ssl_client_hello_by_lua*

Возвращает шестнадцатеричное представление хэш-суммы MD5 аргумента типа `str`.

Например,

```nginx

location = /md5 {
    content_by_lua_block {
        ngx.say(ngx.md5("hello"))
    }
}
```

дает вывод


    5d41402abc4b2a76b9719d911017c592


Для получения сырых двоичных данных хэш-суммы MD5 см. [ngx.md5_bin](#ngxmd5_bin).

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.md5_bin
-----------

**синтаксис:** *digest = ngx.md5_bin(str)*

**контекст:** *set_by_lua*, *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *header_filter_by_lua*, *body_filter_by_lua*, *log_by_lua*, *ngx.timer.*, *balancer_by_lua*, *ssl_certificate_by_lua*, *ssl_session_fetch_by_lua*, *ssl_session_store_by_lua*, *ssl_client_hello_by_lua*

Возвращает двоичную форму хэш-суммы MD5 аргумента типа `str`.

Для получения шестнадцатеричного представления хэш-суммы MD5 см. [ngx.md5](#ngxmd5).

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.sha1_bin
------------

**синтаксис:** *digest = ngx.sha1_bin(str)*

**контекст:** *set_by_lua*, *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *header_filter_by_lua*, *body_filter_by_lua*, *log_by_lua*, *ngx.timer.*, *balancer_by_lua*, *ssl_certificate_by_lua*, *ssl_session_fetch_by_lua*, *ssl_session_store_by_lua*, *ssl_client_hello_by_lua*Возвращает двоичную форму хэш-суммы SHA-1 аргумента типа `str`.

Эта функция требует поддержки алгоритма SHA-1 в сборке Nginx. (Обычно это означает, что OpenSSL должен быть установлен при сборке Nginx).

Эта функция была введена в версии `v0.5.0rc6`.

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.quote_sql_str
-----------------

**синтаксис:** *quoted_value = ngx.quote_sql_str(raw_value)*

**контекст:** *set_by_lua*, *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *header_filter_by_lua*, *body_filter_by_lua*, *log_by_lua*, *ngx.timer.*, *balancer_by_lua*, *ssl_certificate_by_lua*, *ssl_session_fetch_by_lua*, *ssl_session_store_by_lua*, *ssl_client_hello_by_lua*

Возвращает заключенный в кавычки SQL-литерал строки согласно правилам кавычек MySQL.

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.today
---------

**синтаксис:** *str = ngx.today()*

**контекст:** *init_worker_by_lua*, *set_by_lua*, *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *header_filter_by_lua*, *body_filter_by_lua*, *log_by_lua*, *ngx.timer.*, *balancer_by_lua*, *ssl_certificate_by_lua*, *ssl_session_fetch_by_lua*, *ssl_session_store_by_lua*, *exit_worker_by_lua*, *ssl_client_hello_by_lua*

Возвращает текущую дату (в формате `yyyy-mm-dd`) из кеша времени Nginx (не требует системного вызова в отличие от библиотеки дат Lua).

Это локальное время.

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.time
--------

**синтаксис:** *secs = ngx.time()*

**контекст:** *init_worker_by_lua*, *set_by_lua*, *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *header_filter_by_lua*, *body_filter_by_lua*, *log_by_lua*, *ngx.timer.*, *balancer_by_lua*, *ssl_certificate_by_lua*, *ssl_session_fetch_by_lua*, *ssl_session_store_by_lua*, *exit_worker_by_lua*, *ssl_client_hello_by_lua*

Возвращает количество секунд, прошедших с эпохи, для текущего временного штампа из кеша времени Nginx (не требует системного вызова в отличие от библиотеки дат Lua).Обновление кеша времени Nginx можно заставить произойти, вызвав сначала [ngx.update_time](#ngxupdate_time).

[Назад к оглавлению](#nginx-api-for-lua)

ngx.now
-------

**синтаксис:** *secs = ngx.now()*

**контекст:** *init_worker_by_lua*, *set_by_lua*, *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *header_filter_by_lua*, *body_filter_by_lua*, *log_by_lua*, *ngx.timer.*, *balancer_by_lua*, *ssl_certificate_by_lua*, *ssl_session_fetch_by_lua*, *ssl_session_store_by_lua*, *exit_worker_by_lua*, *ssl_client_hello_by_lua*

Возвращает число с плавающей запятой, представляющее собой количество секунд, прошедших с эпохи (включая миллисекунды как десятичную часть), для текущего временного штампа из кеша времени Nginx (не требует системного вызова в отличие от библиотеки дат Lua).

Вы можете принудительно обновить кеш времени Nginx, вызвав сначала [ngx.update_time](#ngxupdate_time).

Эта API была введена впервые в версии `v0.3.1rc32`.

[Назад к оглавлению](#nginx-api-for-lua)

ngx.update_time
---------------

**синтаксис:** *ngx.update_time()*

**контекст:** *init_worker_by_lua*, *set_by_lua*, *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *header_filter_by_lua*, *body_filter_by_lua*, *log_by_lua*, *ngx.timer.*, *balancer_by_lua*, *ssl_certificate_by_lua*, *ssl_session_fetch_by_lua*, *ssl_session_store_by_lua*, *exit_worker_by_lua*, *ssl_client_hello_by_lua*

Принудительно обновляет кеш текущего времени Nginx. Этот вызов требует системного вызова и поэтому имеет некоторую нагрузку, так что не злоупотребляйте им. Эта API была введена впервые в `v0.3.1rc32`.

[Назад к оглавлению](#nginx-api-for-lua)

ngx.localtime
-------------

**синтаксис:** *str = ngx.localtime()***контекст:** *init_worker_by_lua*, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer.*, balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, exit_worker_by_lua, ssl_client_hello_by_lua*

Возвращает текущее местное время (в формате `yyyy-mm-dd hh:mm:ss`) из кеша Nginx (не требует системного вызова, в отличие от функции [os.date](https://www.lua.org/manual/5.1/manual.html#pdf-os.date) в Lua).

Это локальное время.

[Назад к оглавлению](#nginx-api-for-lua)

ngx.utctime
-----------

**синтаксис:** *str = ngx.utctime()*

**контекст:** *init_worker_by_lua*, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer.*, balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, exit_worker_by_lua, ssl_client_hello_by_lua*

Возвращает текущее время (в формате `yyyy-mm-dd hh:mm:ss`) из кеша Nginx (не требует системного вызова, в отличие от функции [os.date](https://www.lua.org/manual/5.1/manual.html#pdf-os.date) в Lua).

Это UTC время.

[Назад к оглавлению](#nginx-api-for-lua)

ngx.cookie_time
---------------

**синтаксис:** *str = ngx.cookie_time(sec)*

**контекст:** *init_worker_by_lua*, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer.*, balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, exit_worker_by_lua, ssl_client_hello_by_lua*

Возвращает отформатированную строку, которая может использоваться как время истечения срока действия cookie. Параметр `sec` представляет метку времени в секундах (например, такие, которые возвращаются из [ngx.time](#ngxtime)).

```nginx ngx.say(ngx.cookie_time(1290079655))
     -- выводит "Thu, 18-Nov-10 11:27:35 GMT"
```

[Назад к оглавлению](#nginx-api-for-lua)

ngx.http_time
-------------

**синтаксис:** *str = ngx.http_time(sec)*

**контекст:** *init_worker_by_lua*, *set_by_lua*, *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *header_filter_by_lua*, *body_filter_by_lua*, *log_by_lua*, *ngx.timer.*, *balancer_by_lua*, *ssl_certificate_by_lua*, *ssl_session_fetch_by_lua*, *ssl_session_store_by_lua*, *exit_worker_by_lua*, *ssl_client_hello_by_lua*

Возвращает отформатированную строку, которая может использоваться в качестве времени HTTP-заголовка (например, используется в заголовке `Last-Modified`). Параметр `sec` представляет собой метку времени в секундах (как те, которые возвращаются из [ngx.time](#ngxtime)).

```nginx

 ngx.say(ngx.http_time(1290079655))
     -- выводит "Thu, 18 Nov 2010 11:27:35 GMT"
```

[Назад к оглавлению](#nginx-api-for-lua)

ngx.parse_http_time
--------------------

**синтаксис:** *sec = ngx.parse_http_time(str)*

**контекст:** *init_worker_by_lua*, *set_by_lua*, *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *header_filter_by_lua*, *body_filter_by_lua*, *log_by_lua*, *ngx.timer.*, *balancer_by_lua*, *ssl_certificate_by_lua*, *ssl_session_fetch_by_lua*, *ssl_session_store_by_lua*, *exit_worker_by_lua*, *ssl_client_hello_by_lua*

Разбирает строку времени HTTP (как возвращается из [ngx.http_time](#ngxhttp_time)) в секунды. Возвращает количество секунд или `nil`, если входная строка имеет некорректный формат.

```nginx

 local time = ngx.parse_http_time("Thu, 18 Nov 2010 11:27:35 GMT")
 if time == nil then
     ...
 end
```

[Назад к оглавлению](#nginx-api-for-lua)

ngx.is_subrequest
-----------------

**синтаксис:** *value = ngx.is_subrequest*

**контекст:** *set_by_lua*, *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *header_filter_by_lua*, *body_filter_by_lua*, *log_by_lua*Возвращает `true`, если текущий запрос является подзапросом Nginx, или `false` в противном случае.

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.re.match
------------

**синтаксис:** *captures, err = ngx.re.match(subject, regex, options?, ctx?, res_table?)*

**контекст:** *init_worker_by_lua*, *set_by_lua*, *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *header_filter_by_lua*, *body_filter_by_lua*, *log_by_lua*, *ngx.timer.*, *balancer_by_lua*, *ssl_certificate_by_lua*, *ssl_session_fetch_by_lua*, *ssl_session_store_by_lua*, *exit_worker_by_lua*, *ssl_client_hello_by_lua*

Соответствует строке `subject` с использованием регулярного выражения, совместимого с Perl (`regex`) с опциональными `options`.

Возвращается только первое вхождение совпадения, или `nil`, если совпадение не найдено. В случае ошибок, таких как некорректное регулярное выражение или превышение лимита стека PCRE, возвращаются `nil` и строка, описывающая ошибку.

При нахождении совпадения возвращается таблица Lua `captures`, где `captures[0]` содержит полную подстроку, соответствующую совпадению, а `captures[1]` — первое захваченное подвыражение, заключенное в скобки, `captures[2]` — второе, и так далее.

```lua

local m, err = ngx.re.match("hello, 1234", "[0-9]+")
if m then
    -- m[0] == "1234"

else
    if err then
        ngx.log(ngx.ERR, "ошибка: ", err)
        return
    end

    ngx.say("совпадение не найдено")
end
```

```lua

local m, err = ngx.re.match("hello, 1234", "([0-9])[0-9]+")
-- m[0] == "1234"
-- m[1] == "1"
```

Поддержка захваченных по имени подвыражений также доступна начиная с версии `v0.7.14` и возвращается в той же таблице Lua в виде пар ключ-значение, аналогично захваченным по номеру подвыражениям.```lua

local m, err = ngx.re.match("hello, 1234", "([0-9])(?<remaining>[0-9]+)")
-- m[0] == "1234"
-- m[1] == "1"
-- m[2] == "234"
-- m["remaining"] == "234"
```

Несоответствующие подвыражения будут иметь значения `false` в соответствующих полях таблицы `captures`.

```lua

local m, err = ngx.re.match("hello, world", "(world)|(hello)|(?<named>howdy)")
-- m[0] == "hello"
-- m[1] == false
-- m[2] == "hello"
-- m[3] == false
-- m["named"] == false
```

Укажите `options`, чтобы контролировать выполнение операции поиска совпадений. Поддерживаются следующие опции:

    a             anchored mode (только совпадение с начала строки)

    d             включение режима DFA (или семантики нахождения самого длинного совпадения).
                  это требует PCRE 6.0+ или иначе выбрасывает исключение Lua.
                  впервые введен в ngx_lua v0.3.1rc30.

    D             включение поддержки повторяющихся имен подвыражений. Это позволяет использовать повторяющиеся имена подвыражений, возвращая захваченные значения в массивной таблице Lua. Например,
                    local m = ngx.re.match("hello, world",
                                           "(?<named>\w+), (?<named>\w+)",
                                           "D")
                    -- m["named"] == {"hello", "world"}
                  эта опция была введена впервые в версии v0.7.14.
                  эта опция требует хотя бы PCRE 8.12.

    i             регистронезависимый режим (похож на модификатор /i в Perl)

    j             включает JIT-компиляцию PCRE, что требует версии PCRE 8.21+ с
                  компиляцией с опцией --enable-jit. для оптимальной производительности,
                  эту опцию следует использовать вместе с опцией 'o'. впервые введен в ngx_lua v0.3.1rc30.
```    J             включает режим совместимости с JavaScript PCRE. Эта опция была
                  введена впервые в версии v0.7.14. Эта опция требует
                  версии PCRE 8.12 и выше.

    m             многострочный режим (похож на модификатор /m в Perl)

    o             режим компиляции один раз (похож на модификатор /o в Perl),
                  чтобы включить кэширование регулярных выражений на уровне рабочего процесса

    s             однобуквенный режим (похож на модификатор /s в Perl)

    u             режим UTF-8. Эта опция требует PCRE, скомпилированного с
                  опцией --enable-utf8, иначе будет выброшено исключение Lua.

    U             похож на "u", но отключает проверку корректности UTF-8 PCRE
                  для строки подстроки. Впервые введен в ngx_lua v0.8.1.

    x             расширенный режим (похож на модификатор /x в Perl)


Эти опции могут быть объединены:

```nginx

 local m, err = ngx.re.match("hello, world", "HEL LO", "ix")
 -- m[0] == "hello"
```

```nginx

 local m, err = ngx.re.match("hello, 美好生活", "HELLO, (.{2})", "iu")
 -- m[0] == "hello, 美好"
 -- m[1] == "美好"
```

Опция `o` полезна для настройки производительности, так как заданное регулярное выражение будет скомпилировано только один раз, закэшировано на уровне рабочего процесса и поделено между всеми запросами в текущем рабочем процессе Nginx. Верхний предел кэша регулярных выражений можно настроить через директиву [lua_regex_cache_max_entries](#lua_regex_cache_max_entries).Необязательный четвертый аргумент, `ctx`, может быть таблицей Lua, содержащей необязательное поле `pos`. Когда поле `pos` в аргументе таблицы `ctx` указано, `ngx.re.match` начнет поиск с этого смещения (начиная с 1). Независимо от присутствия поля `pos` в таблице `ctx`, `ngx.re.match` всегда установит это поле `pos` на позицию *после* подстроки, соответствующей целому шаблону при успешном совпадении. При неудачном совпадении таблица `ctx` останется нетронутой.

```lua
local ctx = {}
local m, err = ngx.re.match("1234, привет", "[0-9]+", "", ctx)
      -- m[0] = "1234"
      -- ctx.pos == 5
```

```lua
local ctx = { pos = 2 }
local m, err = ngx.re.match("1234, привет", "[0-9]+", "", ctx)
      -- m[0] = "234"
      -- ctx.pos == 5
```

Аргумент таблицы `ctx` вместе с модификатором регулярного выражения `a` можно использовать для построения лексера поверх `ngx.re.match`.

Обратите внимание, что аргумент `options` является обязательным при указании аргумента `ctx` и что пустая строка Lua (`""`) должна использоваться в качестве заполнителя для `options`, если нет необходимости в значимых опциях регулярного выражения.

Этот метод требует наличия библиотеки PCRE в Nginx ([Знаменитая проблема со специальными последовательностями экранирования](#special-escaping-sequences)).

Чтобы подтвердить, что PCRE JIT включен, активируйте журнал отладки Nginx, добавив опцию `--with-debug` к скрипту `./configure` Nginx или OpenResty. Затем включите уровень журнала ошибок "debug" в директиве `error_log`. Если PCRE JIT включен, будет сгенерировано следующее сообщение:

```text
pcre_jit: enabled

pcre JIT компиляция результата: 1


Начиная с версии `0.9.4`, эта функция также принимает пятый аргумент `res_table` для предоставления вызывающей стороной таблицы Lua, используемой для хранения всех результатов захвата. Начиная с версии `0.9.6`, вызывающая сторона должна гарантировать, что эта таблица пуста. Это очень полезно для повторного использования таблиц Lua и экономии затрат на сборку мусора и выделение памяти для таблиц.

Эта функциональность была введена в выпуске `v0.2.1rc11`.

[Вернуться к Оглавлению](#nginx-api-for-lua)

ngx.re.find
-----------

**синтаксис:** *from, to, err = ngx.re.find(предмет, регулярное_выражение, опции?, ctx?, nth?)*

**контекст:** *init_worker_by_lua*, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer.*, balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, exit_worker_by_lua, ssl_client_hello_by_lua*

Похож на [ngx.re.match](#ngxrematch), но возвращает только начальный индекс (`from`) и конечный индекс (`to`) совпадающего подстрока. Возвращаемые индексы являются 1-индексированными и могут быть непосредственно переданы в функцию API [string.sub](https://www.lua.org/manual/5.1/manual.html#pdf-string.sub) для получения совпадающего подстрока. В случае ошибок (например, неверных регулярных выражений или любых ошибок выполнения PCRE), эта функция API возвращает два значения `nil` и строку, описывающую ошибку.

Если совпадение не найдено, эта функция просто возвращает значение `nil`.```lua

local s = "hello, 1234"
local from, to, err = ngx.re.find(s, "([0-9]+)", "jo")
if from then
    ngx.say("from: ", from)
    ngx.say("to: ", to)
    ngx.say("matched: ", string.sub(s, from, to))
else
    if err then
        ngx.say("ошибка: ", err)
        return
    end
    ngx.say("не найдено!")
end

Этот пример выводит:

from: 8
to: 11
matched: 1234

Так как эта функция API не создаёт новые строки Lua или новые таблицы Lua, она намного быстрее, чем ngx.re.match. Она должна использоваться там, где это возможно.

С версии 0.9.3 поддерживается необязательный пятый аргумент nth, который позволяет указать, какие индексы захваченного подсовпадения возвращаются. Когда nth равен Yö (что является значением по умолчанию), возвращаются индексы всего совпадающего подстрока; когда nth равен 1, возвращаются индексы первого захваченного подсовпадения; когда nth равен 2, возвращаются индексы второго захваченного подсовпадения, и так далее. Когда указанное подсовпадение не имеет совпадения, то возвращаются два значения nil. Пример использования этого:


local str = "hello, 1234"
local from, to = ngx.re.find(str, "([0-9])([0-9]+)", "jo", nil, 2)
if from then
    ngx.say("matched 2nd submatch: ", string.sub(str, from, to))  -- выводит "234"
end

Эта функция API была введена впервые в выпуске v0.9.2.

Назад к Оглавлению

ngx.re.gmatch

синтаксис: iterator, err = ngx.re.gmatch(предмет, регулярное_выражение, опции?) ```контекст: init_worker_by_lua, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, exit_worker_by_lua, ssl_client_hello_by_luaАналогично ngx.re.match, но вместо этого возвращает Lua-итератор, чтобы позволить программисту итерировать все совпадения над строковым аргументом <subject> с помощью PCRE `regular expression`. В случае ошибок, таких как отображение некорректно сформированного регулярного выражения, будет возвращено значение `nil` и строка, описывающая ошибку.

Вот небольшой пример, демонстрирующий базовое использование:


local iterator, err = ngx.re.gmatch("hello, world!", "([a-z]+)", "i")
if not iterator then
    ngx.log(ngx.ERR, "ошибка: ", err)
    return
end

local m
m, err = iterator()    -- m[0] == m[1] == "hello"
if err then
    ngx.log(ngx.ERR, "ошибка: ", err)
    return
end

m, err = iterator()    -- m[0] == m[1] == "world"
if err then
    ngx.log(ngx.ERR, "ошибка: ", err)
    return
end

m, err = iterator()    -- m == nil
if err then
    ngx.log(ngx.ERR, "ошибка: ", err)
    return
end

Часто мы просто помещаем это в цикл Lua:


local it, err = ngx.re.gmatch("hello, world!", "([a-z]+)", "i")
if not it then
    ngx.log(ngx.ERR, "ошибка: ", err)
    return
end

while true do
    local m, err = it()
    if err then
        ngx.log(ngx.ERR, "ошибка: ", err)
        return
    end

    if not m then
        -- совпадение не найдено (больше)
        break
    end

    -- найдено совпадение
    ngx.say(m[0])
    ngx.say(m[1])
end

Необязательный аргумент options имеет точно такую же семантику, как и метод ngx.re.match.

Текущая реализация требует, чтобы итератор, возвращаемый этим методом, использовался только в одном запросе. То есть, его не следует присваивать переменной, принадлежащей постоянному пространству имен, такому как Lua пакет.Этот метод требует наличия библиотеки PCRE, включенной в Nginx (Знаменитая проблема со специальными последовательностями экранирования).

Эта функция была введена впервые в выпуске v0.2.1rc12.

Назад к Оглавлению

ngx.re.sub

синтаксис: newstr, n, err = ngx.re.sub(subject, regex, replace, options?)

контекст: init_worker_by_lua, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, exit_worker_by_lua, ssl_client_hello_by_lua

Заменяет первое совпадение Perl-совместимого регулярного выражения regex в строке аргумента subject строкой или функцией аргумента replace. Необязательный аргумент options имеет точно такую же семантику, как и метод ngx.re.match. Этот метод возвращает получившуюся новую строку, а также количество успешных замен. В случае ошибок, таких как синтаксические ошибки в регулярных выражениях или аргументе строки replace, он вернет nil и строку, описывающую ошибку.

Когда replace является строкой, то она рассматривается как специальный шаблон для замены строк. Например,


local newstr, n, err = ngx.re.sub("hello, 1234", "([0-9])[0-9]", "[$0][$1]")
if not newstr then
    ngx.log(ngx.ERR, "ошибка: ", err)
    return
end

-- newstr == "hello, [12][1]34"
-- n == 1

где $0 указывает на всю подстроку, совпадающую с шаблоном, а $1 — на первую захватываемую подстроку, заключенную в скобки.Также можно использовать фигурные скобки для разрешения неоднозначностей между именами переменных и строковыми литералами:


local newstr, n, err = ngx.re.sub("hello, 1234", "[0-9]", "${0}00")
-- newstr == "hello, 100234"
-- n == 1

Литеральные знаки доллара ($) в аргументе строки replace могут быть экранированы ещё одним знаком доллара, например,


local newstr, n, err = ngx.re.sub("hello, 1234", "[0-9]", "$$")
-- newstr == "hello, $234"
-- n == 1

Не используйте обратные слэши для экранирования знаков доллара; это не будет работать так, как ожидалось.

Когда аргумент replace имеет тип "функция", то эта функция будет вызвана с таблицей совпадений в качестве аргумента для генерации строкового литерала для замены. Таблица совпадений, передаваемая в функцию replace, точно такая же, как возвращаемое значение функции ngx.re.match. Вот пример:


local func = function (m)
    return "[" .. m[0] .. "][" .. m[1] .. "]"
end

local newstr, n, err = ngx.re.sub("hello, 1234", "( [0-9] ) [0-9]", func, "x")
-- newstr == "hello, [12][1]34"
-- n == 1

Знаки доллара в возвращаемом значении аргумента функции replace не являются специальными.

Этот метод требует включения библиотеки PCRE в Nginx (Известная проблема с особыми последовательностями экранирования).

Эта функциональность была введена впервые в выпуске v0.2.1rc13.

Назад к Оглавлению

ngx.re.gsub -----------синтаксис: newstr, n, err = ngx.re.gsub(subject, regex, replace, options?)

контекст: init_worker_by_lua, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, exit_worker_by_lua, ssl_client_hello_by_lua

Аналогично ngx.re.sub, но выполняет глобальную замену.Вот текст с исправлениями:


local newstr, n, err = ngx.re.gsub("hello, мир", "([a-z])[a-z]+", "[$0,$1]", "i")
if not newstr then
    ngx.log(ngx.ERR, "ошибка: ", err)
    return
end

-- newstr == "[hello,h], [мир,m]"
-- n == 2

local func = function (m)
    return "[" .. m[0] .. "," .. m[1] .. "]"
end
local newstr, n, err = ngx.re.gsub("hello, мир", "([a-z])[a-z]+", func, "i")
-- newstr == "[hello,h], [мир,m]"
-- n == 2

Этот метод требует включения библиотеки PCRE в Nginx (знаменитая проблема с особыми последовательностями экранирования).

Эта функция была введена в версии v0.2.1rc15.

Назад к Оглавлению

ngx.shared.DICT

синтаксис: dict = ngx.shared.DICT

синтаксис: dict = ngx.shared[name_var]

контекст: init_by_lua, init_worker_by_lua, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, exit_worker_by_lua, ssl_client_hello_by_lua

Получение объекта Lua-словаря на основе общего памяти для зоны общего памяти, названной DICT, определенной директивой lua_shared_dict.

Зоны общего памяти всегда являются общими для всех процессов рабочих потоков Nginx в текущем экземпляре сервера Nginx.

Результирующий объект dict имеет следующие методы:

Все эти методы являются операциями с атомарной согласованностью, то есть они защищены от конкурентного доступа со стороны нескольких рабочих процессов Nginx для одной и той же области lua_shared_dict.Вот пример:


http {
    lua_shared_dict dogs 10m;
    server {
        location /set {
            content_by_lua_block {
                local dogs = ngx.shared.dogs
                dogs:set("Jim", 8)
                ngx.say("STORED")
            }
        }
        location /get {
            content_by_lua_block {
                local dogs = ngx.shared.dogs
                ngx.say(dogs:get("Jim"))
            }
        }
    }
}

Давайте протестируем это:


$ curl localhost/set
STORED

$ curl localhost/get
8

$ curl localhost/get
8

Число 8 будет последовательно выводиться при доступе к /get, независимо от того, сколько рабочих процессов Nginx существует, так как словарь dogs находится в общей памяти и виден всем рабочим процессам.

Словарь общего доступа сохраняет свои содержимое после перезагрузки конфигурации сервера (либо путем отправки сигнала HUP процессу Nginx, либо с помощью командной строки -s reload).

Однако содержимое словаря будет потеряно, когда сервер Nginx завершает работу.

Эта функция была введена впервые в выпуске v0.3.1rc22.

Назад к Оглавлению

ngx.shared.DICT.get

синтаксис: значение, флаги = ngx.shared.DICT:get(ключ)

контекст: set_by_lua, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, ngx.timer., balancer_by_lua, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_session_store_by_lua*, ssl_client_hello_by_lua*

Получение значения из словаря [ngx.shared.DICT] для ключа ключ. Если ключ не существует или истек, то будет возвращено nil.

В случае ошибок, будет возвращено nil и строка, описывающая ошибку.Возвращаемое значение будет иметь тот же тип данных, что и при вставке в словарь, например, логические значения Lua, числа или строки.

Первым аргументом этого метода должно быть само объект словаря, например,

local cats = ngx.shared.cats
local value, flags = cats.get(cats, "Мэри")

или используйте синтаксическое сахара Lua для вызова методов:

local cats = ngx.shared.cats
local value, flags = cats:get("Мэри")

Эти две формы фундаментально эквивалентны.

Если флаг пользователя равен 0 (по умолчанию), то значение флага не будет возвращено.

Эта функция была введена впервые в выпуске v0.3.1rc22.

См. также ngx.shared.DICT.

Назад к Оглавлению

ngx.shared.DICT.get_stale

синтаксис: value, flags, stale = ngx.shared.DICT:get_stale(ключ)

контекст: init_by_lua, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, ssl_client_hello_by_lua

Аналогичен методу get, но возвращает значение даже если ключ уже истёк.

Возвращает третье значение, stale, указывающее, истёк ли ключ или нет.

Обратите внимание, что значение истёкшего ключа не гарантировано доступно, поэтому никогда не следует полагаться на доступность истёкших элементов.

Этот метод был введен впервые в выпуске 0.8.6.

См. также ngx.shared.DICT.

Назад к Оглавлениюngx.shared.DICT.set

синтаксис: успех, ошибка, принудительно = ngx.shared.DICT:set(ключ, значение, срок_истечения?, флаги?)

контекст: init_by_lua, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, ssl_client_hello_by_lua

Устанавливает пару ключ-значение в словарь на основе совместного использования памяти ngx.shared.DICT. Возвращает три значения:

  • успех: логическое значение, указывающее, была ли пара ключ-значение сохранена или нет.
  • ошибка: текстовое сообщение об ошибке, может быть "нет памяти".
  • принудительно: логическое значение, указывающее, были ли другие действительные элементы удалены принудительно при недостатке памяти в зоне совместного использования памяти.

Аргумент значение, который можно вставить, может быть логическими значениями Lua, числами, строками или nil. Их тип данных также будет сохранен в словарь, и тот же тип данных можно будет получить позднее через метод get. Необязательный аргумент срок_истечения указывает время истечения (в секундах) для вставленной пары ключ-значение. Разрешение времени составляет 0.001 секунды. Если значение срок_истечения равно 0 (по умолчанию), то элемент никогда не истекает.Необязательный аргумент flags указывает значение пользовательских флагов, связанное с записью, которая будет храниться. Это значение также может быть получено позже. Пользовательские флаги хранятся как беззнаковое 32-битное целое число внутренне. По умолчанию равно 0. Аргумент пользовательских флагов был введен в выпуске v0.5.0rc2.Когда не удается выделить память для текущей пары ключ-значение, метод set попытается удалить существующие записи в хранилище согласно алгоритму наименее недавно использованного (LRU). Обратите внимание, что приоритет отдается LRU перед временем истечения. Если до десятков существующих записей будут удалены, но память все еще будет недостаточной (из-за ограничения полной емкости, указанного в lua_shared_dict или из-за сегментации памяти), то значение err будет равно no memory, а success будет false.

Если размеры записей в словаре не являются кратными или даже степенями определенного значения (например, 2), то легче столкнуться с ошибкой no memory из-за фрагментации памяти. Рекомендуется использовать разные словари для различных размеров записей.

При встрече с ошибкой no memory можно также удалить больше наименее недавно использованных записей, повторив вызов этого метода несколько раз, чтобы освободить место для текущей записи.

Если этот метод успешно сохраняет текущую запись за счет принудительного удаления других еще не истёкших записей в словаре через LRU, то значение forcible будет равно true. Если запись сохраняется без принудительного удаления других действительных записей, то значение forcible будет false.

Первый аргумент этого метода должен быть объектом словаря сам по себе, например,```lua

local cats = ngx.shared.cats local succ, err, forcible = cats.set(cats, "Marry", "it is a nice cat!")


или использовать синтаксическое сахара Lua для вызова методов:

```lua

local cats = ngx.shared.cats
local succ, err, forcible = cats:set("Marry", "it is a nice cat!")

Эти две формы фундаментально эквивалентны.

Эта функция была введена в выпуске v0.3.1rc22. Обратите внимание, что хотя внутренне пара ключ-значение устанавливается атомарно, атомарность не распространяется через границу вызова метода.

См. также ngx.shared.DICT.

Назад к Оглавлению

ngx.shared.DICT.safe_set

синтаксис: ok, err = ngx.shared.DICT:safe_set(ключ, значение, exptime?, flags?)

контекст: init_by_lua, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, ssl_client_hello_by_lua

Аналогично методу set, но никогда не переопределяет (наименее недавно использованные) незавершившиеся элементы в хранилище при исчерпании памяти в зоне общего доступа. В этом случае он немедленно вернет nil и строку "нет памяти".

Эта функция была введена в выпуске v0.7.18.

См. также ngx.shared.DICT.

Назад к Оглавлению

ngx.shared.DICT.add

синтаксис: успех, err, принудительно = ngx.shared.DICT:add(ключ, значение, exptime?, flags?)

контекст: init_by_lua, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, ssl_client_hello_by_lua


Если аргумент `ключ` уже существует в словаре (и точно не истек срок его действия), значение `успех` будет `false`, а значение `ошибка` будет `"существует"`.

Эта функция была введена в выпуске `v0.3.1rc22`.

См. также [ngx.shared.DICT](#ngxshareddict).

[Назад к Оглавлению](#api-nginx-для-lua)

ngx.shared.DICT.safe_add
------------------------

**синтаксис:** *ок, ошибка = ngx.shared.DICT:safe_add(ключ, значение, время_истечения?, флаги?)*

**контекст:** *init_by_lua*, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer.*, balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, ssl_client_hello_by_lua*

Аналогично методу [add](#ngxshareddictadd), но никогда не переопределяет (наименее недавно используемые) незаблокированные элементы в хранилище при исчерпании места в зоне общего памяти. В этом случае он сразу возвращает `nil` и строку "нет памяти".

Эта функция была введена в версии `v0.7.18`.

См. также [ngx.shared.DICT](#ngxshareddict).

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.shared.DICT.replace
-----------------------

**синтаксис:** *успех, ошибка, принудительно = ngx.shared.DICT:replace(ключ, значение, время_истечения?, флаги?)*

**контекст:** *init_by_lua*, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer.*, balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, ssl_client_hello_by_lua*

Аналогично методу [set](#ngxshareddictset), но ключ-значение пару хранит в словаре [ngx.shared.DICT](#ngxshareddict) только если ключ существует.Если аргумент `ключ` отсутствует в словаре (или истек срок его действия), значение `успех` будет `false`, а значение `ошибка` будет `"ключ не найден"`.

Эта функция была введена в версии `v0.3.1rc22`.

См. также [ngx.shared.DICT](#ngxshareddict).

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.shared.DICT.delete
-----------------------

**синтаксис:** *ngx.shared.DICT:delete(ключ)*

**контекст:** *init_by_lua*, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer.*, balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, ssl_client_hello_by_lua*

Безусловно удаляет ключ-значение пару из словаря на основе общего памяти [ngx.shared.DICT](#ngxshareddict).

Это эквивалентно `ngx.shared.DICT:set(ключ, nil)`.

Эта функция была введена в версии `v0.3.1rc22`.

См. также [ngx.shared.DICT](#ngxshareddict).

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.shared.DICT.incr
---------------------

**синтаксис:** *новое_значение, ошибка, принудительно? = ngx.shared.DICT:incr(ключ, значение, начальное_значение?, начальное_время_истечения?)*

**контекст:** *init_by_lua*, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer.*, balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, ssl_client_hello_by_lua*

Необходимое условие: `resty.core.shdict` или `resty.core`

Увеличивает числовое значение для ключа `ключ` в словаре на базе shared memory (shm) [ngx.shared.DICT](#ngxshareddict) на величину шага `значение`. Возвращает новое полученное число, если операция успешно завершена, или `nil` и сообщение об ошибке в противном случае.Когда ключ отсутствует или уже истёк в общем словаре,

1. если аргумент `init` не указан или имеет значение `nil`, этот метод вернёт `nil` и строку ошибки `"не найдено"`, или
1. если аргумент `init` имеет числовое значение, этот метод создаст новый ключ `key` со значением `init + value`.

Как метод [add](#ngxshareddictadd), он также заменяет недавно использованные (least recently used) неистёкшие элементы в хранилище при исчерпании памяти в зоне shared memory.

Необязательный аргумент `init_ttl` указывает время истечения (в секундах) значения при его инициализации через аргумент `init`. Разрешение времени — `0.001` секунды. Если `init_ttl` имеет значение `0` (что является значением по умолчанию), то элемент никогда не истечёт. Этот аргумент не может быть предоставлен без предоставления аргумента `init`, и не будет иметь эффекта, если значение уже существует (например, если оно было ранее вставлено через [set](#ngxshareddictset) или подобные методы).

**Примечание:** Использование аргумента `init_ttl` требует модулей `resty.core.shdict` или `resty.core` из библиотеки [lua-resty-core](https://github.com/openresty/lua-resty-core). Пример:

```lua

require "resty.core"

local cats = ngx.shared.cats
local newval, err = cats:incr("black_cats", 1, 0, 0.1)

print(newval) -- 1

ngx.sleep(0.2)

local val, err = cats:get("black_cats")
print(val) -- nil

Значение возврата forcible всегда будет nil, когда аргумент init не указан.Если этот метод успешно хранит текущий элемент, принудительно удаляя другие ещё не истёкшие элементы в словаре через LRU, значение возврата forcible будет true. Если он хранит элемент без принудительного удаления других действительных элементов, то значение возврата forcible будет false.Если исходное значение не является действительным числом Lua в словаре, он вернёт nil и "не число".

Аргумент value и аргумент init могут быть любыми действительными числами Lua, такими как отрицательные числа или числа с плавающей запятой. Этот метод был введен впервые в выпуске v0.3.1rc22.

Необязательный параметр init был введен впервые в выпуске v0.10.6.

Необязательный параметр init_ttl был введен впервые в выпуске v0.10.12rc2.

См. также ngx.shared.DICT.

Назад к Оглавлению

ngx.shared.DICT.lpush

синтаксис: length, err = ngx.shared.DICT:lpush(key, value)

контекст: init_by_lua, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, ssl_client_hello_by_lua

Добавляет указанное (числовое или строковое) значение value в начало списка с именем key в словаре на основе общего памяти ngx.shared.DICT. Возвращает количество элементов в списке после операции добавления.

Если ключ key отсутствует, он создается как пустой список перед выполнением операции добавления. Когда ключ уже имеет значение, которое не является списком, возвращаются nil и "значение не является списком".

При недостатке места в зоне общего памяти этот метод никогда не перезаписывает (наименее недавно использованные) неистёкшие элементы. В этом случае немедленно возвращаются nil и строка "нет памяти".Эта функциональность была введена впервые в выпуске v0.10.6.

См. также ngx.shared.DICT.

Назад к оглавлению

ngx.shared.DICT.rpush

синтаксис: length, err = ngx.shared.DICT:rpush(key, value)

контекст: init_by_lua, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, ssl_client_hello_by_lua

Аналогично методу lpush, но добавляет указанное (числовое или строковое) значение value в конец списка с именем key.

Эта функциональность была введена впервые в выпуске v0.10.6.

См. также ngx.shared.DICT.

Назад к оглавлению

ngx.shared.DICT.lpop

синтаксис: val, err = ngx.shared.DICT:lpop(key)

контекст: init_by_lua, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, ssl_client_hello_by_lua

Удаляет и возвращает первый элемент списка с именем key в словаре на основе shared memory ngx.shared.DICT.

Если key не существует, будет возвращено nil. Когда key уже имеет значение, которое не является списком, будет возвращено nil и "значение не является списком".

Эта функциональность была введена впервые в выпуске v0.10.6.

См. также ngx.shared.DICT.

Назад к оглавлению

ngx.shared.DICT.rpop

синтаксис: *val, err = ngx.shared.DICT:rpop(key)контекст: init_by_lua, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, ssl_client_hello_by_luaУдаляет и возвращает последний элемент списка с именем key в словаре на основе shared memory ngx.shared.DICT.

Если key не существует, будет возвращено nil. Когда key уже имеет значение, которое не является списком, будет возвращено nil и "значение не является списком".

Эта функциональность была введена впервые в выпуске v0.10.6.

См. также ngx.shared.DICT.

Назад к TOC

ngx.shared.DICT.llen

синтаксис: len, err = ngx.shared.DICT:llen(key)

контекст: init_by_lua, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, ssl_client_hello_by_lua

Возвращает количество элементов в списке с именем key в словаре на основе shared memory ngx.shared.DICT.

Если ключ не существует, он интерпретируется как пустой список и возвращается 0. Когда key уже имеет значение, которое не является списком, будет возвращено nil и "значение не является списком". Эта функция была введена впервые в выпуске v0.10.6.

См. также ngx.shared.DICT.

Назад к Оглавлению

ngx.shared.DICT.ttl

синтаксис: ttl, err = ngx.shared.DICT:ttl(key)

контекст: init_by_lua, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, ssl_client_hello_by_lua

требует: resty.core.shdict или resty.coreПолучает оставшееся время жизни (TTL в секундах) пары ключ-значение в словаре на основе shared memory ngx.shared.DICT. Возвращает TTL как число, если операция успешно завершена, или nil и сообщение об ошибке в противном случае.

Если ключ не существует (или уже истёк), этот метод вернёт nil и строку ошибки "не найдено".

TTL был первоначально определён аргументом exptime методов set, add, replace (и подобных). Он имеет временную разрешающую способность в 0,001 секунды. Значение 0 означает, что элемент никогда не истечёт.

Пример:


require "resty.core"

local cats = ngx.shared.cats
local succ, err = cats:set("Мэри", "симпатичная кошка", 0.5)

ngx.sleep(0.2)

local ttl, err = cats:ttl("Мэри")
ngx.say(ttl) -- 0.3

Эта функция была введена впервые в выпуске v0.10.11.

Примечание: Этот метод требует модулей resty.core.shdict или resty.core из библиотеки lua-resty-core.

См. также ngx.shared.DICT.

Назад к Оглавлению

ngx.shared.DICT.expire

синтаксис: успех, err = ngx.shared.DICT:expire(ключ, exptime)

контекст: init_by_lua, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, ssl_client_hello_by_luaтребует: resty.core.shdict или resty.core. Обновляет exptime (в секундах) пары ключ-значение в словаре на основе shared memory ngx.shared.DICT. Возвращает логическое значение, указывающее на успешность операции, если операция завершена успешно, или nil и сообщение об ошибке в противном случае.Если ключ не существует, этот метод вернет nil и строку ошибки "ключ не найден".

Аргумент exptime имеет разрешение 0.001 секунды. Если exptime равен 0, элемент никогда не истекает.

Пример:


require "resty.core"

local cats = ngx.shared.cats
local succ, err = cats:set("Мэри", "симпатичная кошка", 0.1)

succ, err = cats:expire("Мэри", 0.5)

ngx.sleep(0.2)

local val, err = cats:get("Мэри")
ngx.say(val) -- "симпатичная кошка"

Эта функциональность была введена впервые в выпуске v0.10.11.

Примечание: Этот метод требует модулей resty.core.shdict или resty.core из библиотеки lua-resty-core.

См. также ngx.shared.DICT.

Назад к Оглавлению

ngx.shared.DICT.flush_all

синтаксис: ngx.shared.DICT:flush_all()

контекст: init_by_lua, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, ssl_client_hello_by_lua

Очищает все элементы в словаре. Этот метод не освобождает все блоки памяти в словаре, а просто помечает все существующие элементы как истёкшие.

Эта функциональность была введена впервые в выпуске v0.5.0rc17.

См. также ngx.shared.DICT.flush_expired и ngx.shared.DICT.

Назад к Оглавлению

ngx.shared.DICT.flush_expired

синтаксис: flushed = ngx.shared.DICT:flush_expired(max_count?)контекст: init_by_lua, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, ssl_client_hello_by_lua

Осуществляет очистку просроченных элементов в словаре до максимального числа, указанного необязательным аргументом max_count. Когда аргумент max_count имеет значение 0 или не указан вовсе, это означает неограниченное количество. Возвращает количество элементов, которые были фактически очищены.В отличие от метода flush_all, этот метод действительно освобождает память, используемую просроченными элементами.

Эта функция была введена в версии v0.6.3.

См. также ngx.shared.DICT.flush_all и ngx.shared.DICT.

Назад к Оглавлению

ngx.shared.DICT.get_keys

синтаксис: keys = ngx.shared.DICT:get_keys(max_count?)

контекст: init_by_lua, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, ssl_client_hello_by_lua

Получает список ключей из словаря, до <max_count>.

По умолчанию возвращаются только первые 1024 ключа (если они есть). Когда аргумент <max_count> имеет значение 0, то все ключи будут возвращены, даже если их больше 1024 в словаре.

ВНИМАНИЕ Избегайте вызова этого метода для словарей с очень большим количеством ключей, так как это может заблокировать словарь на значительное время и заблокировать рабочие процессы Nginx, пытающиеся получить доступ к словарю.

Эта функция была введена в версии v0.7.3.

Назад к Оглавлению

ngx.shared.DICT.capacity

синтаксис: capacity_bytes = ngx.shared.DICT:capacity()

контекст: init_by_lua, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, ssl_client_hello_by_lua

требует: resty.core.shdict или resty.coreПолучает размер в байтах для словаря на основе shared memory [ngx.shared.DICT], объявленного с помощью директивы [lua_shared_dict].

require "resty.core.shdict"

local cats = ngx.shared.cats
local capacity_bytes = cats:capacity()

Эта функция была введена впервые в выпуске v0.10.11.

Примечание: Этот метод требует модулей resty.core.shdict или resty.core из библиотеки lua-resty-core.

Для использования этой функции требуется версия ядра Nginx 0.7.3 или выше.

См. также ngx.shared.DICT.

Назад к Оглавлению

ngx.shared.DICT.free_space

синтаксис: free_page_bytes = ngx.shared.DICT:free_space()

контекст: init_by_lua, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, ssl_client_hello_by_lua

требования: resty.core.shdict или resty.core

Получает размер свободной страницы в байтах для словаря на основе shared memory ngx.shared.DICT.

Примечание: Память для ngx.shared.DICT выделяется через аллокатор слотов Nginx, который имеет слоты для диапазонов размеров данных, таких как 8, 916, 1732, ..., 10252048, 2048~ байт. И страницы назначаются слоту, если нет места в уже назначенных страницах для этого слота.

Так что даже если значение метода free_space равно нулю, может быть место в уже назначенных страницах, поэтому вы можете успешно установить новую пару ключ-значение в общем словаре без получения true для forcible или ненулевого err от метода ngx.shared.DICT.set.С другой стороны, если уже назначенные страницы для слота заполнены и добавляется новая пара ключ-значение в этот слот, а свободных страниц нет, вы можете получить true для forcible или ненулевое err от метода ngx.shared.DICT.set.

Пример:


require "resty.core.shdict"

local cats = ngx.shared.cats
local free_page_bytes = cats:free_space()

Эта функция была введена впервые в выпуске v0.10.11.

Примечание: Этот метод требует модулей resty.core.shdict или resty.core из библиотеки lua-resty-core.

Для использования этой функции требуется версия ядра Nginx 1.11.7 или выше. См. также ngx.shared.DICT.

Назад к Оглавлению

ngx.socket.udp

синтаксис: udpsock = ngx.socket.udp()

контекст: rewrite_by_lua, access_by_lua, content_by_lua, ngx.timer., ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_client_hello_by_lua

Создает и возвращает объект Unix-доменного сокета, ориентированного на UDP или дейтаграммы (также известный как один из типов "cosocket" объектов). На этом объекте поддерживаются следующие методы:

Этот объект предназначен для совместимости с API UDP библиотеки LuaSocket, но он полностью асинхронен из коробки.

Эта функция была введена в версии v0.5.7.

См. также ngx.socket.tcp.

Назад к Оглавлениюudpsock:bind

синтаксис: ok, err = udpsock:bind(address)

контекст: rewrite_by_lua, access_by_lua, content_by_lua, ngx.timer., ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_client_hello_by_lua

Аналогично стандартной proxy_bind директиве, этот API заставляет исходящее соединение с сервером-поставщиком происходить от указанного локального IP-адреса.

В качестве аргумента address могут использоваться только IP-адреса.

Пример использования для подключения к TCP-серверу с указанным локальным IP-адресом:


location /test {
    content_by_lua_block {
        local sock = ngx.socket.udp()
        -- предположим, что "192.168.1.10" является локальным IP-адресом
        local ok, err = sock:bind("192.168.1.10")
        if not ok then
            ngx.say("не удалось привязать: ", err)
            return
        end
        sock:close()
    }
}

Назад к Оглавлению

udpsock:setpeername

синтаксис: ok, err = udpsock:setpeername(host, port)

синтаксис: ok, err = udpsock:setpeername("unix:/path/to/unix-domain.socket")

контекст: rewrite_by_lua, access_by_lua, content_by_lua, ngx.timer., ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_client_hello_by_lua

Попытка подключения объекта UDP сокета к удаленному серверу или к файлу домена Unix для дейтаграмм. Поскольку протокол дейтаграмм фактически является безсоединным, этот метод не создает настоящего "соединения", а только устанавливает имя удаленного узла для последующих операций чтения/записи.Как IP-адреса, так и доменные имена могут быть указаны в качестве аргумента host. В случае использования доменных имен этот метод будет использовать динамический резолвер ядра Nginx для парсинга доменного имени без блокировки, и требуется настроить директиву resolver в файле конфигурации nginx.conf следующим образом:

 resolver 8.8.8.8;  # использование публичного DNS-сервера Google

Если сервер резолва возвращает несколько IP-адресов для доменного имени, этот метод случайным образом выберет один из них.

В случае ошибки метод возвращает nil вместе со строкой, описывающей ошибку. В случае успеха метод возвращает 1.

Вот пример подключения к серверу UDP (memcached):

 location /test {
     resolver 8.8.8.8;

     content_by_lua_block {
         local sock = ngx.socket.udp()
         local ok, err = sock:setpeername("my.memcached.server.domain", 11211)
         if not ok then
             ngx.say("не удалось подключиться к memcached: ", err)
             return
         end
         ngx.say("успешное подключение к memcached!")
         sock:close()
     }
 }

С версии v0.7.18 подключение к файлу домена Unix для дейтаграмм также возможно на Linux:

 local sock = ngx.socket.udp()
 local ok, err = sock:setpeername("unix:/tmp/some-datagram-service.sock")
 if not ok then
     ngx.say("не удалось подключиться к дейтаграмному сокету домена Unix: ", err)
     return
 end

 -- выполнение действий после подключения
 -- например, sock:send или sock:receive
```предполагая, что служба дейтаграмм слушает файл сокета домена Unix `/tmp/some-datagram-service.sock`, и клиентский сокет будет использовать функцию "автоматического привязывания" на Linux.

Вызов этого метода для уже подключенного объекта сокета приведет к закрытию исходного соединения.

Этот метод был введен в версии `v0.5.7`.

[Назад к Оглавлению](#nginx-api-for-lua)

udpsock:send
------------

**синтаксис:** *ok, err = udpsock:send(data)*

**контекст:** *rewrite_by_lua\*, access_by_lua\*, content_by_lua\*, ngx.timer.\*, ssl_certificate_by_lua\*, ssl_session_fetch_by_lua\*, ssl_client_hello_by_lua\***

Отправляет данные по текущему объекту сокета UDP или домена Unix.

В случае успеха возвращает `1`. В противном случае возвращает `nil` и строку, описывающую ошибку.

Аргумент входных данных `data` может быть как строкой Lua, так и вложенной таблицей Lua, содержащей фрагменты строк. В случае аргументов типа таблица этот метод будет копировать все элементы строк по одному в нижележащие буферы отправки сокета Nginx, что обычно оптимальнее, чем выполнение операций конкатенации строк в пространстве Lua.

Эта функциональность была введена в версии `v0.5.7`.

[Назад к Оглавлению](#nginx-api-for-lua)

udpsock:receive
---------------

**синтаксис:** *data, err = udpsock:receive(size?)*

**контекст:** *rewrite_by_lua\*, access_by_lua\*, content_by_lua\*, ngx.timer.\*, ssl_certificate_by_lua\*, ssl_session_fetch_by_lua\*, ssl_client_hello_by_lua\***

Получает данные из объекта сокета UDP или домена Unix с необязательным аргументом размера буфера приема, `size`.Этот метод является синхронной операцией и полностью неблокирующей.

В случае успеха он возвращает полученные данные; в случае ошибки возвращает `nil` со строкой, описывающей ошибку.

Если аргумент `size` указан, то этот метод использует этот размер как размер буфера приема. Но если этот размер больше `8192`, то вместо этого используется `8192`.

Если аргументы не указаны, то предполагается максимальный размер буфера, равный `8192`.

Время ожидания операции чтения контролируется директивой конфигурации [lua_socket_read_timeout](#lua_socket_read_timeout) и методом [settimeout](#udpsocksettimeout). Последний имеет приоритет. Например:

```lua
sock:settimeout(1000)  -- один секундный таймаут
local data, err = sock:receive()
if not data then
    ngx.say("не удалось прочитать пакет: ", err)
    return
end
ngx.say("успешно прочитан пакет: ", data)

Важно здесь вызвать метод settimeout до вызова этого метода.

Эта функциональность была введена в версии v0.5.7.

Назад к Оглавлению

udpsock:close

синтаксис: ок, err = udpsock:close()

контекст: перезапись_by_lua*, доступ_by_lua*, контент_by_lua*, ngx.timer.*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_client_hello_by_lua**

Закрывает текущий сокет UDP или datagram unix domain. В случае успеха возвращает 1, в противном случае возвращает nil со строкой, описывающей ошибку.Сокетные объекты, которые не вызвали этот метод (и связанные с ними соединения), будут закрыты при освобождении сокетного объекта Lua сборщиком мусора (Garbage Collector) или завершении обработки текущего HTTP-запроса клиента.Эта функциональность была введена впервые в выпуске v0.5.7.

Назад к Оглавлению

udpsock:settimeout

синтаксис: udpsock:settimeout(время)

контекст: перезапись_by_lua*, доступ_by_lua*, контент_by_lua*, ngx.timer.*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_client_hello_by_lua**

Устанавливает значение таймаута в миллисекундах для последующих операций с сокетом (например, получение).

Настройки, выполненные этим методом, имеют приоритет над директивами конфигурации, такими как lua_socket_read_timeout.

Эта функциональность была введена впервые в выпуске v0.5.7.

Назад к Оглавлению

ngx.socket.stream

Просто псевдоним для ngx.socket.tcp. Если сокет типа stream может также подключаться к Unix domain сокету, то предпочтительнее использовать это имя API.

Эта функция API была добавлена впервые в выпуске v0.10.1.

Назад к Оглавлению

ngx.socket.tcp

синтаксис: tcpsock = ngx.socket.tcp()

контекст: перезапись_by_lua*, доступ_by_lua*, контент_by_lua*, ngx.timer.*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_client_hello_by_lua**

Создает и возвращает объект TCP или потокового ориентированного Unix domain сокета (также известный как один из типов объектов "cosocket"). На этом объекте поддерживаются следующие методы:* bind

Цель состоит в том, чтобы обеспечить совместимость с API TCP библиотеки LuaSocket, но при этом быть полностью неблокирующим из коробки. Также мы представляем несколько новых API для предоставления дополнительных функциональностей.Объект cosocket, созданный этой API-функцией, имеет точно такой же срок службы, как и Lua-обработчик, создающий его. Поэтому никогда не передавайте объект cosocket другому Lua-обработчику (включая функции обратного вызова ngx.timer) и никогда не делитесь объектом cosocket между различными запросами Nginx.

Для каждого подлежащего соединению объекта cosocket, если вы не закроете его явно (через close) или не вернёте его обратно в пул соединений (через setkeepalive), то соединение будет автоматически закрыто при одном из следующих двух событий:

  • завершение текущего обработчика запроса,
  • сбор объекта cosocket сборщиком мусора Lua (GC).

Критические ошибки в операциях с cosocket всегда автоматически закрывают текущее соединение (учтите, что ошибка времени ожидания чтения — это единственная ошибка, которая не является критической), и если вы вызовете close для закрытого соединения, вы получите ошибку "закрыто".

С версии 0.9.9 объект cosocket здесь является полудвунаправленным, то есть "легкий поток" читателя и "легкий поток" писателя могут одновременно работать с одним объектом cosocket (оба "легких потока" должны принадлежать одному и тому же Lua-обработчику, см. причины выше). Но вы не можете иметь два "легких потока", оба читающих (или пишущих или подключающихся) к одному и тому же cosocket, иначе вы можете получить ошибку типа "socket busy reading" при вызове методов объекта cosocket.Эта функция была введена впервые в версии v0.5.0rc1.

См. также ngx.socket.udp.

Назад к Оглавлению

tcpsock:bind

синтаксис: ok, err = tcpsock:bind(address, port?)

контекст: rewrite_by_lua, access_by_lua, content_by_lua, ngx.timer., ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_client_hello_by_lua

Как и стандартная proxy_bind директива, этот API заставляет исходящее соединение с сервером-источником происходить от указанного локального IP-адреса. Адреса IP могут быть указаны в качестве аргумента address.

Необязательный аргумент port обычно используется в прозрачном прокси.

Вот пример подключения к TCP-серверу с указанным локальным адресом IP:


location /test {
    content_by_lua_block {
        local sock = ngx.socket.tcp()
        -- предположим, что "192.168.1.10" является локальным адресом IP
        local ok, err = sock:bind("192.168.1.10")
        if not ok then
            ngx.say("не удалось привязаться")
            return
        end
        local ok, err = sock:connect("192.168.1.67", 80)
        if not ok then
            ngx.say("не удалось подключиться к серверу: ", err)
            return
        end
        ngx.say("успешное подключение!")
        sock:close()
    }
}

Назад к Оглавлению

tcpsock:connect

синтаксис: ok, err = tcpsock:connect(host, port, options_table?)

синтаксис: ok, err = tcpsock:connect("unix:/путь/к/файлу/unix-domain.socket", options_table?)

контекст: rewrite_by_lua, access_by_lua, content_by_lua, ngx.timer., ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_client_hello_by_luaПопытка подключения объекта TCP-сокета к удалённому серверу или к файлу потока домена Unix без блокировки.

Перед фактическим разрешением имени хоста и подключением к удалённому серверу этот метод всегда будет искать соединение в пуле соединений для совпадающих свободных соединений, созданных предыдущими вызовами этого метода (или функции ngx.socket.connect).

Как IP-адреса, так и доменные имена могут быть указаны в качестве аргумента host. В случае использования доменных имен этот метод будет использовать динамический разрешитель ядра Nginx для парсинга доменного имени без блокировки, и требуется настроить директиву resolver в файле конфигурации nginx.conf следующим образом:

resolver 8.8.8.8;  # использование публичного DNS-сервера Google

В случае ошибки метод возвращает nil вместе со строкой, описывающей ошибку. В случае успеха метод возвращает 1.

Вот пример подключения к TCP-серверу:

location /test {
    resolver 8.8.8.8;

    content_by_lua_block {
        local sock = ngx.socket.tcp()
        local ok, err = sock:connect("www.google.com", 80)
        if not ok then
            ngx.say("не удалось подключиться к Google: ", err)
            return
        end
        ngx.say("успешное подключение к Google!")
        sock:close()
    }
}

Подключение к Unix Domain Socket файлу также возможно:

local sock = ngx.socket.tcp()
local ok, err = sock:connect("unix:/tmp/memcached.sock")
if not ok then
    ngx.say("не удалось подключиться к Unix доменному сокету memcached: ", err)
    return
end
``` -- выполнение каких-либо действий после подключения
 -- таких как sock:send или sock:receive

предполагая, что memcached (или что-то другое) прослушивает Unix доменный сокет /tmp/memcached.sock.

Время ожидания подключения контролируется директивой конфигурации lua_socket_connect_timeout и методом settimeout. Последний имеет приоритет. Например:


local sock = ngx.socket.tcp()
sock:settimeout(1000)  -- один секундный таймаут
local ok, err = sock:connect(host, port)

Важно здесь вызвать метод settimeout до вызова этого метода.

Вызов этого метода на уже подключенном объекте сокета приведет к закрытию исходного соединения.

Необязательная таблица Lua может быть указана в качестве последнего аргумента этому методу для указания различных опций подключения:* pool Укажите пользовательское имя для используемого пула подключений. Если опущено, то имя пула подключений будет сгенерировано из строкового шаблона "host:port" или "unix-socket-path".

  • pool_size Укажите размер пула соединений. Если этот параметр не указан и параметр backlog не был предоставлен, пул не будет создан. Если параметр pool_size не указан, но параметр backlog был указан, пул будет создан с размером по умолчанию значения директивы lua_socket_pool_size. Пул соединений удерживает до pool_size активных соединений, готовых к повторному использованию последующими вызовами функции connect, но обратите внимание, что нет верхнего ограничения на общее количество открытых соединений вне пула. Если вам нужно ограничить общее количество открытых соединений, укажите параметр backlog. Когда пул соединений превышает свой лимит размера, самое недавно использованное (сохраненное активным) соединение в пуле будет закрыто, чтобы освободить место для текущего соединения. Обратите внимание, что пул cosocket соединений является уникальным для каждого процесса рабочего потока Nginx, а не для каждого экземпляра сервера Nginx, так что указанный здесь лимит размера также применяется ко всем процессам рабочих потоков Nginx. Также обратите внимание, что размер пула соединений не может быть изменен после его создания. Этот параметр был введен впервые в выпуске v0.10.14. * задачи

    Если указано, этот модуль ограничит общее количество открытых соединений для этого пула. В любое время не может быть открыто больше соединений, чем pool_size. Если pool_size соединений используется, последующие операции подключения будут помещены в очередь, равной значению этого параметра (очередь "задач"). Если количество операций подключения в очереди равно задачам, последующие операции подключения завершатся ошибкой и вернут nil вместе с сообщением об ошибке "слишком много ожидающих операций подключения". Операции подключения в очереди будут возобновлены, когда количество активных соединений станет меньше pool_size. Операции подключения в очереди будут прерваны, если они были помещены в очередь более чем на connect_timeout, контролируемый settimeouts, и вернут nil вместе с сообщением об ошибке "таймаут". Этот параметр был введен впервые в выпуске v0.10.14.Поддержка аргумента таблицы параметров была введена впервые в выпуске v0.5.7.

Этот метод был введен впервые в выпуске v0.5.0rc1.

Назад к оглавлению

tcpsock:getfd

синтаксис: fd, err = tcpsock:getfd()

контекст: rewrite_by_lua, access_by_lua, content_by_lua, ngx.timer., ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_client_hello_by_lua

Получить файловый дескриптор текущего TCP-сокета.

Этот метод был введен впервые в выпуске v0.10.29.

Назад к оглавлению

tcpsock:setclientcert

синтаксис: ok, err = tcpsock:setclientcert(cert, pkey)

контекст: rewrite_by_lua, access_by_lua, content_by_lua, ngx.timer., ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_client_hello_by_luaУстановить цепочку сертификатов клиента и соответствующий закрытый ключ для объекта TCP сокета. Цепочка сертификатов и закрытый ключ, предоставленные здесь, будут использоваться позже методом tcpsock:sslhandshake. * cert указывает цепочку клиентских сертификатов в объекте cdata, который будет использоваться во время установления соединения с удалённым сервером. Эти объекты могут быть созданы с помощью функций ngx.ssl.parse_pem_cert или ngx.ssl.parse_der_cert, предоставляемых библиотекой lua-resty-core. Обратите внимание, что указание опции cert требует также указания соответствующей опции pkey. Смотрите ниже.

  • pkey указывает приватный ключ, соответствующий опции cert выше. Эти объекты могут быть созданы с помощью функций ngx.ssl.parse_pem_priv_key или ngx.ssl.parse_der_priv_key, предоставляемых библиотекой lua-resty-core. Если оба значения cert и pkey равны nil, этот метод очистит любое существующее клиентское сертификат и приватный ключ, который был ранее установлен на объекте cosocket.Этот метод был впервые введен в выпуске v0.10.22.

Назад к Оглавлению

tcpsock:sslhandshake

синтаксис: session, err = tcpsock:sslhandshake(reused_session?, server_name?, ssl_verify?, send_status_req?)

контекст: rewrite_by_lua, access_by_lua*, content_by_lua*, ngx.timer., ssl_certificate_by_lua, ssl_session_fetch_by_lua*, ssl_client_hello_by_lua*

Выполняет SSL/TLS рукопожатие на текущем установленном соединении.

Необязательный аргумент reused_session может принимать значение userdata предыдущего SSL сеанса, возвращённого вызовом sslhandshake для точно такого же целевого объекта. Для краткосрочных соединений повторное использование SSL сеансов обычно может ускорить рукопожатие примерно в десять раз, но это не так полезно, если включен пулинг соединений. Это значение по умолчанию равно nil. Если этот аргумент принимает логическое значение false, userdata SSL сеанса не будет возвращено этим вызовом, и только логическое значение Lua будет возвращено как первое возвращаемое значение; в противном случае текущий SSL сеанс всегда будет возвращен как первое значение аргумента при успешном выполнении.Необязательный аргумент server_name используется для указания имени сервера для нового расширения TLS Server Name Indication (SNI). Использование SNI может позволить различным серверам использовать одинаковый IP-адрес на стороне сервера. Также, когда включена проверка SSL, этот аргумент server_name также используется для проверки имени сервера, указанного в сертификате сервера, отправленном от удалённого сервера.Необязательный аргумент ssl_verify принимает логическое значение Lua для управления выполнением проверки SSL. Когда установлено значение true, сертификат сервера будет проверен в соответствии с сертификатами доверенных центров сертификации, указанными директивой lua_ssl_trusted_certificate. Возможно, вам также потребуется скорректировать директиву lua_ssl_verify_depth для управления глубиной следования по цепочке сертификатов. Также, когда аргумент ssl_verify имеет значение true и аргумент server_name указан, последний будет использоваться для проверки имени сервера в сертификате сервера.

Необязательный аргумент send_status_req принимает логическое значение, которое управляет отправкой запроса статуса OCSP в запросе SSL-рукопожатия (что используется для запроса OCSP stapling).

Для соединений, которые уже выполнили SSL/TLS рукопожатие, этот метод немедленно возвращает результат.

Этот метод был впервые введен в выпуске v0.9.11.

Назад к Оглавлению

tcpsock:send

синтаксис: bytes, err = tcpsock:send(data)

контекст: rewrite_by_lua, access_by_lua, content_by_lua, ngx.timer., ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_client_hello_by_lua

Отправляет данные без блокировки текущего TCP или Unix Domain Socket соединения.Этот метод является синхронной операцией, которая не вернётся до тех пор, пока все данные не будут отправлены в буфер отправки системы сокета или произойдёт ошибка.

В случае успеха он возвращает общее количество отправленных байтов. В противном случае он возвращает nil и строку, описывающую ошибку.

Аргумент входных данных data может быть как Lua строкой, так и (вложенной) Lua таблицей, содержащей фрагменты строк. В случае аргументов типа таблица, этот метод будет копировать все элементы строки по частям в нижележащие буферы отправки сокета Nginx, что обычно оптимальнее, чем выполнение операций конкатенации строк на стороне Lua.

Время ожидания для операции отправки контролируется директивой конфигурации lua_socket_send_timeout и методом settimeout. Последний имеет приоритет. Например:


 sock:settimeout(1000)  -- один секундный таймаут
 local bytes, err = sock:send(request)

Важно здесь вызвать метод settimeout перед вызовом этого метода.

В случае любых ошибок соединения, этот метод всегда автоматически закрывает текущее соединение.

Эта функция была введена впервые в выпуске v0.5.0rc1.

Назад к Оглавлению

tcpsock:receive

синтаксис: data, err, partial = tcpsock:receive(size)

синтаксис: *data, err, partial = tcpsock:receive(pattern?)*контекст: rewrite_by_lua, access_by_lua, content_by_lua, ngx.timer., ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_client_hello_by_lua Получает данные из подключенного сокета в соответствии с шаблоном чтения или размером.Этот метод является синхронной операцией, как и метод send и является полностью неблокирующей.

В случае успеха он возвращает полученные данные; в случае ошибки возвращает nil со строкой, описывающей ошибку, и частично полученными данными.

Если указано число-подобное аргумент (включая строки, которые выглядят как числа), то это интерпретируется как размер. Этот метод не вернётся до тех пор, пока не прочтет именно этот размер данных или не произойдет ошибка.

Если указано строковое аргумент, которое не похоже на число, то это интерпретируется как "шаблон". Поддерживаются следующие шаблоны:

  • '*a': читает из сокета до тех пор, пока соединение не будет закрыто. Преобразование конца строки не выполняется;
  • '*l': читает строку текста из сокета. Строка завершается символом Line Feed (LF) (ASCII 10), который может предваряться символом Carriage Return (CR) (ASCII 13). Символы CR и LF не включаются в возвращаемую строку. В действительности, все символы CR игнорируются шаблоном.

Если аргумент не указан, то считается, что это шаблон '*l', то есть шаблон чтения строки.

Таймаут для операции чтения контролируется директивой конфигурации lua_socket_read_timeout и методом settimeout. Последний имеет приоритет. Например:

``` sock:settimeout(1000)  -- тайм-аут в одну секунду
 local line, err, partial = sock:receive()
 if not line then
     ngx.say("не удалось прочитать строку: ", err)
     return
 end
 ngx.say("успешно прочитана строка: ", line)
```Важно здесь вызвать метод [settimeout](#tcpsocksettimeout) *до* вызова этого метода.

С версии `v0.8.8` этот метод больше не автоматически закрывает текущее соединение при ошибке таймаута чтения. Для других ошибок соединения этот метод всегда автоматически закрывает соединение.

Эта функция была введена в версии `v0.5.0rc1`.

[Назад к Оглавлению](#nginx-api-for-lua)

tcpsock:receiveany
------------------

**синтаксис:** *data, err = tcpsock:receiveany(max)*

**контекст:** *rewrite_by_lua*, access_by_lua, content_by_lua, ngx.timer.*, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_client_hello_by_lua*

Возвращает любые данные, полученные через подключенный сокет, не более `max` байт.

Этот метод является синхронной операцией, как и метод [send](#tcpsocksend), и полностью неблокирующим.

При успешном выполнении он возвращает полученные данные; при ошибке возвращает `nil` со строкой, описывающей ошибку.

Если полученные данные превышают этот размер, этот метод вернёт данные именно этого размера. Оставшиеся данные в нижележащем буфере приема могут быть возвращены в следующей операции чтения.

Таймаут для операции чтения контролируется директивой конфигурации [lua_socket_read_timeout](#lua_socket_read_timeout) и методом [settimeouts](#tcpsocksettimeouts). Последний имеет приоритет. Например:

```lua
sock:settimeouts(1000, 1000, 1000)  -- один секундный таймаут для подключения/чтения/записи
local data, err = sock:receiveany(10 * 1024) -- чтение любых данных, не более 10К
if not data then
    ngx.say("не удалось прочитать данные: ", err)
    return
end
ngx.say("успешно прочитано: ", data)
```Этот метод автоматически не закрывает текущее соединение при возникновении ошибки таймаута чтения. Для других ошибок соединения этот метод всегда автоматически закрывает соединение.

Эта функциональность была введена в выпуске `v0.10.14`.

[Назад к Оглавлению](#nginx-api-for-lua)

tcpsock:receiveuntil
---------------------

**синтаксис:** *iterator = tcpsock:receiveuntil(pattern, options?)*

**контекст:** *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *ngx.timer.*, *ssl_certificate_by_lua*, *ssl_session_fetch_by_lua*, *ssl_client_hello_by_lua*

Этот метод возвращает итератор Lua-функцию, которую можно вызывать для чтения потока данных до тех пор, пока не будет найдено указанное выражение или не произойдет ошибка.

Вот пример использования этого метода для чтения потока данных с границей `--abcedhb`:

```lua

local reader = sock:receiveuntil("\r\n--abcedhb")
local data, err, partial = reader()
if not data then
    ngx.say("не удалось прочитать поток данных: ", err)
end
ngx.say("прочитан поток данных: ", data)

При вызове без аргументов итераторная функция возвращает полученные данные сразу перед указанным выражением в входящем потоке данных. Так что для примера выше, если входящий поток данных будет 'hello, world! -agentzh\r\n--abcedhb blah blah', то будет возвращена строка 'hello, world! -agentzh'. В случае ошибки функция итератора вернет nil вместе со строкой, описывающей ошибку, и частично прочитанными байтами данных.

Функция итератора может быть вызвана несколько раз и безопасно использоваться вместе с другими методами cosocket или другими вызовами функций итератора.Функция итератора ведёт себя по-разному (то есть как настоящий итератор), когда она вызывается с аргументом size. То есть она будет читать указанное количество данных (size) на каждом вызове и вернёт nil при последнем вызове (либо найдет границу, либо столкнётся с ошибкой). Для последнего успешного вызова функции итератора значение err также будет nil. Функция итератора будет сброшена после последнего успешного вызова, который возвращает nil данные и nil ошибку. Рассмотрим следующий пример:


local reader = sock:receiveuntil("\r\n--abcedhb")

while true do
    local data, err, partial = reader(4)
    if not data then
        if err then
            ngx.say("не удалось прочитать поток данных: ", err)
            break
        end

        ngx.say("чтение завершено")
        break
    end
    ngx.say("читаемый блок: [", data, "]")
end

Тогда для входящего потока данных 'hello, world! -agentzh\r\n--abcedhb blah blah', мы получим следующий вывод из приведённого выше примера кода:

читаемый блок: [hell]
читаемый блок: [o, w]
читаемый блок: [orld]
читаемый блок: [! -a]
читаемый блок: [gent]
читаемый блок: [zh]
чтение завершено

Обратите внимание, что фактические данные, возвращаемые, могут быть немного длиннее, чем предел размера, указанный аргументом size, если граница имеет неопределенность для потокового парсинга. Близко к границе потока данных фактическая строка данных также может быть короче, чем предел размера.Таймаут для операции чтения функции итератора контролируется директивой конфигурации lua_socket_read_timeout и методом settimeout. Последний имеет приоритет. Например:


local readline = sock:receiveuntil("\r\n")

sock:settimeout(1000)  -- таймаут в одну секунду
line, err, partial = readline()
if not line then
    ngx.say("не удалось прочитать строку: ", err)
    return
end
ngx.say("успешно прочитана строка: ", line)

Важно здесь вызвать метод settimeout до вызова итераторной функции (отмечено, что вызов receiveuntil здесь не имеет значения).

С версии v0.5.1 этот метод также принимает необязательный аргумент таблицы options для управления поведением. Поддерживаемые опции включают:

  • inclusive

Параметр inclusive принимает булево значение для управления тем, включать ли строку шаблона в возвращаемую строку данных. По умолчанию установлено значение false. Например,


 local reader = tcpsock:receiveuntil("_END_", { inclusive = true })
 local data = reader()
 ngx.say(data)

Тогда для входного потока данных "hello world _END_ blah blah blah" пример выше выведет hello world _END_, включая сам шаблон _END_.

С версии v0.8.8 этот метод больше не автоматически закрывает текущее соединение при ошибке времени ожидания. Для других ошибок соединения этот метод всегда автоматически закрывает соединение.

Этот метод был введен впервые в версии v0.5.0rc1.

Назад к Оглавлениюtcpsock:close

синтаксис: ok, err = tcpsock:close()

контекст: rewrite_by_lua, access_by_lua, content_by_lua, ngx.timer., ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_client_hello_by_lua

Закрывает текущее TCP или Unix доменное сокетное соединение. В случае успеха возвращает 1, в противном случае возвращает nil вместе с описанием ошибки в виде строки.

Обратите внимание, что вызывать этот метод на объектах сокета, которые уже вызвали метод setkeepalive, не требуется, так как объект сокета уже закрыт (и текущее соединение сохранено в встроенный пуле соединений).

Объекты сокета, которые не вызывали этот метод (и связанные с ними соединения), будут закрыты, когда объект сокета будет освобожден Lua GC (Garbage Collector) или завершится текущий запрос HTTP клиента.

Эта функциональность была введена впервые в версии v0.5.0rc1.

Назад к Оглавлению

tcpsock:settimeout

синтаксис: tcpsock:settimeout(time)

контекст: rewrite_by_lua, access_by_lua, content_by_lua, ngx.timer., ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_client_hello_by_lua

Устанавливает значение таймаута в миллисекундах для последующих операций сокета (connect, receive и итераторы, возвращаемые от receiveuntil).

Настройки, выполненные этим методом, имеют приоритет над теми, которые указаны через конфигурационные директивы (т.е. lua_socket_connect_timeout, lua_socket_send_timeout и lua_socket_read_timeout).Обратите внимание, что этот метод не влияет на настройку lua_socket_keepalive_timeout; аргумент timeout метода setkeepalive следует использовать для этой цели.

Эта функция была введена впервые в выпуске v0.5.0rc1.

Назад к Оглавлению

tcpsock:settimeouts

синтаксис: tcpsock:settimeouts(connect_timeout, send_timeout, read_timeout)

контекст: rewrite_by_lua, access_by_lua, content_by_lua, ngx.timer., ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_client_hello_by_lua

Последовательно устанавливает пороги таймаута подключения, отправки и чтения (в миллисекундах) для последующих операций сокета (connect, send, receive и итераторы, возвращаемые от receiveuntil).

Настройки, выполненные этим методом, имеют приоритет над теми, которые указаны через конфигурационные директивы (т.е. lua_socket_connect_timeout, lua_socket_send_timeout и lua_socket_read_timeout).

Рекомендуется использовать settimeouts вместо settimeout.

Обратите внимание, что этот метод не влияет на настройку lua_socket_keepalive_timeout; аргумент timeout метода setkeepalive следует использовать для этой цели.

Эта функция была введена впервые в выпуске v0.10.7.

Назад к Оглавлению

tcpsock:setoption

синтаксис: *ok, err = tcpsock:setoption(option, value?)*Контекст: rewrite_by_lua, access_by_lua, content_by_lua, ngx.timer., ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_client_hello_by_lua Эта функция добавлена для совместимости с API библиотеки LuaSocket, её функциональность реализована в версии v0.10.18.

Эта функциональность была введена впервые в выпуске v0.5.0rc1.

При успешном выполнении она возвращает true. В противном случае возвращается nil и строка, описывающая ошибку.

Параметр option представляет собой строку с именем опции, а значение зависит от установленной опции:

  • keepalive

Установка этой опции на true позволяет отправлять сообщения keep-alive на соединениях, ориентированных на подключение. Убедитесь, что функция connect была вызвана ранее, например,


local ok, err = tcpsock:setoption("keepalive", true)
if not ok then
    ngx.say("setoption keepalive failed: ", err)
end
  • reuseaddr

Включение этой опции указывает, что правила проверки адресов, предоставленных в вызове функции bind, должны позволять повторное использование локальных адресов. Убедитесь, что функция connect была вызвана ранее, например,


local ok, err = tcpsock:setoption("reuseaddr", 0)
if not ok then
    ngx.say("setoption reuseaddr failed: ", err)
end
  • tcp-nodelay

Установка этой опции на true отключает алгоритм Нейгла для соединения. Убедитесь, что функция connect была вызвана ранее, например,


local ok, err = tcpsock:setoption("tcp-nodelay", true)
if not ok then
    ngx.say("setoption tcp-nodelay failed: ", err)
end
```* `sndbuf`

Устанавливает максимальный размер буфера отправки сокета в байтах. Ядро удваивает это значение (чтобы предоставить пространство для служебной информации) при установке с помощью `setsockopt()`. Убедитесь, что функция `connect` была вызвана ранее, например,

```lua

local ok, err = tcpsock:setoption("sndbuf", 1024 * 10)
if not ok then
    ngx.say("setoption sndbuf failed: ", err)
end
  • rcvbuf

Устанавливает максимальный размер буфера приема сокета в байтах. Ядро удваивает это значение (чтобы предоставить пространство для служебной информации) при установке с помощью setsockopt(). Убедитесь, что функция connect была вызвана ранее, например,


local ok, err = tcpsock:setoption("rcvbuf", 1024 * 10)
if not ok then
    ngx.say("setoption rcvbuf failed: ", err)
end

Примечание: Как только опция будет установлена, она вступает в силу до закрытия соединения. Если вы знаете, что соединение происходит из пула соединений и все соединения в пуле уже вызвали метод setoption() с желаемым состоянием опции сокета, то можно пропустить повторный вызов setoption(), чтобы избежать излишних вызовов, например,


local count, err = tcpsock:getreusedtimes()
if not count then
    ngx.say("getreusedtimes failed: ", err)
    return
end

if count == 0 then
    local ok, err = tcpsock:setoption("rcvbuf", 1024 * 10)
    if not ok then
        ngx.say("setoption rcvbuf failed: ", err)
        return
    end
end

Эти опции, описанные выше, поддерживаются в версии v0.10.18, и в будущих версиях будут реализованы дополнительные опции.Назад к Оглавлению

tcpsock:setkeepalive

синтаксис: ok, err = tcpsock:setkeepalive(время_ожидания?, размер_пула?)

контекст: rewrite_by_lua, access_by_lua, content_by_lua, ngx.timer., ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_client_hello_by_lua

Переносит текущее соединение сокета сразу в встроенный пул соединений cosocket и поддерживает его активным до тех пор, пока другое соединение не запросит его с помощью метода connect или пока не истечёт максимальное время бездействия.Первый необязательный аргумент time_out может использоваться для указания максимального времени бездействия (в миллисекундах) для текущего соединения. Если этот аргумент опущен, используется значение по умолчанию из директивы конфигурации lua_socket_keepalive_timeout. Если указано значение 0, то интервал времени ожидания является неограниченным. Второй необязательный аргумент size считается устаревшим с релиза v0.10.14 этого модуля в пользу опции pool_size метода connect. С момента релиза v0.10.14, эта опция будет иметь эффект только в том случае, если вызов connect еще не создал пула соединений. Когда эта опция имеет эффект (пул соединений ранее не был создан), она устанавливает размер пула соединений и создает его. Если опция size не указана (и пула ранее не было создано), по умолчанию используется значение параметра lua_socket_pool_size. Пул соединений удерживает до size активных соединений, готовых к повторному использованию последующими вызовами connect, но обратите внимание, что нет верхнего ограничения на общее количество открытых соединений вне пула. Когда пул соединений превышает свой лимит размера, наименее недавно используемое (сохраненное) соединение уже находящееся в пуле будет закрыто, чтобы освободить место для текущего соединения.Обратите внимание, что пул соединений косокостей относится к каждому отдельному процессу рабочего Nginx, а не к каждому экземпляру сервера Nginx, поэтому указанный здесь лимит размера также применяется ко всем отдельным процессам рабочего Nginx. Также обратите внимание, что размер пула соединений не может быть изменён после его создания.

Если вам нужно ограничить общее количество открытых соединений, укажите как опцию pool_size, так и опцию backlog в вызове connect. В случае успеха этот метод возвращает 1; в противном случае он возвращает nil и строку, описывающую ошибку.Когда буфер системы приема для текущего соединения содержит непрочитанные данные, то данный метод вернет сообщение об ошибке "соединение в сомнительном состоянии" (в качестве второго значения возврата), так как предыдущая сессия оставила непрочитанные данные для следующей сессии, и соединение не безопасно для повторного использования.

Этот метод также заставляет объект cosocket перейти в состояние "закрыто", поэтому нет необходимости вручную вызывать метод close для него после этого.

Эта функция была введена впервые в выпуске v0.5.0rc1.

Назад к Оглавлению

tcpsock:getreusedtimes

синтаксис: count, err = tcpsock:getreusedtimes()

контекст: rewrite_by_lua, access_by_lua, content_by_lua, ngx.timer., ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_client_hello_by_lua

Этот метод возвращает количество успешных переиспользований текущего соединения. В случае ошибки он возвращает nil и строку, описывающую ошибку.

Если текущее соединение не берется из встроенного пула соединений, то этот метод всегда возвращает 0, то есть соединение никогда не переиспользовалось (ещё). Если соединение берется из пула соединений, то значение возврата всегда будет отличаться от нуля. Поэтому этот метод также может использоваться для определения, приходит ли текущее соединение из пула.Эта функция была введена впервые в выпуске v0.5.0rc1.

Назад к Оглавлению

ngx.socket.connect

синтаксис: tcpsock, err = ngx.socket.connect(host, port)

синтаксис: tcpsock, err = ngx.socket.connect("unix:/path/to/unix-domain.socket")

контекст: rewrite_by_lua, access_by_lua, content_by_lua, ngx.timer.

Эта функция является сокращением для объединения ngx.socket.tcp() и вызова метода connect() в одном действии. Она фактически реализована следующим образом:


local sock = ngx.socket.tcp()
local ok, err = sock:connect(...)
if not ok then
    return nil, err
end
return sock

Нет способа использовать метод settimeout для указания времени ожидания подключения для этого метода, а директива lua_socket_connect_timeout должна быть установлена при конфигурировании вместо этого. Эта функция была введена впервые в выпуске v0.5.0rc1.

Назад к Оглавлению

ngx.get_phase

синтаксис: str = ngx.get_phase()

контекст: init_by_lua, init_worker_by_lua, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, exit_worker_by_lua, ssl_client_hello_by_lua

Получает имя текущего выполняющегося этапа. Возможные значения возвращаемых значений:* init для контекста init_by_lua*.

Назад к Оглавлению

ngx.thread.spawn

синтаксис: co = ngx.thread.spawn(func, arg1, arg2, ...)

контекст: rewrite_by_lua, access_by_lua, content_by_lua, ngx.timer., ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_client_hello_by_lua

Создает новый пользовательский "легкий поток" с помощью Lua-функции func вместе с опциональными аргументами arg1, arg2 и так далее. Возвращает объект Lua-потока (или Lua-корутины), представляющий этот "легкий поток".

"Легкие потоки" являются специальным видом Lua-корутин, управляемых модулем ngx_lua.

Перед тем как ngx.thread.spawn вернет управление, функция func будет вызвана с указанными опциональными аргументами до тех пор, пока она не завершится, не прервется ошибкой или не будет приостановлена из-за операций ввода-вывода через API Lua для Nginx (например, tcpsock:receive).

После того как ngx.thread.spawn вернет управление, созданный "легкий поток" продолжит работать асинхронно обычно при различных событиях ввода-вывода.

Все блоки Lua-кода, выполняемые с помощью rewrite_by_lua, access_by_lua и content_by_lua, находятся в шаблонном "легком потоке", созданном автоматически ngx_lua. Такие шаблонные "легкие потоки" также называются "входными потоками".

По умолчанию соответствующий обработчик Nginx (например, обработчик rewrite_by_lua) не завершается до тех пор, пока1. не завершатся как "входной поток", так и все пользовательские "легкие потоки",

  1. один из "легких потоков" (либо "входной поток", либо пользовательский "легкий поток") не прервется вызовом ngx.exit, ngx.exec, ngx.redirect или ngx.req.set_uri(uri, true),
  2. "входной поток" не завершится с ошибкой Lua.

Когда пользовательский "легкий поток" завершается с ошибкой Lua, он не прерывает другие работающие "легкие потоки", как это делает "входной поток".

Из-за ограничений модели подзапросов Nginx в общем случае запрещено прерывать выполняющийся подзапрос Nginx. Поэтому также запрещено прерывать "легкий поток", ожидающий одного или нескольких подзапросов Nginx. Вы должны вызвать ngx.thread.wait, чтобы дождаться завершения этих "легких потоков" перед выходом из мира. Примечательным исключением является возможность прерывания ожидающих подзапросов вызовом ngx.exit только со статусом ngx.ERROR (-1), 408, 444 или 499."Легкие потоки" не планируются с использованием предварительного выделения времени. Другими словами, автоматическое разделение времени не выполняется. "Легкий поток" будет продолжать работу исключительно на процессоре до тех пор, пока:

  1. операция ввода-вывода (I/O) без блокировки не может быть завершена за один проход,
  2. она вызывает coroutine.yield, чтобы активно передать управление, или
  3. она прерывается ошибкой Lua или вызовом ngx.exit, ngx.exec, ngx.redirect или ngx.req.set_uri(uri, true).Для первых двух случаев "лёгкий поток" обычно будет продолжен позже планировщиком ngx_lua, если не произойдёт событие "конца света".

Пользовательские "лёгкие потоки" могут создавать свои "лёгкие потоки". И обычные корутины Lua, созданные с помощью coroutine.create, также могут создавать "лёгкие потоки". Корутина (будь то обычный Lua-поток или "лёгкий поток"), которая непосредственно создаёт "лёгкий поток", называется "родительским потоком" для нового "лёгкого потока".

"Родительский поток" может вызвать ngx.thread.wait, чтобы дождаться завершения своего "лёгкого потока".

Вы можете вызывать coroutine.status() и coroutine.yield() для корутин "лёгких потоков".

Статус корутины "лёгкого потока" может быть "зомби", если

  1. текущий "лёгкий поток" уже завершился (либо успешно, либо с ошибкой),
  2. его родительский поток всё ещё жив,
  3. и его родительский поток не ждёт завершения "лёгкого потока" с помощью ngx.thread.wait.

Приведённый ниже пример демонстрирует использование coroutine.yield() в корутинах "лёгких потоков" для ручного деления времени выполнения:


local yield = coroutine.yield

function f()
    local self = coroutine.running()
    ngx.say("f  метод 1")
    yield(self)
    ngx.say("f  метод 2")
    yield(self)
    ngx.say("f  метод 3")
end

local self = coroutine.running()
ngx.say("0")
yield(self)

ngx.say("1")
ngx.thread.spawn(f)

ngx.say("2")
yield(self)

ngx.say("3")
yield(self)
```ngx.say("4")

Затем он сгенерирует вывод

0
1
f  Метод 1
2
f  Метод 2
3
f  Метод 3
4

"Лёгкие потоки" в основном полезны для параллельных запросов к серверам-источникам в одном обработчике запросов Nginx, аналогично обобщённой версии ngx.location.capture_multi, которая может работать со всеми API Nginx для Lua. Приведённый ниже пример демонстрирует параллельные запросы к MySQL, Memcached и HTTP-серверам-источникам в одном обработчике Lua, а также выводит результаты в порядке их фактического получения (аналогично модели BigPipe от Facebook):```lua

-- запрос к MySQL, memcached и удаленному HTTP сервису одновременно, -- вывод результатов в порядке их получения.

local mysql = require "resty.mysql" local memcached = require "resty.memcached"

local function query_mysql() local db = mysql:new() db:connect{ host = "127.0.0.1", port = 3306, database = "test", user = "monty", password = "mypass" } local res, err, errno, sqlstate = db:query("select * from cats order by id asc") db:set_keepalive(0, 100) ngx.say("mysql завершен: ", cjson.encode(res)) end

local function query_memcached() local memc = memcached:new() memc:connect("127.0.0.1", 11211) local res, err = memc:get("some_key") ngx.say("memcached завершен: ", res) end

local function query_http() local res = ngx.location.capture("/my-http-proxy") ngx.say("http завершен: ", res.body) end

ngx.thread.spawn(query_mysql) -- создание потока 1 ngx.thread.spawn(query_memcached) -- создание потока 2 ngx.thread.spawn(query_http) -- создание потока 3


Этот API был впервые включен в выпуске `v0.7.0`.[Назад к Оглавлению](#nginx-api-for-lua)

ngx.thread.wait
---------------

**синтаксис:** *ok, res1, res2, ... = ngx.thread.wait(thread1, thread2, ...)*

**контекст:** *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *ngx.timer.*, *ssl_certificate_by_lua*, *ssl_session_fetch_by_lua*, *ssl_client_hello_by_lua*

Ждет завершения одного или нескольких дочерних "легких потоков" и возвращает результаты первого "легкого потока", который завершился (либо успешно, либо с ошибкой).

Аргументы `thread1`, `thread2` и т.д. являются объектами Lua-потока, возвращаемыми ранее вызовами [ngx.thread.spawn](#ngxthreadspawn).

Возвращаемые значения имеют точно такое же значение, как [coroutine.resume](#coroutineresume), то есть первый возвращаемый значение является логическим значением, указывающим, завершился ли "легкий поток" успешно или нет, а последующие возвращаемые значения являются возвращаемыми значениями пользователя Lua-функции, использованной для создания "легкого потока" (в случае успеха) или объектом ошибки (в случае неудачи).

Только прямой "родительский корутин" может ждать завершения своего дочернего "легкого потока", в противном случае будет выброшено исключение Lua. Приведенный ниже пример демонстрирует использование `ngx.thread.wait` и [ngx.location.capture](#ngxlocationcapture) для эмуляции [ngx.location.capture_multi](#ngxlocationcapture_multi):

```lua

local capture = ngx.location.capture
local spawn = ngx.thread.spawn
local wait = ngx.thread.wait
local say = ngx.say

local function fetch(uri)
    return capture(uri)
end
```локальные потоки = {
    spawn(запрос, "/foo"),
    spawn(запрос, "/bar"),
    spawn(запрос, "/baz")
}

для i = 1, #потоки делать
    локальное ok, res = ждать(потоки[i])
    если не ok то
        сказать(i, ": не удалось запустить: ", res)
    иначе
        сказать(i, ": статус: ", res.status)
        сказать(i, ": тело: ", res.body)
    конец
конец

Здесь реализуется модель "ожидание всех".

А ниже приведен пример, демонстрирующий модель "ожидание любого":


функция f()
    ngx.sleep(0.2)
    ngx.say("f: привет")
    вернуть "f завершено"
конец

функция g()
    ngx.sleep(0.1)
    ngx.say("g: привет")
    вернуть "g завершено"
конец

локальное tf, err = ngx.thread.spawn(f)
если не tf то
    ngx.say("не удалось запустить поток f: ", err)
    вернуть
конец

ngx.say("поток f создан: ", корутин.status(tf))

локальное tg, err = ngx.thread.spawn(g)
если не tg то
    ngx.say("не удалось запустить поток g: ", err)
    вернуть
конец

ngx.say("поток g создан: ", корутин.status(tg))

ок, res = ngx.thread.wait(tf, tg)
если не ок то
    ngx.say("не удалось дождаться: ", res)
    вернуть
конец

ngx.say("результат: ", res)

-- остановка "мир", прерывание других выполняющихся потоков
ngx.exit(ngx.OK)

И он сгенерирует следующий вывод:

поток f создан: выполняется
поток g создан: выполняется
g: привет
результат: g завершено

Этот API был впервые включен в выпуске v0.7.0.

Назад к Оглавлению

ngx.thread.kill

синтаксис: ок, ошибка = ngx.thread.kill(поток)

контекст: rewrite_by_lua, access_by_lua, content_by_lua, ngx.timer., ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_client_hello_by_luaУничтожает выполняющийся "легкий поток", созданный с помощью ngx.thread.spawn. Возвращает истинное значение при успешном выполнении или nil и строку, описывающую ошибку в противном случае. Согласно текущей реализации, только родительская корутинная задача (или "легкий поток") может завершить работу потока. Также работающий "легкий поток" с ожидающими подзапросами Nginx (например, инициированными с помощью ngx.location.capture) не может быть завершен из-за ограничения в ядре Nginx. Этот API был впервые включен в выпуске v0.9.9.Назад к Оглавлению

ngx.on_abort

синтаксис: ok, err = ngx.on_abort(callback)

контекст: rewrite_by_lua, access_by_lua, content_by_lua

Регистрирует пользовательскую функцию Lua как обратный вызов, который автоматически вызывается, когда клиент преждевременно закрывает соединение.

Возвращает 1, если обратный вызов успешно зарегистрирован, или nil и строку, описывающую ошибку, в противном случае.

Все API Nginx для Lua могут использоваться в функции обратного вызова, так как функция выполняется в специальном "легком потоке", точно так же, как те "легкие потоки", созданные с помощью ngx.thread.spawn.

Функция обратного вызова может сама решить, что делать с событием прерывания соединения клиента. Например, она может просто игнорировать событие, ничего не делая, и текущий обработчик запроса Lua продолжит выполнение без прерываний. И функция обратного вызова также может решить завершить все процессы, вызвав ngx.exit, например,


local function my_cleanup()
    -- здесь выполняются пользовательские операции очистки, такие как отмена ожидающей транзакции базы данных

    -- теперь прерываем все "легкие потоки", выполняющиеся в текущем обработчике запроса
    ngx.exit(499)
end

local ok, err = ngx.on_abort(my_cleanup)
if not ok then
    ngx.log(ngx.ERR, "не удалось зарегистрировать обратный вызов on_abort: ", err)
    ngx.exit(500)
end
```Когда [lua_check_client_abort](#lua_check_client_abort) установлено в `off` (что является значением по умолчанию), то этот вызов функции всегда вернёт сообщение об ошибке "lua_check_client_abort is off".

Согласно текущей реализации, эта функция может быть вызвана только один раз в одном обработчике запроса; последующие вызовы вернут сообщение об ошибке "повторный вызов".

Этот API был введён впервые в выпуске `v0.7.4`.

См. также [lua_check_client_abort](#lua_check_client_abort).

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.timer.at
------------

**синтаксис:** *hdl, err = ngx.timer.at(delay, callback, user_arg1, user_arg2, ...)*

**контекст:** *init_worker_by_lua*, *set_by_lua*, *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *header_filter_by_lua*, *body_filter_by_lua*, *log_by_lua*, *ngx.timer.*, *balancer_by_lua*, *ssl_certificate_by_lua*, *ssl_session_fetch_by_lua*, *ssl_session_store_by_lua*, *ssl_client_hello_by_lua*

Создаёт таймер Nginx с пользовательской функцией обратного вызова, а также с необязательными аргументами пользователя.

Первый аргумент, `delay`, указывает задержку для таймера,
в секундах. Можно указать дробные секунды, такие как `0.001`, что означает 1
миллисекунду. Задержка `0` также может быть указана, в этом случае таймер будет немедленно истекать, когда текущий обработчик передаст выполнение.Второй аргумент, `callback`, может быть любой функцией Lua, которая будет вызвана позже в фоновом "легком потоке" после указанной задержки. Пользовательская функция обратного вызова будет вызываться автоматически ядром Nginx с аргументами `premature`, `user_arg1`, `user_arg2`, и т.д., где аргумент `premature` принимает булево значение, указывающее, является ли это преждевременным истечением таймера или нет (для таймера с задержкой `0` это всегда `false`), а `user_arg1`, `user_arg2`, и т.д., являются этими (дополнительными) аргументами пользователя, указанными при вызове `ngx.timer.at` как оставшиеся аргументы.Преждевременное истечение таймера происходит, когда процесс рабочего узла Nginx пытается завершиться, как при перезагрузке конфигурации Nginx, вызванной сигналом `HUP`, или при завершении работы сервера Nginx. Когда процесс рабочего узла Nginx пытается завершиться, больше нельзя вызывать `ngx.timer.at` для создания новых таймеров с ненулевой задержкой, и в этом случае `ngx.timer.at` вернёт условное ложное значение и строку, описывающую ошибку, то есть "процесс завершается".

Начиная с выпуска `v0.9.3`, разрешено создавать таймеры с задержкой `0`, даже когда процесс рабочего узла Nginx начинает завершаться.

Когда таймер истекает, пользовательский код Lua в функции обратного вызова таймера выполняется в "легком потоке", полностью отсоединившемся от исходного запроса, создающего таймер. Поэтому объекты с тем же сроком жизни, что и исходный запрос, такие как [cosockets](#ngxsockettcp), не могут быть использованы между исходным запросом и функцией обратного вызова пользователя таймера.

Вот простой пример:```nginx
location / {
    ...
    log_by_lua_block {
        local function push_data(premature, uri, args, status)
            -- отправка данных uri, args и status на удалённый сервер
            -- с использованием ngx.socket.tcp или ngx.socket.udp
            -- (можно временно буферизировать данные в Lua для экономии операций ввода-вывода)
        end
        local ok, err = ngx.timer.at(0, push_data, ngx.var.uri, ngx.var.args, ngx.header.status)
        if not ok then
            ngx.log(ngx.ERR, "не удалось создать таймер: ", err)
            return
        end
    }
}
-- другие задачи в логе в блоке log_by_lua_block
}

Также можно создать бесконечные повторяющиеся таймеры, например, таймер, который срабатывает каждые 5 секунд, вызывая рекурсивно ngx.timer.at в обратном вызове таймера. Вот такой пример:


local задержка = 5
local обработчик
обработчик = function (необходимо)
    -- выполняем регулярную работу на Lua, как задачу cron
    if необходимо then
        return
    end
    local ok, err = ngx.timer.at(задержка, обработчик)
    if not ok then
        ngx.log(ngx.ERR, "не удалось создать таймер: ", err)
        return
    end

    -- делаем что-то в таймере
end

local ok, err = ngx.timer.at(задержка, обработчик)
if not ok then
    ngx.log(ngx.ERR, "не удалось создать таймер: ", err)
    return
end

-- делаем другие задачи

Однако рекомендуется использовать API-функцию ngx.timer.every для создания повторяющихся таймеров, так как она более надежна.Поскольку обратные вызовы таймеров выполняются в фоновом режиме и время их выполнения не добавляется к времени ответа клиентского запроса, они могут легко накапливаться на сервере и исчерпывать системные ресурсы из-за ошибок программирования на Lua или из-за большого количества трафика клиентов. Чтобы предотвратить крайние последствия, такие как аварийное завершение работы сервера Nginx, существуют встроенные ограничения на количество "ожидаемых таймеров" и "запущенных таймеров" в процессе рабочего потока Nginx. Здесь "ожидаемые таймеры" означают таймеры, которые ещё не истекли, а "запущенные таймеры" — те, чьи обратные вызовы пользователя выполняются в данный момент.Максимальное количество "ожидаемых таймеров", разрешённое в рабочем процессе Nginx, контролируется директивой lua_max_pending_timers. Максимальное количество "запущенных таймеров" контролируется директивой lua_max_running_timers.

Согласно текущей реализации, каждый "запущенный таймер" будет забирать одну (фиктивную) запись соединения из глобального списка записей соединений, настроенного стандартной директивой worker_connections в nginx.conf. Поэтому убедитесь, что директива worker_connections установлена на достаточно большое значение, которое учитывает как реальные соединения, так и фиктивные соединения, требуемые обратными вызовами таймера (как ограничено директивой lua_max_running_timers). Многие Lua API для Nginx включаются в контексте обратных вызовов таймера, таких как потоки/datagram cosockets (ngx.socket.tcp и ngx.socket.udp), словари с общим доступом (ngx.shared.DICT), пользовательские корутины (coroutine.*), пользовательские "лёгкие потоки" (ngx.thread.*), ngx.exit, ngx.now/ngx.time, ngx.md5/ngx.sha1_bin, все они разрешены. Однако API подзапроса (например, ngx.location.capture), API ngx.req.*, API вывода данных для клиента (например, ngx.say, ngx.print и ngx.flush) явно отключены в этом контексте.Обратите внимание, что каждый таймер будет основан на фиктивном запросе (этот фиктивный запрос также основан на фиктивном соединении). Поскольку освобождение памяти Nginx основано на закрытии соединения, если вы запустите много API, использующих память, в таймере, таких как tcpsock:connect, это приведёт к накоплению памяти. Поэтому рекомендуется создавать новый таймер после нескольких запусков для освобождения памяти.Вы можете передать большинство стандартных значений Lua (nil, булевые значения, числа, строки, таблицы, замыкания, дескрипторы файлов и т. д.) в обратный вызов таймера, как явно в виде аргументов пользователя, так и неявно в виде upvalues для замыкания обратного вызова. Однако существуют некоторые исключения: вы не можете передать объекты потока, возвращаемые coroutine.create и ngx.thread.spawn, или объекты cosocket, возвращаемые ngx.socket.tcp, ngx.socket.udp и ngx.req.socket, поскольку срок службы этих объектов связан с контекстом запроса, создающим их, в то время как обратный вызов таймера отсоединён от контекста запроса, создающего его (по дизайну), и выполняется в своём собственном (фиктивном) контексте запроса. Если вы попытаетесь разделить потоки или объекты cosocket между границами запроса, создающего их, вы получите ошибку "no co ctx found" (для потоков) или "bad request" (для cosocket). Однако создание всех этих объектов внутри обратного вызова таймера допустимо.Пожалуйста, обратите внимание, что обработчик Lua таймера имеет свой собственный экземпляр магической таблицы ngx.ctx. Он не будет делиться одной и той же ngx.ctx с обработчиком Lua, создающим таймер. Если вам нужно передать данные от создателя таймера до обработчика таймера, пожалуйста, используйте дополнительные параметры ngx.timer.at(). Этот API был впервые введен в выпуске v0.8.0.

Назад к Оглавлению

ngx.timer.every

синтаксис: hdl, err = ngx.timer.every(задержка, обратный_вызов, пользовательский_арг1, пользовательский_арг2, ...)

контекст: init_worker_by_lua, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, ssl_client_hello_by_lua

Аналогично API функции ngx.timer.at, но

  1. значение задержка не может быть нулевым,
  2. таймер будет создаваться каждые задержка секунд до тех пор, пока текущий процесс рабочего узла Nginx не начнет завершаться.

Как и в случае с ngx.timer.at, аргумент обратный_вызов будет автоматически вызван с аргументами предварительный, пользовательский_арг1, пользовательский_арг2, и т.д.

При успешном выполнении возвращается условное значение истина (но не истина). В противном случае возвращается условное значение ложь и строка, описывающая ошибку.Этот API также учитывает директивы lua_max_pending_timers и lua_max_running_timers.

Этот API был впервые введен в выпуске v0.10.9.

Назад к Оглавлению

ngx.timer.running_count

синтаксис: количество = ngx.timer.running_count()

контекст: init_worker_by_lua, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, exit_worker_by_lua, ssl_client_hello_by_lua

Возвращает количество таймеров, которые в данный момент выполняются.

Эта директива была введена впервые в выпуске v0.9.20.

Назад к Оглавлению

ngx.timer.pending_count

синтаксис: количество = ngx.timer.pending_count()

контекст: init_worker_by_lua, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, exit_worker_by_lua, ssl_client_hello_by_lua

Возвращает количество ожидающих таймеров.

Эта директива была введена впервые в выпуске v0.9.20.

Назад к Оглавлению

ngx.config.subsystem

синтаксис: subsystem = ngx.config.subsystem

контекст: set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., init_by_lua, init_worker_by_lua, exit_worker_by_luaЭтот строковый параметр указывает подсистему Nginx, на основе которой работает текущее окружение Lua. Для этого модуля этот параметр всегда принимает строковое значение "http". Для ngx_stream_lua_module этот параметр принимает значение "stream".

Также исправлено отсутствие пробела перед закрывающей кавычкой в последнем предложении.Этот параметр был введен впервые в выпуске 0.10.1.

Назад к Оглавлению

ngx.config.debug

синтаксис: debug = ngx.config.debug

контекст: set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., init_by_lua, init_worker_by_lua, exit_worker_by_lua

Этот булевый параметр указывает, является ли текущий Nginx отладочной сборкой, то есть был ли он собран с помощью опции --with-debug команды ./configure.

Этот параметр был введен впервые в выпуске 0.8.7.

Назад к Оглавлению

ngx.config.prefix

синтаксис: prefix = ngx.config.prefix()

контекст: set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., init_by_lua, init_worker_by_lua, exit_worker_by_lua

Возвращает путь "префикса" сервера Nginx, как определенный параметром командной строки -p, когда запускается исполняемый файл Nginx, или параметром командной строки --prefix, когда Nginx собирается с помощью скрипта ./configure.

Эта функция была введена впервые в выпуске 0.9.2.

Назад к Оглавлению

ngx.config.nginx_version

синтаксис: ver = ngx.config.nginx_version

контекст: set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., init_by_lua, init_worker_by_lua, exit_worker_by_lua

Это поле принимает целое значение, указывающее номер версии текущего ядра Nginx, которое используется. Например, версия 1.4.3 приводит к тому, что Lua число равно 1004003.Этот API был впервые введен в выпуске 0.9.3.

Назад к Оглавлению

ngx.config.nginx_configure

синтаксис: str = ngx.config.nginx_configure()

контекст: set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., init_by_lua

Эта функция возвращает строку с аргументами команды ./configure для Nginx.

Этот API был впервые введен в выпуске 0.9.5.

Назад к Оглавлению

ngx.config.ngx_lua_version

синтаксис: ver = ngx.config.ngx_lua_version

контекст: set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., init_by_lua

Это поле принимает целое значение, указывающее номер версии текущего модуля ngx_lua, который используется. Например, версия 0.9.3 приводит к тому, что Lua число равно 9003.

Этот API был впервые введен в выпуске 0.9.3.

Назад к Оглавлению

ngx.worker.exiting

синтаксис: exiting = ngx.worker.exiting()

контекст: set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., init_by_lua, init_worker_by_lua, exit_worker_by_lua

Эта функция возвращает логическое значение, указывающее, начинается ли текущий процесс рабочего узла Nginx завершаться. Завершение процесса рабочего узла происходит при выходе сервера Nginx или перезагрузке конфигурации (также известной как перезагрузка HUP).

Этот API был впервые введен в выпуске 0.9.3.Назад к Оглавлению

ngx.worker.pid

синтаксис: pid = ngx.worker.pid()

контекст: set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., init_by_lua, init_worker_by_lua, exit_worker_by_lua

Эта функция возвращает Lua число для идентификатора процесса (PID) текущего рабочего процесса Nginx. Этот API более эффективен, чем ngx.var.pid, и может использоваться в контекстах, где API ngx.var.VARIABLE использовать нельзя (например, init_worker_by_lua).

Этот API был впервые введен в выпуске 0.9.5.

Назад к Оглавлению

ngx.worker.pids

синтаксис: pids = ngx.worker.pids()

контекст: set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., exit_worker_by_lua

Эта функция возвращает Lua таблицу для всех идентификаторов процессов (PIDs) рабочих процессов Nginx. Nginx использует канал для передачи текущего PID рабочего процесса другому рабочему процессу при запуске или перезапуске. Поэтому этот API может получить все текущие PID рабочих процессов. Эта функция недоступна в Windows.

Этот API был впервые введен в выпуске 0.10.23.

Назад к Оглавлению

ngx.worker.count

синтаксис: count = ngx.worker.count()

контекст: set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., init_by_lua, init_worker_by_lua, exit_worker_by_lua

Возвращает общее количество рабочих процессов Nginx (то есть значение, настроенное директивой worker_processes в nginx.conf).Этот API был впервые введен в выпуске 0.9.20.

Назад к Оглавлению

ngx.worker.id

синтаксис: id = ngx.worker.id()

контекст: set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., init_worker_by_lua, exit_worker_by_lua

Возвращает порядковый номер текущего рабочего процесса Nginx (начиная с нуля).

Поэтому если общее количество рабочих процессов равно N, то эта функция может вернуть число от Yöntem 0 до N - 1 (включительно).

Эта функция возвращает значимые значения только для Nginx 1.9.1+. В более ранних версиях Nginx она всегда возвращает nil.

См. также ngx.worker.count. Этот API был впервые введен в выпуске 0.9.20.

Назад к Оглавлению

ngx.semaphore

синтаксис: local semaphore = require "ngx.semaphore"

Это Lua-модуль, реализующий классический API семафора для эффективной синхронизации между различными "легкими потоками". Поддерживается использование одного и того же семафора различными "легкими потоками", созданными в разных (запросных) контекстах, при условии, что "легкие потоки" находятся в одном процессе Nginx и директива lua_code_cache включена (что является значением по умолчанию).

Этот Lua-модуль не поставляется вместе с этим модулем ngx_lua, а поставляется с библиотекой lua-resty-core.Для получения более подробной информации о данном ngx.semaphore Lua-модуле обратитесь к документации в lua-resty-core.Эта функция требует версию ngx_lua v0.10.0 или выше.

Назад к Оглавлению

ngx.balancer

синтаксис: local balancer = require "ngx.balancer"

Этот Lua-модуль предоставляет API для определения полностью динамических балансировщиков нагрузки на чистом Lua.

Этот Lua-модуль не поставляется вместе с этим модулем ngx_lua, а поставляется с библиотекой lua-resty-core.

Для получения более подробной информации о данном ngx.balancer Lua-модуле обратитесь к документации в lua-resty-core.

Эта функция требует версию ngx_lua v0.10.0 или выше.

Назад к Оглавлению

ngx.ssl

синтаксис: local ssl = require "ngx.ssl"

Этот Lua-модуль предоставляет функции API для контроля процесса SSL-рукопожатия в контекстах, таких как ssl_certificate_by_lua*.

Этот Lua-модуль не поставляется вместе с этим модулем ngx_lua, а поставляется с библиотекой lua-resty-core.

Для получения более подробной информации о данном ngx.ssl Lua-модуле обратитесь к документации в lua-resty-core.

Эта функция требует версию ngx_lua v0.10.0 или выше.

Назад к Оглавлению

ngx.ocsp

синтаксис: local ocsp = require "ngx.ocsp"

Этот модуль Lua предоставляет API для выполнения запросов OCSP, проверки OCSP ответов и плантинга OCSP stapling.Обычно этот модуль используется вместе с модулем ngx.ssl в контексте ssl_certificate_by_lua*.

Этот модуль Lua не входит в состав этого модуля ngx_lua, а поставляется с библиотекой lua-resty-core.

Для получения более подробной информации обратитесь к документации для этого Lua модуля ngx.ocsp.

Эта функция требует хотя бы версию ngx_lua v0.10.0.

Назад к Оглавлению

ndk.set_var.DIREКТИВА

синтаксис: res = ndk.set_var.НАЗВАНИЕ_ДИРЕКТИВЫ

контекст: init_worker_by_lua, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., balancer_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, exit_worker_by_lua, ssl_client_hello_by_lua

Этот механизм позволяет вызывать другие директивы модулей C Nginx, реализованные подмодулем set_var пакета Nginx Devel Kit (NDK) через ndk_set_var_value.Например, следующие директивы модуля set-misc-nginx-module могут быть вызваны таким образом:

Пример:```lua

local res = ndk.set_var.set_escape_uri('a/b') -- Теперь res == 'a%2fb'


Аналогично, следующие директивы, предоставленные модулем [encrypted-session-nginx-module](http://github.com/openresty/encrypted-session-nginx-module), могут быть вызваны из Lua:

* [set_encrypt_session](http://github.com/openresty/encrypted-session-nginx-module#set_encrypt_session)
* [set_decrypt_session](http://github.com/openresty/encrypted-session-nginx-module#set_decrypt_session)

Эта функциональность требует использования модуля [ngx_devel_kit](https://github.com/simplresty/ngx_devel_kit).

[Назад к Оглавлению](#nginx-api-for-lua)

coroutine.create
----------------

**синтаксис:** *co = coroutine.create(f)*

**контекст:** *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *init_by_lua*, *ngx.timer.*, *header_filter_by_lua*, *body_filter_by_lua*, *ssl_certificate_by_lua*, *ssl_session_fetch_by_lua*, *ssl_session_store_by_lua*, *ssl_client_hello_by_lua*

Создает объект пользователя Lua корутины с помощью Lua функции и возвращает объект корутины.

Аналогично стандартному Lua API [coroutine.create](https://www.lua.org/manual/5.1/manual.html#pdf-coroutine.create), но работает в контексте Lua корутин, созданных ngx_lua.

Это API стало доступным в контексте [init_by_lua*](#init_by_lua) начиная с версии `0.9.2`.

Это API было впервые представлено в выпуске `v0.6.0`.

[Назад к Оглавлению](#nginx-api-for-lua)

coroutine.resume
----------------

**синтаксис:** *ok, ... = coroutine.resume(co, ...)*

**контекст:** *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *init_by_lua*, *ngx.timer.*, *header_filter_by_lua*, *body_filter_by_lua*, *ssl_certificate_by_lua*, *ssl_session_fetch_by_lua*, *ssl_session_store_by_lua*, *ssl_client_hello_by_lua*

Перезапускает выполнение объекта пользователя Lua корутины, который был ранее приостановлен или только что создан.Аналогично стандартному Lua API [coroutine.resume](https://www.lua.org/manual/5.1/manual.html#pdf-coroutine.resume), но работает в контексте Lua корутин, созданных ngx_lua.

Это API стало доступным в контексте [init_by_lua*](#init_by_lua) начиная с версии `0.9.2`.

Это API было впервые представлено в выпуске `v0.6.0`.

[Назад к Оглавлению](#nginx-api-for-lua)

coroutine.yield
---------------

**синтаксис:** *... = coroutine.yield(...)*

**контекст:** *rewrite_by_lua*, access_by_lua, content_by_lua, init_by_lua, ngx.timer.*, header_filter_by_lua, body_filter_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, ssl_client_hello_by_lua*

Передает выполнение текущей пользовательской корутине Lua.

Аналогично стандартному Lua API [coroutine.yield](https://www.lua.org/manual/5.1/manual.html#pdf-coroutine.yield), но работает в контексте корутин, созданных ngx_lua.

Этот API стал доступным в контексте [init_by_lua*](#init_by_lua) начиная с версии `0.9.2`.

Этот API был введен в версии `v0.6.0`.

[Назад к Оглавлению](#nginx-api-for-lua)

coroutine.wrap
--------------

**синтаксис:** *co = coroutine.wrap(f)*

**контекст:** *rewrite_by_lua*, access_by_lua, content_by_lua, init_by_lua, ngx.timer.*, header_filter_by_lua, body_filter_by_lua, ssl_certificate_by_lua, ssl_session_fetch_by_lua, ssl_session_store_by_lua, ssl_client_hello_by_lua*

Аналогично стандартному Lua API [coroutine.wrap](https://www.lua.org/manual/5.1/manual.html#pdf-coroutine.wrap), но работает в контексте корутин, созданных ngx_lua.

Этот API стал доступным в контексте [init_by_lua*](#init_by_lua) начиная с версии `0.9.2`.

Этот API был введен в версии `v0.6.0`.

[Назад к Оглавлению](#nginx-api-for-lua)

coroutine.running
-----------------**синтаксис:** *co = coroutine.running()*

**контекст:** *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *init_by_lua*, *ngx.timer.*, *header_filter_by_lua*, *body_filter_by_lua*, *ssl_certificate_by_lua*, *ssl_session_fetch_by_lua*, *ssl_session_store_by_lua*, *ssl_client_hello_by_lua*

Идентичен стандартному Lua [coroutine.running](https://www.lua.org/manual/5.1/manual.html#pdf-coroutine.running) API.

Этот API стал доступен в контексте [init_by_lua*](#init_by_lua) начиная с версии `0.9.2`.

Этот API был включен в версии `v0.6.0`.

[Назад к Оглавлению](#nginx-api-for-lua)

coroutine.status
----------------

**синтаксис:** *status = coroutine.status(co)*

**контекст:** *rewrite_by_lua*, *access_by_lua*, *content_by_lua*, *init_by_lua*, *ngx.timer.*, *header_filter_by_lua*, *body_filter_by_lua*, *ssl_certificate_by_lua*, *ssl_session_fetch_by_lua*, *ssl_session_store_by_lua*, *ssl_client_hello_by_lua*

Идентичен стандартному API Lua [coroutine.status](https://www.lua.org/manual/5.1/manual.html#pdf-coroutine.status).

Этот API стал доступен в контексте [init_by_lua*](#init_by_lua) начиная с версии `0.9.2`.

Этот API был включен в версию `v0.6.0`.

[Назад к Оглавлению](#nginx-api-for-lua)

ngx.run_worker_thread
----------------------

**синтаксис:** *ok, res1, res2, ... = ngx.run_worker_thread(threadpool, module_name, func_name, arg1, arg2, ...)*

**контекст:** *rewrite_by_lua*, *access_by_lua*, *content_by_lua*

**Этот API все еще экспериментальный и может измениться в будущем без уведомления.**

**Этот API доступен только для операционной системы Linux.**

Обертка для выполнения lua-функции в потоке nginx worker. Вызывающая корутина будет приостановлена до тех пор, пока функция не вернёт значение.Только следующие API ngx_lua могут быть использованы в функции `function_name` модуля `module`:

* `ngx.encode_base64`
* `ngx.decode_base64`

* `ngx.hmac_sha1`
* `ngx.encode_args`
* `ngx.decode_args`
* `ngx.quote_sql_str`

* `ngx.crc32_short`
* `ngx.crc32_long`
* `ngx.hmac_sha1`
* `ngx.md5_bin`
* `ngx.md5`

* `ngx.config.subsystem`
* `ngx.config.debug`
* `ngx.config.prefix`
* `ngx.config.nginx_version`
* `ngx.config.nginx_configure`
* `ngx.config.ngx_lua_version`

* `ngx.shared.DICT`

Первый аргумент `threadpool` указывает имя пула потоков Nginx, определённого с помощью [thread_pool](https://nginx.org/en/docs/ngx_core_module.html#thread_pool).

Второй аргумент `module_name` указывает имя lua-модуля, который будет выполнен в потоке worker и который вернёт lua-таблицу. Модуль должен находиться в пути пакета, например:

```nginx

lua_package_path '/opt/openresty/?.lua;;';

Третий аргумент func_name указывает поле функции в таблице модуля как второй аргумент.

Тип args должен быть одним из следующих типов:

  • логический
  • число
  • строка
  • nil
  • таблица (таблица может быть рекурсивной и содержать элементы вышеупомянутых типов.)

Аргумент ok имеет тип логического значения, который указывает ошибку на уровне C (невозможность получить поток из пула потоков, неудача вызова функции модуля pcall и т.д.). Если ok равен false, то res1 — это строка ошибки.

Возвращаемые значения (res1, ...) возвращаются вызовом функции модуля. Обычно res1 должен иметь тип логического значения, чтобы вызывающий код мог проверить наличие ошибки. Этот API полезен, когда вам нужно выполнить следующие типы задач:* Задача, связанная с процессором (CPU-bound task), например вычисление MD5

  • Задача ввода-вывода файлов (File I/O task)
  • Вызов os.execute() или блокирующего C API через ffi
  • Вызов внешней библиотеки Lua, которая не основана на cosocket или Nginx

Пример 1: Вычисление MD5.


location /calc_md5 {
    default_type 'text/plain';

    content_by_lua_block {
        local ok, md5_or_err = ngx.run_worker_thread("testpool", "md5", "md5")
        ngx.say(ok, " : ", md5_or_err)
    }
}

md5.lua

local function md5()
    return ngx.md5("hello")
end

return { md5=md5, }

Пример 2: Запись логов в файл логов.


location /write_log_file {
    default_type 'text/plain';

    content_by_lua_block {
        local ok, err = ngx.run_worker_thread("testpool", "write_log_file", "log", ngx.var.arg_str)
        if not ok then
            ngx.say(ok, " : ", err)
            return
        end
        ngx.say(ok)
    }
}

write_log_file.lua


local function log(str)
    local file, err = io.open("/tmp/tmp.log", "a")
    if not file then
        return false, err
    end
    file:write(str)
    file:flush()
    file:close()
    return true
end
return {log=log}

Назад к Оглавлению

Устаревшие разделы

Этот раздел содержит устаревшие документы, которые были переименованы или удалены, чтобы существующие ссылки в интернете оставались действительными.

Назад к Оглавлению

Специальные последовательности PCRE

Этот раздел был переименован в Специальные последовательности экранирования.

Назад к Оглавлению

Поддержка байткода Lua/LuaJIT -----------------------------Этот раздел был переименован в Поддержка байткода LuaJIT. С версии v0.10.16 этого модуля стандартный интерпретатор Lua (также известный как "PUC-Rio Lua") больше не поддерживается.

Комментарии ( 0 )

Вы можете оставить комментарий после Вход в систему

Введение

Описание недоступно Развернуть Свернуть
Отмена

Обновления

Пока нет обновлений

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/mirrors-lua-nginx-module.git
git@api.gitlife.ru:oschina-mirror/mirrors-lua-nginx-module.git
oschina-mirror
mirrors-lua-nginx-module
mirrors-lua-nginx-module
master