Full Code of openresty/lua-nginx-module for AI

master f4c76d810553 cached
426 files
5.4 MB
1.4M tokens
887 symbols
1 requests
Download .txt
Showing preview only (5,743K chars total). Download the full file or copy to clipboard to get everything.
Repository: openresty/lua-nginx-module
Branch: master
Commit: f4c76d810553
Files: 426
Total size: 5.4 MB

Directory structure:
gitextract_6e6awdd3/

├── .gitattributes
├── .github/
│   ├── ISSUE_TEMPLATE.md
│   ├── PULL_REQUEST_TEMPLATE.md
│   └── workflows/
│       ├── build_and_test.yml
│       └── semantic-pull-request.yml
├── .gitignore
├── .mergify.yml
├── README.markdown
├── config
├── doc/
│   └── HttpLuaModule.wiki
├── dtrace/
│   └── ngx_lua_provider.d
├── misc/
│   └── recv-until-pm/
│       ├── lib/
│       │   └── RecvUntil.pm
│       └── t/
│           └── sanity.t
├── src/
│   ├── api/
│   │   └── ngx_http_lua_api.h
│   ├── ddebug.h
│   ├── ngx_http_lua_accessby.c
│   ├── ngx_http_lua_accessby.h
│   ├── ngx_http_lua_api.c
│   ├── ngx_http_lua_args.c
│   ├── ngx_http_lua_args.h
│   ├── ngx_http_lua_balancer.c
│   ├── ngx_http_lua_balancer.h
│   ├── ngx_http_lua_bodyfilterby.c
│   ├── ngx_http_lua_bodyfilterby.h
│   ├── ngx_http_lua_cache.c
│   ├── ngx_http_lua_cache.h
│   ├── ngx_http_lua_capturefilter.c
│   ├── ngx_http_lua_capturefilter.h
│   ├── ngx_http_lua_clfactory.c
│   ├── ngx_http_lua_clfactory.h
│   ├── ngx_http_lua_common.h
│   ├── ngx_http_lua_config.c
│   ├── ngx_http_lua_config.h
│   ├── ngx_http_lua_consts.c
│   ├── ngx_http_lua_consts.h
│   ├── ngx_http_lua_contentby.c
│   ├── ngx_http_lua_contentby.h
│   ├── ngx_http_lua_control.c
│   ├── ngx_http_lua_control.h
│   ├── ngx_http_lua_coroutine.c
│   ├── ngx_http_lua_coroutine.h
│   ├── ngx_http_lua_ctx.c
│   ├── ngx_http_lua_ctx.h
│   ├── ngx_http_lua_directive.c
│   ├── ngx_http_lua_directive.h
│   ├── ngx_http_lua_exception.c
│   ├── ngx_http_lua_exception.h
│   ├── ngx_http_lua_exitworkerby.c
│   ├── ngx_http_lua_exitworkerby.h
│   ├── ngx_http_lua_headerfilterby.c
│   ├── ngx_http_lua_headerfilterby.h
│   ├── ngx_http_lua_headers.c
│   ├── ngx_http_lua_headers.h
│   ├── ngx_http_lua_headers_in.c
│   ├── ngx_http_lua_headers_in.h
│   ├── ngx_http_lua_headers_out.c
│   ├── ngx_http_lua_headers_out.h
│   ├── ngx_http_lua_initby.c
│   ├── ngx_http_lua_initby.h
│   ├── ngx_http_lua_initworkerby.c
│   ├── ngx_http_lua_initworkerby.h
│   ├── ngx_http_lua_input_filters.c
│   ├── ngx_http_lua_input_filters.h
│   ├── ngx_http_lua_lex.c
│   ├── ngx_http_lua_lex.h
│   ├── ngx_http_lua_log.c
│   ├── ngx_http_lua_log.h
│   ├── ngx_http_lua_log_ringbuf.c
│   ├── ngx_http_lua_log_ringbuf.h
│   ├── ngx_http_lua_logby.c
│   ├── ngx_http_lua_logby.h
│   ├── ngx_http_lua_misc.c
│   ├── ngx_http_lua_misc.h
│   ├── ngx_http_lua_module.c
│   ├── ngx_http_lua_ndk.c
│   ├── ngx_http_lua_ndk.h
│   ├── ngx_http_lua_output.c
│   ├── ngx_http_lua_output.h
│   ├── ngx_http_lua_pcrefix.c
│   ├── ngx_http_lua_pcrefix.h
│   ├── ngx_http_lua_phase.c
│   ├── ngx_http_lua_pipe.c
│   ├── ngx_http_lua_pipe.h
│   ├── ngx_http_lua_precontentby.c
│   ├── ngx_http_lua_precontentby.h
│   ├── ngx_http_lua_probe.h
│   ├── ngx_http_lua_proxy_ssl_certby.c
│   ├── ngx_http_lua_proxy_ssl_certby.h
│   ├── ngx_http_lua_proxy_ssl_verifyby.c
│   ├── ngx_http_lua_proxy_ssl_verifyby.h
│   ├── ngx_http_lua_regex.c
│   ├── ngx_http_lua_req_body.c
│   ├── ngx_http_lua_req_body.h
│   ├── ngx_http_lua_req_method.c
│   ├── ngx_http_lua_rewriteby.c
│   ├── ngx_http_lua_rewriteby.h
│   ├── ngx_http_lua_script.c
│   ├── ngx_http_lua_script.h
│   ├── ngx_http_lua_semaphore.c
│   ├── ngx_http_lua_semaphore.h
│   ├── ngx_http_lua_server_rewriteby.c
│   ├── ngx_http_lua_server_rewriteby.h
│   ├── ngx_http_lua_setby.c
│   ├── ngx_http_lua_setby.h
│   ├── ngx_http_lua_shdict.c
│   ├── ngx_http_lua_shdict.h
│   ├── ngx_http_lua_sleep.c
│   ├── ngx_http_lua_sleep.h
│   ├── ngx_http_lua_socket_tcp.c
│   ├── ngx_http_lua_socket_tcp.h
│   ├── ngx_http_lua_socket_udp.c
│   ├── ngx_http_lua_socket_udp.h
│   ├── ngx_http_lua_ssl.c
│   ├── ngx_http_lua_ssl.h
│   ├── ngx_http_lua_ssl_certby.c
│   ├── ngx_http_lua_ssl_certby.h
│   ├── ngx_http_lua_ssl_client_helloby.c
│   ├── ngx_http_lua_ssl_client_helloby.h
│   ├── ngx_http_lua_ssl_export_keying_material.c
│   ├── ngx_http_lua_ssl_export_keying_material.h
│   ├── ngx_http_lua_ssl_ocsp.c
│   ├── ngx_http_lua_ssl_session_fetchby.c
│   ├── ngx_http_lua_ssl_session_fetchby.h
│   ├── ngx_http_lua_ssl_session_storeby.c
│   ├── ngx_http_lua_ssl_session_storeby.h
│   ├── ngx_http_lua_string.c
│   ├── ngx_http_lua_string.h
│   ├── ngx_http_lua_subrequest.c
│   ├── ngx_http_lua_subrequest.h
│   ├── ngx_http_lua_time.c
│   ├── ngx_http_lua_timer.c
│   ├── ngx_http_lua_timer.h
│   ├── ngx_http_lua_uri.c
│   ├── ngx_http_lua_uri.h
│   ├── ngx_http_lua_uthread.c
│   ├── ngx_http_lua_uthread.h
│   ├── ngx_http_lua_util.c
│   ├── ngx_http_lua_util.h
│   ├── ngx_http_lua_variable.c
│   ├── ngx_http_lua_worker.c
│   ├── ngx_http_lua_worker_thread.c
│   └── ngx_http_lua_worker_thread.h
├── t/
│   ├── .gitignore
│   ├── 000--init.t
│   ├── 000-sanity.t
│   ├── 001-set.t
│   ├── 002-content.t
│   ├── 003-errors.t
│   ├── 004-require.t
│   ├── 005-exit.t
│   ├── 006-escape.t
│   ├── 007-md5.t
│   ├── 008-today.t
│   ├── 009-log.t
│   ├── 010-request_body.t
│   ├── 011-md5_bin.t
│   ├── 012-now.t
│   ├── 013-base64.t
│   ├── 014-bugs.t
│   ├── 015-status.t
│   ├── 016-resp-header.t
│   ├── 017-exec.t
│   ├── 018-ndk.t
│   ├── 019-const.t
│   ├── 020-subrequest.t
│   ├── 021-cookie-time.t
│   ├── 022-redirect.t
│   ├── 023-rewrite/
│   │   ├── client-abort.t
│   │   ├── exec.t
│   │   ├── exit.t
│   │   ├── mixed.t
│   │   ├── multi-capture.t
│   │   ├── on-abort.t
│   │   ├── redirect.t
│   │   ├── req-body.t
│   │   ├── req-socket.t
│   │   ├── request_body.t
│   │   ├── sanity.t
│   │   ├── sleep.t
│   │   ├── socket-keepalive.t
│   │   ├── subrequest.t
│   │   ├── tcp-socket-timeout.t
│   │   ├── tcp-socket.t
│   │   ├── unix-socket.t
│   │   ├── uthread-exec.t
│   │   ├── uthread-exit.t
│   │   ├── uthread-redirect.t
│   │   └── uthread-spawn.t
│   ├── 024-access/
│   │   ├── auth.t
│   │   ├── client-abort.t
│   │   ├── exec.t
│   │   ├── exit.t
│   │   ├── mixed.t
│   │   ├── multi-capture.t
│   │   ├── on-abort.t
│   │   ├── redirect.t
│   │   ├── req-body.t
│   │   ├── request_body.t
│   │   ├── sanity.t
│   │   ├── satisfy.t
│   │   ├── sleep.t
│   │   ├── subrequest.t
│   │   ├── uthread-exec.t
│   │   ├── uthread-exit.t
│   │   ├── uthread-redirect.t
│   │   └── uthread-spawn.t
│   ├── 025-codecache.t
│   ├── 026-mysql.t
│   ├── 027-multi-capture.t
│   ├── 028-req-header.t
│   ├── 029-http-time.t
│   ├── 030-uri-args-with-ctrl.t
│   ├── 030-uri-args.t
│   ├── 031-post-args.t
│   ├── 032-iolist.t
│   ├── 033-ctx.t
│   ├── 034-match.t
│   ├── 035-gmatch.t
│   ├── 036-sub.t
│   ├── 037-gsub.t
│   ├── 038-match-o.t
│   ├── 039-sub-o.t
│   ├── 040-gsub-o.t
│   ├── 041-header-filter.t
│   ├── 042-crc32.t
│   ├── 043-shdict.t
│   ├── 044-req-body.t
│   ├── 045-ngx-var.t
│   ├── 046-hmac.t
│   ├── 047-match-jit.t
│   ├── 048-match-dfa.t
│   ├── 049-gmatch-jit.t
│   ├── 050-gmatch-dfa.t
│   ├── 051-sub-jit.t
│   ├── 052-sub-dfa.t
│   ├── 053-gsub-jit.t
│   ├── 054-gsub-dfa.t
│   ├── 055-subreq-vars.t
│   ├── 056-flush.t
│   ├── 057-flush-timeout.t
│   ├── 058-tcp-socket.t
│   ├── 059-unix-socket.t
│   ├── 060-lua-memcached.t
│   ├── 061-lua-redis.t
│   ├── 062-count.t
│   ├── 063-abort.t
│   ├── 064-pcall.t
│   ├── 065-tcp-socket-timeout.t
│   ├── 066-socket-receiveuntil.t
│   ├── 067-req-socket.t
│   ├── 068-socket-keepalive.t
│   ├── 069-null.t
│   ├── 070-sha1.t
│   ├── 071-idle-socket.t
│   ├── 072-conditional-get.t
│   ├── 073-backtrace.t
│   ├── 074-prefix-var.t
│   ├── 075-logby.t
│   ├── 076-no-postpone.t
│   ├── 077-sleep.t
│   ├── 078-hup-vars.t
│   ├── 079-unused-directives.t
│   ├── 080-hup-shdict.t
│   ├── 081-bytecode.t
│   ├── 082-body-filter-2.t
│   ├── 082-body-filter.t
│   ├── 083-bad-sock-self.t
│   ├── 084-inclusive-receiveuntil.t
│   ├── 085-if.t
│   ├── 086-init-by.t
│   ├── 087-udp-socket.t
│   ├── 088-req-method.t
│   ├── 089-phase.t
│   ├── 090-log-socket-errors.t
│   ├── 091-coroutine.t
│   ├── 092-eof.t
│   ├── 093-uthread-spawn.t
│   ├── 094-uthread-exit.t
│   ├── 095-uthread-exec.t
│   ├── 096-uthread-redirect.t
│   ├── 097-uthread-rewrite.t
│   ├── 098-uthread-wait.t
│   ├── 099-c-api.t
│   ├── 100-client-abort.t
│   ├── 101-on-abort.t
│   ├── 102-req-start-time.t
│   ├── 103-req-http-ver.t
│   ├── 104-req-raw-header.t
│   ├── 105-pressure.t
│   ├── 106-timer.t
│   ├── 107-timer-errors.t
│   ├── 108-timer-safe.t
│   ├── 109-timer-hup.t
│   ├── 110-etag.t
│   ├── 111-req-header-ua.t
│   ├── 112-req-header-conn.t
│   ├── 113-req-header-cookie.t
│   ├── 114-config.t
│   ├── 115-quote-sql-str.t
│   ├── 116-raw-req-socket.t
│   ├── 117-raw-req-socket-timeout.t
│   ├── 118-use-default-type.t
│   ├── 119-config-prefix.t
│   ├── 120-re-find.t
│   ├── 121-version.t
│   ├── 122-worker-2.t
│   ├── 122-worker-3.t
│   ├── 122-worker.t
│   ├── 123-lua-path.t
│   ├── 124-init-worker.t
│   ├── 125-configure-args.t
│   ├── 126-shdict-frag.t
│   ├── 127-uthread-kill.t
│   ├── 128-duplex-tcp-socket.t
│   ├── 129-ssl-socket.t
│   ├── 130-internal-api.t
│   ├── 131-duplex-req-socket.t
│   ├── 132-lua-blocks.t
│   ├── 133-worker-count.t
│   ├── 134-worker-count-5.t
│   ├── 135-worker-id.t
│   ├── 136-timer-counts.t
│   ├── 137-req-misc.t
│   ├── 138-balancer-upstream-bind.t
│   ├── 138-balancer.t
│   ├── 139-ssl-cert-by.t
│   ├── 140-ssl-c-api.t
│   ├── 141-luajit.t
│   ├── 142-ssl-session-store.t
│   ├── 143-ssl-session-fetch.t
│   ├── 144-shdict-incr-init.t
│   ├── 145-shdict-list.t
│   ├── 146-malloc-trim.t
│   ├── 147-tcp-socket-timeouts.t
│   ├── 148-fake-shm-zone.t
│   ├── 149-hup-fake-shm-zone.t
│   ├── 150-fake-delayed-load.t
│   ├── 151-initby-hup.t
│   ├── 152-timer-every.t
│   ├── 153-semaphore-hup.t
│   ├── 154-semaphore.t
│   ├── 155-tls13.t
│   ├── 156-slow-network.t
│   ├── 157-socket-keepalive-hup.t
│   ├── 158-global-var.t
│   ├── 159-sa-restart.t
│   ├── 160-disable-init-by-lua.t
│   ├── 161-load-resty-core.t
│   ├── 162-exit-worker.t
│   ├── 162-socket-tls-handshake.t
│   ├── 162-static-module-location.t
│   ├── 163-exit-worker-hup.t
│   ├── 163-signal.t
│   ├── 164-say.t
│   ├── 165-thread-cache.t
│   ├── 166-ssl-client-hello.t
│   ├── 166-worker-thread.t
│   ├── 167-server-rewrite.t
│   ├── 168-tcp-socket-bind.t
│   ├── 169-proxy-ssl-verify.t
│   ├── 170-proxy-ssl-cert.t
│   ├── 170-ssl-session-reuse.t
│   ├── 185-ngx-buf-double-free.t
│   ├── 186-cosocket-busy-bufs.t
│   ├── 187-ssl-two-verification.t
│   ├── 188-balancer_keepalive_pool_max_retry.t
│   ├── 189-precontent.t
│   ├── 191-pipe-proc-quic-close-crash.t
│   ├── 302-tcp-socket-timeout-log.t
│   ├── 303-udp-socket-error-log.t
│   ├── StapThread.pm
│   ├── cert/
│   │   ├── dst-ca.crt
│   │   ├── equifax.crt
│   │   ├── gen-test-passphrase.sh
│   │   ├── gen-test-rsa1024.sh
│   │   ├── gen-test2.sh
│   │   ├── http3/
│   │   │   ├── http3.crt
│   │   │   └── http3.key
│   │   ├── mtls_ca.crt
│   │   ├── mtls_ca.key
│   │   ├── mtls_cert_gen/
│   │   │   ├── .gitignore
│   │   │   ├── generate.sh
│   │   │   ├── mtls_ca.json
│   │   │   ├── mtls_client.json
│   │   │   ├── mtls_server.json
│   │   │   └── profile.json
│   │   ├── mtls_client.crt
│   │   ├── mtls_client.key
│   │   ├── mtls_server.crt
│   │   ├── mtls_server.key
│   │   ├── test.crl
│   │   ├── test.crt
│   │   ├── test.key
│   │   ├── test2.crt
│   │   ├── test2.key
│   │   ├── test_der.crt
│   │   ├── test_der.key
│   │   ├── test_ecdsa.crt
│   │   ├── test_ecdsa.key
│   │   ├── test_passphrase.crt
│   │   └── test_passphrase.key
│   ├── data/
│   │   ├── fake-delayed-load-module/
│   │   │   ├── config
│   │   │   └── ngx_http_lua_fake_delayed_load_module.c
│   │   ├── fake-module/
│   │   │   ├── config
│   │   │   └── ngx_http_fake_module.c
│   │   └── fake-shm-module/
│   │       ├── config
│   │       └── ngx_http_lua_fake_shm_module.c
│   └── lib/
│       ├── CRC32.lua
│       ├── Memcached.lua
│       ├── Redis.lua
│       └── ljson.lua
├── tapset/
│   └── ngx_lua.stp
├── util/
│   ├── build-with-dd.sh
│   ├── build-without-ssl.sh
│   ├── build.sh
│   ├── fix-comments
│   ├── gen-lexer-c
│   ├── nc_server.py
│   ├── ngx-links
│   ├── retab
│   ├── revim
│   ├── run-ci.sh
│   ├── run_test.sh
│   ├── update-readme.sh
│   └── ver-ge
└── valgrind.suppress

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitattributes
================================================
*.t linguist-language=Text


================================================
FILE: .github/ISSUE_TEMPLATE.md
================================================
This place is for bug reports and development discussions only. For general questions and
discussions, please join the openresty-en mailing list instead: https://openresty.org/en/community.html

Ensure you have provided the following details while reporting a problem:

* The exact version of the related software, including but not limited to the OpenResty version
(if any), the NGINX core version, the `ngx_lua` module version,
and your operating system version.
* A minimal and standalone test case that others can easily run on their side and
reproduce the issue you are seeing.
* Do not simply say "something is broken" or "something does not work". Always provide
as much details as possible. Always describe the symptoms and your expected results.
* You can (temporarily) enable the nginx debugging logs to see the internal workings
of NGINX in your nginx''s `error.log` file. See http://nginx.org/en/docs/debugging_log.html
The same instructions apply equally well to OpenResty.
* If you are seeing crashes, please provide the full backtrace for the crash. See
https://www.nginx.com/resources/wiki/start/topics/tutorials/debugging/#core-dump
for more details.

Please, do not use Chinese here. This place is considered English only. If you
really want to use Chinese, please join and post to the openresty (Chinese)
mailing list instead. Please see https://openresty.org/en/community.html Thanks for
your cooperation.


================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
I hereby granted the copyright of the changes in this pull request
to the authors of this lua-nginx-module project.


================================================
FILE: .github/workflows/build_and_test.yml
================================================
name: Build and test

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:
  test:
    name: ${{ matrix.name }}
    runs-on: ubuntu-latest

    strategy:
      fail-fast: false
      matrix:
        include:
          - name: "nginx 1.29.4 + OpenSSL"
            NGINX_VERSION: "1.29.4"
            TEST_NGINX_TIMEOUT: "5"

          - name: "nginx 1.29.4 + OpenSSL + HTTP/2"
            NGINX_VERSION: "1.29.4"
            TEST_NGINX_TIMEOUT: "5"
            TEST_NGINX_USE_HTTP2: "1"

          - name: "nginx 1.29.4 + OpenSSL + HTTP/3"
            NGINX_VERSION: "1.29.4"
            TEST_NGINX_USE_HTTP3: "1"
            TEST_NGINX_QUIC_IDLE_TIMEOUT: "3"

          - name: "nginx 1.29.4 + BoringSSL + HTTP/3"
            NGINX_VERSION: "1.29.4"
            BORINGSSL: "1"
            TEST_NGINX_USE_HTTP3: "1"
            TEST_NGINX_QUIC_IDLE_TIMEOUT: "3"

    services:
      redis:
        image: redis:7-alpine
        ports:
          - 6379:6379
      mysql:
        image: mysql:8.0
        env:
          MYSQL_ALLOW_EMPTY_PASSWORD: yes
        ports:
          - 3306:3306
        options: >-
          --health-cmd="mysqladmin ping --silent"
          --health-interval=10s
          --health-timeout=5s
          --health-retries=10

    env:
      JOBS: 3
      NGX_BUILD_JOBS: 3
      CC: gcc
      DRIZZLE_VER: "2011.07.21"
      LUAJIT_PREFIX: /opt/luajit21
      LUAJIT_LIB: /opt/luajit21/lib
      LUAJIT_INC: /opt/luajit21/include/luajit-2.1
      LUA_INCLUDE_DIR: /opt/luajit21/include/luajit-2.1
      PCRE2_PREFIX: /usr/local/openresty/pcre2
      PCRE2_LIB: /usr/local/openresty/pcre2/lib
      PCRE2_INC: /usr/local/openresty/pcre2/include
      OPENSSL_PREFIX: /usr/local/openresty/openssl3
      OPENSSL_LIB: /usr/local/openresty/openssl3/lib
      OPENSSL_INC: /usr/local/openresty/openssl3/include
      LIBDRIZZLE_PREFIX: /opt/drizzle
      LIBDRIZZLE_INC: /opt/drizzle/include/libdrizzle-1.0
      LIBDRIZZLE_LIB: /opt/drizzle/lib
      TEST_NGINX_SLEEP: "0.006"
      TEST_NGINX_SKIP_COSOCKET_LOG_TEST: "1"
      MALLOC_PERTURB_: "9"

    steps:
      - uses: actions/checkout@v4

      - name: Install system packages
        run: |
          sudo apt-get update -q
          sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
            ack axel cpanminus \
            libtest-base-perl libtext-diff-perl liburi-perl libwww-perl \
            libtest-longstring-perl liblist-moreutils-perl \
            libgd-dev time cmake libunwind-dev wget \
            libbrotli1 lsb-release gnupg ca-certificates dnsutils

      - name: Install Perl test modules
        run: |
          /usr/bin/env perl $(command -v cpanm) --sudo --notest \
            Test::Nginx IPC::Run Test2::Util > build.log 2>&1 || (cat build.log && exit 1)

      - name: Add OpenResty apt repository
        run: |
          wget -qO- https://openresty.org/package/pubkey.gpg | gpg --dearmor | sudo tee /usr/share/keyrings/openresty.gpg > /dev/null
          echo "deb [signed-by=/usr/share/keyrings/openresty.gpg] https://openresty.org/package/ubuntu $(lsb_release -sc) main" \
            | sudo tee /etc/apt/sources.list.d/openresty.list
          sudo apt-get update -q
          sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
            openresty-pcre2 openresty-openssl3 openresty-pcre2-dev openresty-openssl3-dev

      - name: Cache download directory
        uses: actions/cache@v4
        with:
          path: download-cache
          key: download-cache-${{ runner.os }}-drizzle-${{ env.DRIZZLE_VER }}

      - name: Source code style check
        run: |
          ! grep -n -P '(?<=.{80}).+' --color $(find src -name '*.c') $(find . -name '*.h') \
            || (echo "ERROR: Found C source lines exceeding 80 columns." >&2; exit 1)
          ! grep -n -P '\t+' --color $(find src -name '*.c') $(find . -name '*.h') \
            || (echo "ERROR: Cannot use tabs." >&2; exit 1)

      - name: Clone dependency repositories
        run: |
          # Sibling repos — build scripts reference them via $root/../<name>
          git clone --depth=1 https://github.com/openresty/openresty.git             ../openresty
          git clone --depth=1 https://github.com/openresty/no-pool-nginx.git         ../no-pool-nginx
          git clone --depth=1 https://github.com/openresty/lua-upstream-nginx-module.git ../lua-upstream-nginx-module
          git clone --depth=1 https://github.com/openresty/echo-nginx-module.git         ../echo-nginx-module
          git clone --depth=1 https://github.com/openresty/nginx-eval-module.git         ../nginx-eval-module
          git clone --depth=1 https://github.com/simpl/ngx_devel_kit.git                 ../ndk-nginx-module
          git clone --depth=1 https://github.com/FRiCKLE/ngx_coolkit.git                 ../coolkit-nginx-module
          git clone --depth=1 https://github.com/openresty/headers-more-nginx-module.git ../headers-more-nginx-module
          git clone --depth=1 https://github.com/openresty/drizzle-nginx-module.git      ../drizzle-nginx-module
          git clone --depth=1 https://github.com/openresty/set-misc-nginx-module.git     ../set-misc-nginx-module
          git clone --depth=1 https://github.com/openresty/memc-nginx-module.git         ../memc-nginx-module
          git clone --depth=1 https://github.com/openresty/rds-json-nginx-module.git     ../rds-json-nginx-module
          git clone --depth=1 https://github.com/openresty/srcache-nginx-module.git      ../srcache-nginx-module
          git clone --depth=1 https://github.com/openresty/redis2-nginx-module.git       ../redis2-nginx-module
          git clone --depth=1 https://github.com/openresty/lua-resty-core.git            ../lua-resty-core
          git clone --depth=1 https://github.com/openresty/lua-resty-lrucache.git        ../lua-resty-lrucache
          git clone --depth=1 https://github.com/openresty/lua-resty-mysql.git           ../lua-resty-mysql
          git clone --depth=1 https://github.com/spacewander/lua-resty-rsa.git           ../lua-resty-rsa
          git clone --depth=1 https://github.com/openresty/lua-resty-string.git          ../lua-resty-string
          git clone --depth=1 https://github.com/openresty/stream-lua-nginx-module.git   ../stream-lua-nginx-module

          # Local repos — used directly from the working directory
          git clone --depth=1 https://github.com/openresty/test-nginx.git
          git clone --depth=1 https://github.com/openresty/openresty-devel-utils.git
          git clone --depth=1 https://github.com/openresty/mockeagain.git
          git clone --depth=1 https://github.com/openresty/lua-cjson.git lua-cjson
          git clone -b v2.1-agentzh --depth=1 https://github.com/openresty/luajit2.git luajit2

      - name: Download prebuilt tarballs
        run: |
          mkdir -p download-cache
          if [ ! -f download-cache/drizzle7-$DRIZZLE_VER.tar.gz ]; then
            wget -P download-cache \
              https://github.com/openresty/openresty-deps-prebuild/releases/download/v20230902/drizzle7-$DRIZZLE_VER.tar.gz
          fi
          wget https://github.com/openresty/openresty-deps-prebuild/releases/download/v20230902/boringssl-20230902-x64-focal.tar.gz
          wget https://github.com/openresty/openresty-deps-prebuild/releases/download/v20230902/curl-h3-x64-focal.tar.gz

      - name: Install curl-h3
        run: sudo tar -C / -xf curl-h3-x64-focal.tar.gz

      - name: Start memcached (native, UDP enabled)
        run: |
          sudo apt-get install -y --no-install-recommends memcached
          sudo systemctl stop memcached
          # Ubuntu's default /etc/memcached.conf has "-U 0" which disables UDP.
          # Start manually with UDP on port 11211 so udp-socket tests pass.
          memcached -d -l 127.0.0.1 -p 11211 -U 11211 -m 64
          sudo ss -lntup | grep 11211


      - name: Set up MySQL test database
        run: |
          mysql -h 127.0.0.1 -P 3306 -uroot \
            -e "CREATE DATABASE ngx_test; \
                CREATE USER 'ngx_test'@'%' IDENTIFIED WITH mysql_native_password BY 'ngx_test'; \
                GRANT ALL ON ngx_test.* TO 'ngx_test'@'%'; \
                FLUSH PRIVILEGES;"

      - name: Set up network rules
        run: |
          sudo iptables -I OUTPUT 1 -p udp --dport 10086 -j REJECT
          sudo iptables -I OUTPUT   -p tcp --dst 127.0.0.2 --dport 12345 -j DROP
          sudo iptables -I OUTPUT   -p udp --dst 127.0.0.2 --dport 12345 -j DROP
          sudo ip route add prohibit 0.0.0.1/32
          sudo sysctl -w kernel.pid_max=10000

      - name: Build LuaJIT
        run: |
          cd luajit2
          make -j$JOBS CCDEBUG=-g Q= PREFIX=$LUAJIT_PREFIX CC=$CC \
            XCFLAGS='-DLUA_USE_APICHECK -DLUA_USE_ASSERT -msse4.2' \
            > build.log 2>&1 || (cat build.log && exit 1)
          sudo make install PREFIX=$LUAJIT_PREFIX > build.log 2>&1 || (cat build.log && exit 1)

      - name: Build drizzle7
        run: |
          tar xzf download-cache/drizzle7-$DRIZZLE_VER.tar.gz
          cd drizzle7-$DRIZZLE_VER
          ./configure --prefix=$LIBDRIZZLE_PREFIX --without-server \
            > build.log 2>&1 || (cat build.log && exit 1)
          make libdrizzle-1.0 -j$JOBS > build.log 2>&1 || (cat build.log && exit 1)
          sudo make install-libdrizzle-1.0 > build.log 2>&1 || (cat build.log && exit 1)

      - name: Build mockeagain
        run: cd mockeagain && make CC=$CC -j$JOBS

      - name: Build lua-cjson
        run: cd lua-cjson && make -j$JOBS && sudo make install

      - name: Set up BoringSSL
        if: matrix.BORINGSSL == '1'
        run: |
          sudo rm -fr $OPENSSL_PREFIX
          sudo mkdir -p $OPENSSL_PREFIX
          sudo tar -C $OPENSSL_PREFIX -xf boringssl-20230902-x64-focal.tar.gz --strip-components=1

      - name: Build nginx
        run: |
          export LD_LIBRARY_PATH=$LUAJIT_LIB:$LD_LIBRARY_PATH
          export PATH=$PWD/work/nginx/sbin:$PWD/openresty-devel-utils:/opt/curl-h3/bin:$PATH
          export NGX_BUILD_CC=$CC
          sh util/build-without-ssl.sh ${{ matrix.NGINX_VERSION }} > build.log 2>&1 || (cat build.log && exit 1)
          sh util/build-with-dd.sh     ${{ matrix.NGINX_VERSION }} > build.log 2>&1 || (cat build.log && exit 1)
          rm -fr buildroot
          sh util/build.sh             ${{ matrix.NGINX_VERSION }} > build.log 2>&1 || (cat build.log && exit 1)
          nginx -V
          ldd $(which nginx) | grep -E 'luajit|ssl|pcre'

      - name: Run releng check
        run: |
          export PATH=$PWD/work/nginx/sbin:$PWD/openresty-devel-utils:/opt/curl-h3/bin:$PATH
          ngx-releng > check.txt || true
          lines=$(wc -l check.txt | awk '{print $1}')
          if [ "$lines" -gt 5 ]; then cat check.txt; exit 1; fi

      - name: Set matrix-specific test env vars
        run: |
          # Only export vars that have actual values — Perl's defined() treats
          # empty strings as defined, which would cause false positives in tests
          # like t/103-req-http-ver.t that branch on defined $ENV{TEST_NGINX_USE_HTTP3}.
          [ -n "${{ matrix.TEST_NGINX_TIMEOUT }}" ] \
            && echo "TEST_NGINX_TIMEOUT=${{ matrix.TEST_NGINX_TIMEOUT }}" >> $GITHUB_ENV || true
          [ -n "${{ matrix.TEST_NGINX_USE_HTTP2 }}" ] \
            && echo "TEST_NGINX_USE_HTTP2=${{ matrix.TEST_NGINX_USE_HTTP2 }}" >> $GITHUB_ENV || true
          [ -n "${{ matrix.TEST_NGINX_USE_HTTP3 }}" ] \
            && echo "TEST_NGINX_USE_HTTP3=${{ matrix.TEST_NGINX_USE_HTTP3 }}" >> $GITHUB_ENV || true
          [ -n "${{ matrix.TEST_NGINX_QUIC_IDLE_TIMEOUT }}" ] \
            && echo "TEST_NGINX_QUIC_IDLE_TIMEOUT=${{ matrix.TEST_NGINX_QUIC_IDLE_TIMEOUT }}" >> $GITHUB_ENV || true

      - name: Run tests
        run: |
          export LD_LIBRARY_PATH=$LUAJIT_LIB:$PWD/mockeagain:$LD_LIBRARY_PATH
          export PATH=$PWD/work/nginx/sbin:$PWD/openresty-devel-utils:/opt/curl-h3/bin:$PATH
          export LD_PRELOAD=$PWD/mockeagain/mockeagain.so
          export TEST_NGINX_HTTP3_CRT=$PWD/t/cert/http3/http3.crt
          export TEST_NGINX_HTTP3_KEY=$PWD/t/cert/http3/http3.key
          export TEST_NGINX_RESOLVER=8.8.4.4
          dig +short myip.opendns.com @resolver1.opendns.com || exit 0
          dig +short @$TEST_NGINX_RESOLVER openresty.org || exit 0
          dig +short @$TEST_NGINX_RESOLVER agentzh.org || exit 0
          python3 ./util/nc_server.py &
          /usr/bin/env perl $(command -v prove) -I. -Itest-nginx/inc -Itest-nginx/lib -r t/


================================================
FILE: .github/workflows/semantic-pull-request.yml
================================================
name: "Lint PR"

on:
  pull_request_target:
    types:
      - opened
      - edited
      - synchronize

jobs:
  main:
    name: Validate PR title
    runs-on: ubuntu-latest
    steps:
      - uses: amannn/action-semantic-pull-request@v4
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          # Configure which types are allowed.
          # Default: https://github.com/commitizen/conventional-commit-types
          types: |
            bugfix # bug fixes
            change # backward incompatible changes
            doc # documentation changes including code comments
            editor # code editor related configurations
            feature # implementing a new feature
            optimize # performance optimizations
            refactor # code refactoring and other code rearrangement
            style # coding style changes
            tests # test suite changes


================================================
FILE: .gitignore
================================================
build/
work/
tags
cscope.*
*.mobi
genmobi.sh
.libs
*.swp
*.slo
*.la
*.swo
*.lo
*~
*.o
print.txt
.rsync
*.tar.gz
dist
build[789]
build
tags
update-readme
*.tmp
test/Makefile
test/blib
test.sh
t.sh
t/t.sh
t/servroot*
test/t/servroot/
releng
reset
*.t_
src/handler.h
src/util.c
src/module.h
src/module.c
src/drizzle.c
src/processor.h
src/handler.c
src/util.h
src/drizzle.h
src/processor.c
src/output.c
src/output.h
libdrizzle
ctags
src/stream.h
nginx
keepalive
reindex
src/keepalive.c
src/keepalive.h
src/checker.h
src/checker.c
src/quoting.h
src/quoting.c
src/module.h
src/module.c
src/util.h
src/util.c
src/processor.h
src/processor.c
src/rds.h
src/utils.h
src/handler.c
src/handler.h
util/bench
*.html
trace.out*
try.sh
src/cache.c
src/cache.h
src/common.h
src/directive.c
src/directive.h
src/consts.[ch]
src/contentby.[ch]
src/pcrefix.[ch]
src/util.c
src/clfactory.c
src/directive.c
src/conf.h
src/setby.h
src/cache.h
src/hook.c
src/util.h
src/hook.h
src/common.h
src/directive.h
src/conf.c
src/setby.c
src/cache.c
src/module.c
src/clfactory.h
src/capturefilter.[ch]
src/contentby.c
pack
b.sh
src/in.[ch]
src/out.[ch]
go
all.sh
src/accessby.[ch]
src/rewriteby.[ch]
src/patch.[ch]
src/ndk.[ch]
src/control.[ch]
src/output.[ch]
src/variable.[ch]
src/string.[ch]
src/misc.[ch]
src/log.[ch]
src/exception.[ch]
src/subrequest.[ch]
src/time.[ch]
src/regex.[ch]
src/ctx.[ch]
src/args.[ch]
src/headers.[ch]
src/script.[ch]
src/filter.[ch]
src/shdict.[ch]
src/body.[ch]
src/uri.[ch]
src/api.[ch]
src/coroutine.[ch]
src/logby.[ch]
src/sleep.[ch]
a.patch
all
build1[0-9]
g
buildroot/
src/headerfilterby.[ch]
*.patch
analyze
tsock
a.c
test.lua
build12
ERRORS
src/bodyfilterby.[ch]
src/tcp.[ch]
src/initby.[ch]
src/initworkerby.[ch]
src/socket.[ch]
src/udp.[ch]
src/method.[ch]
tre
src/phase.[ch]
src/probe.h
src/uthread.[ch]
src/timer.[ch]
src/config.[ch]
src/worker.[ch]
src/certby.[ch]
src/storeby.[ch]
src/fetchby.[ch]
src/ssl.[ch]
src/ocsp.c
src/lex.[ch]
src/balancer.[ch]
src/semaphore.[ch]
*.plist
lua
ttimer
Makefile
tsubreq
tthread
addr2line
hup
theaders
src/ngx_http_lua_autoconf.h
src/autoconf.h
src/filters.c
src/filters.h
src/ringbuf.c
src/ringbuf.h
src/pipe.[ch]


================================================
FILE: .mergify.yml
================================================
---
pull_request_rules:
  - name: warn on conflicts
    conditions:
      - conflict
    actions:
      comment:
        message: This pull request is now in conflict :(
      label:
        add:
          - conflict
  - name: remove conflict label if not needed
    conditions:
      - -conflict
    actions:
      label:
        remove:
          - conflict
  - name: add label needs-test-cases
    conditions:
      - files~=^src/
      - -files~=^t/
    actions:
      label:
        add:
          - needs-test-cases
  - name: remove label needs-test-cases
    conditions:
      - label=needs-test-cases
      - files~=^src/
      - files~=^t/
    actions:
      label:
        remove:
          - needs-test-cases
  - name: add label could-be-merged
    conditions:
      - "#approved-reviews-by>=2"
      - status-success=Travis CI - Pull Request
    actions:
      label:
        add:
          - could-be-merged


================================================
FILE: README.markdown
================================================
Name
====

ngx_http_lua_module - Embed the power of Lua into Nginx HTTP Servers.

This module is a core component of [OpenResty](https://openresty.org). If you are using this module,
then you are essentially using OpenResty :)

*This module is not distributed with the Nginx source.* See
[the installation instructions](#installation).

Table of Contents
=================

* [Name](#name)
* [Status](#status)
* [Version](#version)
* [Videos](#videos)
* [Synopsis](#synopsis)
* [Description](#description)
* [Typical Uses](#typical-uses)
* [Nginx Compatibility](#nginx-compatibility)
* [Installation](#installation)
    * [Building as a dynamic module](#building-as-a-dynamic-module)
    * [C Macro Configurations](#c-macro-configurations)
* [Community](#community)
    * [English Mailing List](#english-mailing-list)
    * [Chinese Mailing List](#chinese-mailing-list)
* [Code Repository](#code-repository)
* [Bugs and Patches](#bugs-and-patches)
* [LuaJIT bytecode support](#luajit-bytecode-support)
* [System Environment Variable Support](#system-environment-variable-support)
* [HTTP 1.0 support](#http-10-support)
* [Statically Linking Pure Lua Modules](#statically-linking-pure-lua-modules)
* [Data Sharing within an Nginx Worker](#data-sharing-within-an-nginx-worker)
* [Known Issues](#known-issues)
    * [TCP socket connect operation issues](#tcp-socket-connect-operation-issues)
    * [Lua Coroutine Yielding/Resuming](#lua-coroutine-yieldingresuming)
    * [Lua Variable Scope](#lua-variable-scope)
    * [Locations Configured by Subrequest Directives of Other Modules](#locations-configured-by-subrequest-directives-of-other-modules)
    * [Cosockets Not Available Everywhere](#cosockets-not-available-everywhere)
    * [Special Escaping Sequences](#special-escaping-sequences)
    * [Mixing with SSI Not Supported](#mixing-with-ssi-not-supported)
    * [SPDY Mode Not Fully Supported](#spdy-mode-not-fully-supported)
    * [Missing data on short circuited requests](#missing-data-on-short-circuited-requests)
* [TODO](#todo)
* [Changes](#changes)
* [Build And Test](#build-and-test)
* [Test Suite](#test-suite)
* [Copyright and License](#copyright-and-license)
* [See Also](#see-also)
* [Directives](#directives)
* [Nginx API for Lua](#nginx-api-for-lua)
* [Obsolete Sections](#obsolete-sections)
    * [Special PCRE Sequences](#special-pcre-sequences)
    * [Lua/LuaJIT bytecode support](#lualuajit-bytecode-support)

Status
======

Production ready.

Version
=======

This document describes ngx_lua
[v0.10.29](https://github.com/openresty/lua-nginx-module/tags), which was released
on Oct 24, 2025.

Videos
======

* YouTube video "[Hello World HTTP Example with OpenResty/Lua](https://youtu.be/eSfYLvVQMxw)"

    [![Hello World HTTP Example with OpenResty/Lua](https://img.youtube.com/vi/eSfYLvVQMxw/0.jpg)](https://youtu.be/eSfYLvVQMxw)

* YouTube video "[Write Your Own Lua Modules in OpenResty/Nginx Applications](https://youtu.be/vfYxOMl5LVY)"

    [![Write Your Own Lua Modules in OpenResty/Nginx Applications](https://img.youtube.com/vi/vfYxOMl5LVY/0.jpg)](https://youtu.be/vfYxOMl5LVY)

* YouTube video "[OpenResty's resty Command-Line Utility Demo](https://youtu.be/L1c7aw4mSOo)"

    [![OpenResty's resty Command-Line Utility Demo](https://img.youtube.com/vi/L1c7aw4mSOo/0.jpg)](https://youtu.be/L1c7aw4mSOo)

* YouTube video "[Measure Execution Time of Lua Code Correctly in OpenResty](https://youtu.be/VkRYW_qLoME)"

    [![Measure Execution Time of Lua Code Correctly in OpenResty](https://img.youtube.com/vi/VkRYW_qLoME/0.jpg)](https://youtu.be/VkRYW_qLoME)

* YouTube video "[Precompile Lua Modules into LuaJIT Bytecode to Speedup OpenResty Startup](https://youtu.be/EP7c0BM2yNo)"

    [![Precompile Lua Modules into LuaJIT Bytecode to Speedup OpenResty Startup](https://img.youtube.com/vi/EP7c0BM2yNo/0.jpg)](https://youtu.be/EP7c0BM2yNo)

You are welcome to subscribe to our [official YouTube channel, OpenResty](https://www.youtube.com/channel/UCXVmwF-UCScv2ftsGoMqxhw).

[Back to TOC](#table-of-contents)

Synopsis
========
```nginx

 # set search paths for pure Lua external libraries (';;' is the default path):
 lua_package_path '/foo/bar/?.lua;/blah/?.lua;;';

 # set search paths for Lua external libraries written in C (can also use ';;'):
 lua_package_cpath '/bar/baz/?.so;/blah/blah/?.so;;';

 server {
     location /lua_content {
         # MIME type determined by default_type:
         default_type 'text/plain';

         content_by_lua_block {
             ngx.say('Hello,world!')
         }
     }

     location /nginx_var {
         # MIME type determined by default_type:
         default_type 'text/plain';

         # try access /nginx_var?a=hello,world
         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()  -- explicitly read the req body
             local data = ngx.req.get_body_data()
             if data then
                 ngx.say("body data:")
                 ngx.print(data)
                 return
             end

             -- body may get buffered in a temp file:
             local file = ngx.req.get_body_file()
             if file then
                 ngx.say("body is in file ", file)
             else
                 ngx.say("no body found")
             end
         }
     }

     # transparent non-blocking I/O in Lua via subrequests
     # (well, a better way is to use cosockets)
     location = /lua {
         # MIME type determined by default_type:
         default_type 'text/plain';

         content_by_lua_block {
             local res = ngx.location.capture("/some_other_location")
             if res then
                 ngx.say("status: ", res.status)
                 ngx.say("body:")
                 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;
     }

     # use nginx var in code path
     # CAUTION: contents in nginx var must be carefully filtered,
     # otherwise there'll be great security risk!
     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 {
            -- check the client IP address is in our black list
            if ngx.var.remote_addr == "132.5.72.3" then
                ngx.exit(ngx.HTTP_FORBIDDEN)
            end

            -- check if the URI contains bad words
            if ngx.var.uri and
                   string.match(ngx.var.request_body, "evil")
            then
                return ngx.redirect("/terms_of_use.html")
            end

            -- tests passed
        }

        # proxy_pass/fastcgi_pass/etc settings
     }
 }
```

[Back to TOC](#table-of-contents)

Description
===========

This module embeds [LuaJIT 2.0/2.1](https://luajit.org/luajit.html) into Nginx.
It is a core component of [OpenResty](https://openresty.org). If you are using
this module, then you are essentially using OpenResty.

Since version `v0.10.16` of this module, the standard Lua
interpreter (also known as "PUC-Rio Lua") is not supported anymore. This
document interchangeably uses the terms "Lua" and "LuaJIT" to refer to the
LuaJIT interpreter.

By leveraging Nginx's subrequests, this module allows the integration of the
powerful Lua threads (known as Lua "coroutines") into the Nginx event model.

Unlike [Apache's mod_lua](https://httpd.apache.org/docs/trunk/mod/mod_lua.html)
and [Lighttpd's mod_magnet](http://redmine.lighttpd.net/wiki/1/Docs:ModMagnet),
Lua code executed using this module can be *100% non-blocking* on network
traffic as long as the [Nginx API for Lua](#nginx-api-for-lua) provided by
this module is used to handle requests to upstream services such as MySQL,
PostgreSQL, Memcached, Redis, or upstream HTTP web services.

At least the following Lua libraries and Nginx modules can be used with this
module:

* [lua-resty-memcached](https://github.com/openresty/lua-resty-memcached)
* [lua-resty-mysql](https://github.com/openresty/lua-resty-mysql)
* [lua-resty-redis](https://github.com/openresty/lua-resty-redis)
* [lua-resty-dns](https://github.com/openresty/lua-resty-dns)
* [lua-resty-upload](https://github.com/openresty/lua-resty-upload)
* [lua-resty-websocket](https://github.com/openresty/lua-resty-websocket)
* [lua-resty-lock](https://github.com/openresty/lua-resty-lock)
* [lua-resty-logger-socket](https://github.com/cloudflare/lua-resty-logger-socket)
* [lua-resty-lrucache](https://github.com/openresty/lua-resty-lrucache)
* [lua-resty-string](https://github.com/openresty/lua-resty-string)
* [ngx_memc](http://github.com/openresty/memc-nginx-module)
* [ngx_postgres](https://github.com/FRiCKLE/ngx_postgres)
* [ngx_redis2](http://github.com/openresty/redis2-nginx-module)
* [ngx_redis](http://wiki.nginx.org/HttpRedisModule)
* [ngx_proxy](http://nginx.org/en/docs/http/ngx_http_proxy_module.html)
* [ngx_fastcgi](http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html)

Almost any Nginx modules can be used with this ngx_lua module by means of
[ngx.location.capture](#ngxlocationcapture) or
[ngx.location.capture_multi](#ngxlocationcapture_multi) but it is
recommended to use those `lua-resty-*` libraries instead of creating
subrequests to access the Nginx upstream modules because the former is usually
much more flexible and memory-efficient.

The Lua interpreter (also known as "Lua State" or "LuaJIT VM instance") is
shared across all the requests in a single Nginx worker process to minimize
memory use. Request contexts are segregated using lightweight Lua coroutines.

Loaded Lua modules persist in the Nginx worker process level resulting in a
small memory footprint in Lua even when under heavy loads.

This module is plugged into Nginx's "http" subsystem so it can only speak
downstream communication protocols in the HTTP family (HTTP 0.9/1.0/1.1/2.0,
WebSockets, etc...).  If you want to do generic TCP communications with the
downstream clients, then you should use the
[ngx_stream_lua](https://github.com/openresty/stream-lua-nginx-module#readme)
module instead, which offers a compatible Lua API.

[Back to TOC](#table-of-contents)

Typical Uses
============

Just to name a few:

* Mashup'ing and processing outputs of various Nginx upstream outputs (proxy, drizzle, postgres, redis, memcached, etc.) in Lua,
* doing arbitrarily complex access control and security checks in Lua before requests actually reach the upstream backends,
* manipulating response headers in an arbitrary way (by Lua)
* fetching backend information from external storage backends (like redis, memcached, mysql, postgresql) and use that information to choose which upstream backend to access on-the-fly,
* coding up arbitrarily complex web applications in a content handler using synchronous but still non-blocking access to the database backends and other storage,
* doing very complex URL dispatch in Lua at rewrite phase,
* using Lua to implement advanced caching mechanism for Nginx's subrequests and arbitrary locations.

The possibilities are unlimited as the module allows bringing together various
elements within Nginx as well as exposing the power of the Lua language to the
user. The module provides the full flexibility of scripting while offering
performance levels comparable with native C language programs both in terms of
CPU time as well as memory footprint thanks to LuaJIT 2.x.

Other scripting language implementations typically struggle to match this
performance level.

[Back to TOC](#table-of-contents)

Nginx Compatibility
===================

The latest version of this module is compatible with the following versions of Nginx:

* 1.29.x  (last tested: 1.29.2)
* 1.27.x  (last tested: 1.27.1)
* 1.25.x  (last tested: 1.25.1)
* 1.21.x  (last tested: 1.21.4)
* 1.19.x  (last tested: 1.19.3)
* 1.17.x  (last tested: 1.17.8)
* 1.15.x  (last tested: 1.15.8)
* 1.14.x
* 1.13.x  (last tested: 1.13.6)
* 1.12.x
* 1.11.x  (last tested: 1.11.2)
* 1.10.x
* 1.9.x (last tested: 1.9.15)
* 1.8.x
* 1.7.x (last tested: 1.7.10)
* 1.6.x

Nginx cores older than 1.6.0 (exclusive) are *not* supported.

[Back to TOC](#table-of-contents)

Installation
============

It is *highly* recommended to use [OpenResty releases](https://openresty.org)
which bundle Nginx, ngx_lua (this module), LuaJIT, as well as other powerful
companion Nginx modules and Lua libraries.

It is discouraged to build this module with Nginx yourself since it is tricky
to set up exactly right.

Note that Nginx, LuaJIT, and OpenSSL official releases have various limitations
and long-standing bugs that can cause some of this module's features to be
disabled, not work properly, or run slower. Official OpenResty releases are
recommended because they bundle [OpenResty's optimized LuaJIT 2.1 fork](https://github.com/openresty/luajit2) and
[Nginx/OpenSSL
patches](https://github.com/openresty/openresty/tree/master/patches).

Alternatively, ngx_lua can be manually compiled into Nginx:

1. LuaJIT can be downloaded from the [latest release of OpenResty's LuaJIT fork](https://github.com/openresty/luajit2/releases). The official LuaJIT 2.x releases are also supported, although performance will be significantly lower for reasons elaborated above
1. Download the latest version of the ngx_devel_kit (NDK) module [HERE](https://github.com/simplresty/ngx_devel_kit/tags)
1. Download the latest version of ngx_lua [HERE](https://github.com/openresty/lua-nginx-module/tags)
1. Download the latest supported version of Nginx [HERE](https://nginx.org/) (See [Nginx Compatibility](#nginx-compatibility))
1. Download the latest version of the lua-resty-core [HERE](https://github.com/openresty/lua-resty-core)
1. Download the latest version of the lua-resty-lrucache [HERE](https://github.com/openresty/lua-resty-lrucache)

Build the source with this module:

```bash

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

 # tell nginx's build system where to find LuaJIT 2.0:
 export LUAJIT_LIB=/path/to/luajit/lib
 export LUAJIT_INC=/path/to/luajit/include/luajit-2.0

 # tell nginx's build system where to find LuaJIT 2.1:
 export LUAJIT_LIB=/path/to/luajit/lib
 export LUAJIT_INC=/path/to/luajit/include/luajit-2.1

 # Here we assume Nginx is to be installed under /opt/nginx/.
 ./configure --prefix=/opt/nginx \
         --with-ld-opt="-Wl,-rpath,/path/to/luajit/lib" \
         --add-module=/path/to/ngx_devel_kit \
         --add-module=/path/to/lua-nginx-module

 # Note that you may also want to add `./configure` options which are used in your
 # current nginx build.
 # You can get usually those options using command nginx -V

 # you can change the parallelism number 2 below to fit the number of spare CPU cores in your
 # machine.
 make -j2
 make install

 # Note that this version of lug-nginx-module not allow to set `lua_load_resty_core off;` any more.
 # So, you have to install `lua-resty-core` and `lua-resty-lrucache` manually as below.

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

 # add necessary `lua_package_path` directive to `nginx.conf`, in the http context

 lua_package_path "/opt/nginx/lib/lua/?.lua;;";
```

[Back to TOC](#table-of-contents)

Building as a dynamic module
----------------------------

Starting from NGINX 1.9.11, you can also compile this module as a dynamic module, by using the `--add-dynamic-module=PATH` option instead of `--add-module=PATH` on the
`./configure` command line above. And then you can explicitly load the module in your `nginx.conf` via the [load_module](https://nginx.org/en/docs/ngx_core_module.html#load_module)
directive, for example,

```nginx

 load_module /path/to/modules/ndk_http_module.so;  # assuming NDK is built as a dynamic module too
 load_module /path/to/modules/ngx_http_lua_module.so;
```

[Back to TOC](#table-of-contents)

C Macro Configurations
----------------------

While building this module either via OpenResty or with the Nginx core, you can define the following C macros via the C compiler options:

* `NGX_LUA_USE_ASSERT`
	When defined, will enable assertions in the ngx_lua C code base. Recommended for debugging or testing builds. It can introduce some (small) runtime overhead when enabled. This macro was first introduced in the `v0.9.10` release.
* `NGX_LUA_ABORT_AT_PANIC`
	When the LuaJIT VM panics, ngx_lua will instruct the current nginx worker process to quit gracefully by default. By specifying this C macro, ngx_lua will abort the current nginx worker process (which usually results in a core dump file) immediately. This option is useful for debugging VM panics. This option was first introduced in the `v0.9.8` release.

To enable one or more of these macros, just pass extra C compiler options to the `./configure` script of either Nginx or OpenResty. For instance,


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


[Back to TOC](#table-of-contents)

Community
=========

[Back to TOC](#table-of-contents)

English Mailing List
--------------------

The [openresty-en](https://groups.google.com/group/openresty-en) mailing list is for English speakers.

[Back to TOC](#table-of-contents)

Chinese Mailing List
--------------------

The [openresty](https://groups.google.com/group/openresty) mailing list is for Chinese speakers.

[Back to TOC](#table-of-contents)

Code Repository
===============

The code repository of this project is hosted on GitHub at
[openresty/lua-nginx-module](https://github.com/openresty/lua-nginx-module).

[Back to TOC](#table-of-contents)

Bugs and Patches
================

Please submit bug reports, wishlists, or patches by

1. creating a ticket on the [GitHub Issue Tracker](https://github.com/openresty/lua-nginx-module/issues),
1. or posting to the [OpenResty community](#community).

[Back to TOC](#table-of-contents)

LuaJIT bytecode support
=======================

Watch YouTube video "[Measure Execution Time of Lua Code Correctly in OpenResty](https://youtu.be/VkRYW_qLoME)"

[![Precompile Lua Modules into LuaJIT Bytecode to Speedup OpenResty Startup](https://img.youtube.com/vi/EP7c0BM2yNo/0.jpg)](https://youtu.be/EP7c0BM2yNo)

As from the `v0.5.0rc32` release, all `*_by_lua_file` configure directives (such as [content_by_lua_file](#content_by_lua_file)) support loading LuaJIT 2.0/2.1 raw bytecode files directly:

```bash

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

The `-bg` option can be used to include debug information in the LuaJIT bytecode file:

```bash

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

Please refer to the official LuaJIT documentation on the `-b` option for more details:

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

Note that the bytecode files generated by LuaJIT 2.1 is *not* compatible with
LuaJIT 2.0, and vice versa. The support for LuaJIT 2.1 bytecode was first added
in ngx_lua v0.9.3.

Attempts to load standard Lua 5.1 bytecode files into ngx_lua instances linked
to LuaJIT 2.0/2.1 (or vice versa) will result in an Nginx error message such as
the one below:


    [error] 13909#0: *1 failed to load Lua inlined code: bad byte-code header in /path/to/test_file.luac


Loading bytecode files via the Lua primitives like `require` and
`dofile` should always work as expected.

[Back to TOC](#table-of-contents)

System Environment Variable Support
===================================

If you want to access the system environment variable, say, `foo`, in Lua via the standard Lua API [os.getenv](https://www.lua.org/manual/5.1/manual.html#pdf-os.getenv), then you should also list this environment variable name in your `nginx.conf` file via the [env directive](https://nginx.org/en/docs/ngx_core_module.html#env). For example,

```nginx

 env foo;
```

[Back to TOC](#table-of-contents)

HTTP 1.0 support
================

The HTTP 1.0 protocol does not support chunked output and requires an explicit `Content-Length` header when the response body is not empty in order to support the HTTP 1.0 keep-alive.
So when a HTTP 1.0 request is made and the [lua_http10_buffering](#lua_http10_buffering) directive is turned `on`, ngx_lua will buffer the
output of [ngx.say](#ngxsay) and [ngx.print](#ngxprint) calls and also postpone sending response headers until all the response body output is received.
At that time ngx_lua can calculate the total length of the body and construct a proper `Content-Length` header to return to the HTTP 1.0 client.
If the `Content-Length` response header is set in the running Lua code, however, this buffering will be disabled even if the [lua_http10_buffering](#lua_http10_buffering) directive is turned `on`.

For large streaming output responses, it is important to disable the [lua_http10_buffering](#lua_http10_buffering) directive to minimise memory usage.

Note that common HTTP benchmark tools such as `ab` and `http_load` issue HTTP 1.0 requests by default.
To force `curl` to send HTTP 1.0 requests, use the `-0` option.

[Back to TOC](#table-of-contents)

Statically Linking Pure Lua Modules
===================================

With LuaJIT 2.x, it is possible to statically link the bytecode of pure Lua
modules into the Nginx executable.

You can use the `luajit` executable to compile `.lua` Lua
module files to `.o` object files containing the exported bytecode
data, and then link the `.o` files directly in your Nginx build.

Below is a trivial example to demonstrate this. Consider that we have the following `.lua` file named `foo.lua`:

```lua

 -- foo.lua
 local _M = {}

 function _M.go()
     print("Hello from foo")
 end

 return _M
```

And then we compile this `.lua` file to `foo.o` file:

```bash

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

What matters here is the name of the `.lua` file, which determines how you use this module later on the Lua land. The file name `foo.o` does not matter at all except the `.o` file extension (which tells `luajit` what output format is used). If you want to strip the Lua debug information from the resulting bytecode, you can just specify the `-b` option above instead of `-bg`.

Then when building Nginx or OpenResty, pass the `--with-ld-opt="foo.o"` option to the `./configure` script:

```bash

 ./configure --with-ld-opt="/path/to/foo.o" ...
```

Finally, you can just do the following in any Lua code run by ngx_lua:

```lua

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

And this piece of code no longer depends on the external `foo.lua` file any more because it has already been compiled into the `nginx` executable.

If you want to use dot in the Lua module name when calling `require`, as in

```lua

 local foo = require "resty.foo"
```

then you need to rename the `foo.lua` file to `resty_foo.lua` before compiling it down to a `.o` file with the `luajit` command-line utility.

It is important to use exactly the same version of LuaJIT when compiling `.lua` files to `.o` files as building nginx + ngx_lua. This is because the LuaJIT bytecode format may be incompatible between different LuaJIT versions. When the bytecode format is incompatible, you will see a Lua runtime error saying that the Lua module is not found.

When you have multiple `.lua` files to compile and link, then just specify their `.o` files at the same time in the value of the `--with-ld-opt` option. For instance,

```bash

 ./configure --with-ld-opt="/path/to/foo.o /path/to/bar.o" ...
```

If you have too many `.o` files, then it might not be feasible to name them all in a single command. In this case, you can build a static library (or archive) for your `.o` files, as in

```bash

 ar rcus libmyluafiles.a *.o
```

then you can link the `myluafiles` archive as a whole to your nginx executable:

```bash

 ./configure \
     --with-ld-opt="-L/path/to/lib -Wl,--whole-archive -lmyluafiles -Wl,--no-whole-archive"
```

where `/path/to/lib` is the path of the directory containing the `libmyluafiles.a` file. It should be noted that the linker option `--whole-archive` is required here because otherwise our archive will be skipped because no symbols in our archive are mentioned in the main parts of the nginx executable.

[Back to TOC](#table-of-contents)

Data Sharing within an Nginx Worker
===================================

To globally share data among all the requests handled by the same Nginx worker
process, encapsulate the shared data into a Lua module, use the Lua
`require` builtin to import the module, and then manipulate the
shared data in Lua. This works because required Lua modules are loaded only
once and all coroutines will share the same copy of the module (both its code
and data).

Note that the use of global Lua variables is *strongly discouraged*, as it may
lead to unexpected race conditions between concurrent requests.

Here is a small example on sharing data within an Nginx worker via a Lua module:

```lua

 -- mydata.lua
 local _M = {}

 local data = {
     dog = 3,
     cat = 4,
     pig = 5,
 }

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

 return _M
```

and then accessing it from `nginx.conf`:

```nginx

 location /lua {
     content_by_lua_block {
         local mydata = require "mydata"
         ngx.say(mydata.get_age("dog"))
     }
 }
```

The `mydata` module in this example will only be loaded and run on the first request to the location `/lua`,
and all subsequent requests to the same Nginx worker process will use the reloaded instance of the
module as well as the same copy of the data in it, until a `HUP` signal is sent to the Nginx master process to force a reload.
This data sharing technique is essential for high performance Lua applications based on this module.

Note that this data sharing is on a *per-worker* basis and not on a *per-server* basis. That is, when there are multiple Nginx worker processes under an Nginx master, data sharing cannot cross the process boundary between these workers.

It is usually recommended to share read-only data this way. You can also share changeable data among all the concurrent requests of each Nginx worker process as
long as there is *no* nonblocking I/O operations (including [ngx.sleep](#ngxsleep))
in the middle of your calculations. As long as you do not give the
control back to the Nginx event loop and ngx_lua's light thread
scheduler (even implicitly), there can never be any race conditions in
between. For this reason, always be very careful when you want to share changeable data on the
worker level. Buggy optimizations can easily lead to hard-to-debug
race conditions under load.

If server-wide data sharing is required, then use one or more of the following approaches:

1. Use the [ngx.shared.DICT](#ngxshareddict) API provided by this module.
1. Use only a single Nginx worker and a single server (this is however not recommended when there is a multi core CPU or multiple CPUs in a single machine).
1. Use data storage mechanisms such as `memcached`, `redis`, `MySQL` or `PostgreSQL`. [The OpenResty official releases](https://openresty.org) come with a set of companion Nginx modules and Lua libraries that provide interfaces with these data storage mechanisms.

[Back to TOC](#table-of-contents)

Known Issues
============

[Back to TOC](#table-of-contents)

TCP socket connect operation issues
-----------------------------------

The [tcpsock:connect](#tcpsockconnect) method may indicate `success` despite connection failures such as with `Connection Refused` errors.

However, later attempts to manipulate the cosocket object will fail and return the actual error status message generated by the failed connect operation.

This issue is due to limitations in the Nginx event model and only appears to affect Mac OS X.

[Back to TOC](#table-of-contents)

Lua Coroutine Yielding/Resuming
-------------------------------

* Because Lua's `dofile` and `require` builtins are currently implemented as C functions in LuaJIT 2.0/2.1, if the Lua file being loaded by `dofile` or `require` invokes [ngx.location.capture*](#ngxlocationcapture), [ngx.exec](#ngxexec), [ngx.exit](#ngxexit), or other API functions requiring yielding in the *top-level* scope of the Lua file, then the Lua error "attempt to yield across C-call boundary" will be raised. To avoid this, put these calls requiring yielding into your own Lua functions in the Lua file instead of the top-level scope of the file.

[Back to TOC](#table-of-contents)

Lua Variable Scope
------------------

Care must be taken when importing modules, and this form should be used:

```lua

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

instead of the old deprecated form:

```lua

 require('xxx')
```

Here is the reason: by design, the global environment has exactly the same lifetime as the Nginx request handler associated with it. Each request handler has its own set of Lua global variables and that is the idea of request isolation. The Lua module is actually loaded by the first Nginx request handler and is cached by the `require()` built-in in the `package.loaded` table for later reference, and the `module()` builtin used by some Lua modules has the side effect of setting a global variable to the loaded module table. But this global variable will be cleared at the end of the request handler,  and every subsequent request handler all has its own (clean) global environment. So one will get Lua exception for accessing the `nil` value.

The use of Lua global variables is a generally inadvisable in the ngx_lua context as:

1. the misuse of Lua globals has detrimental side effects on concurrent requests when such variables should instead be local in scope,
1. Lua global variables require Lua table look-ups in the global environment which is computationally expensive, and
1. some Lua global variable references may include typing errors which make such difficult to debug.

It is therefore *highly* recommended to always declare such within an appropriate local scope instead.

```lua

 -- Avoid
 foo = 123
 -- Recommended
 local foo = 123

 -- Avoid
 function foo() return 123 end
 -- Recommended
 local function foo() return 123 end
```

To find all instances of Lua global variables in your Lua code, run the [lua-releng tool](https://github.com/openresty/nginx-devel-utils/blob/master/lua-releng) across all `.lua` source files:

    $ lua-releng
    Checking use of Lua global variables in file lib/foo/bar.lua ...
            1       [1489]  SETGLOBAL       7 -1    ; contains
            55      [1506]  GETGLOBAL       7 -3    ; setvar
            3       [1545]  GETGLOBAL       3 -4    ; varexpand

The output says that the line 1489 of file `lib/foo/bar.lua` writes to a global variable named `contains`, the line 1506 reads from the global variable `setvar`, and line 1545 reads the global `varexpand`.

This tool will guarantee that local variables in the Lua module functions are all declared with the `local` keyword, otherwise a runtime exception will be thrown. It prevents undesirable race conditions while accessing such variables. See [Data Sharing within an Nginx Worker](#data-sharing-within-an-nginx-worker) for the reasons behind this.

[Back to TOC](#table-of-contents)

Locations Configured by Subrequest Directives of Other Modules
--------------------------------------------------------------

The [ngx.location.capture](#ngxlocationcapture) and [ngx.location.capture_multi](#ngxlocationcapture_multi) directives cannot capture locations that include the [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), or [echo_subrequest_async](http://github.com/openresty/echo-nginx-module#echo_subrequest_async) directives.

```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
```

will not work as expected.

[Back to TOC](#table-of-contents)

Cosockets Not Available Everywhere
----------------------------------

Due to internal limitations in the Nginx core, the cosocket API is disabled in the following contexts: [set_by_lua*](#set_by_lua), [log_by_lua*](#log_by_lua), [header_filter_by_lua*](#header_filter_by_lua), and [body_filter_by_lua](#body_filter_by_lua).

The cosockets are currently also disabled in the [init_by_lua*](#init_by_lua) and [init_worker_by_lua*](#init_worker_by_lua) directive contexts but we may add support for these contexts in the future because there is no limitation in the Nginx core (or the limitation might be worked around).

There exists a workaround, however, when the original context does *not* need to wait for the cosocket results. That is, creating a zero-delay timer via the [ngx.timer.at](#ngxtimerat) API and do the cosocket results in the timer handler, which runs asynchronously as to the original context creating the timer.

[Back to TOC](#table-of-contents)

Special Escaping Sequences
--------------------------

**NOTE** Following the `v0.9.17` release, this pitfall can be avoided by using the `*_by_lua_block {}` configuration directives.

PCRE sequences such as `\d`, `\s`, or `\w`, require special attention because in string literals, the backslash character, `\`, is stripped out by both the Lua language parser and by the Nginx config file parser before processing if not within a `*_by_lua_block {}` directive. So the following snippet will not work as expected:

```nginx

 # nginx.conf
 ? location /test {
 ?     content_by_lua '
 ?         local regex = "\d+"  -- THIS IS WRONG OUTSIDE OF A *_by_lua_block DIRECTIVE
 ?         local m = ngx.re.match("hello, 1234", regex)
 ?         if m then ngx.say(m[0]) else ngx.say("not matched!") end
 ?     ';
 ? }
 # evaluates to "not matched!"
```

To avoid this, *double* escape the backslash:

```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("not matched!") end
     ';
 }
 # evaluates to "1234"
```

Here, `\\\\d+` is stripped down to `\\d+` by the Nginx config file parser and this is further stripped down to `\d+` by the Lua language parser before running.

Alternatively, the regex pattern can be presented as a long-bracketed Lua string literal by encasing it in "long brackets", `[[...]]`, in which case backslashes have to only be escaped once for the Nginx config file parser.

```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("not matched!") end
     ';
 }
 # evaluates to "1234"
```

Here, `[[\\d+]]` is stripped down to `[[\d+]]` by the Nginx config file parser and this is processed correctly.

Note that a longer from of the long bracket, `[=[...]=]`, may be required if the regex pattern contains `[...]` sequences.
The `[=[...]=]` form may be used as the default form if desired.

```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("not matched!") end
     ';
 }
 # evaluates to "1234"
```

An alternative approach to escaping PCRE sequences is to ensure that Lua code is placed in external script files and executed using the various `*_by_lua_file` directives.
With this approach, the backslashes are only stripped by the Lua language parser and therefore only need to be escaped once each.

```lua

 -- test.lua
 local regex = "\\d+"
 local m = ngx.re.match("hello, 1234", regex)
 if m then ngx.say(m[0]) else ngx.say("not matched!") end
 -- evaluates to "1234"
```

Within external script files, PCRE sequences presented as long-bracketed Lua string literals do not require modification.

```lua

 -- test.lua
 local regex = [[\d+]]
 local m = ngx.re.match("hello, 1234", regex)
 if m then ngx.say(m[0]) else ngx.say("not matched!") end
 -- evaluates to "1234"
```

As noted earlier, PCRE sequences presented within `*_by_lua_block {}` directives (available following the `v0.9.17` release) do not require modification.

```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("not matched!") end
     }
 }
 # evaluates to "1234"
```

**NOTE** You are recommended to use `by_lua_file` when the Lua code is very long.

[Back to TOC](#table-of-contents)

Mixing with SSI Not Supported
-----------------------------

Mixing SSI with ngx_lua in the same Nginx request is not supported at all. Just use ngx_lua exclusively. Everything you can do with SSI can be done atop ngx_lua anyway and it can be more efficient when using ngx_lua.

[Back to TOC](#table-of-contents)

SPDY Mode Not Fully Supported
-----------------------------

Certain Lua APIs provided by ngx_lua do not work in Nginx's SPDY mode yet: [ngx.location.capture](#ngxlocationcapture), [ngx.location.capture_multi](#ngxlocationcapture_multi), and [ngx.req.socket](#ngxreqsocket).

[Back to TOC](#table-of-contents)

Missing data on short circuited requests
----------------------------------------

Nginx may terminate a request early with (at least):

* 400 (Bad Request)
* 405 (Not Allowed)
* 408 (Request Timeout)
* 413 (Request Entity Too Large)
* 414 (Request URI Too Large)
* 494 (Request Headers Too Large)
* 499 (Client Closed Request)
* 500 (Internal Server Error)
* 501 (Not Implemented)

This means that phases that normally run are skipped, such as the rewrite or
access phase. This also means that later phases that are run regardless, e.g.
[log_by_lua](#log_by_lua), will not have access to information that is normally set in those
phases.

[Back to TOC](#table-of-contents)

TODO
====

* cosocket: implement LuaSocket's unconnected UDP API.
* cosocket: add support in the context of [init_by_lua*](#init_by_lua).
* cosocket: review and merge aviramc's [patch](https://github.com/openresty/lua-nginx-module/pull/290) for adding the `bsdrecv` method.
* cosocket: add configure options for different strategies of handling the cosocket connection exceeding in the pools.
* use `ngx_hash_t` to optimize the built-in header look-up process for [ngx.req.set_header](#ngxreqset_header), and etc.
* add `ignore_resp_headers`, `ignore_resp_body`, and `ignore_resp` options to [ngx.location.capture](#ngxlocationcapture) and [ngx.location.capture_multi](#ngxlocationcapture_multi) methods, to allow micro performance tuning on the user side.
* add automatic Lua code time slicing support by yielding and resuming the Lua VM actively via Lua's debug hooks.
* add `stat` mode similar to [mod_lua](https://httpd.apache.org/docs/trunk/mod/mod_lua.html).

[Back to TOC](#table-of-contents)

Changes
=======

The changes made in every release of this module are listed in the change logs of the OpenResty bundle:

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

[Back to TOC](#table-of-contents)

Build And Test
==============

This module uses `.travis.yml` as the CI configuration.
You can always check `.travis.yml` for the latest CI configuration.

For developers, you need to run tests locally. You can use `util/run-ci.sh`
to easily set up the environment and execute the test suite.

To run the Test from the beginning:

```shell
git clone https://github.com/openresty/lua-nginx-module.git
cd lua-nginx-module
bash util/run-ci.sh
```

Test Suite
==========

The following dependencies are required to run the test suite:

* Nginx version >= 1.4.2

* Perl modules:
	* Test::Nginx: <https://github.com/openresty/test-nginx>

* Nginx modules:
	* [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) (this is not needed if you're using 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 (i.e., this module)
	* [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)

The order in which these modules are added during configuration is important because the position of any filter module in the
filtering chain determines the final output, for example. The correct adding order is shown above.

* 3rd-party Lua libraries:
	* [lua-cjson](https://www.kyne.au/~mark/software/lua-cjson.php)

* Applications:
	* mysql: create database 'ngx_test', grant all privileges to user 'ngx_test', password is 'ngx_test'
	* memcached: listening on the default port, 11211.
	* redis: listening on the default port, 6379.

See also the [developer build script](https://github.com/openresty/lua-nginx-module/blob/master/util/build.sh) for more details on setting up the testing environment.

To run the whole test suite in the default testing mode:

    cd /path/to/lua-nginx-module
    export PATH=/path/to/your/nginx/sbin:$PATH
    prove -I/path/to/test-nginx/lib -r t

To run specific test files:

    cd /path/to/lua-nginx-module
    export PATH=/path/to/your/nginx/sbin:$PATH
    prove -I/path/to/test-nginx/lib t/002-content.t t/003-errors.t


To run a specific test block in a particular test file, add the line `--- ONLY` to the test block you want to run, and then use the `prove` utility to run that `.t` file.

There are also various testing modes based on mockeagain, valgrind, and etc. Refer to the [Test::Nginx documentation](https://search.cpan.org/perldoc?Test::Nginx) for more details for various advanced testing modes. See also the test reports for the Nginx test cluster running on Amazon EC2: <https://qa.openresty.org>.

[Back to TOC](#table-of-contents)

Copyright and License
=====================

This module is licensed under the BSD license.

Copyright (C) 2009-2017, by Xiaozhe Wang (chaoslawful) <chaoslawful@gmail.com>.

Copyright (C) 2009-2025, by Yichun "agentzh" Zhang (章亦春) <agentzh@gmail.com>, OpenResty Inc.

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

[Back to TOC](#table-of-contents)

See Also
========

Blog posts:

* [Introduction to Lua-Land CPU Flame Graphs](https://blog.openresty.com/en/lua-cpu-flame-graph/?src=gh_ngxlua)
* [How OpenResty and Nginx Allocate and Manage Memory](https://blog.openresty.com/en//how-or-alloc-mem?src=gh_ngxlua)
* [How OpenResty and Nginx Shared Memory Zones Consume RAM](https://blog.openresty.com/en/how-nginx-shm-consume-ram/?src=gh_ngxlua)
* [Memory Fragmentation in OpenResty and Nginx's Shared Memory Zones](https://blog.openresty.com/en/nginx-shm-frag/?src=gh_ngxlua)

Other related modules and libraries:

* [ngx_stream_lua_module](https://github.com/openresty/stream-lua-nginx-module#readme) for an official port of this module for the Nginx "stream" subsystem (doing generic downstream TCP communications).
* [lua-resty-memcached](https://github.com/openresty/lua-resty-memcached) library based on ngx_lua cosocket.
* [lua-resty-redis](https://github.com/openresty/lua-resty-redis) library based on ngx_lua cosocket.
* [lua-resty-mysql](https://github.com/openresty/lua-resty-mysql) library based on ngx_lua cosocket.
* [lua-resty-upload](https://github.com/openresty/lua-resty-upload) library based on ngx_lua cosocket.
* [lua-resty-dns](https://github.com/openresty/lua-resty-dns) library based on ngx_lua cosocket.
* [lua-resty-websocket](https://github.com/openresty/lua-resty-websocket) library for both WebSocket server and client, based on ngx_lua cosocket.
* [lua-resty-string](https://github.com/openresty/lua-resty-string) library based on [LuaJIT FFI](https://luajit.org/ext_ffi.html).
* [lua-resty-lock](https://github.com/openresty/lua-resty-lock) library for a nonblocking simple lock API.
* [lua-resty-cookie](https://github.com/cloudflare/lua-resty-cookie) library for HTTP cookie manipulation.
* [Routing requests to different MySQL queries based on URI arguments](https://openresty.org/#RoutingMySQLQueriesBasedOnURIArgs)
* [Dynamic Routing Based on Redis and Lua](https://openresty.org/#DynamicRoutingBasedOnRedis)
* [Using LuaRocks with ngx_lua](https://openresty.org/#UsingLuaRocks)
* [Introduction to 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/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)

[Back to TOC](#table-of-contents)

Directives
==========

* [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)
* [precontent_by_lua_block](#precontent_by_lua_block)
* [precontent_by_lua_file](#precontent_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)
* [proxy_ssl_certificate_by_lua_block](#proxy_ssl_certificate_by_lua_block)
* [proxy_ssl_certificate_by_lua_file](#proxy_ssl_certificate_by_lua_file)
* [proxy_ssl_verify_by_lua_block](#proxy_ssl_verify_by_lua_block)
* [proxy_ssl_verify_by_lua_file](#proxy_ssl_verify_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_key_log](#lua_ssl_key_log)
* [lua_ssl_conf_command](#lua_ssl_conf_command)
* [lua_upstream_skip_openssl_default_verify](#lua_upstream_skip_openssl_default_verify)
* [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)
* [precontent_by_lua_no_postpone](#precontent_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)


The basic building blocks of scripting Nginx with Lua are directives. Directives are used to specify when the user Lua code is run and
how the result will be used. Below is a diagram showing the order in which directives are executed.

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

[Back to TOC](#table-of-contents)

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

**syntax:** *lua_load_resty_core on|off*

**default:** *lua_load_resty_core on*

**context:** *http*

This directive is deprecated since the `v0.10.16` release of this
module. The `resty.core` module from
[lua-resty-core](https://github.com/openresty/lua-resty-core) is now mandatorily
loaded during the Lua VM initialization. Specifying this directive will have no
effect.

This directive was first introduced in the `v0.10.15` release and
used to optionally load the `resty.core` module.

[Back to TOC](#directives)

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

**syntax:** *lua_capture_error_log size*

**default:** *none*

**context:** *http*

Enables a buffer of the specified `size` for capturing all the Nginx error log message data (not just those produced
by this module or the Nginx http subsystem, but everything) without touching files or disks.

You can use units like `k` and `m` in the `size` value, as in

```nginx

 lua_capture_error_log 100k;
```

As a rule of thumb, a 4KB buffer can usually hold about 20 typical error log messages. So do the maths!

This buffer never grows. If it is full, new error log messages will replace the oldest ones in the buffer.

The size of the buffer must be bigger than the maximum length of a single error log message (which is 4K in OpenResty and 2K in stock NGINX).

You can read the messages in the buffer on the Lua land via the
[get_logs()](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/errlog.md#get_logs)
function of the
[ngx.errlog](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/errlog.md#readme)
module of the [lua-resty-core](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/errlog.md#readme)
library. This Lua API function will return the captured error log messages and
also remove these already read from the global capturing buffer, making room
for any new error log data. For this reason, the user should not configure this
buffer to be too big if the user read the buffered error log data fast enough.

Note that the log level specified in the standard [error_log](https://nginx.org/r/error_log) directive
*does* have effect on this capturing facility. It only captures log
messages of a level no lower than the specified log level in the [error_log](https://nginx.org/r/error_log) directive.
The user can still choose to set an even higher filtering log level on the fly via the Lua API function
[errlog.set_filter_level](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/errlog.md#set_filter_level).
So it is more flexible than the static [error_log](https://nginx.org/r/error_log) directive.

It is worth noting that there is no way to capture the debugging logs
without building OpenResty or Nginx with the `./configure`
option `--with-debug`. And enabling debugging logs is
strongly discouraged in production builds due to high overhead.

This directive was first introduced in the `v0.10.9` release.

[Back to TOC](#directives)

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

**syntax:** *lua_use_default_type on | off*

**default:** *lua_use_default_type on*

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

Specifies whether to use the MIME type specified by the [default_type](https://nginx.org/en/docs/http/ngx_http_core_module.html#default_type) directive for the default value of the `Content-Type` response header. Deactivate this directive if a default `Content-Type` response header for Lua request handlers is not desired.

This directive is turned on by default.

This directive was first introduced in the `v0.9.1` release.

[Back to TOC](#directives)

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

**syntax:** *lua_malloc_trim &lt;request-count&gt;*

**default:** *lua_malloc_trim 1000*

**context:** *http*

Asks the underlying `libc` runtime library to release its cached free memory back to the operating system every
`N` requests processed by the Nginx core. By default, `N` is 1000. You can configure the request count
by using your own numbers. Smaller numbers mean more frequent releases, which may introduce higher CPU time consumption and
smaller memory footprint while larger numbers usually lead to less CPU time overhead and relatively larger memory footprint.
Just tune the number for your own use cases.

Configuring the argument to `0` essentially turns off the periodical memory trimming altogether.

```nginx

 lua_malloc_trim 0;  # turn off trimming completely
```

The current implementation uses an Nginx log phase handler to do the request counting. So the appearance of the
[log_subrequest on](https://nginx.org/en/docs/http/ngx_http_core_module.html#log_subrequest) directives in `nginx.conf`
may make the counting faster when subrequests are involved. By default, only "main requests" count.

Note that this directive does *not* affect the memory allocated by LuaJIT's own allocator based on the `mmap`
system call.

This directive was first introduced in the `v0.10.7` release.

[Back to TOC](#directives)

lua_code_cache
--------------
**syntax:** *lua_code_cache on | off*

**default:** *lua_code_cache on*

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

Enables or disables the Lua code cache for Lua code in `*_by_lua_file` directives (like [set_by_lua_file](#set_by_lua_file) and
[content_by_lua_file](#content_by_lua_file)) and Lua modules.

When turning off, every request served by ngx_lua will run in a separate Lua VM instance, starting from the `0.9.3` release. So the Lua files referenced in [set_by_lua_file](#set_by_lua_file),
[content_by_lua_file](#content_by_lua_file), [access_by_lua_file](#access_by_lua_file),
and etc will not be cached
and all Lua modules used will be loaded from scratch. With this in place, developers can adopt an edit-and-refresh approach.

Please note however, that Lua code written inlined within nginx.conf
such as those specified by [set_by_lua](#set_by_lua), [content_by_lua](#content_by_lua),
[access_by_lua](#access_by_lua), and [rewrite_by_lua](#rewrite_by_lua) will not be updated when you edit the inlined Lua code in your `nginx.conf` file because only the Nginx config file parser can correctly parse the `nginx.conf`
file and the only way is to reload the config file
by sending a `HUP` signal or just to restart Nginx.

Even when the code cache is enabled, Lua files which are loaded by `dofile` or `loadfile`
in *_by_lua_file cannot be cached (unless you cache the results yourself). Usually you can either use the [init_by_lua](#init_by_lua)
or [init_by_lua_file](#init-by_lua_file) directives to load all such files or just make these Lua files true Lua modules
and load them via `require`.

The ngx_lua module does not support the `stat` mode available with the
Apache `mod_lua` module (yet).

Disabling the Lua code cache is strongly
discouraged for production use and should only be used during
development as it has a significant negative impact on overall performance. For example, the performance of a "hello world" Lua example can drop by an order of magnitude after disabling the Lua code cache.

[Back to TOC](#directives)

lua_thread_cache_max_entries
----------------------------

**syntax:** *lua_thread_cache_max_entries &lt;num&gt;*

**default:** *lua_thread_cache_max_entries 1024*

**context:** *http*

Specifies the maximum number of entries allowed in the worker process level lua thread object cache.

This cache recycles the lua thread GC objects among all our "light threads".

A zero value of `<num>` disables the cache.

Note that this feature requires OpenResty's LuaJIT with the new C API `lua_resetthread`.

This feature was first introduced in version `v0.10.9`.

[Back to TOC](#directives)

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

**syntax:** *lua_regex_cache_max_entries &lt;num&gt;*

**default:** *lua_regex_cache_max_entries 1024*

**context:** *http*

Specifies the maximum number of entries allowed in the worker process level compiled regex cache.

The regular expressions used in [ngx.re.match](#ngxrematch), [ngx.re.gmatch](#ngxregmatch), [ngx.re.sub](#ngxresub), and [ngx.re.gsub](#ngxregsub) will be cached within this cache if the regex option `o` (i.e., compile-once flag) is specified.

The default number of entries allowed is 1024 and when this limit is reached, new regular expressions will not be cached (as if the `o` option was not specified) and there will be one, and only one, warning in the `error.log` file:


    2011/08/27 23:18:26 [warn] 31997#0: *1 lua exceeding regex cache max entries (1024), ...


If you are using the `ngx.re.*` implementation of [lua-resty-core](https://github.com/openresty/lua-resty-core) by loading the `resty.core.regex` module (or just the `resty.core` module), then an LRU cache is used for the regex cache being used here.

Do not activate the `o` option for regular expressions (and/or `replace` string arguments for [ngx.re.sub](#ngxresub) and [ngx.re.gsub](#ngxregsub)) that are generated *on the fly* and give rise to infinite variations to avoid hitting the specified limit.

[Back to TOC](#directives)

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

**syntax:** *lua_regex_match_limit &lt;num&gt;*

**default:** *lua_regex_match_limit 0*

**context:** *http*

Specifies the "match limit" used by the PCRE library when executing the [ngx.re API](#ngxrematch). To quote the PCRE manpage, "the limit ... has the effect of limiting the amount of backtracking that can take place."

When the limit is hit, the error string "pcre_exec() failed: -8" will be returned by the [ngx.re API](#ngxrematch) functions on the Lua land.

When setting the limit to 0, the default "match limit" when compiling the PCRE library is used. And this is the default value of this directive.

This directive was first introduced in the `v0.8.5` release.

[Back to TOC](#directives)

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

**syntax:** *lua_package_path &lt;lua-style-path-str&gt;*

**default:** *The content of LUA_PATH environment variable or Lua's compiled-in defaults.*

**context:** *http*

Sets the Lua module search path used by scripts specified by [set_by_lua](#set_by_lua),
[content_by_lua](#content_by_lua) and others. The path string is in standard Lua path form, and `;;`
can be used to stand for the original search paths.

As from the `v0.5.0rc29` release, the special notation `$prefix` or `${prefix}` can be used in the search path string to indicate the path of the `server prefix` usually determined by the `-p PATH` command-line option while starting the Nginx server.

[Back to TOC](#directives)

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

**syntax:** *lua_package_cpath &lt;lua-style-cpath-str&gt;*

**default:** *The content of LUA_CPATH environment variable or Lua's compiled-in defaults.*

**context:** *http*

Sets the Lua C-module search path used by scripts specified by [set_by_lua](#set_by_lua),
[content_by_lua](#content_by_lua) and others. The cpath string is in standard Lua cpath form, and `;;`
can be used to stand for the original cpath.

As from the `v0.5.0rc29` release, the special notation `$prefix` or `${prefix}` can be used in the search path string to indicate the path of the `server prefix` usually determined by the `-p PATH` command-line option while starting the Nginx server.

[Back to TOC](#directives)

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

**syntax:** *init_by_lua &lt;lua-script-str&gt;*

**context:** *http*

**phase:** *loading-config*

**NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [init_by_lua_block](#init_by_lua_block) directive instead.

Similar to the [init_by_lua_block](#init_by_lua_block) directive, but accepts the Lua source directly in an Nginx string literal (which requires
special character escaping).

For instance,

```nginx

 init_by_lua '
     print("I need no extra escaping here, for example: \r\nblah")
 '
```

This directive was first introduced in the `v0.5.5` release.

[Back to TOC](#directives)

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

**syntax:** *init_by_lua_block { lua-script }*

**context:** *http*

**phase:** *loading-config*


When Nginx receives the `HUP` signal and starts reloading the config file, the Lua VM will also be re-created and `init_by_lua_block` will run again on the new Lua VM. In case that the [lua_code_cache](#lua_code_cache) directive is turned off (default on), the `init_by_lua_block` handler will run upon every request because in this special mode a standalone Lua VM is always created for each request.

Usually you can pre-load Lua modules at server start-up by means of this hook and take advantage of modern operating systems' copy-on-write (COW) optimization. Here is an example for pre-loading Lua modules:

```nginx

 # this runs before forking out nginx worker processes:
 init_by_lua_block { require "cjson" }

 server {
     location = /api {
         content_by_lua_block {
             -- the following require() will just  return
             -- the already loaded module from package.loaded:
             ngx.say(require "cjson".encode{dog = 5, cat = 6})
         }
     }
 }
```

You can also initialize the [lua_shared_dict](#lua_shared_dict) shm storage at this phase. Here is an example for this:

```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"))
         }
     }
 }
```

But note that, the [lua_shared_dict](#lua_shared_dict)'s shm storage will not be cleared through a config reload (via the `HUP` signal, for example). So if you do *not* want to re-initialize the shm storage in your `init_by_lua_block` code in this case, then you just need to set a custom flag in the shm storage and always check the flag in your `init_by_lua_block` code.

Because the Lua code in this context runs before Nginx forks its worker processes (if any), data or code loaded here will enjoy the [Copy-on-write (COW)](https://en.wikipedia.org/wiki/Copy-on-write) feature provided by many operating systems among all the worker processes, thus saving a lot of memory.

Do *not* initialize your own Lua global variables in this context because use of Lua global variables have performance penalties and can lead to global namespace pollution (see the [Lua Variable Scope](#lua-variable-scope) section for more details). The recommended way is to use proper [Lua module](https://www.lua.org/manual/5.1/manual.html#5.3) files (but do not use the standard Lua function [module()](https://www.lua.org/manual/5.1/manual.html#pdf-module) to define Lua modules because it pollutes the global namespace as well) and call [require()](https://www.lua.org/manual/5.1/manual.html#pdf-require) to load your own module files in `init_by_lua_block` or other contexts ([require()](https://www.lua.org/manual/5.1/manual.html#pdf-require) does cache the loaded Lua modules in the global `package.loaded` table in the Lua registry so your modules will only loaded once for the whole Lua VM instance).

Only a small set of the [Nginx API for Lua](#nginx-api-for-lua) is supported in this context:

* Logging APIs: [ngx.log](#ngxlog) and [print](#print),
* Shared Dictionary API: [ngx.shared.DICT](#ngxshareddict).

More Nginx APIs for Lua may be supported in this context upon future user requests.

Basically you can safely use Lua libraries that do blocking I/O in this very context because blocking the master process during server start-up is completely okay. Even the Nginx core does blocking I/O (at least on resolving upstream's host names) at the configure-loading phase.

You should be very careful about potential security vulnerabilities in your Lua code registered in this context because the Nginx master process is often run under the `root` account.

This directive was first introduced in the `v0.9.17` release.

See also the following blog posts for more details on OpenResty and Nginx's shared memory zones:

* [How OpenResty and Nginx Shared Memory Zones Consume RAM](https://blog.openresty.com/en/how-nginx-shm-consume-ram/?src=gh_ngxlua)
* [Memory Fragmentation in OpenResty and Nginx's Shared Memory Zones](https://blog.openresty.com/en/nginx-shm-frag/?src=gh_ngxlua)

[Back to TOC](#directives)

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

**syntax:** *init_by_lua_file &lt;path-to-lua-script-file&gt;*

**context:** *http*

**phase:** *loading-config*

Equivalent to [init_by_lua_block](#init_by_lua_block), except that the file specified by `<path-to-lua-script-file>` contains the Lua code or [LuaJIT bytecode](#luajit-bytecode-support) to be executed.

When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server.

This directive was first introduced in the `v0.5.5` release.

[Back to TOC](#directives)

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

**syntax:** *init_worker_by_lua &lt;lua-script-str&gt;*

**context:** *http*

**phase:** *starting-worker*

**NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [init_worker_by_lua_block](#init_worker_by_lua_block) directive instead.

Similar to the [init_worker_by_lua_block](#init_worker_by_lua_block) directive, but accepts the Lua source directly in an Nginx string literal (which requires
special character escaping).

For instance,

```nginx

 init_worker_by_lua '
     print("I need no extra escaping here, for example: \r\nblah")
 ';
```

This directive was first introduced in the `v0.9.5` release.

This hook no longer runs in the cache manager and cache loader processes since the `v0.10.12` release.

[Back to TOC](#directives)

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

**syntax:** *init_worker_by_lua_block { lua-script }*

**context:** *http*

**phase:** *starting-worker*

Runs the specified Lua code upon every Nginx worker process's startup when the master process is enabled. When the master process is disabled, this hook will just run after [init_by_lua*](#init_by_lua_block).

This hook is often used to create per-worker reoccurring timers (via the [ngx.timer.at](#ngxtimerat) Lua API), either for backend health-check or other timed routine work. Below is an example,

```nginx

 init_worker_by_lua_block {
     local delay = 3  -- in seconds
     local new_timer = ngx.timer.at
     local log = ngx.log
     local ERR = ngx.ERR
     local check

     check = function(premature)
         if not premature then
             -- do the health check or other routine work
             local ok, err = new_timer(delay, check)
             if not ok then
                 log(ERR, "failed to create timer: ", err)
                 return
             end
         end

         -- do something in timer
     end

     local hdl, err = new_timer(delay, check)
     if not hdl then
         log(ERR, "failed to create timer: ", err)
         return
     end

     -- other job in init_worker_by_lua
 }
```

This directive was first introduced in the `v0.9.17` release.

This hook no longer runs in the cache manager and cache loader processes since the `v0.10.12` release.

[Back to TOC](#directives)

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

**syntax:** *init_worker_by_lua_file &lt;lua-file-path&gt;*

**context:** *http*

**phase:** *starting-worker*

Similar to [init_worker_by_lua_block](#init_worker_by_lua_block), but accepts the file path to a Lua source file or Lua bytecode file.

This directive was first introduced in the `v0.9.5` release.

This hook no longer runs in the cache manager and cache loader processes since the `v0.10.12` release.

[Back to TOC](#directives)

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

**syntax:** *exit_worker_by_lua_block { lua-script }*

**context:** *http*

**phase:** *exiting-worker*

Runs the specified Lua code upon every Nginx worker process's exit when the master process is enabled. When the master process is disabled, this hook will run before the Nginx process exits.

This hook is often used to release resources allocated by each worker (e.g. resources allocated by [init_worker_by_lua*](#init_worker_by_lua_block)), or to prevent workers from exiting abnormally.

For example,

```nginx

 exit_worker_by_lua_block {
     print("log from exit_worker_by_lua_block")
 }
```

It's not allowed to create a timer (even a 0-delay timer) here since it runs after all timers have been processed.

This directive was first introduced in the `v0.10.18` release.

[Back to TOC](#directives)

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

**syntax:** *exit_worker_by_lua_file &lt;path-to-lua-script-file&gt;*

**context:** *http*

**phase:** *exiting-worker*

Similar to [exit_worker_by_lua_block](#exit_worker_by_lua_block), but accepts the file path to a Lua source file or Lua bytecode file.

This directive was first introduced in the `v0.10.18` release.

[Back to TOC](#directives)

set_by_lua
----------

**syntax:** *set_by_lua $res &lt;lua-script-str&gt; [$arg1 $arg2 ...]*

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

**phase:** *rewrite*

**NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [set_by_lua_block](#set_by_lua_block) directive instead.

Similar to the [set_by_lua_block](#set_by_lua_block) directive, but accepts the Lua source directly in an Nginx string literal (which requires
special character escaping), and
1. this directive support extra arguments after the Lua script.

For example,

```nginx

 set_by_lua $res ' return 32 + math.cos(32) ';
 # $res now has the value "32.834223360507" or alike.
```

As from the `v0.5.0rc29` release, Nginx variable interpolation is disabled in the `<lua-script-str>` argument of this directive and therefore, the dollar sign character (`$`) can be used directly.

This directive requires the [ngx_devel_kit](https://github.com/simplresty/ngx_devel_kit) module.

[Back to TOC](#directives)

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

**syntax:** *set_by_lua_block $res { lua-script }*

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

**phase:** *rewrite*

Executes code specified inside a pair of curly braces (`{}`), and returns string output to `$res`.
The code inside a pair of curly braces (`{}`) can make [API calls](#nginx-api-for-lua) and can retrieve input arguments from the `ngx.arg` table (index starts from `1` and increases sequentially).

This directive is designed to execute short, fast running code blocks as the Nginx event loop is blocked during code execution. Time consuming code sequences should therefore be avoided.

This directive is implemented by injecting custom commands into the standard [ngx_http_rewrite_module](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html)'s command list. Because [ngx_http_rewrite_module](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html) does not support nonblocking I/O in its commands, Lua APIs requiring yielding the current Lua "light thread" cannot work in this directive.

At least the following API functions are currently disabled within the context of `set_by_lua_block`:

* Output API functions (e.g., [ngx.say](#ngxsay) and [ngx.send_headers](#ngxsend_headers))
* Control API functions (e.g., [ngx.exit](#ngxexit))
* Subrequest API functions (e.g., [ngx.location.capture](#ngxlocationcapture) and [ngx.location.capture_multi](#ngxlocationcapture_multi))
* Cosocket API functions (e.g., [ngx.socket.tcp](#ngxsockettcp) and [ngx.req.socket](#ngxreqsocket)).
* Sleeping API function [ngx.sleep](#ngxsleep).

In addition, note that this directive can only write out a value to a single Nginx variable at
a time. However, a workaround is possible using the [ngx.var.VARIABLE](#ngxvarvariable) interface.

```nginx

 location /foo {
     set $diff ''; # we have to predefine the $diff variable here

     set_by_lua_block $sum {
         local a = 32
         local b = 56

         ngx.var.diff = a - b  -- write to $diff directly
         return a + b          -- return the $sum value normally
     }

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

This directive can be freely mixed with all directives of the [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), and [array-var-nginx-module](http://github.com/openresty/array-var-nginx-module) modules. All of these directives will run in the same order as they appear in the config file.

```nginx

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

No special escaping is required in the Lua code block.

This directive requires the [ngx_devel_kit](https://github.com/simplresty/ngx_devel_kit) module.

This directive was first introduced in the `v0.9.17` release.

[Back to TOC](#directives)

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

**syntax:** *set_by_lua_file $res &lt;path-to-lua-script-file&gt; [$arg1 $arg2 ...]*

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

**phase:** *rewrite*

Equivalent to [set_by_lua_block](#set_by_lua_block), except that the file specified by `<path-to-lua-script-file>` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed.

Nginx variable interpolation is supported in the `<path-to-lua-script-file>` argument string of this directive. But special care must be taken for injection attacks.

When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server.

When the Lua code cache is turned on (by default), the user code is loaded once at the first request and cached
and the Nginx config must be reloaded each time the Lua source file is modified.
The Lua code cache can be temporarily disabled during development by
switching [lua_code_cache](#lua_code_cache) `off` in `nginx.conf` to avoid reloading Nginx.

This directive requires the [ngx_devel_kit](https://github.com/simplresty/ngx_devel_kit) module.

[Back to TOC](#directives)

precontent_by_lua_block
--------------------

**syntax:** *precontent_by_lua_block { lua-script }*

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

**phase:** *precontent tail*

Acts as a precontent phase handler and executes Lua code string specified in `{ <lua-script }` for every request.
The Lua code may make [API calls](#nginx-api-for-lua) and is executed as a new spawned coroutine in an independent global environment (i.e. a sandbox).

Note that this handler always runs *after* the standard [ngx_http_mirror_module](https://nginx.org/en/docs/http/ngx_http_mirror_module.html) and [ngx_http_try_files_module](https://nginx.org/en/docs/http/ngx_http_core_module.html#try_files). For example:

```nginx
 location /images/ {
     try_files $uri /images/default.gif;
     precontent_by_lua_block {
        ngx.log(ngx.NOTICE, "file found")
     }
 }

 location = /images/default.gif {
     expires 30s;
     precontent_by_lua_block {
        ngx.log(ngx.NOTICE, "file not found, use default.gif instead")
     }
 }
```

That is, if a request for /images/foo.jpg comes in and the file does not exist, the request will be internally redirected to /images/default.gif before [precontent_by_lua_block](#precontent_by_lua_block), and then the [precontent_by_lua_block](#precontent_by_lua_block) in new location will run and log "file not found, use default.gif instead".

You can use [precontent_by_lua_block](#precontent_by_lua_block) to perform some preparatory functions after the access phase handler but before the proxy or other content handler. Especially some functions that cannot be performed in [balancer_by_lua_block](#balancer_by_lua_block).

you can use the [precontent_by_lua_no_postpone](#precontent_by_lua_no_postpone) directive to control when to run this handler inside the "precontent" request-processing phase
of Nginx.

[Back to TOC](#directives)

precontent_by_lua_file
-------------------

**syntax:** *precontent_by_lua_file &lt;path-to-lua-script-file&gt;*

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

**phase:** *precontent tail*

Equivalent to [precontent_by_lua_block](#precontent_by_lua_block), except that the file specified by `<path-to-lua-script-file>` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed.

Nginx variables can be used in the `<path-to-lua-script-file>` string to provide flexibility. This however carries some risks and is not ordinarily recommended.

When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server.

When the Lua code cache is turned on (by default), the user code is loaded once at the first request and cached
and the Nginx config must be reloaded each time the Lua source file is modified.
The Lua code cache can be temporarily disabled during development by switching [lua_code_cache](#lua_code_cache) `off` in `nginx.conf` to avoid repeatedly reloading Nginx.

Nginx variables are supported in the file path for dynamic dispatch just as in [content_by_lua_file](#content_by_lua_file).

But be very careful about malicious user inputs and always carefully validate or filter out the user-supplied path components.

[Back to TOC](#directives)

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

**syntax:** *content_by_lua &lt;lua-script-str&gt;*

**context:** *location, location if*

**phase:** *content*

**NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [content_by_lua_block](#content_by_lua_block) directive instead.

Similar to the [content_by_lua_block](#content_by_lua_block) directive, but accepts the Lua source directly in an Nginx string literal (which requires
special character escaping).

For instance,

```nginx

 content_by_lua '
     ngx.say("I need no extra escaping here, for example: \r\nblah")
 ';
```

[Back to TOC](#directives)

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

**syntax:** *content_by_lua_block { lua-script }*

**context:** *location, location if*

**phase:** *content*

For instance,

```nginx

 content_by_lua_block {
     ngx.say("I need no extra escaping here, for example: \r\nblah")
 }
```

Acts as a "content handler" and executes Lua code string specified in `{ lua-script }` for every request.
The Lua code may make [API calls](#nginx-api-for-lua) and is executed as a new spawned coroutine in an independent global environment (i.e. a sandbox).

Do not use this directive and other content handler directives in the same location. For example, this directive and the [proxy_pass](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass) directive should not be used in the same location.

This directive was first introduced in the `v0.9.17` release.

[Back to TOC](#directives)

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

**syntax:** *content_by_lua_file &lt;path-to-lua-script-file&gt;*

**context:** *location, location if*

**phase:** *content*

Equivalent to [content_by_lua_block](#content_by_lua_block), except that the file specified by `<path-to-lua-script-file>` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed.

If the file is not found, a `404 Not Found` status code will be returned, and a `503 Service Temporarily Unavailable` status code will be returned in case of errors in reading other files.

Nginx variables can be used in the `<path-to-lua-script-file>` string to provide flexibility. This however carries some risks and is not ordinarily recommended.

When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server.

When the Lua code cache is turned on (by default), the user code is loaded once at the first request and cached
and the Nginx config must be reloaded each time the Lua source file is modified.
The Lua code cache can be temporarily disabled during development by
switching [lua_code_cache](#lua_code_cache) `off` in `nginx.conf` to avoid reloading Nginx.

Nginx variables are supported in the file path for dynamic dispatch, for example:

```nginx

 # CAUTION: contents in nginx var must be carefully filtered,
 # otherwise there'll be great security risk!
 location ~ ^/app/([-_a-zA-Z0-9/]+) {
     set $path $1;
     content_by_lua_file /path/to/lua/app/root/$path.lua;
 }
```

But be very careful about malicious user inputs and always carefully validate or filter out the user-supplied path components.

[Back to TOC](#directives)

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

**syntax:** *server_rewrite_by_lua_block { lua-script }*

**context:** *http, server*

**phase:** *server rewrite*

Acts as a server rewrite phase handler and executes Lua code string specified in `{ lua-script }` for every request.
The Lua code may make [API calls](#nginx-api-for-lua) and is executed as a new spawned coroutine in an independent global environment (i.e. a sandbox).

```nginx

 server {
     ...

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

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

Just as any other rewrite phase handlers, [server_rewrite_by_lua_block](#server_rewrite_by_lua_block) also runs in subrequests.

```nginx

 server {
     server_rewrite_by_lua_block {
         ngx.log(ngx.INFO, "is_subrequest:", 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")
         }
     }
 }
```

Note that when calling `ngx.exit(ngx.OK)` within a [server_rewrite_by_lua_block](#server_rewrite_by_lua_block) handler, the Nginx request processing control flow will still continue to the content handler. To terminate the current request from within a [server_rewrite_by_lua_block](#server_rewrite_by_lua_block) handler, call [ngx.exit](#ngxexit) with status >= 200 (`ngx.HTTP_OK`) and status < 300 (`ngx.HTTP_SPECIAL_RESPONSE`) for successful quits and `ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)` (or its friends) for failures.


```nginx

 server_rewrite_by_lua_block {
     ngx.exit(503)
 }

 location /bar {
     ...
     # never exec
 }
```


[Back to TOC](#directives)

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

**syntax:** *server_rewrite_by_lua_file &lt;path-to-lua-script-file&gt;*

**context:** *http, server*

**phase:** *server rewrite*

Equivalent to [server_rewrite_by_lua_block](#server_rewrite_by_lua_block), except that the file specified by `<path-to-lua-script-file>` contains the Lua code, or, as from the `v0.10.22` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed.

Nginx variables can be used in the `<path-to-lua-script-file>` string to provide flexibility. This however carries some risks and is not ordinarily recommended.

When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server.

When the Lua code cache is turned on (by default), the user code is loaded once at the first request and cached and the Nginx config must be reloaded each time the Lua source file is modified. The Lua code cache can be temporarily disabled during development by switching [lua_code_cache](#lua_code_cache) `off` in `nginx.conf` to avoid reloading Nginx.

[Back to TOC](#directives)

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

**syntax:** *rewrite_by_lua &lt;lua-script-str&gt;*

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

**phase:** *rewrite tail*

**NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [rewrite_by_lua_block](#rewrite_by_lua_block) directive instead.

Similar to the [rewrite_by_lua_block](#rewrite_by_lua_block) directive, but accepts the Lua source directly in an Nginx string literal (which requires
special character escaping).

For instance,

```nginx

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

[Back to TOC](#directives)

rewrite_by_lua_block
--------------------

**syntax:** *rewrite_by_lua_block { lua-script }*

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

**phase:** *rewrite tail*

Acts as a rewrite phase handler and executes Lua code string specified in `{ lua-script }` for every request.
The Lua code may make [API calls](#nginx-api-for-lua) and is executed as a new spawned coroutine in an independent global environment (i.e. a sandbox).

Note that this handler always runs *after* the standard [ngx_http_rewrite_module](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html). So the following will work as expected:

```nginx

 location /foo {
     set $a 12; # create and initialize $a
     set $b ""; # create and initialize $b
     rewrite_by_lua_block {
         ngx.var.b = tonumber(ngx.var.a) + 1
     }
     echo "res = $b";
 }
```

because `set $a 12` and `set $b ""` run *before* [rewrite_by_lua_block](#rewrite_by_lua_block).

On the other hand, the following will not work as expected:

```nginx

 ?  location /foo {
 ?      set $a 12; # create and initialize $a
 ?      set $b ''; # create and initialize $b
 ?      rewrite_by_lua_block {
 ?          ngx.var.b = tonumber(ngx.var.a) + 1
 ?      }
 ?      if ($b = '13') {
 ?         rewrite ^ /bar redirect;
 ?         break;
 ?      }
 ?
 ?      echo "res = $b";
 ?  }
```

because `if` runs *before* [rewrite_by_lua_block](#rewrite_by_lua_block) even if it is placed after [rewrite_by_lua_block](#rewrite_by_lua_block) in the config.

The right way of doing this is as follows:

```nginx

 location /foo {
     set $a 12; # create and initialize $a
     set $b ''; # create and initialize $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";
 }
```

Note that the [ngx_eval](http://www.grid.net.ru/nginx/eval.en.html) module can be approximated by using [rewrite_by_lua_block](#rewrite_by_lua_block). For example,

```nginx

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

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

     fastcgi_pass ...;
 }
```

can be implemented in ngx_lua as:

```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 ...;
 }
```

Just as any other rewrite phase handlers, [rewrite_by_lua_block](#rewrite_by_lua_block) also runs in subrequests.

Note that when calling `ngx.exit(ngx.OK)` within a [rewrite_by_lua_block](#rewrite_by_lua_block) handler, the Nginx request processing control flow will still continue to the content handler. To terminate the current request from within a [rewrite_by_lua_block](#rewrite_by_lua_block) handler, call [ngx.exit](#ngxexit) with status >= 200 (`ngx.HTTP_OK`) and status < 300 (`ngx.HTTP_SPECIAL_RESPONSE`) for successful quits and `ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)` (or its friends) for failures.

If the [ngx_http_rewrite_module](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html)'s [rewrite](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite) directive is used to change the URI and initiate location re-lookups (internal redirections), then any [rewrite_by_lua_block](#rewrite_by_lua_block) or [rewrite_by_lua_file_block](#rewrite_by_lua_file_block) code sequences within the current location will not be executed. For example,

```nginx

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

Here the Lua code `ngx.exit(503)` will never run. This will be the case if `rewrite ^ /bar last` is used as this will similarly initiate an internal redirection. If the `break` modifier is used instead, there will be no internal redirection and the `rewrite_by_lua_block` code will be executed.

The `rewrite_by_lua_block` code will always run at the end of the `rewrite` request-processing phase unless [rewrite_by_lua_no_postpone](#rewrite_by_lua_no_postpone) is turned on.

This directive was first introduced in the `v0.9.17` release.

[Back to TOC](#directives)

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

**syntax:** *rewrite_by_lua_file &lt;path-to-lua-script-file&gt;*

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

**phase:** *rewrite tail*

Equivalent to [rewrite_by_lua_block](#rewrite_by_lua_block), except that the file specified by `<path-to-lua-script-file>` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed.

Nginx variables can be used in the `<path-to-lua-script-file>` string to provide flexibility. This however carries some risks and is not ordinarily recommended.

When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server.

When the Lua code cache is turned on (by default), the user code is loaded once at the first request and cached and the Nginx config must be reloaded each time the Lua source file is modified. The Lua code cache can be temporarily disabled during development by switching [lua_code_cache](#lua_code_cache) `off` in `nginx.conf` to avoid reloading Nginx.

The `rewrite_by_lua_file` code will always run at the end of the `rewrite` request-processing phase unless [rewrite_by_lua_no_postpone](#rewrite_by_lua_no_postpone) is turned on.

Nginx variables are supported in the file path for dynamic dispatch just as in [content_by_lua_file](#content_by_lua_file).

[Back to TOC](#directives)

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

**syntax:** *access_by_lua &lt;lua-script-str&gt;*

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

**phase:** *access tail*

**NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [access_by_lua_block](#access_by_lua_block) directive instead.

Similar to the [access_by_lua_block](#access_by_lua_block) directive, but accepts the Lua source directly in an Nginx string literal (which requires
special character escaping).

For instance,

```nginx

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

[Back to TOC](#directives)

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

**syntax:** *access_by_lua_block { lua-script }*

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

**phase:** *access tail*

Acts as an access phase handler and executes Lua code string specified in `{ <lua-script }` for every request.
The Lua code may make [API calls](#nginx-api-for-lua) and is executed as a new spawned coroutine in an independent global environment (i.e. a sandbox).

Note that this handler always runs *after* the standard [ngx_http_access_module](http://nginx.org/en/docs/http/ngx_http_access_module.html). So the following will work as expected:

```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/...
 }
```

That is, if a client IP address is in the blacklist, it will be denied before the MySQL query for more complex authentication is executed by [access_by_lua_block](#access_by_lua_block).

Note that the [ngx_auth_request](http://mdounin.ru/hg/ngx_http_auth_request_module/) module can be approximated by using [access_by_lua_block](#access_by_lua_block):

```nginx

 location / {
     auth_request /auth;

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

can be implemented in ngx_lua as:

```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/...
 }
```

As with other access phase handlers, [access_by_lua_block](#access_by_lua_block) will *not* run in subrequests.

Note that when calling `ngx.exit(ngx.OK)` within a [access_by_lua_block](#access_by_lua_block) handler, the Nginx request processing control flow will still continue to the content handler. To terminate the current request from within a [access_by_lua_block](#access_by_lua_block) handler, call [ngx.exit](#ngxexit) with status >= 200 (`ngx.HTTP_OK`) and status < 300 (`ngx.HTTP_SPECIAL_RESPONSE`) for successful quits and `ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)` (or its friends) for failures.

Starting from the `v0.9.20` release, you can use the [access_by_lua_no_postpone](#access_by_lua_no_postpone)
directive to control when to run this handler inside the "access" request-processing phase
of Nginx.

This directive was first introduced in the `v0.9.17` release.

[Back to TOC](#directives)

access_by_lua_file
------------------

**syntax:** *access_by_lua_file &lt;path-to-lua-script-file&gt;*

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

**phase:** *access tail*

Equivalent to [access_by_lua_block](#access_by_lua_block), except that the file specified by `<path-to-lua-script-file>` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed.

Nginx variables can be used in the `<path-to-lua-script-file>` string to provide flexibility. This however carries some risks and is not ordinarily recommended.

When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server.

When the Lua code cache is turned on (by default), the user code is loaded once at the first request and cached
and the Nginx config must be reloaded each time the Lua source file is modified.
The Lua code cache can be temporarily disabled during development by switching [lua_code_cache](#lua_code_cache) `off` in `nginx.conf` to avoid repeatedly reloading Nginx.

Nginx variables are supported in the file path for dynamic dispatch just as in [content_by_lua_file](#content_by_lua_file).

[Back to TOC](#directives)

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

**syntax:** *header_filter_by_lua &lt;lua-script-str&gt;*

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

**phase:** *output-header-filter*

**NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [header_filter_by_lua_block](#header_filter_by_lua_block) directive instead.

Similar to the [header_filter_by_lua_block](#header_filter_by_lua_block) directive, but accepts the Lua source directly in an Nginx string literal (which requires
special character escaping).

For instance,

```nginx

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

This directive was first introduced in the `v0.2.1rc20` release.

[Back to TOC](#directives)

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

**syntax:** *header_filter_by_lua_block { lua-script }*

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

**phase:** *output-header-filter*

Uses Lua code specified in `{ lua-script }` to define an output header filter.

Note that the following API functions are currently disabled within this context:

* Output API functions (e.g., [ngx.say](#ngxsay) and [ngx.send_headers](#ngxsend_headers))
* Control API functions (e.g., [ngx.redirect](#ngxredirect) and [ngx.exec](#ngxexec))
* Subrequest API functions (e.g., [ngx.location.capture](#ngxlocationcapture) and [ngx.location.capture_multi](#ngxlocationcapture_multi))
* Cosocket API functions (e.g., [ngx.socket.tcp](#ngxsockettcp) and [ngx.req.socket](#ngxreqsocket)).

Here is an example of overriding a response header (or adding one if absent) in our Lua header filter:

```nginx

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

This directive was first introduced in the `v0.9.17` release.

[Back to TOC](#directives)

header_filter_by_lua_file
-------------------------

**syntax:** *header_filter_by_lua_file &lt;path-to-lua-script-file&gt;*

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

**phase:** *output-header-filter*

Equivalent to [header_filter_by_lua_block](#header_filter_by_lua_block), except that the file specified by `<path-to-lua-script-file>` contains the Lua code, or as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed.

When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server.

This directive was first introduced in the `v0.2.1rc20` release.

[Back to TOC](#directives)

body_filter_by_lua
------------------

**syntax:** *body_filter_by_lua &lt;lua-script-str&gt;*

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

**phase:** *output-body-filter*

**NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [body_filter_by_lua_block](#body_filter_by_lua_block) directive instead.

Similar to the [body_filter_by_lua_block](#body_filter_by_lua_block) directive, but accepts the Lua source directly in an Nginx string literal (which requires
special character escaping).

For instance,

```nginx

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

This directive was first introduced in the `v0.5.0rc32` release.

[Back to TOC](#directives)

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

**syntax:** *body_filter_by_lua_block { lua-script-str }*

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

**phase:** *output-body-filter*

Uses Lua code specified in `{ lua-script }` to define an output body filter.

The input data chunk is passed via [ngx.arg](#ngxarg)\[1\] (as a Lua string value) and the "eof" flag indicating the end of the response body data stream is passed via [ngx.arg](#ngxarg)\[2\] (as a Lua boolean value).

Behind the scene, the "eof" flag is just the `last_buf` (for main requests) or `last_in_chain` (for subrequests) flag of the Nginx chain link buffers. (Before the `v0.7.14` release, the "eof" flag does not work at all in subrequests.)

The output data stream can be aborted immediately by running the following Lua statement:

```lua

 return ngx.ERROR
```

This will truncate the response body and usually result in incomplete and also invalid responses.

The Lua code can pass its own modified version of the input data chunk to the downstream Nginx output body filters by overriding [ngx.arg](#ngxarg)\[1\] with a Lua string or a Lua table of strings. For example, to transform all the lowercase letters in the response body, we can just write:

```nginx

 location / {
     proxy_pass http://mybackend;
     body_filter_by_lua_block {
         ngx.arg[1] = string.upper(ngx.arg[1])
     }
 }
```

When setting `nil` or an empty Lua string value to `ngx.arg[1]`, no data chunk will be passed to the downstream Nginx output filters at all.

Likewise, new "eof" flag can also be specified by setting a boolean value to [ngx.arg](#ngxarg)\[2\]. For example,

```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  -- new eof
             return
         end

         -- just throw away any remaining chunk data
         ngx.arg[1] = nil
     }
 }
```

Then `GET /t` will just return the output


    hello world


That is, when the body filter sees a chunk containing the word "hello", then it will set the "eof" flag to true immediately, resulting in truncated but still valid responses.

When the Lua code may change the length of the response body, then it is required to always clear out the `Content-Length` response header (if any) in a header filter to enforce streaming output, as in

```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"
     }
 }
```

Note that the following API functions are currently disabled within this context due to the limitations in Nginx output filter's current implementation:

* Output API functions (e.g., [ngx.say](#ngxsay) and [ngx.send_headers](#ngxsend_headers))
* Control API functions (e.g., [ngx.exit](#ngxexit) and [ngx.exec](#ngxexec))
* Subrequest API functions (e.g., [ngx.location.capture](#ngxlocationcapture) and [ngx.location.capture_multi](#ngxlocationcapture_multi))
* Cosocket API functions (e.g., [ngx.socket.tcp](#ngxsockettcp) and [ngx.req.socket](#ngxreqsocket)).

Nginx output filters may be called multiple times for a single request because response body may be delivered in chunks. Thus, the Lua code specified by in this directive may also run multiple times in the lifetime of a single HTTP request.

This directive was first introduced in the `v0.9.17` release.

[Back to TOC](#directives)

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

**syntax:** *body_filter_by_lua_file &lt;path-to-lua-script-file&gt;*

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

**phase:** *output-body-filter*

Equivalent to [body_filter_by_lua_block](#body_filter_by_lua_block), except that the file specified by `<path-to-lua-script-file>` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed.

When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server.

This directive was first introduced in the `v0.5.0rc32` release.

[Back to TOC](#directives)

log_by_lua
----------

**syntax:** *log_by_lua &lt;lua-script-str&gt;*

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

**phase:** *log*

**NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [log_by_lua_block](#log_by_lua_block) directive instead.

Similar to the [log_by_lua_block](#log_by_lua_block) directive, but accepts the Lua source directly in an Nginx string literal (which requires
special character escaping).

For instance,

```nginx

 log_by_lua '
     print("I need no extra escaping here, for example: \r\nblah")
 ';
```

This directive was first introduced in the `v0.5.0rc31` release.

[Back to TOC](#directives)

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

**syntax:** *log_by_lua_block { lua-script }*

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

**phase:** *log*

Runs the Lua source code inlined as the `{ lua-script }` at the `log` request processing phase. This does not replace the current access logs, but runs before.

Note that the following API functions are currently disabled within this context:

* Output API functions (e.g., [ngx.say](#ngxsay) and [ngx.send_headers](#ngxsend_headers))
* Control API functions (e.g., [ngx.exit](#ngxexit))
* Subrequest API functions (e.g., [ngx.location.capture](#ngxlocationcapture) and [ngx.location.capture_multi](#ngxlocationcapture_multi))
* Cosocket API functions (e.g., [ngx.socket.tcp](#ngxsockettcp) and [ngx.req.socket](#ngxreqsocket)).

Here is an example of gathering average data for [$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")

             if nb and sum then
                 ngx.say("average upstream response time: ", sum / nb,
                         " (", nb, " reqs)")
             else
                 ngx.say("no data yet")
             end
         }
     }
 }
```

This directive was first introduced in the `v0.9.17` release.

[Back to TOC](#directives)

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

**syntax:** *log_by_lua_file &lt;path-to-lua-script-file&gt;*

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

**phase:** *log*

Equivalent to [log_by_lua_block](#log_by_lua_block), except that the file specified by `<path-to-lua-script-file>` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed.

When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server.

This directive was first introduced in the `v0.5.0rc31` release.

[Back to TOC](#directives)

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

**syntax:** *balancer_by_lua_block { lua-script }*

**context:** *upstream*

**phase:** *content*

This directive runs Lua code as an upstream balancer for any upstream entities defined
by the `upstream {}` configuration block.

For instance,

```nginx

 upstream foo {
     server 127.0.0.1;
     balancer_by_lua_block {
         -- use Lua to do something interesting here
         -- as a dynamic balancer
     }
 }

 server {
     location / {
         proxy_pass http://foo;
     }
 }
```

The resulting Lua load balancer can work with any existing Nginx upstream modules
like [ngx_proxy](https://nginx.org/en/docs/http/ngx_http_proxy_module.html) and
[ngx_fastcgi](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html).

Also, the Lua load balancer can work with the standard upstream connection pool mechanism,
i.e., the standard [keepalive](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive) directive.
Just ensure that the [keepalive](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive) directive
is used *after* this `balancer_by_lua_block` directive in a single `upstream {}` configuration block.

The Lua load balancer can totally ignore the list of servers defined in the `upstream {}` block
and select peer from a completely dynamic server list (even changing per request) via the
[ngx.balancer](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/balancer.md) module
from the [lua-resty-core](https://github.com/openresty/lua-resty-core) library.

The Lua code handler registered by this directive might get called more than once in a single
downstream request when the Nginx upstream mechanism retries the request on conditions
specified by directives like the [proxy_next_upstream](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_next_upstream)
directive.

This Lua code execution context does not support yielding, so Lua APIs that may yield
(like cosockets and "light threads") are disabled in this context. One can usually work
around this limitation by doing such operations in an earlier phase handler (like
[precontent_by_lua*](#precontent_by_lua_block)) and passing along the result into this context
via the [ngx.ctx](#ngxctx) table.

This directive was first introduced in the `v0.10.0` release.

[Back to TOC](#directives)

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

**syntax:** *balancer_by_lua_file &lt;path-to-lua-script-file&gt;*

**context:** *upstream*

**phase:** *content*

Equivalent to [balancer_by_lua_block](#balancer_by_lua_block), except that the file specified by `<path-to-lua-script-file>` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed.

When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server.

This directive was first introduced in the `v0.10.0` release.

[Back to TOC](#directives)

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

**syntax:** *balancer_keepalive &lt;total-connections&gt;*

**context:** *upstream*

**phase:** *loading-config*

The `total-connections` parameter sets the maximum number of idle
keepalive connections to upstream servers that are preserved in the cache of
each worker process. When this number is exceeded, the least recently used
connections are closed.

It should be particularly noted that the keepalive directive does not limit the
total number of connections to upstream servers that an nginx worker process
can open. The connections parameter should be set to a number small enough to
let upstream servers process new incoming connections as well.

This directive was first introduced in the `v0.10.21` release.

[Back to TOC](#directives)

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

**syntax:** *lua_need_request_body &lt;on|off&gt;*

**default:** *off*

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

**phase:** *depends on usage*

Determines whether to force the request body data to be read before running rewrite/access/content_by_lua* or not. The Nginx core does not read the client request body by default and if request body data is required, then this directive should be turned `on` or the [ngx.req.read_body](#ngxreqread_body) function should be called within the Lua code.

To read the request body data within the [$request_body](http://nginx.org/en/docs/http/ngx_http_core_module.html#var_request_body) variable,
[client_body_buffer_size](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size) must have the same value as [client_max_body_size](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size). Because when the content length exceeds [client_body_buffer_size](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size) but less than [client_max_body_size](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size), Nginx will buffer the data into a temporary file on the disk, which will lead to empty value in the [$request_body](http://nginx.org/en/docs/http/ngx_http_core_module.html#var_request_body) variable.

If the current location includes [rewrite_by_lua*](#rewrite_by_lua) directives,
then the request body will be read just before the [rewrite_by_lua*](#rewrite_by_lua) code is run (and also at the
`rewrite` phase). Similarly, if only [content_by_lua](#content_by_lua) is specified,
the request body will not be read until the content handler's Lua code is
about to run (i.e., the request body will be read during the content phase).

It is recommended however, to use the [ngx.req.read_body](#ngxreqread_body) and [ngx.req.discard_body](#ngxreqdiscard_body) functions for finer control over the request body reading process instead.

This also applies to [access_by_lua*](#access_by_lua).

[Back to TOC](#directives)

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

**syntax:** *ssl_client_hello_by_lua_block { lua-script }*

**context:** *http, server*

**phase:** *right-after-client-hello-message-was-processed*

This directive runs user Lua code when Nginx is about to post-process the SSL client hello message for the downstream
SSL (https) connections.

It is particularly useful for dynamically setting the SSL protocols according to the SNI.

It is also useful to do some custom operations according to the per-connection information in the client hello message.

For example, one can parse custom client hello extension and do the corresponding handling in pure Lua.

This Lua handler will always run whether the SSL session is resumed (via SSL session IDs or TLS session tickets) or not.
While the `ssl_certificate_by_lua*` Lua handler will only runs when initiating a full SSL handshake.

The [ngx.ssl.clienthello](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/clienthello.md) Lua modules
provided by the [lua-resty-core](https://github.com/openresty/lua-resty-core/#readme)
library are particularly useful in this context.

Note that this handler runs in extremely early stage of SSL handshake, before the SSL client hello extensions are parsed.
So you can not use some Lua API like `ssl.server_name()` which is dependent on the later stage's processing.

Also note that only the directive in default server is valid for several virtual servers with the same IP address and port.

Below is a trivial example using the
[ngx.ssl.clienthello](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/clienthello.md) module
at the same time:

```nginx

 server {
     listen 443 ssl;
     server_name   test.com;
     ssl_certificate /path/to/cert.crt;
     ssl_certificate_key /path/to/key.key;
     ssl_client_hello_by_lua_block {
         local ssl_clt = require "ngx.ssl.clienthello"
         local host, err = ssl_clt.get_client_hello_server_name()
         if host == "test.com" then
             ssl_clt.set_protocols({"TLSv1", "TLSv1.1"})
         elseif host == "test2.com" then
             ssl_clt.set_protocols({"TLSv1.2", "TLSv1.3"})
         elseif not host then
             ngx.log(ngx.ERR, "failed to get the SNI name: ", err)
             ngx.exit(ngx.ERROR)
         else
             ngx.log(ngx.ERR, "unknown SNI name: ", host)
             ngx.exit(ngx.ERROR)
         end
     }
     ...
 }
 server {
     listen 443 ssl;
     server_name   test2.com;
     ssl_certificate /path/to/cert.crt;
     ssl_certificate_key /path/to/key.key;
     ...
 }
```

See more information in the [ngx.ssl.clienthello](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/clienthello.md)
Lua modules' official documentation.

Uncaught Lua exceptions in the user Lua code immediately abort the current SSL session, so does the
[ngx.exit](#ngxexit) call with an error code like `ngx.ERROR`.

This Lua code execution context *does* support yielding, so Lua APIs that may yield
(like cosockets, sleeping, and "light threads")
are enabled in this context

Note, you need to configure the [ssl_certificate](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate)
and [ssl_certificate_key](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate_key)
to avoid the following error while starting NGINX:


    nginx: [emerg] no ssl configured for the server


This directive requires OpenSSL 1.1.1 or greater.

If you are using the [official pre-built
packages](https://openresty.org/en/linux-packages.html) for
[OpenResty](https://openresty.org/) 1.21.4.1 or later, then everything should
work out of the box.

If you are not using the Nginx core shipped with
[OpenResty](https://openresty.org) 1.21.4.1 or later, you will need to apply
patches to the standard Nginx core:

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

**Note for HTTP/3 (QUIC) users**: When using this directive with HTTP/3 connections, certain yield operations may fail if the QUIC SSL Lua yield patch is not applied to your OpenSSL installation. OpenResty packages include this patch by default, but if you are building lua-nginx-module separately, you may need to apply the patch manually to ensure proper yield/resume functionality for HTTP/3 connections in SSL Lua phases. The patch can be found at: [nginx-1.27.1-quic_ssl_lua_yield.patch](https://github.com/openresty/openresty/blob/master/patches/nginx/1.27.1/nginx-1.27.1-quic_ssl_lua_yield.patch)

This directive was first introduced in the `v0.10.21` release.

[Back to TOC](#directives)

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

**syntax:** *ssl_client_hello_by_lua_file &lt;path-to-lua-script-file&gt;*

**context:** *http, server*

**phase:** *right-after-client-hello-message-was-processed*

Equivalent to [ssl_client_hello_by_lua_block](#ssl_client_hello_by_lua_block), except that the file specified by `<path-to-lua-script-file>` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed.

When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server.

**Note for HTTP/3 (QUIC) users**: When using this directive with HTTP/3 connections, certain yield operations may fail if the QUIC SSL Lua yield patch is not applied to your OpenSSL installation. OpenResty packages include this patch by default, but if you are building lua-nginx-module separately, you may need to apply the patch manually to ensure proper yield/resume functionality for HTTP/3 connections in SSL Lua phases. The patch can be found at: [nginx-1.27.1-quic_ssl_lua_yield.patch](https://github.com/openresty/openresty/blob/master/patches/nginx/1.27.1/nginx-1.27.1-quic_ssl_lua_yield.patch)

This directive was first introduced in the `v0.10.21` release.

[Back to TOC](#directives)

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

**syntax:** *ssl_certificate_by_lua_block { lua-script }*

**context:** *server*

**phase:** *right-before-SSL-handshake*

This directive runs user Lua code when Nginx is about to start the SSL handshake for the downstream
SSL (https) connections.

It is particularly useful for setting the SSL certificate chain and the corresponding private key on a per-request
basis. It is also useful to load such handshake configurations nonblockingly from the remote (for example,
with the [cosocket](#ngxsockettcp) API). And one can also do per-request OCSP stapling handling in pure
Lua here as well.

Another typical use case is to do SSL handshake traffic control nonblockingly in this context,
with the help of the [lua-resty-limit-traffic#readme](https://github.com/openresty/lua-resty-limit-traffic)
library, for example.

One can also do interesting things with the SSL handshake requests from the client side, like
rejecting old SSL clients using the SSLv3 protocol or even below selectively.

The [ngx.ssl](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md)
and [ngx.ocsp](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ocsp.md) Lua modules
provided by the [lua-resty-core](https://github.com/openresty/lua-resty-core/#readme)
library are particularly useful in this context. You can use the Lua API offered by these two Lua modules
to manipulate the SSL certificate chain and private key for the current SSL connection
being initiated.

This Lua handler does not run at all, however, when Nginx/OpenSSL successfully resumes
the SSL session via SSL session IDs or TLS session tickets for the current SSL connection. In
other words, this Lua handler only runs when Nginx has to initiate a full SSL handshake.

Below is a trivial example using the
[ngx.ssl](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md) module
at the same time:

```nginx

 server {
     listen 443 ssl;
     server_name   test.com;

     ssl_certificate_by_lua_block {
         print("About to initiate a new SSL handshake!")
     }

     location / {
         root html;
     }
 }
```

See more complicated examples in the [ngx.ssl](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md)
and [ngx.ocsp](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ocsp.md)
Lua modules' official documentation.

Uncaught Lua exceptions in the user Lua code immediately abort the current SSL session, so does the
[ngx.exit](#ngxexit) call with an error code like `ngx.ERROR`.

This Lua code execution context *does* support yielding, so Lua APIs that may yield
(like cosockets, sleeping, and "light threads")
are enabled in this context.

Note, however, you still need to configure the [ssl_certificate](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate) and
[ssl_certificate_key](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate_key)
directives even though you will not use this static certificate and private key at all. This is
because the NGINX core requires their appearance otherwise you are seeing the following error
while starting NGINX:


    nginx: [emerg] no ssl configured for the server


This directive requires OpenSSL 1.0.2e or greater.

If you are using the [official pre-built
packages](https://openresty.org/en/linux-packages.html) for
[OpenResty](https://openresty.org/) 1.9.7.2 or later, then everything should
work out of the box.

If you are not using the Nginx core shipped with
[OpenResty](https://openresty.org) 1.9.7.2 or later, you will need to apply
patches to the standard Nginx core:

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

**Note for HTTP/3 (QUIC) users**: When using this directive with HTTP/3 connections, certain yield operations may fail if the QUIC SSL Lua yield patch is not applied to your OpenSSL installation. OpenResty packages include this patch by default, but if you are building lua-nginx-module separately, you may need to apply the patch manually to ensure proper yield/resume functionality for HTTP/3 connections in SSL Lua phases. The patch can be found at: [nginx-1.27.1-quic_ssl_lua_yield.patch](https://github.com/openresty/openresty/blob/master/patches/nginx/1.27.1/nginx-1.27.1-quic_ssl_lua_yield.patch)

This directive was first introduced in the `v0.10.0` release.

[Back to TOC](#directives)

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

**syntax:** *ssl_certificate_by_lua_file &lt;path-to-lua-script-file&gt;*

**context:** *server*

**phase:** *right-before-SSL-handshake*

Equivalent to [ssl_certificate_by_lua_block](#ssl_certificate_by_lua_block), except that the file specified by `<path-to-lua-script-file>` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed.

When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server.

**Note for HTTP/3 (QUIC) users**: When using this directive with HTTP/3 connections, certain yield operations may fail if the QUIC SSL Lua yield patch is not applied to your OpenSSL installation. OpenResty packages include this patch by default, but if you are building lua-nginx-module separately, you may need to apply the patch manually to ensure proper yield/resume functionality for HTTP/3 connections in SSL Lua phases. The patch can be found at: [nginx-1.27.1-quic_ssl_lua_yield.patch](https://github.com/openresty/openresty/blob/master/patches/nginx/1.27.1/nginx-1.27.1-quic_ssl_lua_yield.patch)

This directive was first introduced in the `v0.10.0` release.

[Back to TOC](#directives)

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

**syntax:** *ssl_session_fetch_by_lua_block { lua-script }*

**context:** *http*

**phase:** *right-before-SSL-handshake*

This directive runs Lua code to look up and load the SSL session (if any) according to the session ID
provided by the current SSL handshake request for the downstream.

The Lua API for obtaining the current session ID and loading a cached SSL session data
is provided in the [ngx.ssl.session](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/session.md)
Lua module shipped with the [lua-resty-core](https://github.com/openresty/lua-resty-core#readme)
library.

Lua APIs that may yield, like [ngx.sleep](#ngxsleep) and [cosockets](#ngxsockettcp),
are enabled in this context.

This hook, together with the [ssl_session_store_by_lua*](#ssl_session_store_by_lua_block) hook,
can be used to implement distributed caching mechanisms in pure Lua (based
on the [cosocket](#ngxsockettcp) API, for example). If a cached SSL session is found
and loaded into the current SSL connection context,
SSL session resumption can then get immediately initiated and bypass the full SSL handshake process which is very expensive in terms of CPU time.

Please note that TLS session tickets are very different and it is the clients' responsibility
to cache the SSL session state when session tickets are used. SSL session resumptions based on
TLS session tickets would happen automatically without going through this hook (nor the
[ssl_session_store_by_lua*](#ssl_session_store_by_lua_block) hook). This hook is mainly
for older or less capable SSL clients that can only do SSL sessions by session IDs.

When [ssl_certificate_by_lua*](#ssl_certificate_by_lua_block) is specified at the same time,
this hook usually runs before [ssl_certificate_by_lua*](#ssl_certificate_by_lua_block).
When the SSL session is found and successfully loaded for the current SSL connection,
SSL session resumption will happen and thus bypass the [ssl_certificate_by_lua*](#ssl_certificate_by_lua_block)
hook completely. In this case, Nginx also bypasses the [ssl_session_store_by_lua*](#ssl_session_store_by_lua_block)
hook, for obvious reasons.

To easily test this hook locally with a modern web browser, you can temporarily put the following line
in your https server block to disable the TLS session ticket support:

    ssl_session_tickets off;

But do not forget to comment this line out before publishing your site to the world.

If you are using the [official pre-built packages](https://openresty.org/en/linux-packages.html) for [OpenResty](https://openresty.org/)
1.11.2.1 or later, then everything should work out of the box.

If you are not using one of the [OpenSSL
packages](https://openresty.org/en/linux-packages.html) provided by
[OpenResty](https://openresty.org), you will need to apply patches to OpenSSL
in order to use this directive:

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

Similarly, if you are not using the Nginx core shipped with
[OpenResty](https://openresty.org) 1.11.2.1 or later, you will need to apply
patches to the standard Nginx core:

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

This directive was first introduced in the `v0.10.6` release.

Note that this directive can only be used in the **http context** starting
with the `v0.10.7` release since SSL session resumption happens
before server name dispatch.

[Back to TOC](#directives)

ssl_session_fetch_by_lua_file
-----------------------------

**syntax:** *ssl_session_fetch_by_lua_file &lt;path-to-lua-script-file&gt;*

**context:** *http*

**phase:** *right-before-SSL-handshake*

Equivalent to [ssl_session_fetch_by_lua_block](#ssl_session_fetch_by_lua_block), except that the file specified by `<path-to-lua-script-file>` contains the Lua code, or rather, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed.

When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server.

This directive was first introduced in the `v0.10.6` release.

Note that: this directive is only allowed to used in **http context** from the `v0.10.7` release
(because SSL session resumption happens before server name dispatch).

[Back to TOC](#directives)

ssl_session_store_by_lua_block
------------------------------

**syntax:** *ssl_session_store_by_lua_block { lua-script }*

**context:** *http*

**phase:** *right-after-SSL-handshake*

This directive runs Lua code to fetch and save the SSL session (if any) according to the session ID
provided by the current SSL handshake request for the downstream. The saved or cached SSL
session data can be used for future SSL connections to resume SSL sessions without going
through the full SSL handshake process (which is very expensive in terms of CPU time).

Lua APIs that may yield, like [ngx.sleep](#ngxsleep) and [cosockets](#ngxsockettcp),
are *disabled* in this context. You can still, however, use the [ngx.timer.at](#ngxtimerat) API
to create 0-delay timers to save the SSL session data asynchronously to external services (like `redis` or `memcached`).

The Lua API for obtaining the current session ID and the associated session state data
is provided in the [ngx.ssl.session](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/session.md#readme)
Lua module shipped with the [lua-resty-core](https://github.com/openresty/lua-resty-core#readme)
library.

To easily test this hook locally with a modern web browser, you can temporarily put the following line
in your https server block to disable the TLS session ticket support:

    ssl_session_tickets off;

But do not forget to comment this line out before publishing your site to the world.

This directive was first introduced in the `v0.10.6` release.

Note that: this directive is only allowed to used in **http context** from the `v0.10.7` release
(because SSL session resumption happens before server name dispatch).

[Back to TOC](#directives)

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

**syntax:** *ssl_session_store_by_lua_file &lt;path-to-lua-script-file&gt;*

**context:** *http*

**phase:** *right-after-SSL-handshake*

Equivalent to [ssl_session_store_by_lua_block](#ssl_session_store_by_lua_block), except that the file specified by `<path-to-lua-script-file>` contains the Lua code, or rather, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed.

When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server.

This directive was first introduced in the `v0.10.6` release.

Note that: this directive is only allowed to used in **http context** from the `v0.10.7` release
(because SSL session resumption happens before server name dispatch).

[Back to TOC](#directives)

proxy_ssl_certificate_by_lua_block
----------------------------------

**syntax:** *proxy_ssl_certificate_by_lua_block { lua-script }*

**context:** *location*

**phase:** *right-after-server-certificate-request-message-was-processed*

This directive runs user Lua code when Nginx is about to post-process the SSL server certificate request message from upstream. It is particularly useful for setting the SSL certificate chain and the corresponding private key for the upstream SSL (https) connections. It is also useful to load such handshake configurations nonblockingly from the remote (for example, with the [cosocket](#ngxsockettcp) API).

The [ngx.ssl.proxysslcert](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/proxysslcert.md) Lua module provided by the [lua-resty-core](https://github.com/openresty/lua-resty-core/#readme) library are particularly useful in this context.

Below is a trivial example using the [ngx.ssl](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md) module and the [ngx.ssl.proxysslcert](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/proxysslcert.md) module at the same time:

```nginx

 server {
     listen 443 ssl;
     server_name   test.com;
     ssl_certificate /path/to/cert.crt;
     ssl_certificate_key /path/to/key.key;

     location /t {
         proxy_pass https://upstream;

         proxy_ssl_certificate_by_lua_block {
             local ssl = require "ngx.ssl"
             local proxy_ssl_cert = require "ngx.ssl.proxysslcert"

             -- NOTE: for illustration only, we don't handle error below

             local f = assert(io.open("/path/to/cert.crt"))
             local cert_data = f:read("*a")
             f:close()

             local cert, err = ssl.parse_pem_cert(cert_data)
             local ok, err = proxy_ssl_cert.set_cert(cert)

             local f = assert(io.open("/path/to/key.key"))
             local pkey_data = f:read("*a")
             f:close()

             local pkey, err = ssl.parse_pem_priv_key(pkey_data)
             local ok, err = proxy_ssl_cert.set_priv_key(pkey)
             -- ...
        }
     }
     ...
 }
```

See more information in the [ngx.ssl.proxysslcert](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/proxysslcert.md) Lua module's official documentation.

Uncaught Lua exceptions in the user Lua code immediately abort the current SSL session, so does the
[ngx.exit](#ngxexit) call with an error code like `ngx.ERROR`.

This Lua code execution context *does* support yielding, so Lua APIs that may yield (like cosockets, sleeping, and "light threads") are enabled in this context.

Note that, unlike the relations between the [ssl_certificate](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate) and [ssl_certificate_key](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate_key) directives and [ssl_certificate_by_lua*](#ssl_certificate_by_lua_block), the [proxy_ssl_certificate](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_certificate) and [proxy_ssl_certificate_key](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_certificate_key) directives can be used together with [proxy_ssl_certificate_by_lua*](#proxy_ssl_certificate_by_lua_block).

* When there are only [proxy_ssl_certificate](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_certificate) and [proxy_ssl_certificate_key](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_certificate_key) directives, the original Nginx behavior will obviously remain the same.

* When there is only [proxy_ssl_certificate_by_lua*](#proxy_ssl_certificate_by_lua_block), Nginx will send the certificate and its related private key and chain set by Lua codes.

* When the [proxy_ssl_certificate](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_certificate) and [proxy_ssl_certificate_key](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_certificate_key) directives and [proxy_ssl_certificate_by_lua*](#proxy_ssl_certificate_by_lua_block) are used at the same time, then [proxy_ssl_certificate_by_lua*](#proxy_ssl_certificate_by_lua_block) will take precedence over the [proxy_ssl_certificate](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_certificate) and [proxy_ssl_certificate_key](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_certificate_key) directives.

Please refer to corresponding test case file and [ngx.ssl.proxysslcert](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/proxysslcert.md) for more details.

Note also that, it has the same condition as the [proxy_ssl_certificate](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_certificate) directive for [proxy_ssl_certificate_by_lua*](#proxy_ssl_certificate_by_lua_block) to work, that is the upstream server should enable verification of client certificates.

This directive requires OpenSSL 1.0.2e or greater.

[Back to TOC](#directives)

proxy_ssl_certificate_by_lua_file
---------------------------------

**syntax:** *proxy_ssl_certificate_by_lua_file &lt;path-to-lua-script-file&gt;*

**context:** *location*

**phase:** *right-after-server-certificate-request-message-was-processed*

Equivalent to [proxy_ssl_certificate_by_lua_block](#proxy_ssl_certificate_by_lua_block), except that the file specified by `<path-to-lua-script-file>` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed.

When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server.

[Back to TOC](#directives)

proxy_ssl_verify_by_lua_block
-----------------------------

**syntax:** *proxy_ssl_verify_by_lua_block { lua-script }*

**context:** *location*

**phase:** *right-after-server-certificate-message-was-processed*

This directive runs user Lua code when Nginx is about to post-process the SSL server certificate message for the upstream SSL (https) connections.

It is particularly useful to parse upstream server certificate and do some custom operations in pure lua.

The [ngx.ssl.proxysslverify](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/proxysslverify.md) Lua module provided by the [lua-resty-core](https://github.com/openresty/lua-resty-core/#readme)
library are particularly useful in this context.

Below is a trivial example using the
[ngx.ssl.proxysslverify](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/proxysslverify.md) module
at the same time:

```nginx

 server {
     listen 443 ssl;
     server_name   test.com;
     ssl_certificate /path/to/cert.crt;
     ssl_certificate_key /path/to/key.key;

     location /t {
         proxy_ssl_certificate /path/to/cert.crt;
         proxy_ssl_certificate_key /path/to/key.key;
         proxy_pass https://upstream;

         proxy_ssl_verify_by_lua_block {
             local proxy_ssl_vfy = require "ngx.ssl.proxysslverify"
             local cert = proxy_ssl_vfy.get_verify_cert()

             -- ocsp to verify cert
             -- check crl
             proxy_ssl_vfy.set_verify_result()
             ...
         }
     }
     ...
 }
```

See more information in the [ngx.ssl.proxysslverify](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/proxysslverify.md)
Lua module's official documentation.

Uncaught Lua exceptions in the user Lua code immediately abort the current SSL session, so does the
[ngx.exit](#ngxexit) call with an error code like `ngx.ERROR`.

This Lua code execution context *does* support yielding, so Lua APIs that may yield
(like cosockets, sleeping, and "light threads")
are enabled in this context

This directive requires OpenSSL 3.0.2 or greater.

[Back to TOC](#directives)

proxy_ssl_verify_by_lua_file
----------------------------

**syntax:** *proxy_ssl_verify_by_lua_file &lt;path-to-lua-script-file&gt;*

**context:** *location*

**phase:** *right-after-server-certificate-message-was-processed*

Equivalent to [proxy_ssl_verify_by_lua_block](#proxy_ssl_verify_by_lua_block), except that the file specified by `<path-to-lua-script-file>` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed.

When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server.

[Back to TOC](#directives)

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

**syntax:** *lua_shared_dict &lt;name&gt; &lt;size&gt;*

**default:** *no*

**context:** *http*

**phase:** *depends on usage*

Declares a shared memory zone, `<name>`, to serve as storage for the shm based Lua dictionary `ngx.shared.<name>`.

Shared memory zones are always shared by all the Nginx worker processes in the current Nginx server instance.

The `<size>` argument accepts size units such as `k` and `m`:

```nginx

 http {
     lua_shared_dict dogs 10m;
     ...
 }
```

The hard-coded minimum size is 8KB while the practical minimum size depends
on actual user data set (some people start with 12KB).

See [ngx.shared.DICT](#ngxshareddict) for details.

This directive was first introduced in the `v0.3.1rc22` release.

[Back to TOC](#directives)

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

**syntax:** *lua_socket_connect_timeout &lt;time&gt;*

**default:** *lua_socket_connect_timeout 60s*

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

This directive controls the default timeout value used in TCP/unix-domain socket object's [connect](#tcpsockconnect) method and can be overridden by the [settimeout](#tcpsocksettimeout) or [settimeouts](#tcpsocksettimeouts) methods.

The `<time>` argument can be an integer, with an optional time unit, like `s` (second), `ms` (millisecond), `m` (minute). The default time unit is `s`, i.e., "second". The default setting is `60s`.

This directive was first introduced in the `v0.5.0rc1` release.

[Back to TOC](#directives)

lua_socket_send_timeout
-----------------------

**syntax:** *lua_socket_send_timeout &lt;time&gt;*

**default:** *lua_socket_send_timeout 60s*

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

Controls the default timeout value used in TCP/unix-domain socket object's [send](#tcpsocksend) method and can be overridden by the [settimeout](#tcpsocksettimeout) or [settimeouts](#tcpsocksettimeouts) methods.

The `<time>` argument can be an integer, with an optional time unit, like `s` (second), `ms` (millisecond), `m` (minute). The default time unit is `s`, i.e., "second". The default setting is `60s`.

This directive was first introduced in the `v0.5.0rc1` release.

[Back to TOC](#directives)

lua_socket_send_lowat
---------------------

**syntax:** *lua_socket_send_lowat &lt;size&gt;*

**default:** *lua_socket_send_lowat 0*

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

Controls the `lowat` (low water) value for the cosocket send buffer.

[Back to TOC](#directives)

lua_socket_read_timeout
-----------------------

**syntax:** *lua_socket_read_timeout &lt;time&gt;*

**default:** *lua_socket_read_timeout 60s*

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

**phase:** *depends on usage*

This directive controls the default timeout value used in TCP/unix-domain socket object's [receive](#tcpsockreceive) method and iterator functions returned by the [receiveuntil](#tcpsockreceiveuntil) method. This setting can be overridden by the [settimeout](#tcpsocksettimeout) or [settimeouts](#tcpsocksettimeouts) methods.

The `<time>` argument can be an integer, with an optional time unit, like `s` (second), `ms` (millisecond), `m` (minute). The default time unit is `s`, i.e., "second". The default setting is `60s`.

This directive was first introduced in the `v0.5.0rc1` release.

[Back to TOC](#directives)

lua_socket_buffer_size
----------------------

**syntax:** *lua_socket_buffer_size &lt;size&gt;*

**default:** *lua_socket_buffer_size 4k/8k*

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

Specifies the buffer size used by cosocket reading operations.

This buffer does not have to be that big to hold everything at the same time because cosocket supports 100% non-buffered reading and parsing. So even `1` byte buffer size should still work everywhere but the performance could be terrible.

This directive was first introduced in the `v0.5.0rc1` release.

[Back to TOC](#directives)

lua_socket_pool_size
--------------------

**syntax:** *lua_socket_pool_size &lt;size&gt;*

**default:** *lua_socket_pool_size 30*

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

Specifies the size limit (in terms of connection count) for every cosocket connection pool associated with every remote server (i.e., identified by either the host-port pair or the unix domain socket file path).

Default to 30 connections for every pool.

When the connection pool exceeds the available size limit, the least recently used (idle) connection already in the pool will be closed to make room for the current connection.

Note that the cosocket connection pool is per Nginx worker process rather than per Nginx server instance, so size limit specified here also applies to every single Nginx worker process.

This directive was first introduced in the `v0.5.0rc1` release.

[Back to TOC](#directives)

lua_socket_keepalive_timeout
----------------------------

**syntax:** *lua_socket_keepalive_timeout &lt;time&gt;*

**default:** *lua_socket_keepalive_timeout 60s*

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

This directive controls the default maximal idle time of the connections in the cosocket built-in connection pool. When this timeout reaches, idle connections will be closed and removed from the pool. This setting can be overridden by cosocket objects' [setkeepalive](#tcpsocksetkeepalive) method.

The `<time>` argument can be an integer, with an optional time unit, like `s` (second), `ms` (millisecond), `m` (minute). The default time unit is `s`, i.e., "second". The default setting is `60s`.

This directive was first introduced in the `v0.5.0rc1` release.

[Back to TOC](#directives)

lua_socket_log_errors
---------------------

**syntax:** *lua_socket_log_errors on|off*

**default:** *lua_socket_log_errors on*

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

This directive can be used to toggle error logging when a failure occurs for the TCP or UDP cosockets. If you are already doing proper error handling and logging in your Lua code, then it is recommended to turn this directive off to prevent data flushing in your Nginx error log files (which is usually rather expensive).

This directive was first introduced in the `v0.5.13` release.

[Back to TOC](#directives)

lua_ssl_ciphers
---------------

**syntax:** *lua_ssl_ciphers &lt;ciphers&gt;*

**default:** *lua_ssl_ciphers DEFAULT*

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

Specifies the enabled ciphers for requests to a SSL/TLS server in the [tcpsock:sslhandshake](#tcpsocksslhandshake) method. The ciphers are specified in the format understood by the OpenSSL library.

The full list can be viewed using the “openssl ciphers” command.

This directive was first introduced in the `v0.9.11` release.

[Back to TOC](#directives)

lua_ssl_crl
-----------

**syntax:** *lua_ssl_crl &lt;file&gt;*

**default:** *no*

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

Specifies a file with revoked certificates (CRL) in the PEM format used to verify the certificate of the SSL/TLS server in the [tcpsock:sslhandshake](#tcpsocksslhandshake) method.

This directive was first introduced in the `v0.9.11` release.

[Back to TOC](#directives)

lua_ssl_protocols
-----------------

**syntax:** *lua_ssl_protocols \[SSLv2\] \[SSLv3\] \[TLSv1\] [TLSv1.1] [TLSv1.2] [TLSv1.3]*

**default:** *lua_ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3*

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

Enables the specified protocols for requests to a SSL/TLS server in the [tcpsock:sslhandshake](#tcpsocksslhandshake) method.

The support for the `TLSv1.3` parameter requires version `v0.10.12` *and* OpenSSL 1.1.1.
From version v0.10.25, the default value change from `SSLV3 TLSv1 TLSv1.1 TLSv1.2` to `TLSv1 TLSv1.1 TLSv1.2 TLSv1.3`.

This directive was first introduced in the `v0.9.11` release.

[Back to TOC](#directives)

lua_ssl_certificate
-------------------

**syntax:** *lua_ssl_certificate &lt;file&gt;*

**default:** *none*

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

Specifies the file path to the SSL/TLS certificate in PEM format used for the [tcpsock:sslhandshake](#tcpsocksslhandshake) method.

This directive allows you to specify the SSL/TLS certificate that will be presented to server during the SSL/TLS handshake process.

This directive was first introduced in the `v0.10.26` release.

See also [lua_ssl_certificate_key](#lua_ssl_certificate_key) and [lua_ssl_verify_depth](#lua_ssl_verify_depth).

[Back to TOC](#directives)

lua_ssl_certificate_key
-----------------------

**syntax:** *lua_ssl_certificate_key &lt;file&gt;*

**default:** *none*

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

Specifies the file path to the private key associated with the SSL/TLS certificate used in the [tcpsock:sslhandshake](#tcpsocksslhandshake) method.

This directive allows you to specify the private key file corresponding to the SSL/TLS certificate specified by lua_ssl_certificate. The private key should be in PEM format and must match the certificate.

This directive was first introduced in the `v0.10.26` release.

See also [lua_ssl_certificate](#lua_ssl_certificate) and [lua_ssl_verify_depth](#lua_ssl_verify_depth).

[Back to TOC](#directives)

lua_ssl_trusted_certificate
---------------------------

**syntax:** *lua_ssl_trusted_certificate &lt;file&gt;*

**default:** *none*

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

Specifies a file path with trusted CA certificates in the PEM format used to verify the certificate of the SSL/TLS server in the [tcpsock:sslhandshake](#tcpsocksslhandshake) method.

This directive was first introduced in the `v0.9.11` release.

See also [lua_ssl_verify_depth](#lua_ssl_verify_depth).

[Back to TOC](#directives)

lua_ssl_verify_depth
--------------------

**syntax:** *lua_ssl_verify_depth &lt;number&gt;*

**default:** *lua_ssl_verify_depth 1*

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

Sets the verification depth in the server certificates chain.

This directive was first introduced in the `v0.9.11` release.

See also [lua_ssl_certificate](#lua_ssl_certificate), [lua_ssl_certificate_key](#lua_ssl_certificate_key) and [lua_ssl_trusted_certificate](#lua_ssl_trusted_certificate).

[Back to TOC](#directives)

lua_ssl_key_log
---------------

**syntax:** *lua_ssl_key_log &lt;file&gt;*

**default:** *none*

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

Enables logging of client connection SSL keys in the [tcpsock:sslhandshake](#tcpsocksslhandshake) method and specifies the path to the key log file. Keys are logged in the SSLKEYLOGFILE format compatible with Wireshark.

[Back to TOC](#directives)

lua_ssl_conf_command
--------------------

**syntax:** *lua_ssl_conf_command &lt;command&gt;*

**default:** *no*

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

Sets arbitrary OpenSSL configuration [commands](https://www.openssl.org/docs/man1.1.1/man3/SSL_CONF_cmd.html).

The directive is supported when using OpenSSL 1.0.2 or higher and nginx 1.19.4 or higher. According to the specify command, higher OpenSSL version may be needed.

Several `lua_ssl_conf_command` directives can be specified on the same level:

```nginx

 lua_ssl_conf_command Options PrioritizeChaCha;
 lua_ssl_conf_command Ciphersuites TLS_CHACHA20_POLY1305_SHA256;
```

Configuration commands are applied after OpenResty own configuration for SSL, so they can be used to override anything set by OpenResty.

Note though that configuring OpenSSL directly with `lua_ssl_conf_command` might result in a behaviour OpenResty does not expect, and should be done with care.

This directive was first introduced in the `v0.10.21` release.



[Back to TOC](#directives)

lua_upstream_skip_openssl_default_verify
--------------------

**syntax:** *lua_upstream_skip_openssl_default_verify on|off*

**default:** *lua_upstream_skip_openssl_default_verify off*

**context:** *location, location-if*

When using proxy_ssl_verify_by_lua directive, `lua_upstream_skip_openssl_default_verify` controls whether to skip default openssl's verify function, that means using pure Lua code to verify upstream server certificate.

This directive is turned `off` by default.

[Back to TOC](#directives)

lua_http10_buffering
--------------------

**syntax:** *lua_http10_buffering on|off*

**default:** *lua_http10_buffering on*

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

Enables or disables automatic response buffering for HTTP 1.0 (or older) requests. This buffering mechanism is mainly used for HTTP 1.0 keep-alive which relies on a proper `Content-Length` response header.

If the Lua code explicitly sets a `Content-Length` response header before sending the headers (either explicitly via [ngx.send_headers](#ngxsend_headers) or implicitly via the first [ngx.say](#ngxsay) or [ngx.print](#ngxprint) call), then the HTTP 1.0 response buffering will be disabled even when this directive is turned on.

To output very large response data in a streaming fashion (via the [ngx.flush](#ngxflush) call, for example), this directive MUST be turned off to minimize memory usage.

This directive is turned `on` by default.

This directive was first introduced in the `v0.5.0rc19` release.

[Back to TOC](#directives)

rewrite_by_lua_no_postpone
--------------------------

**syntax:** *rewrite_by_lua_no_postpone on|off*

**default:** *rewrite_by_lua_no_postpone off*

**context:** *http*

Controls whether or not to disable postponing [rewrite_by_lua*](#rewrite_by_lua) directives to run at the end of the `rewrite` request-processing phase. By default, this directive is turned off and the Lua code is postponed to run at the end of the `rewrite` phase.

This directive was first introduced in the `v0.5.0rc29` release.

[Back to TOC](#directives)

access_by_lua_no_postpone
-------------------------

**syntax:** *access_by_lua_no_postpone on|off*

**default:** *access_by_lua_no_postpone off*

**context:** *http*

Controls whether or not to disable postponing [access_by_lua*](#access_by_lua) directives to run at the end of the `access` request-processing phase. By default, this directive is turned off and the Lua code is postponed to run at the end of the `access` phase.

This directive was first introduced in the `v0.9.20` release.

[Back to TOC](#directives)

precontent_by_lua_no_postpone
-------------------------

**syntax:** *precontent_by_lua_no_postpone on|off*

**default:** *precontent_by_lua_no_postpone off*

**context:** *http*

Controls whether or not to disable postponing [precontent_by_lua*](#precontent_by_lua_block) directives to run at the end of the `precontent` request-processing phase. By default, this directive is turned off and the Lua code is postponed to run at the end of the `precontent` phase.

[Back to TOC](#directives)

lua_transform_underscores_in_response_headers
---------------------------------------------

**syntax:** *lua_transform_underscores_in_response_headers on|off*

**default:** *lua_transform_underscores_in_response_headers on*

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

Controls whether to transform underscores (`_`) in the response header names specified in the [ngx.header.HEADER](#ngxheaderheader) API to hyphens (`-`).

This directive was first introduced in the `v0.5.0rc32` release.

[Back to 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 abortion.

When this directive is on, the ngx_lua module will monitor the premature connection close event on the downstream connections and when there is such an event, it will call the user Lua function callback (registered by [ngx.on_abort](#ngxon_abort)) or just stop and clean up all the Lua "light threads" running in the current request's request handler when there is no user callback function registered.

According to the current implementation, however, if the client closes the connection before the Lua code finishes reading the request body data via [ngx.req.socket](#ngxreqsocket), then ngx_lua will neither stop all the running "light threads" nor call the user callback (if [ngx.on_abort](#ngxon_abort) has been called). Instead, the reading operation on [ngx.req.socket](#ngxreqsocket) will just return the error message "client aborted" as the second return value (the first return value is surely `nil`).

When TCP keepalive is disabled, it is relying on the client side to close the socket gracefully (by sending a `FIN` packet or something like that). For (soft) real-time web applications, it is highly recommended to configure the [TCP keepalive](http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html) support in your system's TCP stack implementation in order to detect "half-open" TCP connections in time.

For example, on Linux, you can configure the standard [listen](http://nginx.org/en/docs/http/ngx_http_core_module.html#listen) directive in your `nginx.conf` file like this:

```nginx

 listen 80 so_keepalive=2s:2s:8;
```

On FreeBSD, you can only tune the system-wide configuration for TCP keepalive, for example:

    # sysctl net.inet.tcp.keepintvl=2000
    # sysctl net.inet.tcp.keepidle=2000

This directive was first introduced in the `v0.7.4` release.

See also [ngx.on_abort](#ngxon_abort).

[Back to TOC](#directives)

lua_max_pending_timers
----------------------

**syntax:** *lua_max_pending_timers &lt;count&gt;*

**default:** *lua_max_pending_timers 1024*

**context:** *http*

Controls the maximum number of pending timers allowed.

Pending timers are those timers that have not expired yet.

When exceeding this limit, the [ngx.timer.at](#ngxtimerat) call will immediately return `nil` and the error string "too many pending timers".

This directive was first introduced in the `v0.8.0` release.

[Back to TOC](#directives)

lua_max_running_timers
----------------------

**syntax:** *lua_max_running_timers &lt;count&gt;*

**default:** *lua_max_running_timers 256*

**context:** *http*

Controls the maximum number of "running timers" allowed.

Running timers are those timers whose user callback functions are still running or `lightthreads` spawned in callback functions are still running.

When exceeding this limit, Nginx will stop running the callbacks of newly expired timers and log an error message "N lua_max_running_timers are not enough" where "N" is the current value of this directive.

This directive was first introduced in the `v0.8.0` release.

[Back to TOC](#directives)

lua_sa_restart
--------------

**syntax:** *lua_sa_restart on|off*

**default:** *lua_sa_restart on*

**context:** *http*

When enabled, this module will set the `SA_RESTART` flag on Nginx workers signal dispositions.

This allows Lua I/O primitives to not be interrupted by Nginx's handling of various signals.

This directive was first introduced in the `v0.10.14` release.

[Back to TOC](#directives)

lua_worker_thread_vm_pool_size
------------------------------

**syntax:** *lua_worker_thread_vm_pool_size &lt;size&gt;*

**default:** *lua_worker_thread_vm_pool_size 10*

**context:** *http*

Specifies the size limit of the Lua VM pool (default 100) that will be used in the [ngx.run_worker_thread](#ngxrun_worker_thread) API.

Also, it is not allowed to create Lua VMs that exceeds the pool size limit.

The Lua VM in the VM pool is used to execute Lua code in separate thread.

The pool is global at Nginx worker level. And it is used to reuse Lua VMs between requests.

**Warning:** Each worker thread uses a separate Lua VM and caches the Lua VM for reuse in subsequent operations. Configuring too many worker threads can result in consuming a lot of memory.

[Back to TOC](#directives)

Nginx API for Lua
=================

* [Introduction](#introduction)
* [ngx.arg](#ngxarg)
* [ngx.var.VARIABLE](#ngxvarvariable)
* [Core constants](#core-constants)
* [HTTP method constants](#http-method-constants)
* [HTTP status constants](#http-status-constants)
* [Nginx log level constants](#nginx-log-level-constants)
* [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)
* [ngx.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](#getfd)
* [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)
* [tcpsock:getsslpointer](#tcpsockgetsslpointer)
* [tcpsock:getsslctx](#tcpsockgetsslctx)
* [tcpsock:getsslsession](#tcpsockgetsslsession)
* [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.ngx_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)


[Back to TOC](#table-of-contents)

Introduction
------------

The various `*_by_lua`, `*_by_lua_block` and `*_by_lua_file` configuration directives serve as gateways to the Lua API within the `nginx.conf` file. The Nginx Lua API described below can only be called within the user Lua code run in the context of these configuration directives.

The API is exposed to Lua in the form of two standard packages `ngx` and `ndk`. These packages are in the default global scope within ngx_lua and are always available within ngx_lua directives.

The packages can be introduced into external Lua modules like this:

```lua

 local say = ngx.say

 local _M = {}

 function _M.foo(a)
     say(a)
 end

 return _M
```

Use of the [package.seeall](https://www.lua.org/manual/5.1/manual.html#pdf-package.seeall) flag is strongly discouraged due to its various bad side-effects.

It is also possible to directly require the packages in external Lua modules:

```lua

 local ngx = require "ngx"
 local ndk = require "ndk"
```

The ability to require these packages was introduced in the `v0.2.1rc19` release.

Network I/O operations in user code should only be done through the Nginx Lua API calls as the Nginx event loop may be blocked and performance drop off dramatically otherwise. Disk operations with relatively small amount of data can be done using the standard Lua `io` library but huge file reading and writing should be avoided wherever possible as they may block the Nginx process significantly. Delegating all network and disk I/O operations to Nginx's subrequests (via the [ngx.location.capture](#ngxlocationcapture) method and similar) is strongly recommended for maximum performance.

[Back to TOC](#nginx-api-for-lua)

ngx.arg
-------

**syntax:** *val = ngx.arg\[index\]*

**context:** *set_by_lua&#42;, body_filter_by_lua&#42;*

When this is used in the context of the [set_by_lua*](#set_by_lua) directives, this table is read-only and holds the input arguments to the config directives:

```lua

 value = ngx.arg[n]
```

Here is an example

```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;
 }
```

that writes out `88`, the sum of `32` and `56`.

When this table is used in the context of [body_filter_by_lua*](#body_filter_by_lua), the first element holds the input data chunk to the output filter code and the second element holds the boolean flag for the "eof" flag indicating the end of the whole output data stream.

The data chunk and "eof" flag passed to the downstream Nginx output filters can also be overridden by assigning values directly to the corresponding table elements. When setting `nil` or an empty Lua string value to `ngx.arg[1]`, no data chunk will be passed to the downstream Nginx output filters at all.

[Back to TOC](#nginx-api-for-lua)

ngx.var.VARIABLE
----------------

**syntax:** *ngx.var.VAR_NAME*

**context:** *set_by_lua&#42;, rewrite_by_lua&#42;, access_by_lua&#42;, content_by_lua&#42;, header_filter_by_lua&#42;, body_filter_by_lua&#42;, log_by_lua&#42;, balancer_by_lua&#42;*

Read and write Nginx variable values.

```nginx

 value = ngx.var.some_nginx_variable_name
 ngx.var.some_nginx_variable_name = value
```

Note that only already defined Nginx variables can be written to.
For example:

```nginx

 location /foo {
     set $my_var ''; # this line is required to create $my_var at config time
     content_by_lua_block {
         ngx.var.my_var = 123
         ...
     }
 }
```

That is, Nginx variables cannot be created on-the-fly. Here is a list of pre-defined
[Nginx variables](http://nginx.org/en/docs/varindex.html).

Some special Nginx variables like `$args` and `$limit_rate` can be assigned a value,
many others are not, like `$query_string`, `$arg_PARAMETER`, and `$http_NAME`.

Nginx regex group capturing variables `$1`, `$2`, `$3`, and etc, can be read by this
interface as well, by writing `ngx.var[1]`, `ngx.var[2]`, `ngx.var[3]`, and etc.

Setting `ngx.var.Foo` to a `nil` value will unset the `$Foo` Nginx variable.

```lua

 ngx.var.args = nil
```

**CAUTION** When reading from an Nginx variable, Nginx will allocate memory in the per-request memory pool which is freed only at request termination. So when you need to read from an Nginx variable repeatedly in your Lua code, cache the Nginx variable value to your own Lua variable, for example,

```lua

 local val = ngx.var.some_var
 --- use the val repeatedly later
```

to prevent (temporary) memory leaking within the current request's lifetime. Another way of caching the result is to use the [ngx.ctx](#ngxctx) table.

Undefined Nginx variables are evaluated to `nil` while uninitialized (but defined) Nginx variables are evaluated to an empty Lua string.

This API requires a relatively expensive metamethod call and it is recommended to avoid using it on hot code paths.

[Back to TOC](#nginx-api-for-lua)

Core constants
--------------

**context:** *init_by_lua&#42;, set_by_lua&#42;, rewrite_by_lua&#42;, access_by_lua&#42;, content_by_lua&#42;, header_filter_by_lua&#42;, body_filter_by_lua&#42;, &#42;log_by_lua&#42;, ngx.timer.&#42;, balancer_by_lua&#42;, ssl_certificate_by_lua&#42;, ssl_session_fetch_by_lua&#42;, ssl_session_store_by_lua&#42;, ssl_client_hello_by_lua&#42;*

```lua

   ngx.OK (0)
   ngx.ERROR (-1)
   ngx.AGAIN (-2)
   ngx.DONE (-4)
   ngx.DECLINED (-5)
```

Note that only three of these constants are utilized by the [Nginx API for Lua](#nginx-api-for-lua) (i.e., [ngx.exit](#ngxexit) accepts `ngx.OK`, `ngx.ERROR`, and `ngx.DECLINED` as input).

```lua

   ngx.null
```

The `ngx.null` constant is a `NULL` light userdata usually used to represent nil values in Lua tables etc and is similar to the [lua-cjson](http://www.kyne.com.au/~mark/software/lua-cjson.php) library's `cjson.null` constant. This constant was first introduced in the `v0.5.0rc5` release.

The `ngx.DECLINED` constant was first introduced in the `v0.5.0rc19` release.

[Back to TOC](#nginx-api-for-lua)

HTTP method constants
---------------------

**context:** *init_by_lua&#42;, set_by_lua&#42;, rewrite_by_lua&#42;, access_by_lua&#42;, content_by_lua&#42;, header_filter_by_lua&#42;, body_filter_by_lua&#42;, log_by_lua&#42;, ngx.timer.&#42;, balancer_by_lua&#42;, ssl_certificate_by_lua&#42;, ssl_session_fetch_by_lua&#42;, ssl_session_store_by_lua&#42;, ssl_client_hello_by_lua&#42;*


      ngx.HTTP_GET
      ngx.HTTP_HEAD
      ngx.HTTP_PUT
      ngx.HTTP_POST
      ngx.HTTP_DELETE
      ngx.HTTP_OPTIONS   (added in the v0.5.0rc24 release)
      ngx.HTTP_MKCOL     (added in the v0.8.2 release)
      ngx.HTTP_COPY      (added in the v0.8.2 release)
      ngx.HTTP_MOVE      (added in the v0.8.2 release)
      ngx.HTTP_PROPFIND  (added in the v0.8.2 release)
      ngx.HTTP_PROPPATCH (added in the v0.8.2 release)
      ngx.HTTP_LOCK      (added in the v0.8.2 release)
      ngx.HTTP_UNLOCK    (added in the v0.8.2 release)
      ngx.HTTP_PATCH     (added in the v0.8.2 release)
      ngx.HTTP_TRACE     (added in the v0.8.2 release)


These constants are usually used in [ngx.location.capture](#ngxlocationcapture) and [ngx.location.capture_multi](#ngxlocationcapture_multi) method calls.

[Back to TOC](#nginx-api-for-lua)

HTTP status constants
---------------------

**context:** *init_by_lua&#42;, set_by_lua&#42;, rewrite_by_lua&#42;, access_by_lua&#42;, content_by_lua&#42;, header_filter_by_lua&#42;, body_filter_by_lua&#42;, log_by_lua&#42;, ngx.timer.&#42;, balancer_by_lua&#42;, ssl_certificate_by_lua&#42;, ssl_session_fetch_by_lua&#42;, ssl_session_store_by_lua&#42;, ssl_client_hello_by_lua&#42;*

```nginx

   value = ngx.HTTP_CONTINUE (100) (first added in the v0.9.20 release)
   value = ngx.HTTP_SWITCHING_PROTOCOLS (101) (first added in the v0.9.20 release)
   value = ngx.HTTP_OK (200)
   value = ngx.HTTP_CREATED (201)
   value = ngx.HTTP_ACCEPTED (202) (first added in the v0.9.20 release)
   value = ngx.HTTP_NO_CONTENT (204) (first added in the v0.9.20 release)
   value = ngx.HTTP_PARTIAL_CONTENT (206) (first added in the v0.9.20 release)
   value = ngx.HTTP_SPECIAL_RESPONSE (300)
   value = ngx.HTTP_MOVED_PERMANENTLY (301)
   value = ngx.HTTP_MOVED_TEMPORARILY (302)
   value = ngx.HTTP_SEE_OTHER (303)
   value = ngx.HTTP_NOT_MODIFIED (304)
   value = ngx.HTTP_TEMPORARY_REDIRECT (307) (first added in the v0.9.20 release)
   value = ngx.HTTP_PERMANENT_REDIRECT (308)
   value = ngx.HTTP_BAD_REQUEST (400)
   value = ngx.HTTP_UNAUTHORIZED (401)
   value = ngx.HTTP_PAYMENT_REQUIRED (402) (first added in the v0.9.20 release)
   value = ngx.HTTP_FORBIDDEN (403)
   value = ngx.HTTP_NOT_FOUND (404)
   value = ngx.HTTP_NOT_ALLOWED (405)
   value = ngx.HTTP_NOT_ACCEPTABLE (406) (first added in the v0.9.20 release)
   value = ngx.HTTP_REQUEST_TIMEOUT (408) (first added in the v0.9.20 release)
   value = ngx.HTTP_CONFLICT (409) (first added in the v0.9.20 release)
   value = ngx.HTTP_GONE (410)
   value = ngx.HTTP_UPGRADE_REQUIRED (426) (first added in the v0.9.20 release)
   value = ngx.HTTP_TOO_MANY_REQUESTS (429) (first added in the v0.9.20 release)
   value = ngx.HTTP_CLOSE (444) (first added in the v0.9.20 release)
   value = ngx.HTTP_ILLEGAL (451) (first added in the v0.9.20 release)
   value = ngx.HTTP_INTERNAL_SERVER_ERROR (500)
   value = ngx.HTTP_NOT_IMPLEMENTED (501)
   value = ngx.HTTP_METHOD_NOT_IMPLEMENTED (501) (kept for compatibility)
   value = ngx.HTTP_BAD_GATEWAY (502) (first added in the v0.9.20 release)
   value = ngx.HTTP_SERVICE_UNAVAILABLE (503)
   value = ngx.HTTP_GATEWAY_TIMEOUT (504) (first added in the v0.3.1rc38 release)
   value = ngx.HTTP_VERSION_NOT_SUPPORTED (505) (first added in the v0.9.20 release)
   value = ngx.HTTP_INSUFFICIENT_STORAGE (507) (first added in the v0.9.20 release)
```

[Back to TOC](#nginx-api-for-lua)

Nginx log level constants
-------------------------

**context:** *init_by_lua&#42;, init_worker_by_lua&#42;, set_by_lua&#42;, rewrite_by_lua&#42;, access_by_lua&#42;, content_by_lua&#42;, header_filter_by_lua&#42;, body_filter_by_lua&#42;, log_by_lua&#42;, ngx.timer.&#42;, balancer_by_lua&#42;, ssl_certificate_by_lua&#42;, ssl_session_fetch_by_lua&#42;, ssl_session_store_by_lua&#42;, exit_worker_by_lua&#42;, ssl_client_hello_by_lua&#42;*

```lua

   ngx.STDERR
   ngx.EMERG
   ngx.ALERT
   ngx.CRIT
   ngx.ERR
   ngx.WARN
   ngx.NOTICE
   ngx.INFO
   ngx.DEBUG
```

These constants ar
Download .txt
gitextract_6e6awdd3/

├── .gitattributes
├── .github/
│   ├── ISSUE_TEMPLATE.md
│   ├── PULL_REQUEST_TEMPLATE.md
│   └── workflows/
│       ├── build_and_test.yml
│       └── semantic-pull-request.yml
├── .gitignore
├── .mergify.yml
├── README.markdown
├── config
├── doc/
│   └── HttpLuaModule.wiki
├── dtrace/
│   └── ngx_lua_provider.d
├── misc/
│   └── recv-until-pm/
│       ├── lib/
│       │   └── RecvUntil.pm
│       └── t/
│           └── sanity.t
├── src/
│   ├── api/
│   │   └── ngx_http_lua_api.h
│   ├── ddebug.h
│   ├── ngx_http_lua_accessby.c
│   ├── ngx_http_lua_accessby.h
│   ├── ngx_http_lua_api.c
│   ├── ngx_http_lua_args.c
│   ├── ngx_http_lua_args.h
│   ├── ngx_http_lua_balancer.c
│   ├── ngx_http_lua_balancer.h
│   ├── ngx_http_lua_bodyfilterby.c
│   ├── ngx_http_lua_bodyfilterby.h
│   ├── ngx_http_lua_cache.c
│   ├── ngx_http_lua_cache.h
│   ├── ngx_http_lua_capturefilter.c
│   ├── ngx_http_lua_capturefilter.h
│   ├── ngx_http_lua_clfactory.c
│   ├── ngx_http_lua_clfactory.h
│   ├── ngx_http_lua_common.h
│   ├── ngx_http_lua_config.c
│   ├── ngx_http_lua_config.h
│   ├── ngx_http_lua_consts.c
│   ├── ngx_http_lua_consts.h
│   ├── ngx_http_lua_contentby.c
│   ├── ngx_http_lua_contentby.h
│   ├── ngx_http_lua_control.c
│   ├── ngx_http_lua_control.h
│   ├── ngx_http_lua_coroutine.c
│   ├── ngx_http_lua_coroutine.h
│   ├── ngx_http_lua_ctx.c
│   ├── ngx_http_lua_ctx.h
│   ├── ngx_http_lua_directive.c
│   ├── ngx_http_lua_directive.h
│   ├── ngx_http_lua_exception.c
│   ├── ngx_http_lua_exception.h
│   ├── ngx_http_lua_exitworkerby.c
│   ├── ngx_http_lua_exitworkerby.h
│   ├── ngx_http_lua_headerfilterby.c
│   ├── ngx_http_lua_headerfilterby.h
│   ├── ngx_http_lua_headers.c
│   ├── ngx_http_lua_headers.h
│   ├── ngx_http_lua_headers_in.c
│   ├── ngx_http_lua_headers_in.h
│   ├── ngx_http_lua_headers_out.c
│   ├── ngx_http_lua_headers_out.h
│   ├── ngx_http_lua_initby.c
│   ├── ngx_http_lua_initby.h
│   ├── ngx_http_lua_initworkerby.c
│   ├── ngx_http_lua_initworkerby.h
│   ├── ngx_http_lua_input_filters.c
│   ├── ngx_http_lua_input_filters.h
│   ├── ngx_http_lua_lex.c
│   ├── ngx_http_lua_lex.h
│   ├── ngx_http_lua_log.c
│   ├── ngx_http_lua_log.h
│   ├── ngx_http_lua_log_ringbuf.c
│   ├── ngx_http_lua_log_ringbuf.h
│   ├── ngx_http_lua_logby.c
│   ├── ngx_http_lua_logby.h
│   ├── ngx_http_lua_misc.c
│   ├── ngx_http_lua_misc.h
│   ├── ngx_http_lua_module.c
│   ├── ngx_http_lua_ndk.c
│   ├── ngx_http_lua_ndk.h
│   ├── ngx_http_lua_output.c
│   ├── ngx_http_lua_output.h
│   ├── ngx_http_lua_pcrefix.c
│   ├── ngx_http_lua_pcrefix.h
│   ├── ngx_http_lua_phase.c
│   ├── ngx_http_lua_pipe.c
│   ├── ngx_http_lua_pipe.h
│   ├── ngx_http_lua_precontentby.c
│   ├── ngx_http_lua_precontentby.h
│   ├── ngx_http_lua_probe.h
│   ├── ngx_http_lua_proxy_ssl_certby.c
│   ├── ngx_http_lua_proxy_ssl_certby.h
│   ├── ngx_http_lua_proxy_ssl_verifyby.c
│   ├── ngx_http_lua_proxy_ssl_verifyby.h
│   ├── ngx_http_lua_regex.c
│   ├── ngx_http_lua_req_body.c
│   ├── ngx_http_lua_req_body.h
│   ├── ngx_http_lua_req_method.c
│   ├── ngx_http_lua_rewriteby.c
│   ├── ngx_http_lua_rewriteby.h
│   ├── ngx_http_lua_script.c
│   ├── ngx_http_lua_script.h
│   ├── ngx_http_lua_semaphore.c
│   ├── ngx_http_lua_semaphore.h
│   ├── ngx_http_lua_server_rewriteby.c
│   ├── ngx_http_lua_server_rewriteby.h
│   ├── ngx_http_lua_setby.c
│   ├── ngx_http_lua_setby.h
│   ├── ngx_http_lua_shdict.c
│   ├── ngx_http_lua_shdict.h
│   ├── ngx_http_lua_sleep.c
│   ├── ngx_http_lua_sleep.h
│   ├── ngx_http_lua_socket_tcp.c
│   ├── ngx_http_lua_socket_tcp.h
│   ├── ngx_http_lua_socket_udp.c
│   ├── ngx_http_lua_socket_udp.h
│   ├── ngx_http_lua_ssl.c
│   ├── ngx_http_lua_ssl.h
│   ├── ngx_http_lua_ssl_certby.c
│   ├── ngx_http_lua_ssl_certby.h
│   ├── ngx_http_lua_ssl_client_helloby.c
│   ├── ngx_http_lua_ssl_client_helloby.h
│   ├── ngx_http_lua_ssl_export_keying_material.c
│   ├── ngx_http_lua_ssl_export_keying_material.h
│   ├── ngx_http_lua_ssl_ocsp.c
│   ├── ngx_http_lua_ssl_session_fetchby.c
│   ├── ngx_http_lua_ssl_session_fetchby.h
│   ├── ngx_http_lua_ssl_session_storeby.c
│   ├── ngx_http_lua_ssl_session_storeby.h
│   ├── ngx_http_lua_string.c
│   ├── ngx_http_lua_string.h
│   ├── ngx_http_lua_subrequest.c
│   ├── ngx_http_lua_subrequest.h
│   ├── ngx_http_lua_time.c
│   ├── ngx_http_lua_timer.c
│   ├── ngx_http_lua_timer.h
│   ├── ngx_http_lua_uri.c
│   ├── ngx_http_lua_uri.h
│   ├── ngx_http_lua_uthread.c
│   ├── ngx_http_lua_uthread.h
│   ├── ngx_http_lua_util.c
│   ├── ngx_http_lua_util.h
│   ├── ngx_http_lua_variable.c
│   ├── ngx_http_lua_worker.c
│   ├── ngx_http_lua_worker_thread.c
│   └── ngx_http_lua_worker_thread.h
├── t/
│   ├── .gitignore
│   ├── 000--init.t
│   ├── 000-sanity.t
│   ├── 001-set.t
│   ├── 002-content.t
│   ├── 003-errors.t
│   ├── 004-require.t
│   ├── 005-exit.t
│   ├── 006-escape.t
│   ├── 007-md5.t
│   ├── 008-today.t
│   ├── 009-log.t
│   ├── 010-request_body.t
│   ├── 011-md5_bin.t
│   ├── 012-now.t
│   ├── 013-base64.t
│   ├── 014-bugs.t
│   ├── 015-status.t
│   ├── 016-resp-header.t
│   ├── 017-exec.t
│   ├── 018-ndk.t
│   ├── 019-const.t
│   ├── 020-subrequest.t
│   ├── 021-cookie-time.t
│   ├── 022-redirect.t
│   ├── 023-rewrite/
│   │   ├── client-abort.t
│   │   ├── exec.t
│   │   ├── exit.t
│   │   ├── mixed.t
│   │   ├── multi-capture.t
│   │   ├── on-abort.t
│   │   ├── redirect.t
│   │   ├── req-body.t
│   │   ├── req-socket.t
│   │   ├── request_body.t
│   │   ├── sanity.t
│   │   ├── sleep.t
│   │   ├── socket-keepalive.t
│   │   ├── subrequest.t
│   │   ├── tcp-socket-timeout.t
│   │   ├── tcp-socket.t
│   │   ├── unix-socket.t
│   │   ├── uthread-exec.t
│   │   ├── uthread-exit.t
│   │   ├── uthread-redirect.t
│   │   └── uthread-spawn.t
│   ├── 024-access/
│   │   ├── auth.t
│   │   ├── client-abort.t
│   │   ├── exec.t
│   │   ├── exit.t
│   │   ├── mixed.t
│   │   ├── multi-capture.t
│   │   ├── on-abort.t
│   │   ├── redirect.t
│   │   ├── req-body.t
│   │   ├── request_body.t
│   │   ├── sanity.t
│   │   ├── satisfy.t
│   │   ├── sleep.t
│   │   ├── subrequest.t
│   │   ├── uthread-exec.t
│   │   ├── uthread-exit.t
│   │   ├── uthread-redirect.t
│   │   └── uthread-spawn.t
│   ├── 025-codecache.t
│   ├── 026-mysql.t
│   ├── 027-multi-capture.t
│   ├── 028-req-header.t
│   ├── 029-http-time.t
│   ├── 030-uri-args-with-ctrl.t
│   ├── 030-uri-args.t
│   ├── 031-post-args.t
│   ├── 032-iolist.t
│   ├── 033-ctx.t
│   ├── 034-match.t
│   ├── 035-gmatch.t
│   ├── 036-sub.t
│   ├── 037-gsub.t
│   ├── 038-match-o.t
│   ├── 039-sub-o.t
│   ├── 040-gsub-o.t
│   ├── 041-header-filter.t
│   ├── 042-crc32.t
│   ├── 043-shdict.t
│   ├── 044-req-body.t
│   ├── 045-ngx-var.t
│   ├── 046-hmac.t
│   ├── 047-match-jit.t
│   ├── 048-match-dfa.t
│   ├── 049-gmatch-jit.t
│   ├── 050-gmatch-dfa.t
│   ├── 051-sub-jit.t
│   ├── 052-sub-dfa.t
│   ├── 053-gsub-jit.t
│   ├── 054-gsub-dfa.t
│   ├── 055-subreq-vars.t
│   ├── 056-flush.t
│   ├── 057-flush-timeout.t
│   ├── 058-tcp-socket.t
│   ├── 059-unix-socket.t
│   ├── 060-lua-memcached.t
│   ├── 061-lua-redis.t
│   ├── 062-count.t
│   ├── 063-abort.t
│   ├── 064-pcall.t
│   ├── 065-tcp-socket-timeout.t
│   ├── 066-socket-receiveuntil.t
│   ├── 067-req-socket.t
│   ├── 068-socket-keepalive.t
│   ├── 069-null.t
│   ├── 070-sha1.t
│   ├── 071-idle-socket.t
│   ├── 072-conditional-get.t
│   ├── 073-backtrace.t
│   ├── 074-prefix-var.t
│   ├── 075-logby.t
│   ├── 076-no-postpone.t
│   ├── 077-sleep.t
│   ├── 078-hup-vars.t
│   ├── 079-unused-directives.t
│   ├── 080-hup-shdict.t
│   ├── 081-bytecode.t
│   ├── 082-body-filter-2.t
│   ├── 082-body-filter.t
│   ├── 083-bad-sock-self.t
│   ├── 084-inclusive-receiveuntil.t
│   ├── 085-if.t
│   ├── 086-init-by.t
│   ├── 087-udp-socket.t
│   ├── 088-req-method.t
│   ├── 089-phase.t
│   ├── 090-log-socket-errors.t
│   ├── 091-coroutine.t
│   ├── 092-eof.t
│   ├── 093-uthread-spawn.t
│   ├── 094-uthread-exit.t
│   ├── 095-uthread-exec.t
│   ├── 096-uthread-redirect.t
│   ├── 097-uthread-rewrite.t
│   ├── 098-uthread-wait.t
│   ├── 099-c-api.t
│   ├── 100-client-abort.t
│   ├── 101-on-abort.t
│   ├── 102-req-start-time.t
│   ├── 103-req-http-ver.t
│   ├── 104-req-raw-header.t
│   ├── 105-pressure.t
│   ├── 106-timer.t
│   ├── 107-timer-errors.t
│   ├── 108-timer-safe.t
│   ├── 109-timer-hup.t
│   ├── 110-etag.t
│   ├── 111-req-header-ua.t
│   ├── 112-req-header-conn.t
│   ├── 113-req-header-cookie.t
│   ├── 114-config.t
│   ├── 115-quote-sql-str.t
│   ├── 116-raw-req-socket.t
│   ├── 117-raw-req-socket-timeout.t
│   ├── 118-use-default-type.t
│   ├── 119-config-prefix.t
│   ├── 120-re-find.t
│   ├── 121-version.t
│   ├── 122-worker-2.t
│   ├── 122-worker-3.t
│   ├── 122-worker.t
│   ├── 123-lua-path.t
│   ├── 124-init-worker.t
│   ├── 125-configure-args.t
│   ├── 126-shdict-frag.t
│   ├── 127-uthread-kill.t
│   ├── 128-duplex-tcp-socket.t
│   ├── 129-ssl-socket.t
│   ├── 130-internal-api.t
│   ├── 131-duplex-req-socket.t
│   ├── 132-lua-blocks.t
│   ├── 133-worker-count.t
│   ├── 134-worker-count-5.t
│   ├── 135-worker-id.t
│   ├── 136-timer-counts.t
│   ├── 137-req-misc.t
│   ├── 138-balancer-upstream-bind.t
│   ├── 138-balancer.t
│   ├── 139-ssl-cert-by.t
│   ├── 140-ssl-c-api.t
│   ├── 141-luajit.t
│   ├── 142-ssl-session-store.t
│   ├── 143-ssl-session-fetch.t
│   ├── 144-shdict-incr-init.t
│   ├── 145-shdict-list.t
│   ├── 146-malloc-trim.t
│   ├── 147-tcp-socket-timeouts.t
│   ├── 148-fake-shm-zone.t
│   ├── 149-hup-fake-shm-zone.t
│   ├── 150-fake-delayed-load.t
│   ├── 151-initby-hup.t
│   ├── 152-timer-every.t
│   ├── 153-semaphore-hup.t
│   ├── 154-semaphore.t
│   ├── 155-tls13.t
│   ├── 156-slow-network.t
│   ├── 157-socket-keepalive-hup.t
│   ├── 158-global-var.t
│   ├── 159-sa-restart.t
│   ├── 160-disable-init-by-lua.t
│   ├── 161-load-resty-core.t
│   ├── 162-exit-worker.t
│   ├── 162-socket-tls-handshake.t
│   ├── 162-static-module-location.t
│   ├── 163-exit-worker-hup.t
│   ├── 163-signal.t
│   ├── 164-say.t
│   ├── 165-thread-cache.t
│   ├── 166-ssl-client-hello.t
│   ├── 166-worker-thread.t
│   ├── 167-server-rewrite.t
│   ├── 168-tcp-socket-bind.t
│   ├── 169-proxy-ssl-verify.t
│   ├── 170-proxy-ssl-cert.t
│   ├── 170-ssl-session-reuse.t
│   ├── 185-ngx-buf-double-free.t
│   ├── 186-cosocket-busy-bufs.t
│   ├── 187-ssl-two-verification.t
│   ├── 188-balancer_keepalive_pool_max_retry.t
│   ├── 189-precontent.t
│   ├── 191-pipe-proc-quic-close-crash.t
│   ├── 302-tcp-socket-timeout-log.t
│   ├── 303-udp-socket-error-log.t
│   ├── StapThread.pm
│   ├── cert/
│   │   ├── dst-ca.crt
│   │   ├── equifax.crt
│   │   ├── gen-test-passphrase.sh
│   │   ├── gen-test-rsa1024.sh
│   │   ├── gen-test2.sh
│   │   ├── http3/
│   │   │   ├── http3.crt
│   │   │   └── http3.key
│   │   ├── mtls_ca.crt
│   │   ├── mtls_ca.key
│   │   ├── mtls_cert_gen/
│   │   │   ├── .gitignore
│   │   │   ├── generate.sh
│   │   │   ├── mtls_ca.json
│   │   │   ├── mtls_client.json
│   │   │   ├── mtls_server.json
│   │   │   └── profile.json
│   │   ├── mtls_client.crt
│   │   ├── mtls_client.key
│   │   ├── mtls_server.crt
│   │   ├── mtls_server.key
│   │   ├── test.crl
│   │   ├── test.crt
│   │   ├── test.key
│   │   ├── test2.crt
│   │   ├── test2.key
│   │   ├── test_der.crt
│   │   ├── test_der.key
│   │   ├── test_ecdsa.crt
│   │   ├── test_ecdsa.key
│   │   ├── test_passphrase.crt
│   │   └── test_passphrase.key
│   ├── data/
│   │   ├── fake-delayed-load-module/
│   │   │   ├── config
│   │   │   └── ngx_http_lua_fake_delayed_load_module.c
│   │   ├── fake-module/
│   │   │   ├── config
│   │   │   └── ngx_http_fake_module.c
│   │   └── fake-shm-module/
│   │       ├── config
│   │       └── ngx_http_lua_fake_shm_module.c
│   └── lib/
│       ├── CRC32.lua
│       ├── Memcached.lua
│       ├── Redis.lua
│       └── ljson.lua
├── tapset/
│   └── ngx_lua.stp
├── util/
│   ├── build-with-dd.sh
│   ├── build-without-ssl.sh
│   ├── build.sh
│   ├── fix-comments
│   ├── gen-lexer-c
│   ├── nc_server.py
│   ├── ngx-links
│   ├── retab
│   ├── revim
│   ├── run-ci.sh
│   ├── run_test.sh
│   ├── update-readme.sh
│   └── ver-ge
└── valgrind.suppress
Download .txt
SYMBOL INDEX (887 symbols across 85 files)

FILE: src/api/ngx_http_lua_api.h
  type ngx_http_lua_co_ctx_t (line 26) | typedef struct ngx_http_lua_co_ctx_s  ngx_http_lua_co_ctx_t;
  type ngx_http_lua_value_t (line 29) | typedef struct {
  type ngx_http_lua_ffi_str_t (line 41) | typedef struct {

FILE: src/ddebug.h
  function ngx_inline (line 31) | static ngx_inline void
  function ngx_inline (line 47) | static ngx_inline void

FILE: src/ngx_http_lua_accessby.c
  function ngx_int_t (line 25) | ngx_int_t
  function ngx_int_t (line 165) | ngx_int_t
  function ngx_int_t (line 196) | ngx_int_t
  function ngx_int_t (line 244) | static ngx_int_t

FILE: src/ngx_http_lua_api.c
  function lua_State (line 19) | lua_State *
  function ngx_http_request_t (line 30) | ngx_http_request_t *
  function ngx_int_t (line 41) | ngx_int_t
  function ngx_shm_zone_t (line 86) | ngx_shm_zone_t *
  function ngx_int_t (line 155) | static ngx_int_t
  function ngx_http_lua_co_ctx_t (line 217) | ngx_http_lua_co_ctx_t *
  function ngx_http_lua_set_cur_co_ctx (line 228) | void
  function lua_State (line 241) | lua_State *
  function ngx_http_lua_set_co_ctx_cleanup (line 255) | void
  function ngx_http_lua_cleanup_co_ctx_pending_operation (line 264) | void
  function ngx_int_t (line 271) | static ngx_int_t
  function ngx_http_lua_co_ctx_resume_helper (line 314) | void
  function ngx_http_lua_get_lua_http10_buffering (line 356) | int

FILE: src/ngx_http_lua_args.c
  function ngx_http_lua_escape_args (line 22) | uintptr_t
  function ngx_http_lua_ngx_req_set_uri_args (line 84) | static int
  function ngx_http_lua_ngx_req_get_post_args (line 170) | static int
  function ngx_http_lua_parse_args (line 264) | int
  function ngx_http_lua_inject_req_args_api (line 394) | void
  function ngx_http_lua_ffi_req_get_querystring_len (line 405) | size_t
  function ngx_http_lua_ffi_req_get_uri_args_count (line 412) | int
  function ngx_http_lua_ffi_req_get_uri_args (line 462) | int

FILE: src/ngx_http_lua_balancer.c
  type ngx_http_lua_balancer_ka_item_t (line 19) | typedef struct {
  type ngx_http_lua_balancer_peer_data_s (line 34) | struct ngx_http_lua_balancer_peer_data_s {
  type sockaddr (line 98) | struct sockaddr
  type sockaddr (line 101) | struct sockaddr
  function ngx_int_t (line 104) | ngx_int_t
  function ngx_int_t (line 125) | ngx_int_t
  function ngx_int_t (line 286) | static ngx_int_t
  function ngx_int_t (line 343) | static ngx_int_t
  function ngx_int_t (line 384) | static ngx_int_t
  function ngx_int_t (line 521) | static ngx_int_t
  function ngx_http_lua_balancer_free_peer (line 576) | static void
  function ngx_http_lua_balancer_notify_peer (line 743) | static void
  function ngx_http_lua_balancer_close (line 755) | static void
  function ngx_http_lua_balancer_dummy_handler (line 781) | static void
  function ngx_http_lua_balancer_close_handler (line 789) | static void
  function ngx_int_t (line 830) | static ngx_int_t
  function ngx_http_lua_balancer_save_session (line 844) | static void
  function ngx_http_lua_ffi_balancer_set_current_peer (line 860) | int
  function ngx_http_lua_ffi_balancer_bind_to_local_addr (line 954) | int
  function ngx_http_lua_ffi_balancer_enable_keepalive (line 1020) | int
  function ngx_http_lua_ffi_balancer_set_timeouts (line 1066) | int
  function ngx_http_lua_ffi_balancer_set_more_tries (line 1154) | int
  function ngx_http_lua_ffi_balancer_get_last_failure (line 1210) | int
  function ngx_http_lua_ffi_balancer_recreate_request (line 1256) | int
  function ngx_http_lua_ffi_balancer_set_upstream_tls (line 1302) | int
  function ngx_int_t (line 1380) | static ngx_int_t
  function ngx_uint_t (line 1431) | static ngx_uint_t
  function ngx_connection_t (line 1447) | static ngx_connection_t *

FILE: src/ngx_http_lua_bodyfilterby.c
  function ngx_http_lua_body_filter_by_lua_env (line 43) | static void
  function ngx_int_t (line 81) | ngx_int_t
  function ngx_int_t (line 147) | ngx_int_t
  function ngx_int_t (line 186) | ngx_int_t
  function ngx_int_t (line 238) | static ngx_int_t
  function ngx_int_t (line 396) | ngx_int_t
  function ngx_http_lua_ffi_get_body_filter_param_eof (line 407) | int
  function ngx_http_lua_ffi_get_body_filter_param_body (line 430) | int
  function ngx_http_lua_ffi_copy_body_filter_param_body (line 481) | int
  function ngx_http_lua_body_filter_param_set (line 508) | int

FILE: src/ngx_http_lua_cache.c
  function ngx_int_t (line 38) | static ngx_int_t
  function ngx_int_t (line 148) | static ngx_int_t
  function ngx_int_t (line 200) | ngx_int_t
  function ngx_int_t (line 261) | ngx_int_t
  function u_char (line 351) | u_char *
  function u_char (line 375) | static u_char *
  function u_char (line 395) | u_char *

FILE: src/ngx_http_lua_capturefilter.c
  function ngx_int_t (line 30) | ngx_int_t
  function ngx_int_t (line 44) | static ngx_int_t
  function ngx_int_t (line 113) | static ngx_int_t

FILE: src/ngx_http_lua_clfactory.c
  type ngx_http_lua_clfactory_file_type_e (line 288) | typedef enum {
  type ngx_http_lua_clfactory_file_ctx_t (line 300) | typedef struct {
  type ngx_http_lua_clfactory_buffer_ctx_t (line 324) | typedef struct {
  function ngx_http_lua_clfactory_bytecode_prepare (line 346) | int
  function ngx_int_t (line 614) | ngx_int_t
  function ngx_int_t (line 745) | ngx_int_t
  function ngx_http_lua_clfactory_errfile (line 844) | static int
  function ngx_http_lua_clfactory_file_size (line 900) | static long

FILE: src/ngx_http_lua_common.h
  type ngx_http_lua_set_var_data_t (line 52) | typedef struct {
  type ngx_http_lua_co_ctx_t (line 190) | typedef struct ngx_http_lua_co_ctx_s  ngx_http_lua_co_ctx_t;
  type ngx_http_lua_sema_mm_t (line 192) | typedef struct ngx_http_lua_sema_mm_s  ngx_http_lua_sema_mm_t;
  type ngx_http_lua_srv_conf_t (line 194) | typedef struct ngx_http_lua_srv_conf_s  ngx_http_lua_srv_conf_t;
  type ngx_http_lua_main_conf_t (line 196) | typedef struct ngx_http_lua_main_conf_s  ngx_http_lua_main_conf_t;
  type ngx_http_lua_loc_conf_t (line 198) | typedef struct ngx_http_lua_loc_conf_s  ngx_http_lua_loc_conf_t;
  type ngx_http_lua_header_val_t (line 200) | typedef struct ngx_http_lua_header_val_s  ngx_http_lua_header_val_t;
  type ngx_http_lua_posted_thread_t (line 202) | typedef struct ngx_http_lua_posted_thread_s  ngx_http_lua_posted_thread_t;
  type ngx_http_lua_balancer_peer_data_t (line 204) | typedef struct ngx_http_lua_balancer_peer_data_s
  type ngx_int_t (line 207) | typedef ngx_int_t (*ngx_http_lua_main_conf_handler_pt)(ngx_log_t *log,
  type ngx_int_t (line 210) | typedef ngx_int_t (*ngx_http_lua_srv_conf_handler_pt)(ngx_http_request_t...
  type ngx_int_t (line 213) | typedef ngx_int_t (*ngx_http_lua_loc_conf_handler_pt)(ngx_http_request_t...
  type ngx_int_t (line 216) | typedef ngx_int_t (*ngx_http_lua_set_header_pt)(ngx_http_request_t *r,
  type ngx_http_lua_preload_hook_t (line 220) | typedef struct {
  type ngx_http_lua_thread_ref_t (line 226) | typedef struct {
  type ngx_http_lua_main_conf_s (line 233) | struct ngx_http_lua_main_conf_s {
  type ngx_http_lua_srv_conf_s (line 350) | struct ngx_http_lua_srv_conf_s {
  type ngx_http_lua_loc_conf_s (line 403) | struct ngx_http_lua_loc_conf_s {
  type ngx_http_lua_user_coro_op_t (line 527) | typedef enum {
  type ngx_http_lua_co_status_t (line 535) | typedef enum {
  type ngx_http_lua_posted_thread_s (line 544) | struct ngx_http_lua_posted_thread_s {
  type ngx_http_lua_co_ctx_s (line 550) | struct ngx_http_lua_co_ctx_s {
  type ngx_http_lua_vm_state_t (line 622) | typedef struct {
  type ngx_http_lua_ctx_t (line 628) | typedef struct ngx_http_lua_ctx_s {
  type ngx_http_lua_header_val_s (line 749) | struct ngx_http_lua_header_val_s {
  type ngx_http_lua_set_header_t (line 759) | typedef struct {

FILE: src/ngx_http_lua_config.c
  function ngx_http_lua_inject_config_api (line 21) | void
  function ngx_http_lua_config_prefix (line 54) | static int
  function ngx_http_lua_config_configure (line 63) | static int

FILE: src/ngx_http_lua_consts.c
  function ngx_http_lua_inject_core_consts (line 17) | void
  function ngx_http_lua_inject_http_consts (line 42) | void

FILE: src/ngx_http_lua_contentby.c
  function ngx_int_t (line 24) | ngx_int_t
  function ngx_http_lua_content_wev_handler (line 142) | void
  function ngx_int_t (line 156) | ngx_int_t
  function ngx_http_lua_content_phase_post_read (line 227) | static void
  function ngx_int_t (line 246) | ngx_int_t
  function ngx_int_t (line 293) | ngx_int_t
  function ngx_int_t (line 324) | ngx_int_t

FILE: src/ngx_http_lua_control.c
  function ngx_http_lua_inject_control_api (line 24) | void
  function ngx_http_lua_ngx_exec (line 44) | static int
  function ngx_http_lua_ngx_redirect (line 183) | static int
  function ngx_http_lua_on_abort (line 312) | static int
  function ngx_http_lua_ffi_exit (line 362) | int

FILE: src/ngx_http_lua_coroutine.c
  function ngx_http_lua_coroutine_create (line 46) | static int
  function ngx_http_lua_coroutine_wrap_runner (line 66) | static int
  function ngx_http_lua_coroutine_wrap (line 78) | static int
  function ngx_http_lua_coroutine_create_helper (line 105) | int
  function ngx_http_lua_coroutine_resume (line 182) | static int
  function ngx_http_lua_coroutine_yield (line 244) | static int
  function ngx_http_lua_inject_coroutine_api (line 285) | void
  function ngx_http_lua_coroutine_status (line 396) | static int

FILE: src/ngx_http_lua_ctx.c
  type ngx_http_lua_ngx_ctx_cleanup_data_t (line 18) | typedef struct {
  function ngx_http_lua_ngx_set_ctx_helper (line 29) | int
  function ngx_http_lua_ffi_get_ctx_ref (line 72) | int
  function ngx_http_lua_ffi_set_ctx_ref (line 110) | int
  function ngx_int_t (line 158) | static ngx_int_t
  function ngx_http_lua_ngx_ctx_cleanup (line 187) | static void

FILE: src/ngx_http_lua_directive.c
  type ngx_http_lua_block_parser_ctx_t (line 43) | typedef struct ngx_http_lua_block_parser_ctx_s
  type ngx_http_lua_block_parser_ctx_s (line 60) | struct ngx_http_lua_block_parser_ctx_s {
  function ngx_int_t (line 404) | ngx_int_t
  function ngx_int_t (line 440) | ngx_int_t
  function ngx_int_t (line 1536) | static ngx_int_t
  function u_char (line 1572) | u_char *
  function ngx_int_t (line 1821) | static ngx_int_t
  function u_char (line 2147) | static u_char *

FILE: src/ngx_http_lua_exception.c
  function ngx_http_lua_atpanic (line 30) | int

FILE: src/ngx_http_lua_exitworkerby.c
  function ngx_http_lua_exit_worker (line 21) | void
  function ngx_int_t (line 93) | ngx_int_t
  function ngx_int_t (line 115) | ngx_int_t

FILE: src/ngx_http_lua_headerfilterby.c
  function ngx_http_lua_header_filter_by_lua_env (line 39) | static void
  function ngx_int_t (line 72) | ngx_int_t
  function ngx_int_t (line 157) | ngx_int_t
  function ngx_int_t (line 190) | ngx_int_t
  function ngx_int_t (line 236) | static ngx_int_t
  function ngx_int_t (line 301) | ngx_int_t

FILE: src/ngx_http_lua_headers.c
  function ngx_http_lua_inject_resp_header_api (line 30) | void
  function ngx_http_lua_inject_req_header_api (line 42) | void
  function ngx_http_lua_ngx_req_http_version (line 56) | static int
  function ngx_http_lua_ngx_resp_get_headers (line 423) | static int
  function ngx_http_lua_ngx_req_header_set (line 616) | static int
  function ngx_http_lua_ngx_req_header_set_helper (line 628) | static int
  function ngx_http_lua_create_headers_metatable (line 748) | void
  function ngx_http_lua_ffi_req_get_headers_count (line 779) | int
  function ngx_http_lua_ffi_req_get_headers (line 864) | int
  function ngx_http_lua_ffi_set_resp_header (line 939) | int
  function ngx_http_lua_ffi_req_set_header (line 1059) | int
  function ngx_http_lua_ffi_get_resp_header (line 1148) | int
  function ngx_http_lua_ngx_raw_header_cleanup (line 1307) | void
  function ngx_http_lua_ffi_set_resp_header_macos (line 1323) | int

FILE: src/ngx_http_lua_headers_in.c
  function ngx_int_t (line 171) | static ngx_int_t
  function ngx_int_t (line 179) | static ngx_int_t
  function ngx_int_t (line 302) | static ngx_int_t
  function ngx_int_t (line 343) | static ngx_int_t
  function ngx_int_t (line 435) | static ngx_int_t
  function ngx_int_t (line 468) | static ngx_int_t
  function ngx_int_t (line 491) | static ngx_int_t
  function ngx_int_t (line 565) | static ngx_int_t
  function ngx_int_t (line 588) | static ngx_int_t
  function ngx_int_t (line 683) | static ngx_int_t
  function ngx_int_t (line 693) | static ngx_int_t
  function ngx_int_t (line 702) | ngx_int_t
  function ngx_int_t (line 775) | static ngx_int_t

FILE: src/ngx_http_lua_headers_out.c
  function ngx_int_t (line 121) | static ngx_int_t
  function ngx_int_t (line 129) | static ngx_int_t
  function ngx_int_t (line 251) | static ngx_int_t
  function ngx_int_t (line 277) | static ngx_int_t
  function ngx_int_t (line 313) | static ngx_int_t
  function ngx_int_t (line 457) | static ngx_int_t
  function ngx_int_t (line 484) | static ngx_int_t ngx_http_set_last_modified_header(ngx_http_request_t *r,
  function ngx_int_t (line 500) | static ngx_int_t
  function ngx_int_t (line 510) | static ngx_int_t
  function ngx_int_t (line 531) | static ngx_int_t
  function ngx_int_t (line 541) | static ngx_int_t
  function ngx_int_t (line 551) | ngx_int_t
  function ngx_http_lua_get_output_header (line 593) | int
  function ngx_int_t (line 702) | ngx_int_t

FILE: src/ngx_http_lua_headers_out.h
  type ngx_http_lua_set_resp_header_params_t (line 16) | typedef struct {

FILE: src/ngx_http_lua_initby.c
  function ngx_int_t (line 16) | ngx_int_t
  function ngx_int_t (line 39) | ngx_int_t

FILE: src/ngx_http_lua_initworkerby.c
  function ngx_int_t (line 22) | ngx_int_t
  function ngx_int_t (line 332) | ngx_int_t
  function ngx_int_t (line 354) | ngx_int_t
  function u_char (line 367) | static u_char *

FILE: src/ngx_http_lua_input_filters.c
  function ngx_int_t (line 16) | ngx_int_t
  function ngx_int_t (line 43) | ngx_int_t
  function ngx_int_t (line 58) | ngx_int_t
  function ngx_int_t (line 77) | ngx_int_t

FILE: src/ngx_http_lua_lex.c
  function ngx_http_lua_lex (line 42) | int

FILE: src/ngx_http_lua_log.c
  function ngx_http_lua_ngx_log (line 34) | int
  function ngx_http_lua_print (line 71) | int
  function log_wrapper (line 90) | static int
  function ngx_http_lua_inject_log_api (line 279) | void
  function ngx_http_lua_inject_log_consts (line 292) | static void
  function ngx_int_t (line 327) | ngx_int_t
  function ngx_http_lua_ffi_errlog_set_filter_level (line 351) | int
  function ngx_http_lua_ffi_errlog_get_msg (line 383) | int
  function ngx_http_lua_ffi_errlog_get_sys_filter_level (line 417) | int
  function ngx_http_lua_ffi_raw_log (line 439) | int

FILE: src/ngx_http_lua_log_ringbuf.c
  type ngx_http_lua_log_ringbuf_header_t (line 12) | typedef struct {
  function ngx_http_lua_log_ringbuf_init (line 32) | void
  function ngx_http_lua_log_ringbuf_reset (line 49) | void
  function ngx_http_lua_log_ringbuf_append (line 84) | static void
  function ngx_http_lua_log_ringbuf_throw_away (line 112) | static void
  function ngx_http_lua_log_ringbuf_free_spaces (line 137) | static size_t
  function ngx_int_t (line 156) | ngx_int_t
  function ngx_int_t (line 190) | ngx_int_t

FILE: src/ngx_http_lua_log_ringbuf.h
  type ngx_http_lua_log_ringbuf_t (line 9) | typedef struct {

FILE: src/ngx_http_lua_logby.c
  function ngx_http_lua_log_by_lua_env (line 33) | static void
  function ngx_int_t (line 66) | ngx_int_t
  function ngx_int_t (line 139) | ngx_int_t
  function ngx_int_t (line 171) | ngx_int_t
  function ngx_int_t (line 211) | ngx_int_t

FILE: src/ngx_http_lua_misc.c
  function ngx_http_lua_inject_req_misc_api (line 21) | void
  function ngx_http_lua_ngx_req_is_internal (line 29) | static int
  function ngx_http_lua_ffi_get_resp_status (line 44) | int
  function ngx_http_lua_ffi_set_resp_status_and_reason (line 66) | int
  function ngx_http_lua_ffi_set_resp_status (line 125) | int
  function ngx_http_lua_ffi_req_is_internal (line 132) | int
  function ngx_http_lua_ffi_is_subrequest (line 143) | int
  function ngx_http_lua_ffi_headers_sent (line 154) | int
  function ngx_http_lua_ffi_get_conf_env (line 172) | int

FILE: src/ngx_http_lua_module.c
  function ngx_int_t (line 839) | static ngx_int_t
  function ngx_int_t (line 1771) | static ngx_int_t
  function ngx_int_t (line 1821) | static ngx_int_t
  function key_log_callback (line 1913) | static void
  function ngx_http_lua_ssl_cleanup_key_log (line 1933) | static void
  function ngx_int_t (line 1945) | static ngx_int_t

FILE: src/ngx_http_lua_ndk.c
  function ngx_http_lua_inject_ndk_api (line 24) | void
  function ndk_set_var_value_pt (line 39) | static ndk_set_var_value_pt
  function ngx_http_lua_ffi_ndk_lookup_directive (line 90) | int
  function ngx_http_lua_ffi_ndk_set_var_get (line 104) | int

FILE: src/ngx_http_lua_output.c
  function ngx_http_lua_ngx_print (line 22) | static int
  function ngx_http_lua_ngx_say (line 30) | static int
  function ngx_http_lua_ngx_echo (line 38) | static int
  function ngx_http_lua_calc_strlen_in_table (line 262) | size_t
  function u_char (line 383) | u_char *
  function ngx_http_lua_ngx_flush (line 472) | static int
  function ngx_http_lua_ngx_eof (line 626) | static int
  function ngx_http_lua_inject_output_api (line 683) | void
  function ngx_http_lua_ngx_send_headers (line 706) | static int
  function ngx_int_t (line 744) | ngx_int_t
  function ngx_http_lua_flush_cleanup (line 802) | static void

FILE: src/ngx_http_lua_output.h
  function ngx_inline (line 27) | static ngx_inline size_t
  function ngx_inline (line 41) | static ngx_inline u_char *

FILE: src/ngx_http_lua_pcrefix.c
  function ngx_http_lua_pcre_free (line 55) | void
  function ngx_http_lua_pcre_free (line 90) | static void
  function ngx_pool_t (line 108) | ngx_pool_t *
  function ngx_http_lua_pcre_malloc_done (line 126) | void
  function ngx_pool_t (line 139) | ngx_pool_t *
  function ngx_http_lua_pcre_malloc_done (line 170) | void

FILE: src/ngx_http_lua_phase.c
  function ngx_http_lua_ffi_get_phase (line 16) | int

FILE: src/ngx_http_lua_pipe.c
  type signalfd_siginfo (line 94) | struct signalfd_siginfo
  function ngx_http_lua_pipe_init (line 148) | void
  function ngx_int_t (line 156) | ngx_int_t
  function ngx_rbtree_node_t (line 297) | static ngx_rbtree_node_t *
  function ngx_http_lua_pipe_sigchld_handler (line 324) | static void
  function ngx_http_lua_pipe_sigchld_event_handler (line 364) | static void
  function ngx_http_lua_pipe_reap_pids (line 395) | static void
  function ngx_http_lua_pipe_reap_timer_handler (line 471) | static void
  function ngx_http_lua_pipe_fd_read (line 483) | static ssize_t
  function ngx_http_lua_pipe_fd_write (line 538) | static ssize_t
  function ngx_http_lua_execvpe (line 586) | static int
  function ngx_http_lua_ffi_pipe_spawn (line 601) | int
  function ngx_http_lua_pipe_close_helper (line 990) | static void
  function ngx_http_lua_pipe_close_stdin (line 1015) | static void
  function ngx_http_lua_pipe_close_stdout (line 1037) | static void
  function ngx_http_lua_pipe_close_stderr (line 1059) | static void
  function ngx_http_lua_ffi_pipe_proc_shutdown_stdin (line 1081) | int
  function ngx_http_lua_ffi_pipe_proc_shutdown_stdout (line 1099) | int
  function ngx_http_lua_ffi_pipe_proc_shutdown_stderr (line 1117) | int
  function ngx_http_lua_pipe_proc_finalize (line 1142) | static void
  function ngx_http_lua_ffi_pipe_proc_destroy (line 1170) | void
  function ngx_int_t (line 1242) | static ngx_int_t
  function ngx_http_lua_pipe_put_error (line 1263) | static void
  function ngx_http_lua_pipe_put_data (line 1313) | static void
  function ngx_int_t (line 1375) | static ngx_int_t
  function ngx_int_t (line 1398) | static ngx_int_t
  function ngx_int_t (line 1409) | static ngx_int_t
  function ngx_int_t (line 1429) | static ngx_int_t
  function ngx_int_t (line 1448) | static ngx_int_t
  function ngx_int_t (line 1466) | static ngx_int_t
  function ngx_int_t (line 1555) | static ngx_int_t
  function ngx_http_lua_ffi_pipe_proc_read (line 1601) | int
  function ngx_http_lua_ffi_pipe_get_read_result (line 1790) | int
  function ngx_int_t (line 1822) | static ngx_int_t
  function ngx_http_lua_ffi_pipe_proc_write (line 1889) | ssize_t
  function ngx_http_lua_ffi_pipe_get_write_result (line 2006) | ssize_t
  function ngx_http_lua_ffi_pipe_proc_wait (line 2029) | int
  function ngx_http_lua_ffi_pipe_proc_kill (line 2115) | int
  function ngx_http_lua_pipe_read_stdout_retval (line 2156) | static int
  function ngx_http_lua_pipe_read_stderr_retval (line 2164) | static int
  function ngx_http_lua_pipe_read_retval_helper (line 2172) | static int
  function ngx_http_lua_pipe_write_retval (line 2234) | static int
  function ngx_http_lua_pipe_wait_retval (line 2284) | static int
  function ngx_http_lua_pipe_resume_helper (line 2337) | static void
  function ngx_http_lua_pipe_resume_read_stdout_handler (line 2376) | static void
  function ngx_http_lua_pipe_resume_read_stderr_handler (line 2392) | static void
  function ngx_http_lua_pipe_resume_write_handler (line 2408) | static void
  function ngx_http_lua_pipe_resume_wait_handler (line 2424) | static void
  function ngx_int_t (line 2438) | static ngx_int_t
  function ngx_http_lua_pipe_dummy_event_handler (line 2494) | static void
  function ngx_http_lua_pipe_clear_event (line 2501) | static void
  function ngx_http_lua_pipe_proc_read_stdout_cleanup (line 2520) | static void
  function ngx_http_lua_pipe_proc_read_stderr_cleanup (line 2549) | static void
  function ngx_http_lua_pipe_proc_write_cleanup (line 2576) | static void
  function ngx_http_lua_pipe_proc_wait_cleanup (line 2603) | static void

FILE: src/ngx_http_lua_pipe.h
  type ngx_int_t (line 14) | typedef ngx_int_t (*ngx_http_lua_pipe_input_filter)(void *data, ssize_t ...
  type ngx_http_lua_pipe_ctx_t (line 17) | typedef struct {
  type ngx_http_lua_pipe_t (line 31) | typedef struct ngx_http_lua_pipe_s  ngx_http_lua_pipe_t;
  type ngx_http_lua_ffi_pipe_proc_t (line 34) | typedef struct {
  type ngx_http_lua_pipe_s (line 49) | struct ngx_http_lua_pipe_s {
  type ngx_http_lua_pipe_node_t (line 70) | typedef struct {
  type ngx_http_lua_pipe_signal_t (line 79) | typedef struct {

FILE: src/ngx_http_lua_precontentby.c
  function ngx_int_t (line 25) | ngx_int_t
  function ngx_int_t (line 157) | ngx_int_t
  function ngx_int_t (line 189) | ngx_int_t
  function ngx_int_t (line 239) | static ngx_int_t

FILE: src/ngx_http_lua_proxy_ssl_certby.c
  function ngx_int_t (line 30) | ngx_int_t
  function ngx_int_t (line 60) | ngx_int_t
  function ngx_int_t (line 81) | ngx_int_t
  function ngx_http_lua_proxy_ssl_cert_handler (line 198) | int
  function ngx_http_lua_proxy_ssl_cert_done (line 330) | static void
  function ngx_http_lua_proxy_ssl_cert_aborted (line 366) | static void
  function ngx_int_t (line 391) | static ngx_int_t
  function ngx_http_lua_ffi_proxy_ssl_get_tls1_version (line 493) | int
  function ngx_http_lua_ffi_proxy_ssl_clear_certs (line 524) | int
  function ngx_http_lua_ffi_proxy_ssl_set_der_certificate (line 554) | int
  function ngx_http_lua_ffi_proxy_ssl_set_der_private_key (line 639) | int
  function ngx_http_lua_ffi_proxy_ssl_set_cert (line 705) | int
  function ngx_http_lua_ffi_proxy_ssl_set_priv_key (line 783) | int

FILE: src/ngx_http_lua_proxy_ssl_verifyby.c
  function ngx_int_t (line 29) | ngx_int_t
  function ngx_int_t (line 59) | ngx_int_t
  function ngx_int_t (line 80) | ngx_int_t
  function ngx_http_lua_proxy_ssl_verify_handler (line 196) | int
  function ngx_http_lua_proxy_ssl_verify_done (line 342) | static void
  function ngx_http_lua_proxy_ssl_verify_aborted (line 378) | static void
  function ngx_int_t (line 403) | static ngx_int_t
  function ngx_http_lua_ffi_proxy_ssl_set_verify_result (line 511) | int
  function ngx_http_lua_ffi_proxy_ssl_get_verify_result (line 557) | int
  function ngx_http_lua_ffi_proxy_ssl_free_verify_cert (line 600) | void

FILE: src/ngx_http_lua_regex.c
  type ngx_http_lua_regex_t (line 46) | typedef struct {
  type ngx_http_lua_regex_compile_t (line 74) | typedef struct {
  type ngx_http_lua_regex_ctx_t (line 89) | typedef struct {
  function ngx_http_lua_regex_free_study_data (line 118) | static void
  function ngx_int_t (line 150) | static ngx_int_t
  function ngx_int_t (line 269) | static ngx_int_t
  function ngx_int_t (line 324) | ngx_int_t
  function ngx_http_lua_regex_jit_compile (line 391) | static void
  function ngx_http_lua_regex_jit_compile (line 431) | static void
  function ngx_http_lua_regex_cleanup (line 494) | void
  function ngx_http_lua_regex_t (line 535) | ngx_http_lua_regex_t *
  function ngx_http_lua_ffi_exec_regex (line 690) | int
  function ngx_http_lua_ffi_exec_regex (line 786) | int
  function ngx_http_lua_ffi_destroy_regex (line 842) | void
  function ngx_http_lua_ffi_compile_replace_template (line 857) | int
  function ngx_http_lua_script_engine_t (line 901) | ngx_http_lua_script_engine_t *
  function ngx_http_lua_ffi_init_script_engine (line 908) | void
  function ngx_http_lua_ffi_destroy_script_engine (line 919) | void
  function ngx_http_lua_ffi_script_eval_len (line 926) | size_t
  function ngx_http_lua_ffi_script_eval_data (line 946) | void
  function ngx_http_lua_ffi_max_regex_cache_size (line 962) | uint32_t

FILE: src/ngx_http_lua_req_body.c
  function ngx_http_lua_inject_req_body_api (line 36) | void
  function ngx_http_lua_ngx_req_read_body (line 68) | static int
  function ngx_http_lua_req_body_post_read (line 157) | static void
  function ngx_http_lua_ngx_req_discard_body (line 198) | static int
  function ngx_http_lua_ngx_req_get_body_data (line 228) | static int
  function ngx_http_lua_ngx_req_get_body_file (line 319) | static int
  function ngx_http_lua_ngx_req_set_body_data (line 358) | static int
  function ngx_http_lua_ngx_req_init_body (line 531) | static int
  function ngx_http_lua_ngx_req_append_body (line 629) | static int
  function ngx_http_lua_ngx_req_body_finish (line 712) | static int
  function ngx_http_lua_pool_cleanup_file (line 807) | static void
  function ngx_http_lua_ngx_req_set_body_file (line 829) | static int
  function ngx_int_t (line 1079) | static ngx_int_t
  function ngx_int_t (line 1140) | static ngx_int_t
  function ngx_http_lua_req_body_cleanup (line 1180) | static void

FILE: src/ngx_http_lua_req_method.c
  function ngx_http_lua_ffi_req_get_method (line 16) | int
  function ngx_http_lua_ffi_req_get_method_name (line 27) | int
  function ngx_http_lua_ffi_req_set_method (line 42) | int

FILE: src/ngx_http_lua_rewriteby.c
  function ngx_int_t (line 24) | ngx_int_t
  function ngx_int_t (line 168) | ngx_int_t
  function ngx_int_t (line 200) | ngx_int_t
  function ngx_int_t (line 244) | static ngx_int_t

FILE: src/ngx_http_lua_script.c
  function ngx_int_t (line 34) | ngx_int_t
  function ngx_int_t (line 105) | ngx_int_t
  function ngx_int_t (line 161) | static ngx_int_t
  function ngx_int_t (line 317) | static ngx_int_t
  function ngx_http_lua_script_copy_len_code (line 354) | static size_t
  function ngx_http_lua_script_copy_code (line 367) | static void
  function ngx_int_t (line 390) | static ngx_int_t
  function ngx_http_lua_script_copy_capture_len_code (line 419) | static size_t
  function ngx_http_lua_script_copy_capture_code (line 441) | static void
  function ngx_int_t (line 470) | static ngx_int_t
  function ngx_int_t (line 505) | static ngx_int_t

FILE: src/ngx_http_lua_script.h
  type ngx_http_lua_script_compile_t (line 14) | typedef struct {
  type ngx_http_lua_complex_value_t (line 29) | typedef struct {
  type ngx_http_lua_compile_complex_value_t (line 36) | typedef struct {
  type ngx_http_lua_script_engine_t (line 44) | typedef struct {
  type ngx_http_lua_script_copy_code_t (line 65) | typedef struct {
  type ngx_http_lua_script_capture_code_t (line 71) | typedef struct {

FILE: src/ngx_http_lua_semaphore.c
  function ngx_int_t (line 44) | ngx_int_t
  function ngx_http_lua_sema_t (line 71) | static ngx_http_lua_sema_t *
  function ngx_http_lua_sema_mm_cleanup (line 155) | void
  function ngx_http_lua_free_sema (line 202) | static void
  function ngx_int_t (line 256) | static ngx_int_t
  function ngx_http_lua_ffi_sema_new (line 310) | int
  function ngx_http_lua_ffi_sema_post (line 336) | int
  function ngx_http_lua_ffi_sema_wait (line 357) | int
  function ngx_http_lua_ffi_sema_count (line 426) | int
  function ngx_http_lua_sema_cleanup (line 433) | static void
  function ngx_http_lua_sema_handler (line 457) | static void
  function ngx_http_lua_sema_timeout_handler (line 511) | static void
  function ngx_http_lua_ffi_sema_gc (line 552) | void

FILE: src/ngx_http_lua_semaphore.h
  type ngx_http_lua_sema_mm_block_t (line 17) | typedef struct ngx_http_lua_sema_mm_block_s {
  type ngx_http_lua_sema_mm_s (line 24) | struct ngx_http_lua_sema_mm_s {
  type ngx_http_lua_sema_t (line 34) | typedef struct ngx_http_lua_sema_s {

FILE: src/ngx_http_lua_server_rewriteby.c
  function ngx_int_t (line 22) | ngx_int_t
  function ngx_int_t (line 131) | ngx_int_t
  function ngx_int_t (line 156) | ngx_int_t
  function ngx_int_t (line 194) | static ngx_int_t

FILE: src/ngx_http_lua_setby.c
  function ngx_int_t (line 30) | ngx_int_t
  function ngx_http_lua_ffi_get_setby_param (line 126) | void
  function ngx_http_lua_set_by_lua_env (line 166) | static void

FILE: src/ngx_http_lua_shdict.c
  function ngx_inline (line 61) | static ngx_inline ngx_queue_t *
  function ngx_int_t (line 69) | ngx_int_t
  function ngx_http_lua_shdict_rbtree_insert_value (line 124) | void
  function ngx_int_t (line 165) | static ngx_int_t
  function ngx_http_lua_shdict_expire (line 234) | static int
  function ngx_http_lua_inject_shdict_api (line 308) | void
  function ngx_inline (line 375) | static ngx_inline ngx_shm_zone_t *
  function ngx_http_lua_shdict_flush_expired (line 394) | static int
  function ngx_http_lua_shdict_get_keys (line 491) | static int
  function ngx_int_t (line 585) | ngx_int_t
  function ngx_http_lua_shdict_lpush (line 688) | static int
  function ngx_http_lua_shdict_rpush (line 695) | static int
  function ngx_http_lua_shdict_push_helper (line 702) | static int
  function ngx_http_lua_shdict_lpop (line 979) | static int
  function ngx_http_lua_shdict_rpop (line 986) | static int
  function ngx_http_lua_shdict_pop_helper (line 993) | static int
  function ngx_http_lua_shdict_llen (line 1169) | static int
  function ngx_shm_zone_t (line 1256) | ngx_shm_zone_t *
  function ngx_shm_zone_t (line 1297) | ngx_shm_zone_t *
  function ngx_http_lua_ffi_shdict_store (line 1308) | int
  function ngx_http_lua_ffi_shdict_get (line 1567) | int
  function ngx_http_lua_ffi_shdict_incr (line 1706) | int
  function ngx_http_lua_ffi_shdict_flush_all (line 1911) | int
  function ngx_int_t (line 1938) | static ngx_int_t
  function ngx_http_lua_ffi_shdict_get_ttl (line 1985) | long
  function ngx_http_lua_ffi_shdict_set_expire (line 2027) | int
  function ngx_http_lua_ffi_shdict_capacity (line 2070) | size_t
  function ngx_http_lua_ffi_shdict_free_space (line 2078) | size_t
  function ngx_http_lua_ffi_shdict_get_macos (line 2096) | int
  function ngx_http_lua_ffi_shdict_store_macos (line 2108) | int
  function ngx_http_lua_ffi_shdict_incr_macos (line 2121) | int

FILE: src/ngx_http_lua_shdict.h
  type ngx_http_lua_shdict_node_t (line 14) | typedef struct {
  type ngx_http_lua_shdict_list_node_t (line 26) | typedef struct {
  type ngx_http_lua_shdict_shctx_t (line 34) | typedef struct {
  type ngx_http_lua_shdict_ctx_t (line 41) | typedef struct {
  type ngx_http_lua_shm_zone_ctx_t (line 50) | typedef struct {
  type ngx_http_lua_shdict_get_params_t (line 59) | typedef struct {
  type ngx_http_lua_shdict_store_params_t (line 74) | typedef struct {
  type ngx_http_lua_shdict_incr_params_t (line 90) | typedef struct {

FILE: src/ngx_http_lua_sleep.c
  function ngx_http_lua_ngx_sleep (line 25) | static int
  function ngx_http_lua_sleep_handler (line 97) | void
  function ngx_http_lua_inject_sleep_api (line 141) | void
  function ngx_int_t (line 181) | static ngx_int_t

FILE: src/ngx_http_lua_socket_tcp.c
  function ngx_http_lua_inject_socket_tcp_api (line 238) | void
  function ngx_http_lua_inject_req_socket_api (line 423) | void
  function u_char (line 431) | static u_char *
  function ngx_http_lua_socket_tcp (line 471) | static int
  function ngx_http_lua_socket_tcp_create_socket_pool (line 506) | static void
  function ngx_http_lua_socket_tcp_connect_helper (line 585) | static int
  function ngx_http_lua_socket_tcp_bind (line 914) | static int
  function ngx_http_lua_socket_tcp_connect (line 989) | static int
  function ngx_http_lua_socket_resolve_handler (line 1313) | static void
  function ngx_http_lua_socket_init_peer_connection_addr_text (line 1476) | static void
  function ngx_http_lua_socket_resolve_retval_handler (line 1520) | static int
  function ngx_http_lua_socket_conn_error_retval_handler (line 1698) | static int
  function ngx_http_lua_socket_tcp_get_ssl_session (line 1745) | int
  function ngx_http_lua_ffi_socket_tcp_sslhandshake (line 1781) | int
  function ngx_http_lua_ssl_handshake_handler (line 2037) | static void
  function ngx_http_lua_ffi_socket_tcp_get_sslhandshake_result (line 2143) | int
  function ngx_http_lua_ssl_handshake_retval_handler (line 2164) | static int
  function ngx_http_lua_ffi_ssl_free_session (line 2192) | void
  function ngx_http_lua_ffi_socket_tcp_get_ssl_pointer (line 2202) | int
  function ngx_http_lua_ffi_socket_tcp_get_ssl_ctx (line 2230) | int
  function ngx_http_lua_socket_read_error_retval_handler (line 2261) | static int
  function ngx_http_lua_socket_write_error_retval_handler (line 2285) | static int
  function ngx_http_lua_socket_prepare_error_retvals (line 2303) | static int
  function ngx_http_lua_socket_tcp_conn_retval_handler (line 2352) | static int
  function ngx_http_lua_socket_tcp_receive_helper (line 2365) | static int
  function ngx_http_lua_socket_tcp_receiveany (line 2451) | static int
  function ngx_http_lua_socket_tcp_receive (line 2528) | static int
  function ngx_int_t (line 2664) | static ngx_int_t
  function ngx_int_t (line 2684) | static ngx_int_t
  function ngx_int_t (line 2696) | static ngx_int_t
  function ngx_int_t (line 2717) | static ngx_int_t
  function ngx_http_lua_socket_tcp_read_prepare (line 2738) | static void
  function ngx_int_t (line 2819) | static ngx_int_t
  function ngx_http_lua_socket_tcp_send (line 3108) | static int
  function ngx_http_lua_socket_tcp_send_retval_handler (line 3365) | static int
  function ngx_http_lua_socket_tcp_receive_retval_handler (line 3381) | static int
  function ngx_http_lua_socket_tcp_close (line 3452) | static int
  function ngx_http_lua_socket_tcp_settimeout (line 3504) | static int
  function ngx_http_lua_socket_tcp_settimeouts (line 3551) | static int
  function ngx_http_lua_socket_tcp_handler (line 3615) | static void
  function ngx_int_t (line 3649) | static ngx_int_t
  function ngx_http_lua_socket_read_handler (line 3657) | static void
  function ngx_http_lua_socket_send_handler (line 3696) | static void
  function ngx_int_t (line 3727) | static ngx_int_t
  function ngx_http_lua_socket_handle_conn_success (line 3818) | static void
  function ngx_http_lua_socket_handle_read_success (line 3856) | static void
  function ngx_http_lua_socket_handle_write_success (line 3893) | static void
  function ngx_http_lua_socket_handle_conn_error (line 3930) | static void
  function ngx_http_lua_socket_handle_read_error (line 3975) | static void
  function ngx_http_lua_socket_handle_write_error (line 4016) | static void
  function ngx_http_lua_socket_connected_handler (line 4057) | static void
  function ngx_http_lua_socket_tcp_cleanup (line 4121) | static void
  function ngx_http_lua_socket_tcp_conn_op_timeout_handler (line 4258) | static void
  function ngx_http_lua_socket_tcp_conn_op_timeout_retval_handler (line 4324) | static int
  function ngx_http_lua_socket_tcp_resume_conn_op (line 4334) | static void
  function ngx_http_lua_socket_tcp_conn_op_ctx_cleanup (line 4381) | static void
  function ngx_http_lua_socket_tcp_conn_op_resume_handler (line 4399) | static void
  function ngx_http_lua_socket_tcp_conn_op_resume_retval_handler (line 4484) | static int
  function ngx_http_lua_socket_tcp_finalize (line 4521) | static void
  function ngx_http_lua_socket_tcp_close_connection (line 4595) | static void
  function ngx_int_t (line 4618) | static ngx_int_t
  function ngx_http_lua_socket_dummy_handler (line 4684) | static void
  function ngx_http_lua_socket_tcp_receiveuntil (line 4693) | static int
  function ngx_http_lua_socket_receiveuntil_iterator (line 4785) | static int
  function ngx_int_t (line 4939) | static ngx_int_t
  function ngx_int_t (line 5037) | static ngx_int_t
  function ngx_http_lua_socket_cleanup_compiled_pattern (line 5214) | static int
  function ngx_http_lua_req_socket (line 5266) | static int
  function ngx_http_lua_req_socket_rev_handler (line 5517) | static void
  function ngx_http_lua_socket_tcp_getreusedtimes (line 5542) | static int
  function ngx_http_lua_socket_tcp_setkeepalive (line 5571) | static int
  function ngx_int_t (line 5845) | static ngx_int_t
  function ngx_http_lua_socket_keepalive_dummy_handler (line 5930) | static void
  function ngx_http_lua_socket_keepalive_rev_handler (line 5938) | static void
  function ngx_int_t (line 5945) | static ngx_int_t
  function ngx_http_lua_socket_free_pool (line 6013) | static void
  function ngx_http_lua_socket_shutdown_pool_helper (line 6033) | static void
  function ngx_http_lua_socket_shutdown_pool (line 6079) | static int
  function ngx_http_lua_socket_tcp_upstream_destroy (line 6094) | static int
  function ngx_http_lua_socket_downstream_destroy (line 6114) | static int
  function ngx_http_lua_socket_push_input_data (line 6135) | static void
  function ngx_int_t (line 6210) | static ngx_int_t
  function ngx_int_t (line 6235) | static ngx_int_t
  function ngx_int_t (line 6268) | static ngx_int_t ngx_http_lua_socket_insert_buffer(ngx_http_request_t *r,
  function ngx_int_t (line 6327) | static ngx_int_t
  function ngx_int_t (line 6334) | static ngx_int_t
  function ngx_int_t (line 6341) | static ngx_int_t
  function ngx_int_t (line 6348) | static ngx_int_t
  function ngx_int_t (line 6355) | static ngx_int_t
  function ngx_http_lua_tcp_resolve_cleanup (line 6493) | static void
  function ngx_http_lua_coctx_cleanup (line 6523) | static void
  function ngx_http_lua_cleanup_conn_pools (line 6544) | void
  function ngx_http_lua_ffi_socket_tcp_init_udata_queue (line 6573) | int
  function ngx_http_lua_ffi_socket_tcp_count_udata (line 6623) | int
  function ngx_http_lua_ffi_socket_tcp_add_udata (line 6636) | int
  function ngx_http_lua_ffi_socket_tcp_get_udata (line 6731) | int
  function ngx_http_lua_ffi_socket_tcp_del_udata (line 6767) | int
  function ngx_http_lua_ffi_socket_tcp_getoption (line 6803) | int
  function ngx_http_lua_ffi_socket_tcp_setoption (line 6870) | int
  function ngx_http_lua_ffi_socket_tcp_getfd (line 6944) | int
  function ngx_http_lua_ffi_socket_tcp_hack_fd (line 6967) | int

FILE: src/ngx_http_lua_socket_tcp.h
  type ngx_http_lua_socket_tcp_upstream_t (line 32) | typedef struct ngx_http_lua_socket_tcp_upstream_s
  type ngx_http_lua_socket_udata_queue_t (line 36) | typedef struct ngx_http_lua_socket_udata_queue_s
  type ngx_http_lua_socket_tcp_conn_op_ctx_t (line 49) | typedef struct {
  type ngx_http_lua_socket_pool_t (line 64) | typedef struct {
  type ngx_http_lua_socket_tcp_upstream_s (line 87) | struct ngx_http_lua_socket_tcp_upstream_s {
  type ngx_http_lua_dfa_edge_t (line 160) | typedef struct ngx_http_lua_dfa_edge_s  ngx_http_lua_dfa_edge_t;
  type ngx_http_lua_dfa_edge_s (line 163) | struct ngx_http_lua_dfa_edge_s {
  type ngx_http_lua_socket_compiled_pattern_t (line 170) | typedef struct {
  type ngx_http_lua_socket_pool_item_t (line 181) | typedef struct {
  type ngx_http_lua_socket_udata_queue_s (line 197) | struct ngx_http_lua_socket_udata_queue_s {
  type ngx_http_lua_socket_node_t (line 206) | typedef struct {

FILE: src/ngx_http_lua_socket_udp.c
  function ngx_http_lua_inject_socket_udp_api (line 78) | void
  function u_char (line 127) | static u_char *
  function ngx_http_lua_socket_udp (line 167) | static int
  function ngx_http_lua_socket_udp_setpeername (line 202) | static int
  function ngx_http_lua_socket_resolve_handler (line 477) | static void
  function ngx_http_lua_socket_resolve_retval_handler (line 646) | static int
  function ngx_http_lua_socket_error_retval_handler (line 735) | static int
  function ngx_http_lua_socket_udp_bind (line 783) | static int
  function ngx_http_lua_socket_udp_send (line 833) | static int
  function ngx_http_lua_socket_udp_receive (line 1016) | static int
  function ngx_http_lua_socket_udp_receive_retval_handler (line 1143) | static int
  function ngx_http_lua_socket_udp_settimeout (line 1159) | static int
  function ngx_http_lua_socket_udp_finalize (line 1195) | static void
  function ngx_http_lua_socket_udp_upstream_destroy (line 1226) | static int
  function ngx_http_lua_socket_dummy_handler (line 1246) | static void
  function ngx_int_t (line 1255) | static ngx_int_t
  function ngx_http_lua_socket_udp_read_handler (line 1309) | static void
  function ngx_http_lua_socket_udp_handle_error (line 1346) | static void
  function ngx_http_lua_socket_udp_cleanup (line 1389) | static void
  function ngx_http_lua_socket_udp_handler (line 1405) | static void
  function ngx_http_lua_socket_udp_handle_success (line 1434) | static void
  function ngx_int_t (line 1465) | static ngx_int_t
  function ngx_http_lua_socket_udp_close (line 1591) | static int
  function ngx_int_t (line 1636) | static ngx_int_t
  function ngx_http_lua_udp_resolve_cleanup (line 1703) | static void
  function ngx_http_lua_udp_socket_cleanup (line 1725) | static void

FILE: src/ngx_http_lua_socket_udp.h
  type ngx_http_lua_socket_udp_upstream_t (line 14) | typedef struct ngx_http_lua_socket_udp_upstream_s
  type ngx_http_lua_udp_connection_t (line 27) | typedef struct {
  type ngx_http_lua_socket_udp_upstream_s (line 36) | struct ngx_http_lua_socket_udp_upstream_s {

FILE: src/ngx_http_lua_ssl.c
  function ngx_int_t (line 21) | ngx_int_t
  function ngx_ssl_conn_t (line 50) | ngx_ssl_conn_t *

FILE: src/ngx_http_lua_ssl.h
  type ngx_http_lua_ssl_ctx_t (line 17) | typedef struct {
  type ngx_http_lua_ssl_key_log_t (line 58) | typedef struct {

FILE: src/ngx_http_lua_ssl_certby.c
  function ngx_int_t (line 47) | ngx_int_t
  function ngx_int_t (line 68) | ngx_int_t
  function ngx_http_lua_ssl_cert_handler (line 194) | int
  function ngx_http_lua_ssl_cert_done (line 369) | static void
  function ngx_http_lua_ssl_cert_aborted (line 405) | static void
  function u_char (line 427) | static u_char *
  function ngx_http_lua_is_grease_cipher (line 463) | static int
  function ngx_int_t (line 475) | static ngx_int_t
  function ngx_http_lua_ffi_ssl_get_tls1_version (line 570) | int
  function ngx_http_lua_ffi_ssl_clear_certs (line 592) | int
  function ngx_http_lua_ffi_ssl_set_der_certificate (line 630) | int
  function ngx_http_lua_ffi_ssl_set_der_private_key (line 730) | int
  function ngx_http_lua_ffi_ssl_raw_server_addr (line 787) | int
  function ngx_http_lua_ffi_req_shared_ssl_ciphers (line 862) | int
  function ngx_http_lua_ffi_ssl_server_name (line 930) | int
  function ngx_http_lua_ffi_ssl_server_port (line 967) | int
  function ngx_http_lua_ffi_ssl_raw_client_addr (line 1000) | int
  function ngx_http_lua_ffi_cert_pem_to_der (line 1068) | int
  function ngx_http_lua_ffi_priv_key_pem_to_der (line 1147) | int
  function ngx_http_lua_ffi_free_cert (line 1344) | void
  function ngx_http_lua_ffi_free_priv_key (line 1415) | void
  function ngx_http_lua_ffi_set_cert (line 1424) | int
  function ngx_http_lua_ffi_set_priv_key (line 1510) | int
  function ngx_http_lua_ssl_verify_callback (line 1550) | static int
  function ngx_http_lua_ffi_ssl_verify_client (line 1564) | int
  function ngx_ssl_conn_t (line 1717) | ngx_ssl_conn_t *
  function ngx_http_lua_ffi_ssl_client_random (line 1734) | int

FILE: src/ngx_http_lua_ssl_client_helloby.c
  function ngx_int_t (line 32) | ngx_int_t
  function ngx_int_t (line 53) | ngx_int_t
  function ngx_http_lua_ssl_client_hello_handler (line 181) | int
  function ngx_http_lua_ssl_client_hello_done (line 371) | static void
  function ngx_http_lua_ssl_client_hello_aborted (line 407) | static void
  function u_char (line 429) | static u_char *
  function ngx_int_t (line 464) | static ngx_int_t
  function ngx_http_lua_ffi_ssl_get_client_hello_server_name (line 559) | int
  function ngx_http_lua_ffi_ssl_get_client_hello_ext (line 649) | int
  function ngx_http_lua_ffi_ssl_get_client_hello_ext_present (line 684) | int
  function ngx_http_lua_ffi_ssl_get_client_hello_ciphers (line 729) | int ngx_http_lua_ffi_ssl_get_client_hello_ciphers(ngx_http_request_t *r,
  function ngx_http_lua_ffi_ssl_set_protocols (line 777) | int

FILE: src/ngx_http_lua_ssl_export_keying_material.c
  function ngx_int_t (line 29) | ngx_int_t
  function ngx_int_t (line 77) | ngx_int_t

FILE: src/ngx_http_lua_ssl_ocsp.c
  function ngx_http_lua_ffi_ssl_get_ocsp_responder_from_der_chain (line 26) | int
  function ngx_http_lua_ffi_ssl_create_ocsp_request (line 149) | int
  function ngx_http_lua_ffi_ssl_validate_ocsp_response (line 263) | int
  function ngx_http_lua_ssl_empty_status_callback (line 446) | static int
  function ngx_http_lua_ssl_stapling_time (line 453) | static long

FILE: src/ngx_http_lua_ssl_session_fetchby.c
  function ngx_int_t (line 36) | ngx_int_t
  function ngx_int_t (line 58) | ngx_int_t
  function ngx_ssl_session_t (line 176) | ngx_ssl_session_t *
  function ngx_http_lua_ssl_sess_fetch_done (line 386) | static void
  function ngx_http_lua_ssl_sess_fetch_aborted (line 414) | static void
  function u_char (line 436) | static u_char *
  function ngx_int_t (line 473) | static ngx_int_t
  function ngx_http_lua_ffi_ssl_set_serialized_session (line 569) | int

FILE: src/ngx_http_lua_ssl_session_storeby.c
  function ngx_int_t (line 34) | ngx_int_t
  function ngx_int_t (line 56) | ngx_int_t
  function ngx_http_lua_ssl_sess_store_handler (line 174) | int
  function u_char (line 322) | static u_char *
  function ngx_int_t (line 359) | static ngx_int_t
  function ngx_http_lua_ffi_ssl_get_serialized_session (line 437) | int
  function ngx_http_lua_ffi_ssl_get_serialized_session_size (line 483) | int
  function ngx_http_lua_ffi_ssl_get_session_id (line 531) | int
  function ngx_http_lua_ffi_ssl_get_session_id_size (line 580) | int

FILE: src/ngx_http_lua_string.c
  function ngx_http_lua_inject_string_api (line 40) | void
  function ngx_http_lua_ngx_quote_sql_str (line 59) | static int
  function ngx_http_lua_ngx_escape_sql_str (line 108) | static uintptr_t
  function ngx_http_lua_encode_base64 (line 209) | static void
  function ngx_http_lua_ngx_encode_args (line 254) | static int
  function ngx_http_lua_ngx_decode_args (line 271) | static int
  function ngx_http_lua_ngx_hmac_sha1 (line 306) | static int
  function ngx_http_lua_ffi_md5_bin (line 334) | void
  function ngx_http_lua_ffi_md5 (line 345) | void
  function ngx_http_lua_ffi_sha1_bin (line 359) | int
  function ngx_http_lua_ffi_crc32_short (line 376) | unsigned int
  function ngx_http_lua_ffi_crc32_long (line 383) | unsigned int
  function ngx_http_lua_ffi_encode_base64 (line 390) | size_t
  function ngx_http_lua_ffi_decode_base64 (line 407) | int
  function ngx_http_lua_ffi_decode_base64mime (line 427) | int
  function ngx_http_lua_ffi_unescape_uri (line 447) | size_t
  function ngx_http_lua_ffi_uri_escaped_length (line 458) | size_t
  function ngx_http_lua_ffi_escape_uri (line 466) | void
  function ngx_http_lua_ffi_str_replace_char (line 474) | void

FILE: src/ngx_http_lua_subrequest.c
  function ngx_http_lua_ngx_location_capture (line 92) | static int
  function ngx_http_lua_ngx_location_capture_multi (line 121) | static int
  function ngx_int_t (line 656) | static ngx_int_t
  function ngx_int_t (line 801) | static ngx_int_t
  function ngx_http_lua_process_keyval_option (line 911) | static void
  function ngx_int_t (line 966) | ngx_int_t
  function ngx_http_lua_handle_subreq_responses (line 1150) | static void
  function ngx_http_lua_inject_subrequest_api (line 1356) | void
  function ngx_int_t (line 1371) | static ngx_int_t
  function ngx_int_t (line 1526) | static ngx_int_t
  function ngx_http_lua_cancel_subreq (line 1592) | static void
  function ngx_int_t (line 1614) | static ngx_int_t
  function ngx_int_t (line 1632) | static ngx_int_t
  function ngx_int_t (line 1669) | static ngx_int_t

FILE: src/ngx_http_lua_subrequest.h
  type ngx_http_lua_post_subrequest_data_t (line 37) | typedef struct ngx_http_lua_post_subrequest_data_s {

FILE: src/ngx_http_lua_time.c
  function ngx_http_lua_ffi_now (line 17) | double
  function ngx_http_lua_ffi_req_start_time (line 28) | double
  function ngx_http_lua_ffi_time (line 49) | long
  function ngx_http_lua_ffi_monotonic_msec (line 56) | long
  function ngx_http_lua_ffi_update_time (line 63) | void
  function ngx_http_lua_ffi_today (line 70) | void
  function ngx_http_lua_ffi_localtime (line 82) | void
  function ngx_http_lua_ffi_utctime (line 95) | void
  function ngx_http_lua_ffi_cookie_time (line 108) | int
  function ngx_http_lua_ffi_http_time (line 118) | void
  function ngx_http_lua_ffi_parse_http_time (line 125) | void

FILE: src/ngx_http_lua_timer.c
  type ngx_http_lua_timer_ctx_t (line 22) | typedef struct {
  function ngx_http_lua_inject_timer_api (line 55) | void
  function ngx_http_lua_ngx_timer_running_count (line 76) | static int
  function ngx_http_lua_ngx_timer_pending_count (line 95) | static int
  function ngx_http_lua_ngx_timer_at (line 114) | static int
  function ngx_http_lua_ngx_timer_every (line 125) | static int
  function ngx_http_lua_ngx_timer_helper (line 132) | static int
  function ngx_int_t (line 376) | static ngx_int_t
  function ngx_http_lua_timer_handler (line 513) | static void
  function u_char (line 728) | static u_char *
  function ngx_http_lua_abort_pending_timers (line 767) | static void

FILE: src/ngx_http_lua_uri.c
  function ngx_http_lua_inject_req_uri_api (line 21) | void
  function ngx_http_lua_ngx_req_set_uri (line 29) | static int

FILE: src/ngx_http_lua_uthread.c
  function ngx_http_lua_inject_uthread_api (line 30) | void
  function ngx_http_lua_uthread_spawn (line 49) | static int
  function ngx_http_lua_uthread_wait (line 104) | static int
  function ngx_http_lua_uthread_kill (line 202) | static int

FILE: src/ngx_http_lua_util.c
  function ngx_http_lua_create_new_globals_table (line 211) | void
  function lua_State (line 221) | static lua_State *
  function lua_State (line 334) | lua_State *
  function u_char (line 503) | u_char *
  function ngx_int_t (line 529) | ngx_int_t
  function ngx_int_t (line 569) | ngx_int_t
  function ngx_int_t (line 685) | static ngx_int_t
  function ngx_int_t (line 707) | static ngx_int_t
  function ngx_int_t (line 746) | static ngx_int_t
  function ngx_http_lua_init_registry (line 781) | static void
  function ngx_http_lua_init_globals (line 819) | static void
  function ngx_http_lua_inject_ngx_api (line 834) | static void
  function ngx_http_lua_inject_global_write_guard (line 881) | static void
  function ngx_http_lua_discard_bufs (line 929) | void
  function ngx_int_t (line 941) | ngx_int_t
  function ngx_http_lua_reset_ctx (line 993) | void
  function ngx_http_lua_generic_phase_post_read (line 1034) | void
  function ngx_http_lua_request_cleanup_handler (line 1059) | void
  function ngx_http_lua_request_cleanup (line 1068) | void
  function ngx_int_t (line 1119) | ngx_int_t
  function ngx_int_t (line 1716) | ngx_int_t
  function ngx_int_t (line 1818) | static ngx_int_t
  function ngx_int_t (line 1896) | static ngx_int_t
  function u_char (line 1970) | u_char *
  function ngx_http_lua_set_multi_value_table (line 1984) | void
  function ngx_http_lua_escape_uri (line 2025) | uintptr_t
  function ngx_http_lua_util_hex2int (line 2239) | static int
  function ngx_http_lua_unescape_uri (line 2256) | void
  function ngx_http_lua_inject_req_api (line 2315) | void
  function ngx_int_t (line 2333) | static ngx_int_t
  function ngx_int_t (line 2430) | static ngx_int_t
  function ngx_http_lua_process_args_option (line 2526) | void
  function ngx_int_t (line 2798) | static ngx_int_t
  function ngx_int_t (line 2824) | ngx_int_t
  function ngx_chain_t (line 2932) | ngx_chain_t *
  function ngx_http_lua_thread_traceback (line 3025) | static int
  function ngx_http_lua_traceback (line 3101) | int
  function ngx_http_lua_inject_arg_api (line 3127) | static void
  function ngx_http_lua_param_set (line 3146) | static int
  function ngx_http_lua_co_ctx_t (line 3168) | ngx_http_lua_co_ctx_t *
  function ngx_http_lua_co_ctx_t (line 3213) | ngx_http_lua_co_ctx_t *
  function ngx_int_t (line 3241) | ngx_int_t
  function ngx_int_t (line 3293) | ngx_int_t
  function ngx_http_lua_finalize_threads (line 3316) | static void
  function ngx_int_t (line 3387) | static ngx_int_t
  function ngx_http_lua_cleanup_zombie_child_uthreads (line 3410) | static void
  function ngx_int_t (line 3428) | ngx_int_t
  function ngx_http_lua_rd_check_broken_connection (line 3535) | void
  function ngx_int_t (line 3603) | static ngx_int_t
  function ngx_int_t (line 3653) | ngx_int_t
  function ngx_http_lua_finalize_request (line 3695) | void
  function ngx_http_lua_finalize_fake_request (line 3748) | void
  function ngx_http_lua_close_fake_request (line 3805) | static void
  function ngx_http_lua_free_fake_request (line 3832) | void
  function ngx_http_lua_close_fake_connection (line 3866) | void
  function ngx_int_t (line 3920) | ngx_int_t
  function ngx_http_lua_cleanup_vm (line 4013) | void
  function ngx_connection_t (line 4042) | ngx_connection_t *
  function ngx_http_request_t (line 4112) | ngx_http_request_t *
  function ngx_int_t (line 4195) | ngx_int_t
  function ngx_http_lua_do_call (line 4218) | int
  function ngx_http_lua_get_raw_phase_context (line 4246) | static int
  function ngx_http_cleanup_t (line 4272) | ngx_http_cleanup_t *
  function ngx_http_lua_cleanup_free (line 4305) | void
  function ngx_http_lua_set_sa_restart (line 4346) | void
  function ngx_http_lua_escape_log (line 4373) | size_t
  function ngx_int_t (line 4440) | ngx_int_t
  function ngx_int_t (line 4475) | ngx_int_t
  function ngx_addr_t (line 4555) | ngx_addr_t *
  function ngx_http_lua_ffi_bypass_if_checks (line 4627) | void
  function ngx_http_lua_resume_quic_ssl_handshake (line 4635) | void

FILE: src/ngx_http_lua_util.h
  type ngx_http_lua_ffi_table_elt_t (line 111) | typedef struct {
  function ngx_inline (line 132) | static ngx_inline ngx_int_t
  function ngx_inline (line 280) | static ngx_inline void
  function ngx_inline (line 293) | static ngx_inline ngx_http_lua_ctx_t *
  function ngx_inline (line 363) | static ngx_inline lua_State *
  function ngx_inline (line 391) | static ngx_inline ngx_http_request_t *
  function ngx_inline (line 408) | static ngx_inline void
  function ngx_inline (line 420) | static ngx_inline void
  function ngx_inline (line 430) | static ngx_inline void
  function ngx_inline (line 437) | static ngx_inline void
  function ngx_inline (line 445) | static ngx_inline ngx_uint_t
  function ngx_inline (line 461) | static ngx_inline ngx_int_t
  function ngx_inline (line 479) | static ngx_inline void
  function ngx_inline (line 489) | static ngx_inline ngx_chain_t *
  function ngx_inline (line 507) | static ngx_inline in_port_t
  function ngx_inline (line 536) | static ngx_inline ngx_int_t
  function ngx_inline (line 575) | static ngx_inline void
  function ngx_inline (line 630) | static ngx_inline int
  function ngx_inline (line 702) | static ngx_inline void *

FILE: src/ngx_http_lua_variable.c
  function ngx_http_lua_ffi_var_get (line 17) | int
  function ngx_http_lua_ffi_var_set (line 103) | int

FILE: src/ngx_http_lua_worker.c
  function ngx_http_lua_ffi_worker_pid (line 20) | int
  function ngx_http_lua_ffi_worker_pids (line 28) | int
  function ngx_http_lua_ffi_worker_id (line 61) | int
  function ngx_http_lua_ffi_worker_exiting (line 78) | int
  function ngx_http_lua_ffi_worker_count (line 85) | int
  function ngx_http_lua_ffi_master_pid (line 97) | int
  function ngx_http_lua_ffi_get_process_type (line 112) | int
  function ngx_http_lua_ffi_process_signal_graceful_exit (line 165) | void

FILE: src/ngx_http_lua_worker_thread.c
  type ngx_http_lua_task_ctx_t (line 34) | typedef struct ngx_http_lua_task_ctx_s {
  type ngx_http_lua_worker_thread_ctx_t (line 40) | typedef struct {
  function ngx_http_lua_thread_exit_process (line 54) | void
  function ngx_thread_task_t (line 74) | static ngx_thread_task_t *
  function ngx_http_lua_thread_task_free (line 90) | static void
  function ngx_http_lua_task_ctx_t (line 98) | static ngx_http_lua_task_ctx_t *
  function ngx_http_lua_free_task_ctx (line 194) | static void
  function ngx_http_lua_xcopy (line 215) | static int
  function ngx_http_lua_worker_thread_handler (line 310) | static void
  function ngx_int_t (line 323) | static ngx_int_t
  function ngx_http_lua_worker_thread_event_handler (line 368) | static void
  function ngx_http_lua_worker_thread_cleanup (line 459) | static void
  function ngx_http_lua_run_worker_thread (line 469) | static int
  function ngx_http_lua_inject_worker_thread_api (line 634) | void

FILE: t/data/fake-delayed-load-module/ngx_http_lua_fake_delayed_load_module.c
  function ngx_int_t (line 52) | static ngx_int_t
  function ngx_http_lua_fake_delayed_load_preload (line 61) | static int
  function ngx_http_lua_fake_delayed_load_function (line 73) | static int

FILE: t/data/fake-module/ngx_http_fake_module.c
  type ngx_http_fake_srv_conf_t (line 13) | typedef struct {
  type ngx_http_fake_loc_conf_t (line 18) | typedef struct {

FILE: t/data/fake-shm-module/ngx_http_lua_fake_shm_module.c
  type ngx_http_lua_fake_shm_main_conf_t (line 26) | typedef struct {
  type ngx_http_lua_fake_shm_ctx_t (line 75) | typedef struct {
  function ngx_int_t (line 179) | static ngx_int_t
  function ngx_int_t (line 198) | static ngx_int_t
  function ngx_http_lua_fake_shm_preload (line 207) | static int
  function ngx_http_lua_fake_shm_get_info (line 263) | static int
Condensed preview — 426 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (5,984K chars).
[
  {
    "path": ".gitattributes",
    "chars": 27,
    "preview": "*.t linguist-language=Text\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "chars": 1426,
    "preview": "This place is for bug reports and development discussions only. For general questions and\ndiscussions, please join the o"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "chars": 116,
    "preview": "I hereby granted the copyright of the changes in this pull request\nto the authors of this lua-nginx-module project.\n"
  },
  {
    "path": ".github/workflows/build_and_test.yml",
    "chars": 12592,
    "preview": "name: Build and test\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  test:\n    n"
  },
  {
    "path": ".github/workflows/semantic-pull-request.yml",
    "chars": 910,
    "preview": "name: \"Lint PR\"\n\non:\n  pull_request_target:\n    types:\n      - opened\n      - edited\n      - synchronize\n\njobs:\n  main:\n"
  },
  {
    "path": ".gitignore",
    "chars": 2165,
    "preview": "build/\nwork/\ntags\ncscope.*\n*.mobi\ngenmobi.sh\n.libs\n*.swp\n*.slo\n*.la\n*.swo\n*.lo\n*~\n*.o\nprint.txt\n.rsync\n*.tar.gz\ndist\nbui"
  },
  {
    "path": ".mergify.yml",
    "chars": 921,
    "preview": "---\npull_request_rules:\n  - name: warn on conflicts\n    conditions:\n      - conflict\n    actions:\n      comment:\n       "
  },
  {
    "path": "README.markdown",
    "chars": 413163,
    "preview": "Name\n====\n\nngx_http_lua_module - Embed the power of Lua into Nginx HTTP Servers.\n\nThis module is a core component of [Op"
  },
  {
    "path": "config",
    "chars": 18790,
    "preview": "ngx_lua_opt_I=\nngx_lua_opt_L=\nluajit_ld_opt=\n\nngx_feature_name=\nngx_feature_run=no\nngx_feature_incs=\nngx_feature_test=\n\n"
  },
  {
    "path": "doc/HttpLuaModule.wiki",
    "chars": 387733,
    "preview": "= Name =\n\nngx_http_lua_module - Embed the power of Lua into Nginx HTTP Servers.\n\nThis module is a core component of [htt"
  },
  {
    "path": "dtrace/ngx_lua_provider.d",
    "chars": 2269,
    "preview": "provider nginx_lua {\n    probe http__lua__info(char *s);\n\n    /* lua_State *L */\n    probe http__lua__register__preload_"
  },
  {
    "path": "misc/recv-until-pm/lib/RecvUntil.pm",
    "chars": 3890,
    "preview": "package RecvUntil;\n\nuse strict;\nuse warnings;\n\nsub recv_until {\n    my ($pat) = @_;\n\n    my $len = length $pat;\n    my @"
  },
  {
    "path": "misc/recv-until-pm/t/sanity.t",
    "chars": 1605,
    "preview": "# vi:ft=\n\nuse 5.10.1;\nuse Test::Base;\nuse RecvUntil;\n\nplan tests => 1 * blocks();\n\nrun {\n    my $block = shift;\n    my $"
  },
  {
    "path": "src/api/ngx_http_lua_api.h",
    "chars": 2063,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_API_H_INCLUDED_\n#define _NGX_HTTP_LUA_API_H_INCL"
  },
  {
    "path": "src/ddebug.h",
    "chars": 2206,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _DDEBUG_H_INCLUDED_\n#define _DDEBUG_H_INCLUDED_\n\n\n#include <ng"
  },
  {
    "path": "src/ngx_http_lua_accessby.c",
    "chars": 10686,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDE"
  },
  {
    "path": "src/ngx_http_lua_accessby.h",
    "chars": 509,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_ACCE"
  },
  {
    "path": "src/ngx_http_lua_api.c",
    "chars": 7949,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n#include \"ddebug.h\"\n\n\n#include "
  },
  {
    "path": "src/ngx_http_lua_args.c",
    "chars": 13831,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDE"
  },
  {
    "path": "src/ngx_http_lua_args.h",
    "chars": 387,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_ARGS_H_INCLUDED_\n#define _NGX_HTTP_LUA_ARGS_H_IN"
  },
  {
    "path": "src/ngx_http_lua_balancer.c",
    "chars": 40389,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n#include \"ddebug.h\"\n\n\n#include "
  },
  {
    "path": "src/ngx_http_lua_balancer.h",
    "chars": 737,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_BALANCER_H_INCLUDED_\n#define _NGX_HTTP_LUA_BALAN"
  },
  {
    "path": "src/ngx_http_lua_bodyfilterby.c",
    "chars": 18903,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDE"
  },
  {
    "path": "src/ngx_http_lua_bodyfilterby.h",
    "chars": 785,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_BODYFILTERBY_H_INCLUDED_\n#define _NGX_HTTP_LUA_B"
  },
  {
    "path": "src/ngx_http_lua_cache.c",
    "chars": 10209,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDE"
  },
  {
    "path": "src/ngx_http_lua_cache.h",
    "chars": 821,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_CACH"
  },
  {
    "path": "src/ngx_http_lua_capturefilter.c",
    "chars": 4902,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDE"
  },
  {
    "path": "src/ngx_http_lua_capturefilter.h",
    "chars": 375,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_CAPT"
  },
  {
    "path": "src/ngx_http_lua_clfactory.c",
    "chars": 27832,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDE"
  },
  {
    "path": "src/ngx_http_lua_clfactory.h",
    "chars": 505,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_CLFA"
  },
  {
    "path": "src/ngx_http_lua_common.h",
    "chars": 28075,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_COMM"
  },
  {
    "path": "src/ngx_http_lua_config.c",
    "chars": 1345,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n#include \"ddebug.h\"\n\n\n#include "
  },
  {
    "path": "src/ngx_http_lua_config.h",
    "chars": 312,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_CONFIG_H_INCLUDED_\n#define _NGX_HTTP_LUA_CONFIG_"
  },
  {
    "path": "src/ngx_http_lua_consts.c",
    "chars": 5442,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDE"
  },
  {
    "path": "src/ngx_http_lua_consts.h",
    "chars": 365,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_CONSTS_H_INCLUDED_\n#define _NGX_HTTP_LUA_CONSTS_"
  },
  {
    "path": "src/ngx_http_lua_contentby.c",
    "chars": 9576,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDE"
  },
  {
    "path": "src/ngx_http_lua_contentby.h",
    "chars": 782,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_CONT"
  },
  {
    "path": "src/ngx_http_lua_control.c",
    "chars": 13550,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDE"
  },
  {
    "path": "src/ngx_http_lua_control.h",
    "chars": 376,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_CONT"
  },
  {
    "path": "src/ngx_http_lua_coroutine.c",
    "chars": 11729,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDE"
  },
  {
    "path": "src/ngx_http_lua_coroutine.h",
    "chars": 538,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_CORO"
  },
  {
    "path": "src/ngx_http_lua_ctx.c",
    "chars": 5004,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n#include \"ddebug.h\"\n\n\n#include "
  },
  {
    "path": "src/ngx_http_lua_ctx.h",
    "chars": 410,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_CTX_"
  },
  {
    "path": "src/ngx_http_lua_directive.c",
    "chars": 58536,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDE"
  },
  {
    "path": "src/ngx_http_lua_directive.h",
    "chars": 3870,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_DIRE"
  },
  {
    "path": "src/ngx_http_lua_exception.c",
    "chars": 1311,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDE"
  },
  {
    "path": "src/ngx_http_lua_exception.h",
    "chars": 731,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_EXCE"
  },
  {
    "path": "src/ngx_http_lua_exitworkerby.c",
    "chars": 2780,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n#include \"ddebug.h\"\n\n\n#include "
  },
  {
    "path": "src/ngx_http_lua_exitworkerby.h",
    "chars": 554,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_EXITWORKERBY_H_INCLUDED_\n#define _NGX_HTTP_LUA_E"
  },
  {
    "path": "src/ngx_http_lua_headerfilterby.c",
    "chars": 8334,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n#include \"ddebug.h\"\n\n#include \""
  },
  {
    "path": "src/ngx_http_lua_headerfilterby.h",
    "chars": 645,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_HEADERFILTERBY_H_INCLUDED_\n#define _NGX_HTTP_LUA"
  },
  {
    "path": "src/ngx_http_lua_headers.c",
    "chars": 33905,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDE"
  },
  {
    "path": "src/ngx_http_lua_headers.h",
    "chars": 585,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_HEAD"
  },
  {
    "path": "src/ngx_http_lua_headers_in.c",
    "chars": 22846,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n#include \"ddebug.h\"\n\n\n#include "
  },
  {
    "path": "src/ngx_http_lua_headers_in.h",
    "chars": 455,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_HEAD"
  },
  {
    "path": "src/ngx_http_lua_headers_out.c",
    "chars": 18807,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDE"
  },
  {
    "path": "src/ngx_http_lua_headers_out.h",
    "chars": 1110,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_HEAD"
  },
  {
    "path": "src/ngx_http_lua_initby.c",
    "chars": 1075,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n\n#include \"ddebug.h\"\n#include \""
  },
  {
    "path": "src/ngx_http_lua_initby.h",
    "chars": 470,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_INITBY_H_INCLUDED_\n#define _NGX_HTTP_LUA_INITBY_"
  },
  {
    "path": "src/ngx_http_lua_initworkerby.c",
    "chars": 10130,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n#include \"ddebug.h\"\n\n\n#include "
  },
  {
    "path": "src/ngx_http_lua_initworkerby.h",
    "chars": 559,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_INITWORKERBY_H_INCLUDED_\n#define _NGX_HTTP_LUA_I"
  },
  {
    "path": "src/ngx_http_lua_input_filters.c",
    "chars": 2511,
    "preview": "\n/*\n * Copyright (C) by OpenResty Inc.\n */\n\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n#include \"ddebug.h\"\n\n\n#include \"ngx_"
  },
  {
    "path": "src/ngx_http_lua_input_filters.h",
    "chars": 730,
    "preview": "\n/*\n * Copyright (C) by OpenResty Inc.\n */\n\n\n#ifndef _NGX_HTTP_LUA_INPUT_FILTERS_H_INCLUDED_\n#define _NGX_HTTP_LUA_INPUT"
  },
  {
    "path": "src/ngx_http_lua_lex.c",
    "chars": 182949,
    "preview": "/*\n * Copyright (C) Yichun Zhang (agentzh)\n *\n * WARNING: DO NOT EVER EDIT THIS FILE!!\n *\n * This file was automatically"
  },
  {
    "path": "src/ngx_http_lua_lex.h",
    "chars": 246,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_LEX_H_INCLUDED_\n#define _NGX_HTTP_LUA_LEX_H_INCL"
  },
  {
    "path": "src/ngx_http_lua_log.c",
    "chars": 10895,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDE"
  },
  {
    "path": "src/ngx_http_lua_log.h",
    "chars": 494,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_LOG_"
  },
  {
    "path": "src/ngx_http_lua_log_ringbuf.c",
    "chars": 4867,
    "preview": "\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n#include \"ddebug.h\"\n\n\n#include \"ngx_http_lua_common.h\"\n#include \"ngx_http_lua_lo"
  },
  {
    "path": "src/ngx_http_lua_log_ringbuf.h",
    "chars": 1009,
    "preview": "\n#ifndef _NGX_HTTP_LUA_RINGBUF_H_INCLUDED_\n#define _NGX_HTTP_LUA_RINGBUF_H_INCLUDED_\n\n\n#include \"ngx_http_lua_common.h\"\n"
  },
  {
    "path": "src/ngx_http_lua_logby.c",
    "chars": 7272,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n#include \"ddebug.h\"\n\n\n#include "
  },
  {
    "path": "src/ngx_http_lua_logby.h",
    "chars": 447,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_LOGBY_H_INCLUDED_\n#define _NGX_HTTP_LUA_LOGBY_H_"
  },
  {
    "path": "src/ngx_http_lua_misc.c",
    "chars": 4394,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDE"
  },
  {
    "path": "src/ngx_http_lua_misc.h",
    "chars": 352,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_MISC"
  },
  {
    "path": "src/ngx_http_lua_module.c",
    "chars": 66852,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDE"
  },
  {
    "path": "src/ngx_http_lua_ndk.c",
    "chars": 2782,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n#include \"ddebug.h\"\n\n\n#include "
  },
  {
    "path": "src/ngx_http_lua_ndk.h",
    "chars": 331,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_NDK_H_INCLUDED_\n#define _NGX_HTTP_LUA_NDK_H_INCL"
  },
  {
    "path": "src/ngx_http_lua_output.c",
    "chars": 20998,
    "preview": "#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n#include \"ddebug.h\"\n\n\n#include \"ngx_http_lua_output.h\"\n#include \"ngx_http_lua_uti"
  },
  {
    "path": "src/ngx_http_lua_output.h",
    "chars": 1883,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_OUTP"
  },
  {
    "path": "src/ngx_http_lua_pcrefix.c",
    "chars": 3784,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDE"
  },
  {
    "path": "src/ngx_http_lua_pcrefix.h",
    "chars": 582,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_PCRE"
  },
  {
    "path": "src/ngx_http_lua_phase.c",
    "chars": 469,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n#include \"ddebug.h\"\n\n\n#include "
  },
  {
    "path": "src/ngx_http_lua_pipe.c",
    "chars": 75684,
    "preview": "\n/*\n * Copyright (C) by OpenResty Inc.\n */\n\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n#include \"ddebug.h\"\n\n\n#include \"ngx_"
  },
  {
    "path": "src/ngx_http_lua_pipe.h",
    "chars": 2859,
    "preview": "\n/*\n * Copyright (C) by OpenResty Inc.\n */\n\n\n#ifndef _NGX_HTTP_LUA_PIPE_H_INCLUDED_\n#define _NGX_HTTP_LUA_PIPE_H_INCLUDE"
  },
  {
    "path": "src/ngx_http_lua_precontentby.c",
    "chars": 10707,
    "preview": "\n/*\n * Copyright (C) Hanada <im@hanada.info>\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDEBUG"
  },
  {
    "path": "src/ngx_http_lua_precontentby.h",
    "chars": 533,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_PREC"
  },
  {
    "path": "src/ngx_http_lua_probe.h",
    "chars": 3579,
    "preview": "/*\n * automatically generated from the file dtrace/ngx_lua_provider.d by the\n *  gen-dtrace-probe-header tool in the ngi"
  },
  {
    "path": "src/ngx_http_lua_proxy_ssl_certby.c",
    "chars": 19704,
    "preview": "/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n\n#include \"ddebug.h\"\n#include \"ng"
  },
  {
    "path": "src/ngx_http_lua_proxy_ssl_certby.h",
    "chars": 1065,
    "preview": "/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n#ifndef _NGX_HTTP_LUA_PROXY_SSL_CERTBY_H_INCLUDED_\n#define _NGX_HTTP_LUA"
  },
  {
    "path": "src/ngx_http_lua_proxy_ssl_verifyby.c",
    "chars": 16947,
    "preview": "/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n\n#include \"ddebug.h\"\n#include \"ng"
  },
  {
    "path": "src/ngx_http_lua_proxy_ssl_verifyby.h",
    "chars": 1136,
    "preview": "/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n#ifndef _NGX_HTTP_LUA_PROXY_SSL_VERIFYBY_H_INCLUDED_\n#define _NGX_HTTP_L"
  },
  {
    "path": "src/ngx_http_lua_regex.c",
    "chars": 25440,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n#include \"ddebug.h\"\n\n#if (NGX_P"
  },
  {
    "path": "src/ngx_http_lua_req_body.c",
    "chars": 30375,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n#include \"ddebug.h\"\n\n#include \""
  },
  {
    "path": "src/ngx_http_lua_req_body.h",
    "chars": 364,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_REQ_"
  },
  {
    "path": "src/ngx_http_lua_req_method.c",
    "chars": 2550,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n\n\n#include \"ddebug.h\"\n#include "
  },
  {
    "path": "src/ngx_http_lua_rewriteby.c",
    "chars": 10598,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDE"
  },
  {
    "path": "src/ngx_http_lua_rewriteby.h",
    "chars": 515,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_REWR"
  },
  {
    "path": "src/ngx_http_lua_script.c",
    "chars": 13668,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n#include \"ddebug.h\"\n\n\n#include "
  },
  {
    "path": "src/ngx_http_lua_script.h",
    "chars": 2166,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_SCRIPT_H_INCLUDED_\n#define _NGX_HTTP_LUA_SCRIPT_"
  },
  {
    "path": "src/ngx_http_lua_semaphore.c",
    "chars": 15625,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n * Copyright (C) cuiweixie\n * I hereby assign copyright in this code to the "
  },
  {
    "path": "src/ngx_http_lua_semaphore.h",
    "chars": 1445,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n * Copyright (C) cuiweixie\n * I hereby assign copyright in this code to the "
  },
  {
    "path": "src/ngx_http_lua_server_rewriteby.c",
    "chars": 9455,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDE"
  },
  {
    "path": "src/ngx_http_lua_server_rewriteby.h",
    "chars": 650,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n#ifndef _NGX_HTTP_LUA_SERVE"
  },
  {
    "path": "src/ngx_http_lua_setby.c",
    "chars": 5163,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDE"
  },
  {
    "path": "src/ngx_http_lua_setby.h",
    "chars": 374,
    "preview": "#ifndef _NGX_HTTP_LUA_SET_BY_H_INCLUDED_\n#define _NGX_HTTP_LUA_SET_BY_H_INCLUDED_\n\n#include \"ngx_http_lua_common.h\"\n\n\nng"
  },
  {
    "path": "src/ngx_http_lua_shdict.c",
    "chars": 53857,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n#include \"ddebug.h\"\n\n\n#include "
  },
  {
    "path": "src/ngx_http_lua_shdict.h",
    "chars": 3170,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_SHDICT_H_INCLUDED_\n#define _NGX_HTTP_LUA_SHDICT_"
  },
  {
    "path": "src/ngx_http_lua_sleep.c",
    "chars": 5661,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDE"
  },
  {
    "path": "src/ngx_http_lua_sleep.h",
    "chars": 352,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_SLEE"
  },
  {
    "path": "src/ngx_http_lua_socket_tcp.c",
    "chars": 196084,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n#include \"ddebug.h\"\n\n\n#include "
  },
  {
    "path": "src/ngx_http_lua_socket_tcp.h",
    "chars": 7021,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_SOCKET_TCP_H_INCLUDED_\n#define _NGX_HTTP_LUA_SOC"
  },
  {
    "path": "src/ngx_http_lua_socket_udp.c",
    "chars": 45471,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n#include \"ddebug.h\"\n\n\n#include "
  },
  {
    "path": "src/ngx_http_lua_socket_udp.h",
    "chars": 1886,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_SOCKET_UDP_H_INCLUDED_\n#define _NGX_HTTP_LUA_SOC"
  },
  {
    "path": "src/ngx_http_lua_ssl.c",
    "chars": 1784,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n#include \"ddebug.h\"\n\n#if (NGX_H"
  },
  {
    "path": "src/ngx_http_lua_ssl.h",
    "chars": 1992,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_SSL_H_INCLUDED_\n#define _NGX_HTTP_LUA_SSL_H_INCL"
  },
  {
    "path": "src/ngx_http_lua_ssl_certby.c",
    "chars": 41055,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n#include \"ddebug.h\"\n\n\n#if (NGX_"
  },
  {
    "path": "src/ngx_http_lua_ssl_certby.h",
    "chars": 820,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_SSL_CERTBY_H_INCLUDED_\n#define _NGX_HTTP_LUA_SSL"
  },
  {
    "path": "src/ngx_http_lua_ssl_client_helloby.c",
    "chars": 21500,
    "preview": "/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n#include \"ddebug.h\"\n\n\n#if (NGX_HT"
  },
  {
    "path": "src/ngx_http_lua_ssl_client_helloby.h",
    "chars": 893,
    "preview": "/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n#ifndef _NGX_HTTP_LUA_SSL_CLIENT_HELLOBY_H_INCLUDED_\n#define _NGX_HTTP_L"
  },
  {
    "path": "src/ngx_http_lua_ssl_export_keying_material.c",
    "chars": 3327,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n\n\n#include \"ddebug.h\"\n\n#if (NGX"
  },
  {
    "path": "src/ngx_http_lua_ssl_export_keying_material.h",
    "chars": 753,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_SSL_EXPORT_KEYING_MATERIAL_H_INCLUDED_\n#define _"
  },
  {
    "path": "src/ngx_http_lua_ssl_ocsp.c",
    "chars": 12510,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n#include \"ddebug.h\"\n\n\n#if (NGX_"
  },
  {
    "path": "src/ngx_http_lua_ssl_session_fetchby.c",
    "chars": 16456,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n#include \"ddebug.h\"\n\n\n#if (NGX_"
  },
  {
    "path": "src/ngx_http_lua_ssl_session_fetchby.h",
    "chars": 956,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_SSL_SESSION_FETCHBY_H_INCLUDED_\n#define _NGX_HTT"
  },
  {
    "path": "src/ngx_http_lua_ssl_session_storeby.c",
    "chars": 16542,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n#include \"ddebug.h\"\n\n\n#if (NGX_"
  },
  {
    "path": "src/ngx_http_lua_ssl_session_storeby.h",
    "chars": 871,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_SSL_SESSION_STOREBY_H_INCLUDED_\n#define _NGX_HTT"
  },
  {
    "path": "src/ngx_http_lua_string.c",
    "chars": 10168,
    "preview": "/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDEB"
  },
  {
    "path": "src/ngx_http_lua_string.h",
    "chars": 356,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_STRI"
  },
  {
    "path": "src/ngx_http_lua_subrequest.c",
    "chars": 50478,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDE"
  },
  {
    "path": "src/ngx_http_lua_subrequest.h",
    "chars": 1321,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_SUBR"
  },
  {
    "path": "src/ngx_http_lua_time.c",
    "chars": 2414,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDE"
  },
  {
    "path": "src/ngx_http_lua_timer.c",
    "chars": 23024,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n#include \"ddebug.h\"\n\n\n#include "
  },
  {
    "path": "src/ngx_http_lua_timer.h",
    "chars": 352,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_TIME"
  },
  {
    "path": "src/ngx_http_lua_uri.c",
    "chars": 3448,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDE"
  },
  {
    "path": "src/ngx_http_lua_uri.h",
    "chars": 364,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_URI_"
  },
  {
    "path": "src/ngx_http_lua_uthread.c",
    "chars": 6926,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n#include \"ddebug.h\"\n\n\n#include "
  },
  {
    "path": "src/ngx_http_lua_uthread.h",
    "chars": 964,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_UTHREAD_H_INCLUDED_\n#define _NGX_HTTP_LUA_UTHREA"
  },
  {
    "path": "src/ngx_http_lua_util.c",
    "chars": 126623,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDE"
  },
  {
    "path": "src/ngx_http_lua_util.h",
    "chars": 22109,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef _NGX_HTTP_LUA_UTIL"
  },
  {
    "path": "src/ngx_http_lua_variable.c",
    "chars": 6493,
    "preview": "\n/*\n * Copyright (C) Xiaozhe Wang (chaoslawful)\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDE"
  },
  {
    "path": "src/ngx_http_lua_worker.c",
    "chars": 3087,
    "preview": "\n/*\n * Copyright (C) Yichun Zhang (agentzh)\n */\n\n\n#ifndef DDEBUG\n#define DDEBUG 0\n#endif\n#include \"ddebug.h\"\n\n#if !(NGX_"
  },
  {
    "path": "src/ngx_http_lua_worker_thread.c",
    "chars": 16783,
    "preview": "/*\n * Copyright (C) Yichun Zhang (agentzh)\n * Copyright (C) Jinhua Luo (kingluo)\n * I hereby assign copyright in this co"
  },
  {
    "path": "src/ngx_http_lua_worker_thread.h",
    "chars": 576,
    "preview": "/*\n * Copyright (C) Yichun Zhang (agentzh)\n * Copyright (C) Jinhua Luo (kingluo)\n * I hereby assign copyright in this co"
  },
  {
    "path": "t/.gitignore",
    "chars": 10,
    "preview": "servroot\n\n"
  },
  {
    "path": "t/000--init.t",
    "chars": 1966,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\nrepeat_each(1);\n\nplan tests => repeat_each() * (b"
  },
  {
    "path": "t/000-sanity.t",
    "chars": 425,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\nrepeat_each(2);\n\nplan tests => blocks() * repeat_"
  },
  {
    "path": "t/001-set.t",
    "chars": 14556,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\nrepeat_each(2);\n\nplan tests => repeat_each() * (b"
  },
  {
    "path": "t/002-content.t",
    "chars": 22052,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\n#worker_connections(1014);\n#master_on();\n#workers"
  },
  {
    "path": "t/003-errors.t",
    "chars": 2610,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\nrepeat_each(1);\n\nplan tests => blocks() * repeat_"
  },
  {
    "path": "t/004-require.t",
    "chars": 3847,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\n#worker_connections(1014);\n#log_level('warn');\n\n#"
  },
  {
    "path": "t/005-exit.t",
    "chars": 17060,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\n#repeat_each(20000);\n#repeat_each(200);\nrepeat_ea"
  },
  {
    "path": "t/006-escape.t",
    "chars": 6550,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\nrepeat_each(2);\n\nplan tests => repeat_each() * (b"
  },
  {
    "path": "t/007-md5.t",
    "chars": 1692,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\n#worker_connections(1014);\n#master_process_enable"
  },
  {
    "path": "t/008-today.t",
    "chars": 676,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\n#worker_connections(1014);\n#master_process_enable"
  },
  {
    "path": "t/009-log.t",
    "chars": 11639,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\n#worker_connections(1014);\n#master_process_enable"
  },
  {
    "path": "t/010-request_body.t",
    "chars": 5647,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\n#worker_connections(1014);\n#master_process_enable"
  },
  {
    "path": "t/011-md5_bin.t",
    "chars": 3600,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\n#worker_connections(1014);\n#master_process_enable"
  },
  {
    "path": "t/012-now.t",
    "chars": 2200,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\n#worker_connections(1014);\n#master_process_enable"
  },
  {
    "path": "t/013-base64.t",
    "chars": 4622,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\n#worker_connections(1014);\n#master_process_enable"
  },
  {
    "path": "t/014-bugs.t",
    "chars": 38584,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\n#worker_connections(1014);\n#master_on();\nlog_leve"
  },
  {
    "path": "t/015-status.t",
    "chars": 9370,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\n#worker_connections(1014);\n#master_process_enable"
  },
  {
    "path": "t/016-resp-header.t",
    "chars": 48261,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\n#worker_connections(1014);\n#master_process_enable"
  },
  {
    "path": "t/017-exec.t",
    "chars": 10341,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\nrepeat_each(2);\n\nplan tests => repeat_each() * (b"
  },
  {
    "path": "t/018-ndk.t",
    "chars": 3058,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\nrepeat_each(2);\n\nplan tests => repeat_each() * (b"
  },
  {
    "path": "t/019-const.t",
    "chars": 647,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\nrepeat_each(2);\n\nplan tests => blocks() * repeat_"
  },
  {
    "path": "t/020-subrequest.t",
    "chars": 76409,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\nuse Test::Nginx::Util 'is_tcp_port_used';\n\n#master"
  },
  {
    "path": "t/021-cookie-time.t",
    "chars": 739,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\n#worker_connections(1014);\n#master_process_enable"
  },
  {
    "path": "t/022-redirect.t",
    "chars": 8642,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\n#worker_connections(1014);\n#master_process_enable"
  },
  {
    "path": "t/023-rewrite/client-abort.t",
    "chars": 15533,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\nuse t::StapThread;\n\nour $GCScript = <<_EOC_;\n$t::S"
  },
  {
    "path": "t/023-rewrite/exec.t",
    "chars": 7162,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\nrepeat_each(2);\n#repeat_each(1);\n\nplan tests => r"
  },
  {
    "path": "t/023-rewrite/exit.t",
    "chars": 13063,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\n#repeat_each(20000);\n\nrepeat_each(2);\n\n#master_on"
  },
  {
    "path": "t/023-rewrite/mixed.t",
    "chars": 3689,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\nuse Test::Nginx::Socket::Lua;\n\n#worker_connections(1014);\n#master_process_enabled"
  },
  {
    "path": "t/023-rewrite/multi-capture.t",
    "chars": 9342,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\nrepeat_each(10);\n\nplan tests => blocks() * repeat"
  },
  {
    "path": "t/023-rewrite/on-abort.t",
    "chars": 13680,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\nuse t::StapThread;\n\nour $GCScript = <<_EOC_;\n$t::S"
  },
  {
    "path": "t/023-rewrite/redirect.t",
    "chars": 3320,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\n#worker_connections(1014);\n#master_process_enable"
  },
  {
    "path": "t/023-rewrite/req-body.t",
    "chars": 4163,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\n#worker_connections(1014);\n#master_process_enable"
  },
  {
    "path": "t/023-rewrite/req-socket.t",
    "chars": 22218,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nour $SkipReason;\n\nBEGIN {\n    if ($ENV{TEST_NGINX_USE_HTTP3}) {\n        $SkipRea"
  },
  {
    "path": "t/023-rewrite/request_body.t",
    "chars": 3396,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\nuse Test::Nginx::Socket::Lua;\n\n#worker_connections(1014);\n#master_process_enabled"
  },
  {
    "path": "t/023-rewrite/sanity.t",
    "chars": 15666,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\nuse Test::Nginx::Socket::Lua;\n\n#worker_connections(1014);\n#no_nginx_manager();\n#l"
  },
  {
    "path": "t/023-rewrite/sleep.t",
    "chars": 4486,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\n#worker_connections(1014);\n#master_on();\n#workers"
  },
  {
    "path": "t/023-rewrite/socket-keepalive.t",
    "chars": 24212,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\nrepeat_each(2);\n\nplan tests => repeat_each() * (b"
  },
  {
    "path": "t/023-rewrite/subrequest.t",
    "chars": 12966,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\nuse Test::Nginx::Socket::Lua;\n\n#worker_connections(1014);\n#master_process_enabled"
  },
  {
    "path": "t/023-rewrite/tcp-socket-timeout.t",
    "chars": 14334,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nBEGIN {\n    if (!defined $ENV{LD_PRELOAD}) {\n        $ENV{LD_PRELOAD} = '';\n    "
  },
  {
    "path": "t/023-rewrite/tcp-socket.t",
    "chars": 57301,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\nrepeat_each(2);\n\nplan tests => repeat_each() * 10"
  },
  {
    "path": "t/023-rewrite/unix-socket.t",
    "chars": 3565,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\nrepeat_each(2);\n\nplan tests => repeat_each() * (2"
  },
  {
    "path": "t/023-rewrite/uthread-exec.t",
    "chars": 6040,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\nuse t::StapThread;\n\nour $GCScript = $t::StapThread"
  },
  {
    "path": "t/023-rewrite/uthread-exit.t",
    "chars": 25176,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\nuse t::StapThread;\n\nour $GCScript = $t::StapThread"
  },
  {
    "path": "t/023-rewrite/uthread-redirect.t",
    "chars": 3487,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\nuse t::StapThread;\n\nour $GCScript = $t::StapThread"
  },
  {
    "path": "t/023-rewrite/uthread-spawn.t",
    "chars": 29474,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\nuse t::StapThread;\n\nour $GCScript = $t::StapThread"
  },
  {
    "path": "t/024-access/auth.t",
    "chars": 2585,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\nuse Test::Nginx::Socket::Lua;\n\n#worker_connections(1014);\n#master_process_enabled"
  },
  {
    "path": "t/024-access/client-abort.t",
    "chars": 15639,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nour $SkipReason;\n\nBEGIN {\n    if ($ENV{TEST_NGINX_USE_HTTP3}) {\n        $SkipRea"
  },
  {
    "path": "t/024-access/exec.t",
    "chars": 6946,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\nrepeat_each(2);\n\nplan tests => repeat_each() * (b"
  },
  {
    "path": "t/024-access/exit.t",
    "chars": 12113,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\n#repeat_each(20000);\nrepeat_each(2);\n\n#master_on("
  },
  {
    "path": "t/024-access/mixed.t",
    "chars": 5918,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\nuse Test::Nginx::Socket::Lua;\n\n#worker_connections(1014);\n#master_process_enabled"
  },
  {
    "path": "t/024-access/multi-capture.t",
    "chars": 9334,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\nrepeat_each(10);\n\nplan tests => blocks() * repeat"
  },
  {
    "path": "t/024-access/on-abort.t",
    "chars": 13541,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\nuse t::StapThread;\n\nour $GCScript = <<_EOC_;\n$t::S"
  },
  {
    "path": "t/024-access/redirect.t",
    "chars": 2526,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\n#worker_connections(1014);\n#master_process_enable"
  },
  {
    "path": "t/024-access/req-body.t",
    "chars": 4123,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\n\nuse Test::Nginx::Socket::Lua;\n\n#worker_connections(1014);\n#master_process_enable"
  },
  {
    "path": "t/024-access/request_body.t",
    "chars": 3388,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\nuse Test::Nginx::Socket::Lua;\n\n#worker_connections(1014);\n#master_process_enabled"
  },
  {
    "path": "t/024-access/sanity.t",
    "chars": 14597,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\nuse Test::Nginx::Socket::Lua;\n\n#worker_connections(1014);\n#log_level('warn');\n#no"
  },
  {
    "path": "t/024-access/satisfy.t",
    "chars": 3561,
    "preview": "# vim:set ft= ts=4 sw=4 et fdm=marker:\nuse Test::Nginx::Socket::Lua;\n\nworker_connections(1014);\n#master_on();\n#workers(4"
  }
]

// ... and 226 more files (download for full content)

About this extraction

This page contains the full source code of the openresty/lua-nginx-module GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 426 files (5.4 MB), approximately 1.4M tokens, and a symbol index with 887 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!