Skip to content
Snippets Groups Projects
README.markdown 383 KiB
Newer Older
  • Learn to ignore specific revisions
  •    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*, init_worker_by_lua*, set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, ngx.timer.*, balancer_by_lua*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_session_store_by_lua*, exit_worker_by_lua*, ssl_client_hello_by_lua**
    
    ```lua
    
       ngx.STDERR
       ngx.EMERG
       ngx.ALERT
       ngx.CRIT
       ngx.ERR
       ngx.WARN
       ngx.NOTICE
       ngx.INFO
       ngx.DEBUG
    ```
    
    These constants are usually used by the [ngx.log](#ngxlog) method.
    
    [Back to TOC](#nginx-api-for-lua)
    
    print
    -----
    
    **syntax:** *print(...)*
    
    **context:** *init_by_lua*, init_worker_by_lua*, set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, ngx.timer.*, balancer_by_lua*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_session_store_by_lua*, exit_worker_by_lua*, ssl_client_hello_by_lua**
    
    Writes argument values into the Nginx `error.log` file with the `ngx.NOTICE` log level.
    
    It is equivalent to
    
    ```lua
    
     ngx.log(ngx.NOTICE, ...)
    ```
    
    Lua `nil` arguments are accepted and result in literal `"nil"` strings while Lua booleans result in literal `"true"` or `"false"` strings. And the `ngx.null` constant will yield the `"null"` string output.
    
    There is a hard coded `2048` byte limitation on error message lengths in the Nginx core. This limit includes trailing newlines and leading time stamps. If the message size exceeds this limit, Nginx will truncate the message text accordingly. This limit can be manually modified by editing the `NGX_MAX_ERROR_STR` macro definition in the `src/core/ngx_log.h` file in the Nginx source tree.
    
    [Back to TOC](#nginx-api-for-lua)
    
    ngx.ctx
    -------
    
    **context:** *init_worker_by_lua*, set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, ngx.timer.*, balancer_by_lua*, exit_worker_by_lua**
    
    This table can be used to store per-request Lua context data and has a life time identical to the current request (as with the Nginx variables).
    
    Consider the following example,
    
    ```nginx
    
     location /test {
         rewrite_by_lua_block {
             ngx.ctx.foo = 76
         }
         access_by_lua_block {
             ngx.ctx.foo = ngx.ctx.foo + 3
         }
         content_by_lua_block {
             ngx.say(ngx.ctx.foo)
         }
     }
    ```
    
    Then `GET /test` will yield the output
    
    ```bash
    
     79
    ```
    
    That is, the `ngx.ctx.foo` entry persists across the rewrite, access, and content phases of a request.
    
    Every request, including subrequests, has its own copy of the table. For example:
    
    ```nginx
    
     location /sub {
         content_by_lua_block {
             ngx.say("sub pre: ", ngx.ctx.blah)
             ngx.ctx.blah = 32
             ngx.say("sub post: ", ngx.ctx.blah)
         }
     }
    
     location /main {
         content_by_lua_block {
             ngx.ctx.blah = 73
             ngx.say("main pre: ", ngx.ctx.blah)
             local res = ngx.location.capture("/sub")
             ngx.print(res.body)
             ngx.say("main post: ", ngx.ctx.blah)
         }
     }
    ```
    
    Then `GET /main` will give the output
    
    ```bash
    
     main pre: 73
     sub pre: nil
     sub post: 32
     main post: 73
    ```
    
    Here, modification of the `ngx.ctx.blah` entry in the subrequest does not affect the one in the parent request. This is because they have two separate versions of `ngx.ctx.blah`.
    
    
    Internal redirects (triggered by nginx configuration directives like `error_page`, `try_files`, `index`, etc.) will destroy the original request `ngx.ctx` data (if any) and the new request will have an empty `ngx.ctx` table. For instance,
    
    
    ```nginx
    
     location /new {
         content_by_lua_block {
             ngx.say(ngx.ctx.foo)
         }
     }
    
     location /orig {
         content_by_lua_block {
             ngx.ctx.foo = "hello"
             ngx.exec("/new")
         }
     }
    ```
    
    Then `GET /orig` will give
    
    ```bash
    
     nil
    ```
    
    rather than the original `"hello"` value.
    
    Because HTTP request is created after SSL handshake, the `ngx.ctx` created
    in [ssl_certificate_by_lua*](#ssl_certificate_by_lua), [ssl_session_store_by_lua*](#ssl_session_store_by_lua), [ssl_session_fetch_by_lua*](#ssl_session_fetch_by_lua) and [ssl_client_hello_by_lua*](#ssl_client_hello_by_lua)
    is not available in the following phases like [rewrite_by_lua*](#rewrite_by_lua).
    
    
    Since `v0.10.18`, the `ngx.ctx` created during a SSL handshake
    
    will be inherited by the requests which share the same TCP connection established by the handshake.
    Note that overwrite values in `ngx.ctx` in the http request phases (like `rewrite_by_lua*`) will only take affect in the current http request.
    
    Arbitrary data values, including Lua closures and nested tables, can be inserted into this "magic" table. It also allows the registration of custom meta methods.
    
    Overriding `ngx.ctx` with a new Lua table is also supported, for example,
    
    ```lua
    
     ngx.ctx = { foo = 32, bar = 54 }
    ```
    
    When being used in the context of [init_worker_by_lua*](#init_worker_by_lua), this table just has the same lifetime of the current Lua handler.
    
    The `ngx.ctx` lookup requires relatively expensive metamethod calls and it is much slower than explicitly passing per-request data along by your own function arguments. So do not abuse this API for saving your own function arguments because it usually has quite some performance impact.
    
    Because of the metamethod magic, never "local" the `ngx.ctx` table outside your Lua function scope on the Lua module level due to [worker-level data sharing](#data-sharing-within-an-nginx-worker). For example, the following is bad:
    
    ```lua
    
     -- mymodule.lua
     local _M = {}
    
     -- the following line is bad since ngx.ctx is a per-request
     -- data while this <code>ctx</code> variable is on the Lua module level
     -- and thus is per-nginx-worker.
     local ctx = ngx.ctx
    
     function _M.main()
         ctx.foo = "bar"
     end
    
     return _M
    ```
    
    Use the following instead:
    
    ```lua
    
     -- mymodule.lua
     local _M = {}
    
     function _M.main(ctx)
         ctx.foo = "bar"
     end
    
     return _M
    ```
    
    That is, let the caller pass the `ctx` table explicitly via a function argument.
    
    [Back to TOC](#nginx-api-for-lua)
    
    ngx.location.capture
    --------------------
    
    **syntax:** *res = ngx.location.capture(uri, options?)*
    
    **context:** *rewrite_by_lua&#42;, access_by_lua&#42;, content_by_lua&#42;*
    
    Issues a synchronous but still non-blocking *Nginx Subrequest* using `uri`.
    
    Nginx's subrequests provide a powerful way to make non-blocking internal requests to other locations configured with disk file directory or *any* other Nginx C modules like `ngx_proxy`, `ngx_fastcgi`, `ngx_memc`,
    `ngx_postgres`, `ngx_drizzle`, and even ngx_lua itself and etc etc etc.
    
    Also note that subrequests just mimic the HTTP interface but there is *no* extra HTTP/TCP traffic *nor* IPC involved. Everything works internally, efficiently, on the C level.
    
    Subrequests are completely different from HTTP 301/302 redirection (via [ngx.redirect](#ngxredirect)) and internal redirection (via [ngx.exec](#ngxexec)).
    
    You should always read the request body (by either calling [ngx.req.read_body](#ngxreqread_body) or configuring [lua_need_request_body](#lua_need_request_body) on) before initiating a subrequest.
    
    This API function (as well as [ngx.location.capture_multi](#ngxlocationcapture_multi)) always buffers the whole response body of the subrequest in memory. Thus, you should use [cosockets](#ngxsockettcp)
    and streaming processing instead if you have to handle large subrequest responses.
    
    Here is a basic example:
    
    ```lua
    
     res = ngx.location.capture(uri)
    ```
    
    Returns a Lua table with 4 slots: `res.status`, `res.header`, `res.body`, and `res.truncated`.
    
    `res.status` holds the response status code for the subrequest response.
    
    `res.header` holds all the response headers of the
    subrequest and it is a normal Lua table. For multi-value response headers,
    the value is a Lua (array) table that holds all the values in the order that
    they appear. For instance, if the subrequest response headers contain the following
    lines:
    
    ```bash
    
     Set-Cookie: a=3
     Set-Cookie: foo=bar
     Set-Cookie: baz=blah
    ```
    
    Then `res.header["Set-Cookie"]` will be evaluated to the table value
    `{"a=3", "foo=bar", "baz=blah"}`.
    
    `res.body` holds the subrequest's response body data, which might be truncated. You always need to check the `res.truncated` boolean flag to see if `res.body` contains truncated data. The data truncation here can only be caused by those unrecoverable errors in your subrequests like the cases that the remote end aborts the connection prematurely in the middle of the response body data stream or a read timeout happens when your subrequest is receiving the response body data from the remote.
    
    URI query strings can be concatenated to URI itself, for instance,
    
    ```lua
    
     res = ngx.location.capture('/foo/bar?a=3&b=4')
    ```
    
    Named locations like `@foo` are not allowed due to a limitation in
    the Nginx core. Use normal locations combined with the `internal` directive to
    prepare internal-only locations.
    
    An optional option table can be fed as the second
    argument, which supports the options:
    
    * `method`
    	specify the subrequest's request method, which only accepts constants like `ngx.HTTP_POST`.
    * `body`
    	specify the subrequest's request body (string value only).
    * `args`
    	specify the subrequest's URI query arguments (both string value and Lua tables are accepted)
    
    * `headers`
        specify the subrequest's request headers (Lua table only). this headers will override the original headers of the subrequest.
    
    * `ctx`
    	specify a Lua table to be the [ngx.ctx](#ngxctx) table for the subrequest. It can be the current request's [ngx.ctx](#ngxctx) table, which effectively makes the parent and its subrequest to share exactly the same context table. This option was first introduced in the `v0.3.1rc25` release.
    * `vars`
    	take a Lua table which holds the values to set the specified Nginx variables in the subrequest as this option's value. This option was first introduced in the `v0.3.1rc31` release.
    * `copy_all_vars`
    	specify whether to copy over all the Nginx variable values of the current request to the subrequest in question. modifications of the Nginx variables in the subrequest will not affect the current (parent) request. This option was first introduced in the `v0.3.1rc31` release.
    * `share_all_vars`
    	specify whether to share all the Nginx variables of the subrequest with the current (parent) request. modifications of the Nginx variables in the subrequest will affect the current (parent) request. Enabling this option may lead to hard-to-debug issues due to bad side-effects and is considered bad and harmful. Only enable this option when you completely know what you are doing.
    * `always_forward_body`
    	when set to true, the current (parent) request's request body will always be forwarded to the subrequest being created if the `body` option is not specified. The request body read by either [ngx.req.read_body()](#ngxreqread_body) or [lua_need_request_body on](#lua_need_request_body) will be directly forwarded to the subrequest without copying the whole request body data when creating the subrequest (no matter the request body data is buffered in memory buffers or temporary files). By default, this option is `false` and when the `body` option is not specified, the request body of the current (parent) request is only forwarded when the subrequest takes the `PUT` or `POST` request method.
    
    Issuing a POST subrequest, for example, can be done as follows
    
    ```lua
    
     res = ngx.location.capture(
         '/foo/bar',
         { method = ngx.HTTP_POST, body = 'hello, world' }
     )
    ```
    
    See HTTP method constants methods other than POST.
    The `method` option is `ngx.HTTP_GET` by default.
    
    The `args` option can specify extra URI arguments, for instance,
    
    ```lua
    
     ngx.location.capture('/foo?a=1',
         { args = { b = 3, c = ':' } }
     )
    ```
    
    is equivalent to
    
    ```lua
    
     ngx.location.capture('/foo?a=1&b=3&c=%3a')
    ```
    
    that is, this method will escape argument keys and values according to URI rules and
    concatenate them together into a complete query string. The format for the Lua table passed as the `args` argument is identical to the format used in the [ngx.encode_args](#ngxencode_args) method.
    
    The `args` option can also take plain query strings:
    
    ```lua
    
     ngx.location.capture('/foo?a=1',
         { args = 'b=3&c=%3a' }
     )
    ```
    
    This is functionally identical to the previous examples.
    
    The `share_all_vars` option controls whether to share Nginx variables among the current request and its subrequests.
    If this option is set to `true`, then the current request and associated subrequests will share the same Nginx variable scope. Hence, changes to Nginx variables made by a subrequest will affect the current request.
    
    Care should be taken in using this option as variable scope sharing can have unexpected side effects. The `args`, `vars`, or `copy_all_vars` options are generally preferable instead.
    
    This option is set to `false` by default
    
    ```nginx
    
     location /other {
         set $dog "$dog world";
         echo "$uri dog: $dog";
     }
    
     location /lua {
         set $dog 'hello';
         content_by_lua_block {
             res = ngx.location.capture("/other",
                 { share_all_vars = true })
    
             ngx.print(res.body)
             ngx.say(ngx.var.uri, ": ", ngx.var.dog)
         }
     }
    ```
    
    Accessing location `/lua` gives
    
    
        /other dog: hello world
        /lua: hello world
    
    
    The `copy_all_vars` option provides a copy of the parent request's Nginx variables to subrequests when such subrequests are issued. Changes made to these variables by such subrequests will not affect the parent request or any other subrequests sharing the parent request's variables.
    
    ```nginx
    
     location /other {
         set $dog "$dog world";
         echo "$uri dog: $dog";
     }
    
     location /lua {
         set $dog 'hello';
         content_by_lua_block {
             res = ngx.location.capture("/other",
                 { copy_all_vars = true })
    
             ngx.print(res.body)
             ngx.say(ngx.var.uri, ": ", ngx.var.dog)
         }
     }
    ```
    
    Request `GET /lua` will give the output
    
    
        /other dog: hello world
        /lua: hello
    
    
    Note that if both `share_all_vars` and `copy_all_vars` are set to true, then `share_all_vars` takes precedence.
    
    In addition to the two settings above, it is possible to specify
    values for variables in the subrequest using the `vars` option. These
    variables are set after the sharing or copying of variables has been
    evaluated, and provides a more efficient method of passing specific
    values to a subrequest over encoding them as URL arguments and
    unescaping them in the Nginx config file.
    
    ```nginx
    
     location /other {
         content_by_lua_block {
             ngx.say("dog = ", ngx.var.dog)
             ngx.say("cat = ", ngx.var.cat)
         }
     }
    
     location /lua {
         set $dog '';
         set $cat '';
         content_by_lua_block {
             res = ngx.location.capture("/other",
                 { vars = { dog = "hello", cat = 32 }})
    
             ngx.print(res.body)
         }
     }
    ```
    
    Accessing `/lua` will yield the output
    
    
        dog = hello
        cat = 32
    
    
    The `headers` option can be used to specify the request headers for the subrequest. The value of this option should be a Lua table where the keys are the header names and the values are the header values. For example,
    
    ```lua
    
    location /foo {
        content_by_lua_block {
            ngx.print(ngx.var.http_x_test)
        }
    }
    
    location /lua {
        content_by_lua_block {
            local res = ngx.location.capture("/foo", {
                headers = {
                    ["X-Test"] = "aa",
                }
            })
            ngx.print(res.body)
        }
    }
    ```
    
    Accessing `/lua` will yield the output
    
    
        aa
    
    
    
    The `ctx` option can be used to specify a custom Lua table to serve as the [ngx.ctx](#ngxctx) table for the subrequest.
    
    ```nginx
    
     location /sub {
         content_by_lua_block {
             ngx.ctx.foo = "bar";
         }
     }
     location /lua {
         content_by_lua_block {
             local ctx = {}
             res = ngx.location.capture("/sub", { ctx = ctx })
    
             ngx.say(ctx.foo)
             ngx.say(ngx.ctx.foo)
         }
     }
    ```
    
    Then request `GET /lua` gives
    
    
        bar
        nil
    
    
    It is also possible to use this `ctx` option to share the same [ngx.ctx](#ngxctx) table between the current (parent) request and the subrequest:
    
    ```nginx
    
     location /sub {
         content_by_lua_block {
             ngx.ctx.foo = "bar"
         }
     }
     location /lua {
         content_by_lua_block {
             res = ngx.location.capture("/sub", { ctx = ngx.ctx })
             ngx.say(ngx.ctx.foo)
         }
     }
    ```
    
    Request `GET /lua` yields the output
    
    
        bar
    
    
    Note that subrequests issued by [ngx.location.capture](#ngxlocationcapture) inherit all the
    request headers of the current request by default and that this may have unexpected side effects on the
    subrequest responses. For example, when using the standard `ngx_proxy` module to serve
    subrequests, an "Accept-Encoding: gzip" header in the main request may result
    in gzipped responses that cannot be handled properly in Lua code. Original request headers should be ignored by setting
    [proxy_pass_request_headers](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass_request_headers) to `off` in subrequest locations.
    
    When the `body` option is not specified and the `always_forward_body` option is false (the default value), the `POST` and `PUT` subrequests will inherit the request bodies of the parent request (if any).
    
    There is a hard-coded upper limit on the number of subrequests possible for every main request. In older versions of Nginx, the limit was `50` concurrent subrequests and in more recent versions, Nginx `1.9.5` onwards, the same limit is changed to limit the depth of recursive subrequests. When this limit is exceeded, the following error message is added to the `error.log` file:
    
    
        [error] 13983#0: *1 subrequests cycle while processing "/uri"
    
    
    The limit can be manually modified if required by editing the definition of the `NGX_HTTP_MAX_SUBREQUESTS` macro in the `nginx/src/http/ngx_http_request.h` file in the Nginx source tree.
    
    Please also refer to restrictions on capturing locations configured by [subrequest directives of other modules](#locations-configured-by-subrequest-directives-of-other-modules).
    
    [Back to TOC](#nginx-api-for-lua)
    
    ngx.location.capture_multi
    --------------------------
    
    **syntax:** *res1, res2, ... = ngx.location.capture_multi({ {uri, options?}, {uri, options?}, ... })*
    
    **context:** *rewrite_by_lua&#42;, access_by_lua&#42;, content_by_lua&#42;*
    
    Just like [ngx.location.capture](#ngxlocationcapture), but supports multiple subrequests running in parallel.
    
    This function issues several parallel subrequests specified by the input table and returns their results in the same order. For example,
    
    ```lua
    
     res1, res2, res3 = ngx.location.capture_multi{
         { "/foo", { args = "a=3&b=4" } },
         { "/bar" },
         { "/baz", { method = ngx.HTTP_POST, body = "hello" } },
     }
    
     if res1.status == ngx.HTTP_OK then
         ...
     end
    
     if res2.body == "BLAH" then
         ...
     end
    ```
    
    This function will not return until all the subrequests terminate.
    The total latency is the longest latency of the individual subrequests rather than the sum.
    
    Lua tables can be used for both requests and responses when the number of subrequests to be issued is not known in advance:
    
    ```lua
    
     -- construct the requests table
     local reqs = {}
     table.insert(reqs, { "/mysql" })
     table.insert(reqs, { "/postgres" })
     table.insert(reqs, { "/redis" })
     table.insert(reqs, { "/memcached" })
    
     -- issue all the requests at once and wait until they all return
    
     local resps = {
         ngx.location.capture_multi(reqs)
     }
    
    
     -- loop over the responses table
     for i, resp in ipairs(resps) do
         -- process the response table "resp"
     end
    ```
    
    The [ngx.location.capture](#ngxlocationcapture) function is just a special form
    of this function. Logically speaking, the [ngx.location.capture](#ngxlocationcapture) can be implemented like this
    
    ```lua
    
     ngx.location.capture =
         function (uri, args)
             return ngx.location.capture_multi({ {uri, args} })
         end
    ```
    
    Please also refer to restrictions on capturing locations configured by [subrequest directives of other modules](#locations-configured-by-subrequest-directives-of-other-modules).
    
    [Back to TOC](#nginx-api-for-lua)
    
    ngx.status
    ----------
    
    **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;*
    
    Read and write the current request's response status. This should be called
    before sending out the response headers.
    
    ```lua
    
     ngx.status = ngx.HTTP_CREATED
     status = ngx.status
    ```
    
    Setting `ngx.status` after the response header is sent out has no effect but leaving an error message in your Nginx's error log file:
    
    
        attempt to set ngx.status after sending out response headers
    
    
    [Back to TOC](#nginx-api-for-lua)
    
    ngx.header.HEADER
    -----------------
    
    **syntax:** *ngx.header.HEADER = VALUE*
    
    **syntax:** *value = ngx.header.HEADER*
    
    **context:** *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;*
    
    Set, add to, or clear the current request's `HEADER` response header that is to be sent.
    
    Underscores (`_`) in the header names will be replaced by hyphens (`-`) by default. This transformation can be turned off via the [lua_transform_underscores_in_response_headers](#lua_transform_underscores_in_response_headers) directive.
    
    The header names are matched case-insensitively.
    
    ```lua
    
     -- equivalent to ngx.header["Content-Type"] = 'text/plain'
     ngx.header.content_type = 'text/plain'
    
     ngx.header["X-My-Header"] = 'blah blah'
    ```
    
    Multi-value headers can be set this way:
    
    ```lua
    
     ngx.header['Set-Cookie'] = {'a=32; path=/', 'b=4; path=/'}
    ```
    
    will yield
    
    ```bash
    
     Set-Cookie: a=32; path=/
     Set-Cookie: b=4; path=/
    ```
    
    in the response headers.
    
    Only Lua tables are accepted (Only the last element in the table will take effect for standard headers such as `Content-Type` that only accept a single value).
    
    ```lua
    
     ngx.header.content_type = {'a', 'b'}
    ```
    
    is equivalent to
    
    ```lua
    
     ngx.header.content_type = 'b'
    ```
    
    Setting a slot to `nil` effectively removes it from the response headers:
    
    ```lua
    
     ngx.header["X-My-Header"] = nil
    ```
    
    The same applies to assigning an empty table:
    
    ```lua
    
     ngx.header["X-My-Header"] = {}
    ```
    
    Setting `ngx.header.HEADER` after sending out response headers (either explicitly with [ngx.send_headers](#ngxsend_headers) or implicitly with [ngx.print](#ngxprint) and similar) will log an error message.
    
    Reading `ngx.header.HEADER` will return the value of the response header named `HEADER`.
    
    Underscores (`_`) in the header names will also be replaced by dashes (`-`) and the header names will be matched case-insensitively. If the response header is not present at all, `nil` will be returned.
    
    This is particularly useful in the context of [header_filter_by_lua*](#header_filter_by_lua), for example,
    
    ```nginx
    
     location /test {
         set $footer '';
    
         proxy_pass http://some-backend;
    
         header_filter_by_lua_block {
             if ngx.header["X-My-Header"] == "blah" then
                 ngx.var.footer = "some value"
             end
         }
    
         echo_after_body $footer;
     }
    ```
    
    For multi-value headers, all of the values of header will be collected in order and returned as a Lua table. For example, response headers
    
    
        Foo: bar
        Foo: baz
    
    
    will result in
    
    ```lua
    
     {"bar", "baz"}
    ```
    
    to be returned when reading `ngx.header.Foo`.
    
    Note that `ngx.header` is not a normal Lua table and as such, it is not possible to iterate through it using the Lua `ipairs` function.
    
    Note: this function throws a Lua error if `HEADER` or
    `VALUE` contain unsafe characters (control characters).
    
    For reading *request* headers, use the [ngx.req.get_headers](#ngxreqget_headers) function instead.
    
    [Back to TOC](#nginx-api-for-lua)
    
    ngx.resp.get_headers
    --------------------
    
    **syntax:** *headers, err = ngx.resp.get_headers(max_headers?, raw?)*
    
    **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;*
    
    Returns a Lua table holding all the current response headers for the current request.
    
    ```lua
    
     local h, err = ngx.resp.get_headers()
    
     if err == "truncated" then
         -- one can choose to ignore or reject the current response here
     end
    
     for k, v in pairs(h) do
         ...
     end
    ```
    
    This function has the same signature as [ngx.req.get_headers](#ngxreqget_headers) except getting response headers instead of request headers.
    
    Note that a maximum of 100 response headers are parsed by default (including those with the same name) and that additional response headers are silently discarded to guard against potential denial of service attacks. Since `v0.10.13`, when the limit is exceeded, it will return a second value which is the string `"truncated"`.
    
    This API was first introduced in the `v0.9.5` release.
    
    [Back to TOC](#nginx-api-for-lua)
    
    ngx.req.is_internal
    -------------------
    
    **syntax:** *is_internal = ngx.req.is_internal()*
    
    **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;*
    
    Returns a boolean indicating whether the current request is an "internal request", i.e.,
    a request initiated from inside the current Nginx server instead of from the client side.
    
    Subrequests are all internal requests and so are requests after internal redirects.
    
    This API was first introduced in the `v0.9.20` release.
    
    [Back to TOC](#nginx-api-for-lua)
    
    ngx.req.start_time
    ------------------
    
    **syntax:** *secs = ngx.req.start_time()*
    
    **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;*
    
    Returns a floating-point number representing the timestamp (including milliseconds as the decimal part) when the current request was created.
    
    The following example emulates the `$request_time` variable value (provided by [ngx_http_log_module](http://nginx.org/en/docs/http/ngx_http_log_module.html)) in pure Lua:
    
    ```lua
    
     local request_time = ngx.now() - ngx.req.start_time()
    ```
    
    This function was first introduced in the `v0.7.7` release.
    
    See also [ngx.now](#ngxnow) and [ngx.update_time](#ngxupdate_time).
    
    [Back to TOC](#nginx-api-for-lua)
    
    ngx.req.http_version
    --------------------
    
    **syntax:** *num = ngx.req.http_version()*
    
    **context:** *set_by_lua&#42;, rewrite_by_lua&#42;, access_by_lua&#42;, content_by_lua&#42;, header_filter_by_lua&#42;*
    
    Returns the HTTP version number for the current request as a Lua number.
    
    
    Current possible values are 3.0, 2.0, 1.0, 1.1, and 0.9. Returns `nil` for unrecognized values.
    
    
    This method was first introduced in the `v0.7.17` release.
    
    [Back to TOC](#nginx-api-for-lua)
    
    ngx.req.raw_header
    ------------------
    
    **syntax:** *str = ngx.req.raw_header(no_request_line?)*
    
    **context:** *set_by_lua&#42;, rewrite_by_lua&#42;, access_by_lua&#42;, content_by_lua&#42;, header_filter_by_lua&#42;*
    
    Returns the original raw HTTP protocol header received by the Nginx server.
    
    By default, the request line and trailing `CR LF` terminator will also be included. For example,
    
    ```lua
    
     ngx.print(ngx.req.raw_header())
    ```
    
    gives something like this:
    
    
        GET /t HTTP/1.1
        Host: localhost
        Connection: close
        Foo: bar
    
    
    
    You can specify the optional
    `no_request_line` argument as a `true` value to exclude the request line from the result. For example,
    
    ```lua
    
     ngx.print(ngx.req.raw_header(true))
    ```
    
    outputs something like this:
    
    
        Host: localhost
        Connection: close
        Foo: bar
    
    
    
    This method was first introduced in the `v0.7.17` release.
    
    This method does not work in HTTP/2 requests yet.
    
    [Back to TOC](#nginx-api-for-lua)
    
    ngx.req.get_method
    ------------------
    
    **syntax:** *method_name = ngx.req.get_method()*
    
    **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;, balancer_by_lua&#42;, log_by_lua&#42;*
    
    Retrieves the current request's request method name. Strings like `"GET"` and `"POST"` are returned instead of numerical [method constants](#http-method-constants).
    
    If the current request is an Nginx subrequest, then the subrequest's method name will be returned.
    
    This method was first introduced in the `v0.5.6` release.
    
    See also [ngx.req.set_method](#ngxreqset_method).
    
    [Back to TOC](#nginx-api-for-lua)
    
    ngx.req.set_method
    ------------------
    
    **syntax:** *ngx.req.set_method(method_id)*
    
    **context:** *set_by_lua&#42;, rewrite_by_lua&#42;, access_by_lua&#42;, content_by_lua&#42;, header_filter_by_lua&#42;*
    
    Overrides the current request's request method with the `method_id` argument. Currently only numerical [method constants](#http-method-constants) are supported, like `ngx.HTTP_POST` and `ngx.HTTP_GET`.
    
    If the current request is an Nginx subrequest, then the subrequest's method will be overridden.
    
    This method was first introduced in the `v0.5.6` release.
    
    See also [ngx.req.get_method](#ngxreqget_method).
    
    [Back to TOC](#nginx-api-for-lua)
    
    ngx.req.set_uri
    ---------------
    
    **syntax:** *ngx.req.set_uri(uri, jump?, binary?)*
    
    **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;*
    
    Rewrite the current request's (parsed) URI by the `uri` argument. The `uri` argument must be a Lua string and cannot be of zero length, or a Lua exception will be thrown.
    
    The optional boolean `jump` argument can trigger location rematch (or location jump) as [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, that is, when `jump` is `true` (default to `false`), this function will never return and it will tell Nginx to try re-searching locations with the new URI value at the later `post-rewrite` phase and jumping to the new location.
    
    Location jump will not be triggered otherwise, and only the current request's URI will be modified, which is also the default behavior. This function will return but with no returned values when the `jump` argument is `false` or absent altogether.
    
    For example, the following Nginx config snippet
    
    ```nginx
    
     rewrite ^ /foo last;
    ```
    
    can be coded in Lua like this:
    
    ```lua
    
     ngx.req.set_uri("/foo", true)
    ```
    
    Similarly, Nginx config
    
    ```nginx
    
     rewrite ^ /foo break;
    ```
    
    can be coded in Lua as
    
    ```lua
    
     ngx.req.set_uri("/foo", false)
    ```
    
    or equivalently,
    
    ```lua
    
     ngx.req.set_uri("/foo")
    ```
    
    The `jump` argument can only be set to `true` in [rewrite_by_lua*](#rewrite_by_lua). Use of jump in other contexts is prohibited and will throw out a Lua exception.
    
    A more sophisticated example involving regex substitutions is as follows
    
    ```nginx
    
     location /test {
         rewrite_by_lua_block {
             local uri = ngx.re.sub(ngx.var.uri, "^/test/(.*)", "/$1", "o")
             ngx.req.set_uri(uri)
         }
         proxy_pass http://my_backend;
     }
    ```
    
    which is functionally equivalent to
    
    ```nginx