improved the README file's formatting.
This commit is contained in:
Родитель
58d6bc91e2
Коммит
b25d06b326
511
README
511
README
|
@ -8,8 +8,8 @@ Status
|
|||
This module is under active development and is already production ready.
|
||||
|
||||
Version
|
||||
This document describes ngx_lua v0.3.1rc18
|
||||
(<https://github.com/chaoslawful/lua-nginx-module/tags>) released on 21
|
||||
This document describes ngx_lua v0.3.1rc19
|
||||
(<https://github.com/chaoslawful/lua-nginx-module/tags>) released on 22
|
||||
October 2011.
|
||||
|
||||
Synopsis
|
||||
|
@ -300,8 +300,10 @@ Directives
|
|||
|
||||
Note that set_by_lua can only output a value to a single Nginx variable
|
||||
at a time. But a work-around is also available by means of the
|
||||
ngx.var.VARIABLE interface, for example, location /foo { set $diff ''; #
|
||||
we have to predefine the $diff variable here
|
||||
ngx.var.VARIABLE interface, for example,
|
||||
|
||||
location /foo {
|
||||
set $diff ''; # we have to predefine the $diff variable here
|
||||
|
||||
set_by_lua $sum '
|
||||
local a = 32
|
||||
|
@ -317,9 +319,11 @@ Directives
|
|||
This directive can be freely mixed with all the directives of
|
||||
[[HttpRewriteModule]], [[HttpSetMiscModule]], and
|
||||
[[HttpArrayVarModule]]. All of these directives will run in exactly the
|
||||
same order that they are written in the config file. For example, set
|
||||
$foo 32; set_by_lua $bar 'tonumber(ngx.var.foo) + 1'; set $baz "bar:
|
||||
$bar"; # $baz == "bar: 33"
|
||||
same order that they are written in the config file. For example,
|
||||
|
||||
set $foo 32;
|
||||
set_by_lua $bar 'tonumber(ngx.var.foo) + 1';
|
||||
set $baz "bar: $bar"; # $baz == "bar: 33"
|
||||
|
||||
This directive requires the ngx_devel_kit
|
||||
(<https://github.com/simpl/ngx_devel_kit>) module.
|
||||
|
@ -637,8 +641,12 @@ Directives
|
|||
ngx.location.capture_multi)
|
||||
|
||||
Here's a small example of overriding a response header (or adding if it
|
||||
does not exist) in our Lua header filter: location / { proxy_pass
|
||||
http://mybackend; header_filter_by_lua 'ngx.header.Foo = "blah"'; }
|
||||
does not exist) in our Lua header filter:
|
||||
|
||||
location / {
|
||||
proxy_pass http://mybackend;
|
||||
header_filter_by_lua 'ngx.header.Foo = "blah"';
|
||||
}
|
||||
|
||||
This directive was first introduced in the "v0.2.1rc20" release.
|
||||
|
||||
|
@ -757,10 +765,17 @@ Nginx API for Lua
|
|||
context: *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*,
|
||||
header_filter_by_lua** value = ngx.var.some_nginx_variable_name
|
||||
ngx.var.some_nginx_variable_name = value Note that you can only write to
|
||||
nginx variables that are already defined. For example: location /foo {
|
||||
set $my_var ''; # this line is required to create $my_var at config time
|
||||
content_by_lua ' ngx.var.my_var = 123; ... '; } That is, nginx variables
|
||||
cannot be created on-the-fly.
|
||||
nginx variables that are already defined. For example:
|
||||
|
||||
location /foo {
|
||||
set $my_var ''; # this line is required to create $my_var at config time
|
||||
content_by_lua '
|
||||
ngx.var.my_var = 123;
|
||||
...
|
||||
';
|
||||
}
|
||||
|
||||
That is, nginx variables cannot be created on-the-fly.
|
||||
|
||||
Some special nginx variables like $args and $limit_rate can be assigned
|
||||
a value, some are not, like $arg_PARAMETER.
|
||||
|
@ -777,8 +792,10 @@ Nginx API for Lua
|
|||
ngx.ERROR (-1)
|
||||
ngx.AGAIN (-2)
|
||||
ngx.DONE (-4)
|
||||
They take the same values of C<NGX_OK>, C<NGX_AGAIN>, C<NGX_DONE>, C<NGX_ERROR>, and etc. But now
|
||||
only L<ngx.exit|/"ngx.exit"> only take two of these values, i.e., C<NGX_OK> and C<NGX_ERROR>.
|
||||
|
||||
They take the same values of "NGX_OK", "NGX_AGAIN", "NGX_DONE",
|
||||
"NGX_ERROR", and etc. But now only ngx.exit only take two of these
|
||||
values, i.e., "NGX_OK" and "NGX_ERROR".
|
||||
|
||||
HTTP method constants
|
||||
context: *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*,
|
||||
|
@ -795,21 +812,38 @@ Nginx API for Lua
|
|||
|
||||
HTTP status constants
|
||||
context: *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*,
|
||||
header_filter_by_lua** value = ngx.HTTP_OK (200) value =
|
||||
ngx.HTTP_CREATED (201) 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_BAD_REQUEST (400) value = ngx.HTTP_UNAUTHORIZED
|
||||
(401) value = ngx.HTTP_FORBIDDEN (403) value = ngx.HTTP_NOT_FOUND (404)
|
||||
value = ngx.HTTP_NOT_ALLOWED (405) value = ngx.HTTP_GONE (410) value =
|
||||
ngx.HTTP_INTERNAL_SERVER_ERROR (500) value =
|
||||
ngx.HTTP_METHOD_NOT_IMPLEMENTED (501) value =
|
||||
ngx.HTTP_SERVICE_UNAVAILABLE (503)
|
||||
header_filter_by_lua**
|
||||
|
||||
value = ngx.HTTP_OK (200)
|
||||
value = ngx.HTTP_CREATED (201)
|
||||
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_BAD_REQUEST (400)
|
||||
value = ngx.HTTP_UNAUTHORIZED (401)
|
||||
value = ngx.HTTP_FORBIDDEN (403)
|
||||
value = ngx.HTTP_NOT_FOUND (404)
|
||||
value = ngx.HTTP_NOT_ALLOWED (405)
|
||||
value = ngx.HTTP_GONE (410)
|
||||
value = ngx.HTTP_INTERNAL_SERVER_ERROR (500)
|
||||
value = ngx.HTTP_METHOD_NOT_IMPLEMENTED (501)
|
||||
value = ngx.HTTP_SERVICE_UNAVAILABLE (503)
|
||||
|
||||
Nginx log level constants
|
||||
context: *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*,
|
||||
header_filter_by_lua** ngx.STDERR ngx.EMERG ngx.ALERT ngx.CRIT ngx.ERR
|
||||
ngx.WARN ngx.NOTICE ngx.INFO ngx.DEBUG
|
||||
header_filter_by_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 method.
|
||||
|
||||
|
@ -822,8 +856,11 @@ Nginx API for Lua
|
|||
Emit args concatenated to nginx's "error.log" file, with log level
|
||||
"ngx.NOTICE" and prefix "lua print: ".
|
||||
|
||||
It's equivalent to ngx.log(ngx.NOTICE, 'lua print: ', a, b, ...) Lua
|
||||
"nil" arguments are accepted and result in literal "nil", and Lua
|
||||
It's equivalent to
|
||||
|
||||
ngx.log(ngx.NOTICE, 'lua print: ', a, b, ...)
|
||||
|
||||
Lua "nil" arguments are accepted and result in literal "nil", and Lua
|
||||
booleans result in "true" or "false".
|
||||
|
||||
ngx.ctx
|
||||
|
@ -834,16 +871,38 @@ Nginx API for Lua
|
|||
programmers.
|
||||
|
||||
This table has a liftime identical to the current request (just like
|
||||
Nginx variables). Consider the following example, location /test {
|
||||
rewrite_by_lua ' ngx.say("foo = ", ngx.ctx.foo) ngx.ctx.foo = 76 ';
|
||||
access_by_lua ' ngx.ctx.foo = ngx.ctx.foo + 3 '; content_by_lua '
|
||||
ngx.say(ngx.ctx.foo) '; } Then "GET /test" will yield the output foo =
|
||||
nil 79 That is, the "ngx.ctx.foo" entry persists across the rewrite,
|
||||
access, and content phases of a request.
|
||||
Nginx variables). Consider the following example,
|
||||
|
||||
location /test {
|
||||
rewrite_by_lua '
|
||||
ngx.say("foo = ", ngx.ctx.foo)
|
||||
ngx.ctx.foo = 76
|
||||
';
|
||||
access_by_lua '
|
||||
ngx.ctx.foo = ngx.ctx.foo + 3
|
||||
';
|
||||
content_by_lua '
|
||||
ngx.say(ngx.ctx.foo)
|
||||
';
|
||||
}
|
||||
|
||||
Then "GET /test" will yield the output
|
||||
|
||||
foo = nil
|
||||
79
|
||||
|
||||
That is, the "ngx.ctx.foo" entry persists across the rewrite, access,
|
||||
and content phases of a request.
|
||||
|
||||
Also, every request has its own copy, include subrequests, for example:
|
||||
location /sub { content_by_lua ' ngx.say("sub pre: ", ngx.ctx.blah)
|
||||
ngx.ctx.blah = 32 ngx.say("sub post: ", ngx.ctx.blah) '; }
|
||||
|
||||
location /sub {
|
||||
content_by_lua '
|
||||
ngx.say("sub pre: ", ngx.ctx.blah)
|
||||
ngx.ctx.blah = 32
|
||||
ngx.say("sub post: ", ngx.ctx.blah)
|
||||
';
|
||||
}
|
||||
|
||||
location /main {
|
||||
content_by_lua '
|
||||
|
@ -854,16 +913,27 @@ Nginx API for Lua
|
|||
ngx.say("main post: ", ngx.ctx.blah)
|
||||
';
|
||||
}
|
||||
Then C<GET /main> will give the output
|
||||
|
||||
Then "GET /main" will give the output
|
||||
|
||||
main pre: 73
|
||||
sub pre: nil
|
||||
sub post: 32
|
||||
main post: 73
|
||||
We can see that modification of the C<ngx.ctx.blah> entry in the subrequest does not affect the one in its parent request. They do have two separate versions of C<ngx.ctx.blah> per se.
|
||||
|
||||
We can see that modification of the "ngx.ctx.blah" entry in the
|
||||
subrequest does not affect the one in its parent request. They do have
|
||||
two separate versions of "ngx.ctx.blah" per se.
|
||||
|
||||
Internal redirection will destroy the original request's "ngx.ctx" data
|
||||
(if any) and the new request will have an emptied "ngx.ctx" table. For
|
||||
instance, location /new { content_by_lua ' ngx.say(ngx.ctx.foo) '; }
|
||||
instance,
|
||||
|
||||
location /new {
|
||||
content_by_lua '
|
||||
ngx.say(ngx.ctx.foo)
|
||||
';
|
||||
}
|
||||
|
||||
location /orig {
|
||||
content_by_lua '
|
||||
|
@ -871,16 +941,21 @@ Nginx API for Lua
|
|||
ngx.exec("/new")
|
||||
';
|
||||
}
|
||||
Then C<GET /orig> will give you
|
||||
|
||||
Then "GET /orig" will give you
|
||||
|
||||
nil
|
||||
rather than the original C<"hello"> value.
|
||||
|
||||
rather than the original "hello" value.
|
||||
|
||||
Arbitrary data values can be inserted into this "matic" table, including
|
||||
Lua closures and nested tables. You can also register your own meta
|
||||
methods with it.
|
||||
|
||||
Overriding "ngx.ctx" with a new Lua table is also supported, for
|
||||
example, ngx.ctx = { foo = 32, bar = 54 }
|
||||
example,
|
||||
|
||||
ngx.ctx = { foo = 32, bar = 54 }
|
||||
|
||||
ngx.location.capture
|
||||
syntax: *res = ngx.location.capture(uri, options?)*
|
||||
|
@ -903,30 +978,46 @@ Nginx API for Lua
|
|||
Subrequests are completely different from HTTP 301/302 redirection (via
|
||||
ngx.redirect) and internal redirection (via ngx.exec).
|
||||
|
||||
Here's a basic example: res = ngx.location.capture(uri) Returns a Lua
|
||||
table with three slots ("res.status", "res.header", and "res.body").
|
||||
Here's a basic example:
|
||||
|
||||
res = ngx.location.capture(uri)
|
||||
|
||||
Returns a Lua table with three slots ("res.status", "res.header", and
|
||||
"res.body").
|
||||
|
||||
"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 contains the following
|
||||
lines: Set-Cookie: a=3 Set-Cookie: foo=bar Set-Cookie: baz=blah Then
|
||||
"res.header["Set-Cookie"]" will be evaluted to the table value "{"a=3",
|
||||
"foo=bar", "baz=blah"}".
|
||||
lines:
|
||||
|
||||
URI query strings can be concatenated to URI itself, for instance, 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.
|
||||
Set-Cookie: a=3
|
||||
Set-Cookie: foo=bar
|
||||
Set-Cookie: baz=blah
|
||||
|
||||
Then "res.header["Set-Cookie"]" will be evaluted to the table value
|
||||
"{"a=3", "foo=bar", "baz=blah"}".
|
||||
|
||||
URI query strings can be concatenated to URI itself, for instance,
|
||||
|
||||
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
|
||||
support various options like "method", "body", "args", and
|
||||
"share_all_vars". Issuing a POST subrequest, for example, can be done as
|
||||
follows 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.
|
||||
follows
|
||||
|
||||
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 "share_all_vars" option can control whether to share nginx variables
|
||||
among the current request and the new subrequest. If this option is set
|
||||
|
@ -937,16 +1028,27 @@ Nginx API for Lua
|
|||
special care. So, by default, the option is set to "false".
|
||||
|
||||
The "args" option can specify extra url arguments, for instance,
|
||||
ngx.location.capture('/foo?a=1', { args = { b = 3, c = ':' } } ) is
|
||||
equivalent to ngx.location.capture('/foo?a=1&b=3&c=%3a') that is, this
|
||||
method will automatically escape argument keys and values according to
|
||||
URI rules and concatenating them together into a complete query string.
|
||||
Because it's all done in hand-written C, it should be faster than your
|
||||
own Lua code.
|
||||
|
||||
ngx.location.capture('/foo?a=1',
|
||||
{ args = { b = 3, c = ':' } }
|
||||
)
|
||||
|
||||
is equivalent to
|
||||
|
||||
ngx.location.capture('/foo?a=1&b=3&c=%3a')
|
||||
|
||||
that is, this method will automatically escape argument keys and values
|
||||
according to URI rules and concatenating them together into a complete
|
||||
query string. Because it's all done in hand-written C, it should be
|
||||
faster than your own Lua code.
|
||||
|
||||
The "args" option can also take plain query string:
|
||||
ngx.location.capture('/foo?a=1', { args = 'b=3&c=%3a' } } ) This is
|
||||
functionally identical to the previous examples.
|
||||
|
||||
ngx.location.capture('/foo?a=1',
|
||||
{ args = 'b=3&c=%3a' } }
|
||||
)
|
||||
|
||||
This is functionally identical to the previous examples.
|
||||
|
||||
Note that, by default, subrequests issued by ngx.location.capture
|
||||
inherit all the request headers of the current request. This may have
|
||||
|
@ -967,9 +1069,13 @@ Nginx API for Lua
|
|||
running in parallel.
|
||||
|
||||
This function issue several parallel subrequests specified by the input
|
||||
table, and returns their results in the same order. For example, res1,
|
||||
res2, res3 = ngx.location.capture_multi{ { "/foo", { args = "a=3&b=4" }
|
||||
}, { "/bar" }, { "/baz", { method = ngx.HTTP_POST, body = "hello" } }, }
|
||||
table, and returns their results in the same order. For example,
|
||||
|
||||
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
|
||||
...
|
||||
|
@ -978,14 +1084,20 @@ Nginx API for Lua
|
|||
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 subrequests, instead of their sum.
|
||||
|
||||
This function will not return until all the subrequests terminate. The
|
||||
total latency is the longest latency of the subrequests, instead of
|
||||
their sum.
|
||||
|
||||
When you don't know inadvance how many subrequests you want to issue,
|
||||
you can use Lua tables for both requests and responses. For instance, --
|
||||
construct the requests table local reqs = {} table.insert(reqs, {
|
||||
"/mysql" }) table.insert(reqs, { "/postgres" }) table.insert(reqs, {
|
||||
"/redis" }) table.insert(reqs, { "/memcached" })
|
||||
you can use Lua tables for both requests and responses. For instance,
|
||||
|
||||
-- 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) }
|
||||
|
@ -994,8 +1106,11 @@ Nginx API for Lua
|
|||
for i, resp in ipairs(resps) do
|
||||
-- process the response table "resp"
|
||||
end
|
||||
The L<ngx.location.capture|/"ngx.location.capture"> function is just a special form
|
||||
of this function. Logically speaking, the L<ngx.location.capture|/"ngx.location.capture"> can be implemented like this
|
||||
|
||||
The ngx.location.capture function is just a special form of this
|
||||
function. Logically speaking, the ngx.location.capture can be
|
||||
implemented like this
|
||||
|
||||
ngx.location.capture =
|
||||
function (uri, args)
|
||||
return ngx.location.capture_multi({ {uri, args} })
|
||||
|
@ -1006,8 +1121,10 @@ Nginx API for Lua
|
|||
header_filter_by_lua**
|
||||
|
||||
Read and write the current request's response status. This should be
|
||||
called before sending out the response headers. ngx.status =
|
||||
ngx.HTTP_CREATED status = ngx.status
|
||||
called before sending out the response headers.
|
||||
|
||||
ngx.status = ngx.HTTP_CREATED
|
||||
status = ngx.status
|
||||
|
||||
ngx.header.HEADER
|
||||
syntax: *ngx.header.HEADER = VALUE*
|
||||
|
@ -1212,28 +1329,62 @@ Nginx API for Lua
|
|||
Returns a Lua table holds all of the current request's request URL query
|
||||
arguments.
|
||||
|
||||
Here's an example, location = /test { content_by_lua ' local args =
|
||||
ngx.req.get_uri_args() for key, val in pairs(args) do if type(val) ==
|
||||
"table" then ngx.say(key, ": ", table.concat(val, ", ")) else
|
||||
ngx.say(key, ": ", val) end end '; } Then "GET
|
||||
/test?foo=bar&bar=baz&bar=blah" will yield the response body foo: bar
|
||||
bar: baz, blah Multiple occurrences of an argument key will result in a
|
||||
table value holding all of the values for that key in order.
|
||||
Here's an example,
|
||||
|
||||
location = /test {
|
||||
content_by_lua '
|
||||
local args = ngx.req.get_uri_args()
|
||||
for key, val in pairs(args) do
|
||||
if type(val) == "table" then
|
||||
ngx.say(key, ": ", table.concat(val, ", "))
|
||||
else
|
||||
ngx.say(key, ": ", val)
|
||||
end
|
||||
end
|
||||
';
|
||||
}
|
||||
|
||||
Then "GET /test?foo=bar&bar=baz&bar=blah" will yield the response body
|
||||
|
||||
foo: bar
|
||||
bar: baz, blah
|
||||
|
||||
Multiple occurrences of an argument key will result in a table value
|
||||
holding all of the values for that key in order.
|
||||
|
||||
Keys and values will be automatically unescaped according to URI
|
||||
escaping rules. For example, in the above settings, "GET
|
||||
/test?a%20b=1%61+2" will yield the output a b: 1a 2 Arguments without
|
||||
the "=<value>" parts are treated as boolean arguments. For example, "GET
|
||||
/test?foo&bar" will yield the outputs foo: true bar: true That is, they
|
||||
will take Lua boolean values "true". However, they're different from
|
||||
arguments taking empty string values. For example, "GET /test?foo=&bar="
|
||||
will give something like foo: bar: Empty key arguments are discarded,
|
||||
for instance, "GET /test?=hello&=world" will yield empty outputs.
|
||||
/test?a%20b=1%61+2" will yield the output
|
||||
|
||||
a b: 1a 2
|
||||
|
||||
Arguments without the "=<value>" parts are treated as boolean arguments.
|
||||
For example, "GET /test?foo&bar" will yield the outputs
|
||||
|
||||
foo: true
|
||||
bar: true
|
||||
|
||||
That is, they will take Lua boolean values "true". However, they're
|
||||
different from arguments taking empty string values. For example, "GET
|
||||
/test?foo=&bar=" will give something like
|
||||
|
||||
foo:
|
||||
bar:
|
||||
|
||||
Empty key arguments are discarded, for instance, "GET
|
||||
/test?=hello&=world" will yield empty outputs.
|
||||
|
||||
Updating query arguments via the nginx variable $args (or "ngx.var.args"
|
||||
in Lua) at runtime are also supported: ngx.var.args = "a=3&b=42" local
|
||||
args = ngx.req.get_uri_args() Here the "args" table will always look
|
||||
like {a = 3, b = 42} regardless of the actual request query string.
|
||||
in Lua) at runtime are also supported:
|
||||
|
||||
ngx.var.args = "a=3&b=42"
|
||||
local args = ngx.req.get_uri_args()
|
||||
|
||||
Here the "args" table will always look like
|
||||
|
||||
{a = 3, b = 42}
|
||||
|
||||
regardless of the actual request query string.
|
||||
|
||||
ngx.req.get_post_args
|
||||
syntax: *ngx.req.get_post_args()*
|
||||
|
@ -1242,30 +1393,63 @@ Nginx API for Lua
|
|||
header_filter_by_lua**
|
||||
|
||||
Returns a Lua table holds all of the current request's POST query
|
||||
arguments. It's required to turn on the lua_need_request_body directive,
|
||||
or a Lua exception will be thrown.
|
||||
arguments. It's required to read the request body first by calling
|
||||
ngx.req.read_body or to turn on the lua_need_request_body directive, or
|
||||
a Lua exception will be thrown.
|
||||
|
||||
Here's an example, location = /test { lua_need_request_body on;
|
||||
content_by_lua ' local args = ngx.req.get_post_args() for key, val in
|
||||
pairs(args) do if type(val) == "table" then ngx.say(key, ": ",
|
||||
table.concat(val, ", ")) else ngx.say(key, ": ", val) end end '; } Then
|
||||
# Post request with the body 'foo=bar&bar=baz&bar=blah' $ curl --data
|
||||
'foo=bar&bar=baz&bar=blah' localhost/test will yield the response body
|
||||
like foo: bar bar: baz, blah Multiple occurrences of an argument key
|
||||
will result in a table value holding all of the values for that key in
|
||||
order.
|
||||
Here's an example,
|
||||
|
||||
location = /test {
|
||||
content_by_lua '
|
||||
ngx.req.read_body()
|
||||
for key, val in pairs(args) do
|
||||
if type(val) == "table" then
|
||||
ngx.say(key, ": ", table.concat(val, ", "))
|
||||
else
|
||||
ngx.say(key, ": ", val)
|
||||
end
|
||||
end
|
||||
';
|
||||
}
|
||||
|
||||
Then
|
||||
|
||||
# Post request with the body 'foo=bar&bar=baz&bar=blah'
|
||||
$ curl --data 'foo=bar&bar=baz&bar=blah' localhost/test
|
||||
|
||||
will yield the response body like
|
||||
|
||||
foo: bar
|
||||
bar: baz, blah
|
||||
|
||||
Multiple occurrences of an argument key will result in a table value
|
||||
holding all of the values for that key in order.
|
||||
|
||||
Keys and values will be automatically unescaped according to URI
|
||||
escaping rules. For example, in the above settings, # POST request with
|
||||
body 'a%20b=1%61+2' $ curl -d 'a%20b=1%61+2' localhost/test will yield
|
||||
the output a b: 1a 2 Arguments without the "=<value>" parts are treated
|
||||
as boolean arguments. For example, "GET /test?foo&bar" will yield the
|
||||
outputs foo: true bar: true That is, they will take Lua boolean values
|
||||
"true". However, they're different from arguments taking empty string
|
||||
values. For example, "POST /test" with request body "foo=&bar=" will
|
||||
give something like foo: bar: Empty key arguments are discarded, for
|
||||
instance, "POST /test" with body "=hello&=world" will yield empty
|
||||
outputs.
|
||||
escaping rules. For example, in the above settings,
|
||||
|
||||
# POST request with body 'a%20b=1%61+2'
|
||||
$ curl -d 'a%20b=1%61+2' localhost/test
|
||||
|
||||
will yield the output
|
||||
|
||||
a b: 1a 2
|
||||
|
||||
Arguments without the "=<value>" parts are treated as boolean arguments.
|
||||
For example, "GET /test?foo&bar" will yield the outputs
|
||||
|
||||
foo: true
|
||||
bar: true
|
||||
|
||||
That is, they will take Lua boolean values "true". However, they're
|
||||
different from arguments taking empty string values. For example, "POST
|
||||
/test" with request body "foo=&bar=" will give something like
|
||||
|
||||
foo:
|
||||
bar:
|
||||
|
||||
Empty key arguments are discarded, for instance, "POST /test" with body
|
||||
"=hello&=world" will yield empty outputs.
|
||||
|
||||
ngx.req.get_headers
|
||||
syntax: *headers = ngx.req.get_headers()*
|
||||
|
@ -1275,14 +1459,30 @@ Nginx API for Lua
|
|||
|
||||
Returns a Lua table holds all of the current request's request headers.
|
||||
|
||||
Here's an example, local h = ngx.req.get_headers() for k, v in pairs(h)
|
||||
do ... end To read an individual header: ngx.say("Host: ",
|
||||
ngx.req.get_headers()["Host"]) For multiple instances of request headers
|
||||
like Foo: foo Foo: bar Foo: baz the value of
|
||||
"ngx.req.get_headers()["Foo"]" will be a Lua (array) table like this:
|
||||
{"foo", "bar", "baz"} Another way to read individual request headers is
|
||||
to use "ngx.var.http_HEADER", that is, nginx's standard $http_HEADER
|
||||
variables.
|
||||
Here's an example,
|
||||
|
||||
local h = ngx.req.get_headers()
|
||||
for k, v in pairs(h) do
|
||||
...
|
||||
end
|
||||
|
||||
To read an individual header:
|
||||
|
||||
ngx.say("Host: ", ngx.req.get_headers()["Host"])
|
||||
|
||||
For multiple instances of request headers like
|
||||
|
||||
Foo: foo
|
||||
Foo: bar
|
||||
Foo: baz
|
||||
|
||||
the value of "ngx.req.get_headers()["Foo"]" will be a Lua (array) table
|
||||
like this:
|
||||
|
||||
{"foo", "bar", "baz"}
|
||||
|
||||
Another way to read individual request headers is to use
|
||||
"ngx.var.http_HEADER", that is, nginx's standard $http_HEADER variables.
|
||||
|
||||
ngx.req.set_header
|
||||
syntax: *ngx.req.set_header(header_name, header_value)*
|
||||
|
@ -1295,14 +1495,28 @@ Nginx API for Lua
|
|||
request's subrequests will be affected.
|
||||
|
||||
Here's an example of setting the "Content-Length" header:
|
||||
ngx.req.set_header("Content-Type", "text/css") The "header_value" can
|
||||
take an array list of values, for example, ngx.req.set_header("Foo",
|
||||
{"a", "abc"}) will produce two new request headers: Foo: a Foo: abc and
|
||||
old "Foo" headers will be overridden if there's any.
|
||||
|
||||
ngx.req.set_header("Content-Type", "text/css")
|
||||
|
||||
The "header_value" can take an array list of values, for example,
|
||||
|
||||
ngx.req.set_header("Foo", {"a", "abc"})
|
||||
|
||||
will produce two new request headers:
|
||||
|
||||
Foo: a
|
||||
Foo: abc
|
||||
|
||||
and old "Foo" headers will be overridden if there's any.
|
||||
|
||||
When the "header_value" argument is "nil", the request header will be
|
||||
removed. So ngx.req.set_header("X-Foo", nil) is equivalent to
|
||||
ngx.req.clear_header("X-Foo")
|
||||
removed. So
|
||||
|
||||
ngx.req.set_header("X-Foo", nil)
|
||||
|
||||
is equivalent to
|
||||
|
||||
ngx.req.clear_header("X-Foo")
|
||||
|
||||
ngx.req.read_body
|
||||
syntax: *ngx.req.read_body()*
|
||||
|
@ -1337,6 +1551,11 @@ Nginx API for Lua
|
|||
ngx.req.discard_body function to explicitly discard the request body, or
|
||||
you'll break HTTP 1.1 keepalive and HTTP 1.1 pipelining.
|
||||
|
||||
Here's a small example:
|
||||
|
||||
ngx.req.read_body()
|
||||
local args = ngx.req.get_post_args()
|
||||
|
||||
This function was first introduced in the "v0.3.1rc17" release.
|
||||
|
||||
ngx.req.discard_body
|
||||
|
@ -1841,8 +2060,10 @@ Nginx API for Lua
|
|||
|
||||
Returns a formated string can be used as the cookie expiration time. The
|
||||
parameter "sec" is the timestamp in seconds (like those returned from
|
||||
ngx.time). ngx.say(ngx.cookie_time(1290079655)) -- yields "Thu,
|
||||
18-Nov-10 11:27:35 GMT"
|
||||
ngx.time).
|
||||
|
||||
ngx.say(ngx.cookie_time(1290079655))
|
||||
-- yields "Thu, 18-Nov-10 11:27:35 GMT"
|
||||
|
||||
ngx.http_time
|
||||
syntax: *str = ngx.http_time(sec)*
|
||||
|
@ -1853,8 +2074,9 @@ Nginx API for Lua
|
|||
Returns a formated string can be used as the http header time (for
|
||||
example, being used in "Last-Modified" header). The parameter "sec" is
|
||||
the timestamp in seconds (like those returned from ngx.time).
|
||||
ngx.say(ngx.http_time(1290079655)) -- yields "Thu, 18 Nov 10 11:27:35
|
||||
GMT"
|
||||
|
||||
ngx.say(ngx.http_time(1290079655))
|
||||
-- yields "Thu, 18 Nov 10 11:27:35 GMT"
|
||||
|
||||
ngx.parse_http_time
|
||||
syntax: *sec = ngx.parse_http_time(str)*
|
||||
|
@ -1863,9 +2085,12 @@ Nginx API for Lua
|
|||
header_filter_by_lua**
|
||||
|
||||
Parse the http time string (as returned by ngx.http_time) into seconds.
|
||||
Returns the seconds or "nil" if the input string is in bad forms. local
|
||||
time = ngx.parse_http_time("Thu, 18 Nov 10 11:27:35 GMT") if time == nil
|
||||
then ... end
|
||||
Returns the seconds or "nil" if the input string is in bad forms.
|
||||
|
||||
local time = ngx.parse_http_time("Thu, 18 Nov 10 11:27:35 GMT")
|
||||
if time == nil then
|
||||
...
|
||||
end
|
||||
|
||||
ngx.is_subrequest
|
||||
syntax: *value = ngx.is_subrequest*
|
||||
|
@ -2280,9 +2505,9 @@ Installation
|
|||
example, the version 1.0.5 (see nginx compatibility), and then build
|
||||
the source with this module:
|
||||
|
||||
$ wget 'http://nginx.org/download/nginx-1.0.5.tar.gz'
|
||||
$ tar -xzvf nginx-1.0.5.tar.gz
|
||||
$ cd nginx-1.0.5/
|
||||
wget 'http://nginx.org/download/nginx-1.0.5.tar.gz'
|
||||
tar -xzvf nginx-1.0.5.tar.gz
|
||||
cd nginx-1.0.5/
|
||||
|
||||
# tell nginx's build system where to find lua:
|
||||
export LUA_LIB=/path/to/lua/lib
|
||||
|
@ -2293,12 +2518,12 @@ Installation
|
|||
# export LUAJIT_INC=/path/to/luajit/include/luajit-2.0
|
||||
|
||||
# Here we assume you would install you nginx under /opt/nginx/.
|
||||
$ ./configure --prefix=/opt/nginx \
|
||||
./configure --prefix=/opt/nginx \
|
||||
--add-module=/path/to/ngx_devel_kit \
|
||||
--add-module=/path/to/lua-nginx-module
|
||||
|
||||
$ make -j2
|
||||
$ make install
|
||||
make -j2
|
||||
make install
|
||||
|
||||
Compatibility
|
||||
The following versions of Nginx should work with this module:
|
||||
|
|
121
README.markdown
121
README.markdown
|
@ -13,7 +13,7 @@ This module is under active development and is already production ready.
|
|||
Version
|
||||
=======
|
||||
|
||||
This document describes ngx_lua [v0.3.1rc18](https://github.com/chaoslawful/lua-nginx-module/tags) released on 21 October 2011.
|
||||
This document describes ngx_lua [v0.3.1rc19](https://github.com/chaoslawful/lua-nginx-module/tags) released on 22 October 2011.
|
||||
|
||||
Synopsis
|
||||
========
|
||||
|
@ -310,6 +310,7 @@ Note that [set_by_lua](http://wiki.nginx.org/HttpLuaModule#set_by_lua) can only
|
|||
a time. But a work-around is also available by means of the [ngx.var.VARIABLE](http://wiki.nginx.org/HttpLuaModule#ngx.var.VARIABLE) interface,
|
||||
for example,
|
||||
|
||||
|
||||
location /foo {
|
||||
set $diff ''; # we have to predefine the $diff variable here
|
||||
|
||||
|
@ -327,6 +328,7 @@ for example,
|
|||
|
||||
This directive can be freely mixed with all the directives of [HttpRewriteModule](http://wiki.nginx.org/HttpRewriteModule), [HttpSetMiscModule](http://wiki.nginx.org/HttpSetMiscModule), and [HttpArrayVarModule](http://wiki.nginx.org/HttpArrayVarModule). All of these directives will run in exactly the same order that they are written in the config file. For example,
|
||||
|
||||
|
||||
set $foo 32;
|
||||
set_by_lua $bar 'tonumber(ngx.var.foo) + 1';
|
||||
set $baz "bar: $bar"; # $baz == "bar: 33"
|
||||
|
@ -633,6 +635,7 @@ Use Lua defined in `<lua-script-str>` to define an output header filter. For now
|
|||
|
||||
Here's a small example of overriding a response header (or adding if it does not exist) in our Lua header filter:
|
||||
|
||||
|
||||
location / {
|
||||
proxy_pass http://mybackend;
|
||||
header_filter_by_lua 'ngx.header.Foo = "blah"';
|
||||
|
@ -757,6 +760,7 @@ ngx.var.VARIABLE
|
|||
Note that you can only write to nginx variables that are already defined.
|
||||
For example:
|
||||
|
||||
|
||||
location /foo {
|
||||
set $my_var ''; # this line is required to create $my_var at config time
|
||||
content_by_lua '
|
||||
|
@ -765,6 +769,7 @@ For example:
|
|||
';
|
||||
}
|
||||
|
||||
|
||||
That is, nginx variables cannot be created on-the-fly.
|
||||
|
||||
Some special nginx variables like `$args` and `$limit_rate` can be assigned a value,
|
||||
|
@ -783,6 +788,7 @@ Core constants
|
|||
ngx.AGAIN (-2)
|
||||
ngx.DONE (-4)
|
||||
|
||||
|
||||
They take the same values of `NGX_OK`, `NGX_AGAIN`, `NGX_DONE`, `NGX_ERROR`, and etc. But now
|
||||
only [ngx.exit](http://wiki.nginx.org/HttpLuaModule#ngx.exit) only take two of these values, i.e., `NGX_OK` and `NGX_ERROR`.
|
||||
|
||||
|
@ -804,6 +810,7 @@ HTTP status constants
|
|||
---------------------
|
||||
**context:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua**
|
||||
|
||||
|
||||
value = ngx.HTTP_OK (200)
|
||||
value = ngx.HTTP_CREATED (201)
|
||||
value = ngx.HTTP_SPECIAL_RESPONSE (300)
|
||||
|
@ -826,6 +833,7 @@ Nginx log level constants
|
|||
-------------------------
|
||||
**context:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua**
|
||||
|
||||
|
||||
ngx.STDERR
|
||||
ngx.EMERG
|
||||
ngx.ALERT
|
||||
|
@ -849,8 +857,10 @@ Emit args concatenated to nginx's `error.log` file, with log level `ngx.NOTICE`
|
|||
|
||||
It's equivalent to
|
||||
|
||||
|
||||
ngx.log(ngx.NOTICE, 'lua print: ', a, b, ...)
|
||||
|
||||
|
||||
Lua `nil` arguments are accepted and result in literal `"nil"`, and Lua booleans result in `"true"` or `"false"`.
|
||||
|
||||
ngx.ctx
|
||||
|
@ -861,6 +871,7 @@ This table can be used to store per-request context data for Lua programmers.
|
|||
|
||||
This table has a liftime identical to the current request (just like Nginx variables). Consider the following example,
|
||||
|
||||
|
||||
location /test {
|
||||
rewrite_by_lua '
|
||||
ngx.say("foo = ", ngx.ctx.foo)
|
||||
|
@ -874,15 +885,19 @@ This table has a liftime identical to the current request (just like Nginx varia
|
|||
';
|
||||
}
|
||||
|
||||
|
||||
Then `GET /test` will yield the output
|
||||
|
||||
|
||||
foo = nil
|
||||
79
|
||||
|
||||
|
||||
That is, the `ngx.ctx.foo` entry persists across the rewrite, access, and content phases of a request.
|
||||
|
||||
Also, every request has its own copy, include subrequests, for example:
|
||||
|
||||
|
||||
location /sub {
|
||||
content_by_lua '
|
||||
ngx.say("sub pre: ", ngx.ctx.blah)
|
||||
|
@ -901,17 +916,21 @@ Also, every request has its own copy, include subrequests, for example:
|
|||
';
|
||||
}
|
||||
|
||||
|
||||
Then `GET /main` will give the output
|
||||
|
||||
|
||||
main pre: 73
|
||||
sub pre: nil
|
||||
sub post: 32
|
||||
main post: 73
|
||||
|
||||
|
||||
We can see that modification of the `ngx.ctx.blah` entry in the subrequest does not affect the one in its parent request. They do have two separate versions of `ngx.ctx.blah` per se.
|
||||
|
||||
Internal redirection will destroy the original request's `ngx.ctx` data (if any) and the new request will have an emptied `ngx.ctx` table. For instance,
|
||||
|
||||
|
||||
location /new {
|
||||
content_by_lua '
|
||||
ngx.say(ngx.ctx.foo)
|
||||
|
@ -925,16 +944,20 @@ Internal redirection will destroy the original request's `ngx.ctx` data (if any)
|
|||
';
|
||||
}
|
||||
|
||||
|
||||
Then `GET /orig` will give you
|
||||
|
||||
|
||||
nil
|
||||
|
||||
|
||||
rather than the original `"hello"` value.
|
||||
|
||||
Arbitrary data values can be inserted into this "matic" table, including Lua closures and nested tables. You can also register your own meta methods with it.
|
||||
|
||||
Overriding `ngx.ctx` with a new Lua table is also supported, for example,
|
||||
|
||||
|
||||
ngx.ctx = { foo = 32, bar = 54 }
|
||||
|
||||
|
||||
|
@ -955,8 +978,10 @@ Subrequests are completely different from HTTP 301/302 redirection (via [ngx.red
|
|||
|
||||
Here's a basic example:
|
||||
|
||||
|
||||
res = ngx.location.capture(uri)
|
||||
|
||||
|
||||
Returns a Lua table with three slots (`res.status`, `res.header`, and `res.body`).
|
||||
|
||||
`res.header` holds all the response headers of the
|
||||
|
@ -965,17 +990,21 @@ 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 contains the following
|
||||
lines:
|
||||
|
||||
|
||||
Set-Cookie: a=3
|
||||
Set-Cookie: foo=bar
|
||||
Set-Cookie: baz=blah
|
||||
|
||||
|
||||
Then `res.header["Set-Cookie"]` will be evaluted to the table value
|
||||
`{"a=3", "foo=bar", "baz=blah"}`.
|
||||
|
||||
URI query strings can be concatenated to URI itself, for instance,
|
||||
|
||||
|
||||
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.
|
||||
|
@ -986,11 +1015,13 @@ argument, which support various options like
|
|||
Issuing a POST subrequest, for example,
|
||||
can be done as follows
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
@ -1004,24 +1035,30 @@ care. So, by default, the option is set to `false`.
|
|||
|
||||
The `args` option can specify extra url arguments, for instance,
|
||||
|
||||
|
||||
ngx.location.capture('/foo?a=1',
|
||||
{ args = { b = 3, c = ':' } }
|
||||
)
|
||||
|
||||
|
||||
is equivalent to
|
||||
|
||||
|
||||
ngx.location.capture('/foo?a=1&b=3&c=%3a')
|
||||
|
||||
|
||||
that is, this method will automatically escape argument keys and values according to URI rules and
|
||||
concatenating them together into a complete query string. Because it's all done in hand-written C,
|
||||
it should be faster than your own Lua code.
|
||||
|
||||
The `args` option can also take plain query string:
|
||||
|
||||
|
||||
ngx.location.capture('/foo?a=1',
|
||||
{ args = 'b=3&c=%3a' } }
|
||||
)
|
||||
|
||||
|
||||
This is functionally identical to the previous examples.
|
||||
|
||||
Note that, by default, subrequests issued by [ngx.location.capture](http://wiki.nginx.org/HttpLuaModule#ngx.location.capture) inherit all the
|
||||
|
@ -1041,6 +1078,7 @@ Just like [ngx.location.capture](http://wiki.nginx.org/HttpLuaModule#ngx.locatio
|
|||
|
||||
This function issue several parallel subrequests specified by the input table, and returns their results in the same order. For example,
|
||||
|
||||
|
||||
res1, res2, res3 = ngx.location.capture_multi{
|
||||
{ "/foo", { args = "a=3&b=4" } },
|
||||
{ "/bar" },
|
||||
|
@ -1055,12 +1093,14 @@ This function issue several parallel subrequests specified by the input table, a
|
|||
...
|
||||
end
|
||||
|
||||
|
||||
This function will not return until all the subrequests terminate.
|
||||
The total latency is the longest latency of the subrequests, instead of their sum.
|
||||
|
||||
When you don't know inadvance how many subrequests you want to issue,
|
||||
you can use Lua tables for both requests and responses. For instance,
|
||||
|
||||
|
||||
-- construct the requests table
|
||||
local reqs = {}
|
||||
table.insert(reqs, { "/mysql" })
|
||||
|
@ -1076,9 +1116,11 @@ you can use Lua tables for both requests and responses. For instance,
|
|||
-- process the response table "resp"
|
||||
end
|
||||
|
||||
|
||||
The [ngx.location.capture](http://wiki.nginx.org/HttpLuaModule#ngx.location.capture) function is just a special form
|
||||
of this function. Logically speaking, the [ngx.location.capture](http://wiki.nginx.org/HttpLuaModule#ngx.location.capture) can be implemented like this
|
||||
|
||||
|
||||
ngx.location.capture =
|
||||
function (uri, args)
|
||||
return ngx.location.capture_multi({ {uri, args} })
|
||||
|
@ -1092,6 +1134,7 @@ ngx.status
|
|||
Read and write the current request's response status. This should be called
|
||||
before sending out the response headers.
|
||||
|
||||
|
||||
ngx.status = ngx.HTTP_CREATED
|
||||
status = ngx.status
|
||||
|
||||
|
@ -1313,6 +1356,7 @@ Returns a Lua table holds all of the current request's request URL query argumen
|
|||
|
||||
Here's an example,
|
||||
|
||||
|
||||
location = /test {
|
||||
content_by_lua '
|
||||
local args = ngx.req.get_uri_args()
|
||||
|
@ -1326,38 +1370,51 @@ Here's an example,
|
|||
';
|
||||
}
|
||||
|
||||
|
||||
Then `GET /test?foo=bar&bar=baz&bar=blah` will yield the response body
|
||||
|
||||
|
||||
foo: bar
|
||||
bar: baz, blah
|
||||
|
||||
|
||||
Multiple occurrences of an argument key will result in a table value holding all of the values for that key in order.
|
||||
|
||||
Keys and values will be automatically unescaped according to URI escaping rules. For example, in the above settings, `GET /test?a%20b=1%61+2` will yield the output
|
||||
|
||||
|
||||
a b: 1a 2
|
||||
|
||||
|
||||
Arguments without the `=<value>` parts are treated as boolean arguments. For example, `GET /test?foo&bar` will yield the outputs
|
||||
|
||||
|
||||
foo: true
|
||||
bar: true
|
||||
|
||||
|
||||
That is, they will take Lua boolean values `true`. However, they're different from arguments taking empty string values. For example, `GET /test?foo=&bar=` will give something like
|
||||
|
||||
|
||||
foo:
|
||||
bar:
|
||||
|
||||
|
||||
Empty key arguments are discarded, for instance, `GET /test?=hello&=world` will yield empty outputs.
|
||||
|
||||
Updating query arguments via the nginx variable `$args` (or `ngx.var.args` in Lua) at runtime are also supported:
|
||||
|
||||
|
||||
ngx.var.args = "a=3&b=42"
|
||||
local args = ngx.req.get_uri_args()
|
||||
|
||||
|
||||
Here the `args` table will always look like
|
||||
|
||||
|
||||
{a = 3, b = 42}
|
||||
|
||||
|
||||
regardless of the actual request query string.
|
||||
|
||||
ngx.req.get_post_args
|
||||
|
@ -1366,14 +1423,14 @@ ngx.req.get_post_args
|
|||
|
||||
**context:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua**
|
||||
|
||||
Returns a Lua table holds all of the current request's POST query arguments. It's required to turn on the [lua_need_request_body](http://wiki.nginx.org/HttpLuaModule#lua_need_request_body) directive, or a Lua exception will be thrown.
|
||||
Returns a Lua table holds all of the current request's POST query arguments. It's required to read the request body first by calling [ngx.req.read_body](http://wiki.nginx.org/HttpLuaModule#ngx.req.read_body) or to turn on the [lua_need_request_body](http://wiki.nginx.org/HttpLuaModule#lua_need_request_body) directive, or a Lua exception will be thrown.
|
||||
|
||||
Here's an example,
|
||||
|
||||
|
||||
location = /test {
|
||||
lua_need_request_body on;
|
||||
content_by_lua '
|
||||
local args = ngx.req.get_post_args()
|
||||
ngx.req.read_body()
|
||||
for key, val in pairs(args) do
|
||||
if type(val) == "table" then
|
||||
ngx.say(key, ": ", table.concat(val, ", "))
|
||||
|
@ -1384,37 +1441,50 @@ Here's an example,
|
|||
';
|
||||
}
|
||||
|
||||
|
||||
Then
|
||||
|
||||
|
||||
# Post request with the body 'foo=bar&bar=baz&bar=blah'
|
||||
$ curl --data 'foo=bar&bar=baz&bar=blah' localhost/test
|
||||
|
||||
|
||||
will yield the response body like
|
||||
|
||||
|
||||
foo: bar
|
||||
bar: baz, blah
|
||||
|
||||
|
||||
Multiple occurrences of an argument key will result in a table value holding all of the values for that key in order.
|
||||
|
||||
Keys and values will be automatically unescaped according to URI escaping rules. For example, in the above settings,
|
||||
|
||||
|
||||
# POST request with body 'a%20b=1%61+2'
|
||||
$ curl -d 'a%20b=1%61+2' localhost/test
|
||||
|
||||
|
||||
will yield the output
|
||||
|
||||
|
||||
a b: 1a 2
|
||||
|
||||
|
||||
Arguments without the `=<value>` parts are treated as boolean arguments. For example, `GET /test?foo&bar` will yield the outputs
|
||||
|
||||
|
||||
foo: true
|
||||
bar: true
|
||||
|
||||
|
||||
That is, they will take Lua boolean values `true`. However, they're different from arguments taking empty string values. For example, `POST /test` with request body `foo=&bar=` will give something like
|
||||
|
||||
|
||||
foo:
|
||||
bar:
|
||||
|
||||
|
||||
Empty key arguments are discarded, for instance, `POST /test` with body `=hello&=world` will yield empty outputs.
|
||||
|
||||
ngx.req.get_headers
|
||||
|
@ -1427,25 +1497,33 @@ Returns a Lua table holds all of the current request's request headers.
|
|||
|
||||
Here's an example,
|
||||
|
||||
|
||||
local h = ngx.req.get_headers()
|
||||
for k, v in pairs(h) do
|
||||
...
|
||||
end
|
||||
|
||||
|
||||
To read an individual header:
|
||||
|
||||
|
||||
ngx.say("Host: ", ngx.req.get_headers()["Host"])
|
||||
|
||||
|
||||
For multiple instances of request headers like
|
||||
|
||||
|
||||
Foo: foo
|
||||
Foo: bar
|
||||
Foo: baz
|
||||
|
||||
|
||||
the value of `ngx.req.get_headers()["Foo"]` will be a Lua (array) table like this:
|
||||
|
||||
|
||||
{"foo", "bar", "baz"}
|
||||
|
||||
|
||||
Another way to read individual request headers is to use `ngx.var.http_HEADER`, that is, nginx's standard [$http_HEADER](http://wiki.nginx.org/HttpCoreModule#.24http_HEADER) variables.
|
||||
|
||||
ngx.req.set_header
|
||||
|
@ -1459,26 +1537,35 @@ None of the current request's subrequests will be affected.
|
|||
|
||||
Here's an example of setting the `Content-Length` header:
|
||||
|
||||
|
||||
ngx.req.set_header("Content-Type", "text/css")
|
||||
|
||||
|
||||
The `header_value` can take an array list of values,
|
||||
for example,
|
||||
|
||||
|
||||
ngx.req.set_header("Foo", {"a", "abc"})
|
||||
|
||||
|
||||
will produce two new request headers:
|
||||
|
||||
|
||||
Foo: a
|
||||
Foo: abc
|
||||
|
||||
|
||||
and old `Foo` headers will be overridden if there's any.
|
||||
|
||||
When the `header_value` argument is `nil`, the request header will be removed. So
|
||||
|
||||
|
||||
ngx.req.set_header("X-Foo", nil)
|
||||
|
||||
|
||||
is equivalent to
|
||||
|
||||
|
||||
ngx.req.clear_header("X-Foo")
|
||||
|
||||
|
||||
|
@ -1503,6 +1590,13 @@ You can later either retrieve the request body data via [ngx.req.get_body_data](
|
|||
|
||||
In case that you do not want to read the request body and the current request may have a request body, then it's crucial to use the [ngx.req.discard_body](http://wiki.nginx.org/HttpLuaModule#ngx.req.discard_body) function to explicitly discard the request body, or you'll break HTTP 1.1 keepalive and HTTP 1.1 pipelining.
|
||||
|
||||
Here's a small example:
|
||||
|
||||
|
||||
ngx.req.read_body()
|
||||
local args = ngx.req.get_post_args()
|
||||
|
||||
|
||||
This function was first introduced in the `v0.3.1rc17` release.
|
||||
|
||||
ngx.req.discard_body
|
||||
|
@ -1962,9 +2056,11 @@ ngx.cookie_time
|
|||
|
||||
Returns a formated string can be used as the cookie expiration time. The parameter `sec` is the timestamp in seconds (like those returned from [ngx.time](http://wiki.nginx.org/HttpLuaModule#ngx.time)).
|
||||
|
||||
|
||||
ngx.say(ngx.cookie_time(1290079655))
|
||||
-- yields "Thu, 18-Nov-10 11:27:35 GMT"
|
||||
|
||||
|
||||
ngx.http_time
|
||||
-------------
|
||||
**syntax:** *str = ngx.http_time(sec)*
|
||||
|
@ -1973,9 +2069,11 @@ ngx.http_time
|
|||
|
||||
Returns a formated string can be used as the http header time (for example, being used in `Last-Modified` header). The parameter `sec` is the timestamp in seconds (like those returned from [ngx.time](http://wiki.nginx.org/HttpLuaModule#ngx.time)).
|
||||
|
||||
|
||||
ngx.say(ngx.http_time(1290079655))
|
||||
-- yields "Thu, 18 Nov 10 11:27:35 GMT"
|
||||
|
||||
|
||||
ngx.parse_http_time
|
||||
-------------------
|
||||
**syntax:** *sec = ngx.parse_http_time(str)*
|
||||
|
@ -1984,11 +2082,13 @@ ngx.parse_http_time
|
|||
|
||||
Parse the http time string (as returned by [ngx.http_time](http://wiki.nginx.org/HttpLuaModule#ngx.http_time)) into seconds. Returns the seconds or `nil` if the input string is in bad forms.
|
||||
|
||||
|
||||
local time = ngx.parse_http_time("Thu, 18 Nov 10 11:27:35 GMT")
|
||||
if time == nil then
|
||||
...
|
||||
end
|
||||
|
||||
|
||||
ngx.is_subrequest
|
||||
-----------------
|
||||
**syntax:** *value = ngx.is_subrequest*
|
||||
|
@ -2354,9 +2454,10 @@ Alternatively, you can compile this module with nginx core's source by hand:
|
|||
1. Download the latest version of the release tarball of this module from lua-nginx-module [file list](http://github.com/chaoslawful/lua-nginx-module/tags).
|
||||
1. Grab the nginx source code from [nginx.org](http://nginx.org/), for example, the version 1.0.5 (see nginx compatibility), and then build the source with this module:
|
||||
|
||||
$ wget 'http://nginx.org/download/nginx-1.0.5.tar.gz'
|
||||
$ tar -xzvf nginx-1.0.5.tar.gz
|
||||
$ cd nginx-1.0.5/
|
||||
|
||||
wget 'http://nginx.org/download/nginx-1.0.5.tar.gz'
|
||||
tar -xzvf nginx-1.0.5.tar.gz
|
||||
cd nginx-1.0.5/
|
||||
|
||||
# tell nginx's build system where to find lua:
|
||||
export LUA_LIB=/path/to/lua/lib
|
||||
|
@ -2367,12 +2468,12 @@ Alternatively, you can compile this module with nginx core's source by hand:
|
|||
# export LUAJIT_INC=/path/to/luajit/include/luajit-2.0
|
||||
|
||||
# Here we assume you would install you nginx under /opt/nginx/.
|
||||
$ ./configure --prefix=/opt/nginx \
|
||||
./configure --prefix=/opt/nginx \
|
||||
--add-module=/path/to/ngx_devel_kit \
|
||||
--add-module=/path/to/lua-nginx-module
|
||||
|
||||
$ make -j2
|
||||
$ make install
|
||||
make -j2
|
||||
make install
|
||||
|
||||
|
||||
Compatibility
|
||||
|
|
|
@ -10,7 +10,7 @@ This module is under active development and is already production ready.
|
|||
|
||||
= Version =
|
||||
|
||||
This document describes ngx_lua [https://github.com/chaoslawful/lua-nginx-module/tags v0.3.1rc18] released on 21 October 2011.
|
||||
This document describes ngx_lua [https://github.com/chaoslawful/lua-nginx-module/tags v0.3.1rc19] released on 22 October 2011.
|
||||
|
||||
= Synopsis =
|
||||
<geshi lang="nginx">
|
||||
|
@ -298,6 +298,7 @@ anything that may be blocked or time-consuming.
|
|||
Note that [[#set_by_lua|set_by_lua]] can only output a value to a single Nginx variable at
|
||||
a time. But a work-around is also available by means of the [[#ngx.var.VARIABLE|ngx.var.VARIABLE]] interface,
|
||||
for example,
|
||||
|
||||
<geshi lang="nginx">
|
||||
location /foo {
|
||||
set $diff ''; # we have to predefine the $diff variable here
|
||||
|
@ -315,6 +316,7 @@ for example,
|
|||
</geshi>
|
||||
|
||||
This directive can be freely mixed with all the directives of [[HttpRewriteModule]], [[HttpSetMiscModule]], and [[HttpArrayVarModule]]. All of these directives will run in exactly the same order that they are written in the config file. For example,
|
||||
|
||||
<geshi lang="nginx">
|
||||
set $foo 32;
|
||||
set_by_lua $bar 'tonumber(ngx.var.foo) + 1';
|
||||
|
@ -613,6 +615,7 @@ Use Lua defined in <code><lua-script-str></code> to define an output header filt
|
|||
* Subrequest APIs (e.g., [[#ngx.location.capture|ngx.location.capture]] and [[#ngx.location.capture_multi|ngx.location.capture_multi]])
|
||||
|
||||
Here's a small example of overriding a response header (or adding if it does not exist) in our Lua header filter:
|
||||
|
||||
<geshi lang="nginx">
|
||||
location / {
|
||||
proxy_pass http://mybackend;
|
||||
|
@ -732,6 +735,7 @@ that outputs <code>88</code>, the sum of <code>32</code> and <code>56</code>.
|
|||
</geshi>
|
||||
Note that you can only write to nginx variables that are already defined.
|
||||
For example:
|
||||
|
||||
<geshi lang="nginx">
|
||||
location /foo {
|
||||
set $my_var ''; # this line is required to create $my_var at config time
|
||||
|
@ -741,6 +745,7 @@ For example:
|
|||
';
|
||||
}
|
||||
</geshi>
|
||||
|
||||
That is, nginx variables cannot be created on-the-fly.
|
||||
|
||||
Some special nginx variables like <code>$args</code> and <code>$limit_rate</code> can be assigned a value,
|
||||
|
@ -758,6 +763,7 @@ interface as well, by writing <code>ngx.var[1]</code>, <code>ngx.var[2]</code>,
|
|||
ngx.AGAIN (-2)
|
||||
ngx.DONE (-4)
|
||||
</geshi>
|
||||
|
||||
They take the same values of <code>NGX_OK</code>, <code>NGX_AGAIN</code>, <code>NGX_DONE</code>, <code>NGX_ERROR</code>, and etc. But now
|
||||
only [[#ngx.exit|ngx.exit]] only take two of these values, i.e., <code>NGX_OK</code> and <code>NGX_ERROR</code>.
|
||||
|
||||
|
@ -776,6 +782,7 @@ These constants are usually used in [[#ngx.location.capture|ngx.location.catpure
|
|||
|
||||
== HTTP status constants ==
|
||||
'''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*''
|
||||
|
||||
<geshi lang="nginx">
|
||||
value = ngx.HTTP_OK (200)
|
||||
value = ngx.HTTP_CREATED (201)
|
||||
|
@ -797,6 +804,7 @@ These constants are usually used in [[#ngx.location.capture|ngx.location.catpure
|
|||
|
||||
== Nginx log level constants ==
|
||||
'''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*''
|
||||
|
||||
<geshi lang="lua">
|
||||
ngx.STDERR
|
||||
ngx.EMERG
|
||||
|
@ -819,9 +827,11 @@ These constants are usually used by the [[#ngx.log|ngx.log]] method.
|
|||
Emit args concatenated to nginx's <code>error.log</code> file, with log level <code>ngx.NOTICE</code> and prefix <code>lua print: </code>.
|
||||
|
||||
It's equivalent to
|
||||
|
||||
<geshi lang="lua">
|
||||
ngx.log(ngx.NOTICE, 'lua print: ', a, b, ...)
|
||||
</geshi>
|
||||
|
||||
Lua <code>nil</code> arguments are accepted and result in literal <code>"nil"</code>, and Lua booleans result in <code>"true"</code> or <code>"false"</code>.
|
||||
|
||||
== ngx.ctx ==
|
||||
|
@ -830,6 +840,7 @@ Lua <code>nil</code> arguments are accepted and result in literal <code>"nil"</c
|
|||
This table can be used to store per-request context data for Lua programmers.
|
||||
|
||||
This table has a liftime identical to the current request (just like Nginx variables). Consider the following example,
|
||||
|
||||
<geshi lang="nginx">
|
||||
location /test {
|
||||
rewrite_by_lua '
|
||||
|
@ -844,14 +855,18 @@ This table has a liftime identical to the current request (just like Nginx varia
|
|||
';
|
||||
}
|
||||
</geshi>
|
||||
|
||||
Then <code>GET /test</code> will yield the output
|
||||
|
||||
<geshi lang="bash">
|
||||
foo = nil
|
||||
79
|
||||
</geshi>
|
||||
|
||||
That is, the <code>ngx.ctx.foo</code> entry persists across the rewrite, access, and content phases of a request.
|
||||
|
||||
Also, every request has its own copy, include subrequests, for example:
|
||||
|
||||
<geshi lang="nginx">
|
||||
location /sub {
|
||||
content_by_lua '
|
||||
|
@ -871,16 +886,20 @@ Also, every request has its own copy, include subrequests, for example:
|
|||
';
|
||||
}
|
||||
</geshi>
|
||||
|
||||
Then <code>GET /main</code> will give the output
|
||||
|
||||
<geshi lang="bash">
|
||||
main pre: 73
|
||||
sub pre: nil
|
||||
sub post: 32
|
||||
main post: 73
|
||||
</geshi>
|
||||
|
||||
We can see that modification of the <code>ngx.ctx.blah</code> entry in the subrequest does not affect the one in its parent request. They do have two separate versions of <code>ngx.ctx.blah</code> per se.
|
||||
|
||||
Internal redirection will destroy the original request's <code>ngx.ctx</code> data (if any) and the new request will have an emptied <code>ngx.ctx</code> table. For instance,
|
||||
|
||||
<geshi lang="nginx">
|
||||
location /new {
|
||||
content_by_lua '
|
||||
|
@ -895,15 +914,19 @@ Internal redirection will destroy the original request's <code>ngx.ctx</code> da
|
|||
';
|
||||
}
|
||||
</geshi>
|
||||
|
||||
Then <code>GET /orig</code> will give you
|
||||
|
||||
<geshi lang="bash">
|
||||
nil
|
||||
</geshi>
|
||||
|
||||
rather than the original <code>"hello"</code> value.
|
||||
|
||||
Arbitrary data values can be inserted into this "matic" table, including Lua closures and nested tables. You can also register your own meta methods with it.
|
||||
|
||||
Overriding <code>ngx.ctx</code> with a new Lua table is also supported, for example,
|
||||
|
||||
<geshi lang="lua">
|
||||
ngx.ctx = { foo = 32, bar = 54 }
|
||||
</geshi>
|
||||
|
@ -923,9 +946,11 @@ Also note that subrequests just mimic the HTTP interface but there's ''no'' extr
|
|||
Subrequests are completely different from HTTP 301/302 redirection (via [[#ngx.redirect|ngx.redirect]]) and internal redirection (via [[#ngx.exec|ngx.exec]]).
|
||||
|
||||
Here's a basic example:
|
||||
|
||||
<geshi lang="lua">
|
||||
res = ngx.location.capture(uri)
|
||||
</geshi>
|
||||
|
||||
Returns a Lua table with three slots (<code>res.status</code>, <code>res.header</code>, and <code>res.body</code>).
|
||||
|
||||
<code>res.header</code> holds all the response headers of the
|
||||
|
@ -933,18 +958,22 @@ 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 contains the following
|
||||
lines:
|
||||
|
||||
<geshi lang="bash">
|
||||
Set-Cookie: a=3
|
||||
Set-Cookie: foo=bar
|
||||
Set-Cookie: baz=blah
|
||||
</geshi>
|
||||
|
||||
Then <code>res.header["Set-Cookie"]</code> will be evaluted to the table value
|
||||
<code>{"a=3", "foo=bar", "baz=blah"}</code>.
|
||||
|
||||
URI query strings can be concatenated to URI itself, for instance,
|
||||
|
||||
<geshi lang="lua">
|
||||
res = ngx.location.capture('/foo/bar?a=3&b=4')
|
||||
</geshi>
|
||||
|
||||
Named locations like <code>@foo</code> are not allowed due to a limitation in
|
||||
the nginx core. Use normal locations combined with the <code>internal</code> directive to
|
||||
prepare internal-only locations.
|
||||
|
@ -954,12 +983,14 @@ argument, which support various options like
|
|||
<code>method</code>, <code>body</code>, <code>args</code>, and <code>share_all_vars</code>.
|
||||
Issuing a POST subrequest, for example,
|
||||
can be done as follows
|
||||
|
||||
<geshi lang="lua">
|
||||
res = ngx.location.capture(
|
||||
'/foo/bar',
|
||||
{ method = ngx.HTTP_POST, body = 'hello, world' }
|
||||
)
|
||||
</geshi>
|
||||
|
||||
See HTTP method constants methods other than POST.
|
||||
The <code>method</code> option is <code>ngx.HTTP_GET</code> by default.
|
||||
|
||||
|
@ -972,25 +1003,31 @@ and lead to confusing issues, use it with special
|
|||
care. So, by default, the option is set to <code>false</code>.
|
||||
|
||||
The <code>args</code> option can specify extra url arguments, for instance,
|
||||
|
||||
<geshi lang="lua">
|
||||
ngx.location.capture('/foo?a=1',
|
||||
{ args = { b = 3, c = ':' } }
|
||||
)
|
||||
</geshi>
|
||||
|
||||
is equivalent to
|
||||
|
||||
<geshi lang="lua">
|
||||
ngx.location.capture('/foo?a=1&b=3&c=%3a')
|
||||
</geshi>
|
||||
|
||||
that is, this method will automatically escape argument keys and values according to URI rules and
|
||||
concatenating them together into a complete query string. Because it's all done in hand-written C,
|
||||
it should be faster than your own Lua code.
|
||||
|
||||
The <code>args</code> option can also take plain query string:
|
||||
|
||||
<geshi lang="lua">
|
||||
ngx.location.capture('/foo?a=1',
|
||||
{ args = 'b=3&c=%3a' } }
|
||||
)
|
||||
</geshi>
|
||||
|
||||
This is functionally identical to the previous examples.
|
||||
|
||||
Note that, by default, subrequests issued by [[#ngx.location.capture|ngx.location.capture]] inherit all the
|
||||
|
@ -1008,6 +1045,7 @@ in gzip'd responses that your Lua code is not able to handle properly. So always
|
|||
Just like [[#ngx.location.capture|ngx.location.capture]], but supports multiple subrequests running in parallel.
|
||||
|
||||
This function issue several parallel subrequests specified by the input table, and returns their results in the same order. For example,
|
||||
|
||||
<geshi lang="lua">
|
||||
res1, res2, res3 = ngx.location.capture_multi{
|
||||
{ "/foo", { args = "a=3&b=4" } },
|
||||
|
@ -1023,11 +1061,13 @@ This function issue several parallel subrequests specified by the input table, a
|
|||
...
|
||||
end
|
||||
</geshi>
|
||||
|
||||
This function will not return until all the subrequests terminate.
|
||||
The total latency is the longest latency of the subrequests, instead of their sum.
|
||||
|
||||
When you don't know inadvance how many subrequests you want to issue,
|
||||
you can use Lua tables for both requests and responses. For instance,
|
||||
|
||||
<geshi lang="lua">
|
||||
-- construct the requests table
|
||||
local reqs = {}
|
||||
|
@ -1044,8 +1084,10 @@ you can use Lua tables for both requests and responses. For instance,
|
|||
-- process the response table "resp"
|
||||
end
|
||||
</geshi>
|
||||
|
||||
The [[#ngx.location.capture|ngx.location.capture]] function is just a special form
|
||||
of this function. Logically speaking, the [[#ngx.location.capture|ngx.location.capture]] can be implemented like this
|
||||
|
||||
<geshi lang="lua">
|
||||
ngx.location.capture =
|
||||
function (uri, args)
|
||||
|
@ -1058,6 +1100,7 @@ of this function. Logically speaking, the [[#ngx.location.capture|ngx.location.c
|
|||
|
||||
Read and write the current request's response status. This should be called
|
||||
before sending out the response headers.
|
||||
|
||||
<geshi lang="lua">
|
||||
ngx.status = ngx.HTTP_CREATED
|
||||
status = ngx.status
|
||||
|
@ -1275,6 +1318,7 @@ See also [[#ngx.req.set_uri|ngx.req.set_uri]].
|
|||
Returns a Lua table holds all of the current request's request URL query arguments.
|
||||
|
||||
Here's an example,
|
||||
|
||||
<geshi lang="nginx">
|
||||
location = /test {
|
||||
content_by_lua '
|
||||
|
@ -1289,38 +1333,51 @@ Here's an example,
|
|||
';
|
||||
}
|
||||
</geshi>
|
||||
|
||||
Then <code>GET /test?foo=bar&bar=baz&bar=blah</code> will yield the response body
|
||||
|
||||
<geshi lang="bash">
|
||||
foo: bar
|
||||
bar: baz, blah
|
||||
</geshi>
|
||||
|
||||
Multiple occurrences of an argument key will result in a table value holding all of the values for that key in order.
|
||||
|
||||
Keys and values will be automatically unescaped according to URI escaping rules. For example, in the above settings, <code>GET /test?a%20b=1%61+2</code> will yield the output
|
||||
|
||||
<geshi lang="bash">
|
||||
a b: 1a 2
|
||||
</geshi>
|
||||
|
||||
Arguments without the <code>=<value></code> parts are treated as boolean arguments. For example, <code>GET /test?foo&bar</code> will yield the outputs
|
||||
|
||||
<geshi lang="bash">
|
||||
foo: true
|
||||
bar: true
|
||||
</geshi>
|
||||
|
||||
That is, they will take Lua boolean values <code>true</code>. However, they're different from arguments taking empty string values. For example, <code>GET /test?foo=&bar=</code> will give something like
|
||||
|
||||
<geshi lang="bash">
|
||||
foo:
|
||||
bar:
|
||||
</geshi>
|
||||
|
||||
Empty key arguments are discarded, for instance, <code>GET /test?=hello&=world</code> will yield empty outputs.
|
||||
|
||||
Updating query arguments via the nginx variable <code>$args</code> (or <code>ngx.var.args</code> in Lua) at runtime are also supported:
|
||||
|
||||
<geshi lang="lua">
|
||||
ngx.var.args = "a=3&b=42"
|
||||
local args = ngx.req.get_uri_args()
|
||||
</geshi>
|
||||
|
||||
Here the <code>args</code> table will always look like
|
||||
|
||||
<geshi lang="lua">
|
||||
{a = 3, b = 42}
|
||||
</geshi>
|
||||
|
||||
regardless of the actual request query string.
|
||||
|
||||
== ngx.req.get_post_args ==
|
||||
|
@ -1328,14 +1385,14 @@ regardless of the actual request query string.
|
|||
|
||||
'''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*''
|
||||
|
||||
Returns a Lua table holds all of the current request's POST query arguments. It's required to turn on the [[#lua_need_request_body|lua_need_request_body]] directive, or a Lua exception will be thrown.
|
||||
Returns a Lua table holds all of the current request's POST query arguments. It's required to read the request body first by calling [[#ngx.req.read_body|ngx.req.read_body]] or to turn on the [[#lua_need_request_body|lua_need_request_body]] directive, or a Lua exception will be thrown.
|
||||
|
||||
Here's an example,
|
||||
|
||||
<geshi lang="nginx">
|
||||
location = /test {
|
||||
lua_need_request_body on;
|
||||
content_by_lua '
|
||||
local args = ngx.req.get_post_args()
|
||||
ngx.req.read_body()
|
||||
for key, val in pairs(args) do
|
||||
if type(val) == "table" then
|
||||
ngx.say(key, ": ", table.concat(val, ", "))
|
||||
|
@ -1346,37 +1403,50 @@ Here's an example,
|
|||
';
|
||||
}
|
||||
</geshi>
|
||||
|
||||
Then
|
||||
|
||||
<geshi lang="bash">
|
||||
# Post request with the body 'foo=bar&bar=baz&bar=blah'
|
||||
$ curl --data 'foo=bar&bar=baz&bar=blah' localhost/test
|
||||
</geshi>
|
||||
|
||||
will yield the response body like
|
||||
|
||||
<geshi lang="bash">
|
||||
foo: bar
|
||||
bar: baz, blah
|
||||
</geshi>
|
||||
|
||||
Multiple occurrences of an argument key will result in a table value holding all of the values for that key in order.
|
||||
|
||||
Keys and values will be automatically unescaped according to URI escaping rules. For example, in the above settings,
|
||||
|
||||
<geshi lang="bash">
|
||||
# POST request with body 'a%20b=1%61+2'
|
||||
$ curl -d 'a%20b=1%61+2' localhost/test
|
||||
</geshi>
|
||||
|
||||
will yield the output
|
||||
|
||||
<geshi lang="bash">
|
||||
a b: 1a 2
|
||||
</geshi>
|
||||
|
||||
Arguments without the <code>=<value></code> parts are treated as boolean arguments. For example, <code>GET /test?foo&bar</code> will yield the outputs
|
||||
|
||||
<geshi lang="bash">
|
||||
foo: true
|
||||
bar: true
|
||||
</geshi>
|
||||
|
||||
That is, they will take Lua boolean values <code>true</code>. However, they're different from arguments taking empty string values. For example, <code>POST /test</code> with request body <code>foo=&bar=</code> will give something like
|
||||
|
||||
<geshi lang="bash">
|
||||
foo:
|
||||
bar:
|
||||
</geshi>
|
||||
|
||||
Empty key arguments are discarded, for instance, <code>POST /test</code> with body <code>=hello&=world</code> will yield empty outputs.
|
||||
|
||||
== ngx.req.get_headers ==
|
||||
|
@ -1387,26 +1457,34 @@ Empty key arguments are discarded, for instance, <code>POST /test</code> with bo
|
|||
Returns a Lua table holds all of the current request's request headers.
|
||||
|
||||
Here's an example,
|
||||
|
||||
<geshi lang="lua">
|
||||
local h = ngx.req.get_headers()
|
||||
for k, v in pairs(h) do
|
||||
...
|
||||
end
|
||||
</geshi>
|
||||
|
||||
To read an individual header:
|
||||
|
||||
<geshi lang="lua">
|
||||
ngx.say("Host: ", ngx.req.get_headers()["Host"])
|
||||
</geshi>
|
||||
|
||||
For multiple instances of request headers like
|
||||
|
||||
<geshi lang="bash">
|
||||
Foo: foo
|
||||
Foo: bar
|
||||
Foo: baz
|
||||
</geshi>
|
||||
|
||||
the value of <code>ngx.req.get_headers()["Foo"]</code> will be a Lua (array) table like this:
|
||||
|
||||
<geshi lang="lua">
|
||||
{"foo", "bar", "baz"}
|
||||
</geshi>
|
||||
|
||||
Another way to read individual request headers is to use <code>ngx.var.http_HEADER</code>, that is, nginx's standard [[HttpCoreModule#$http_HEADER|$http_HEADER]] variables.
|
||||
|
||||
== ngx.req.set_header ==
|
||||
|
@ -1418,26 +1496,35 @@ Set the current request's request header named <code>header_name</code> to value
|
|||
None of the current request's subrequests will be affected.
|
||||
|
||||
Here's an example of setting the <code>Content-Length</code> header:
|
||||
|
||||
<geshi lang="lua">
|
||||
ngx.req.set_header("Content-Type", "text/css")
|
||||
</geshi>
|
||||
|
||||
The <code>header_value</code> can take an array list of values,
|
||||
for example,
|
||||
|
||||
<geshi lang="lua">
|
||||
ngx.req.set_header("Foo", {"a", "abc"})
|
||||
</geshi>
|
||||
|
||||
will produce two new request headers:
|
||||
|
||||
<geshi lang="bash">
|
||||
Foo: a
|
||||
Foo: abc
|
||||
</geshi>
|
||||
|
||||
and old <code>Foo</code> headers will be overridden if there's any.
|
||||
|
||||
When the <code>header_value</code> argument is <code>nil</code>, the request header will be removed. So
|
||||
|
||||
<geshi lang="lua">
|
||||
ngx.req.set_header("X-Foo", nil)
|
||||
</geshi>
|
||||
|
||||
is equivalent to
|
||||
|
||||
<geshi lang="lua">
|
||||
ngx.req.clear_header("X-Foo")
|
||||
</geshi>
|
||||
|
@ -1462,6 +1549,13 @@ You can later either retrieve the request body data via [[#ngx.req.get_body_data
|
|||
|
||||
In case that you do not want to read the request body and the current request may have a request body, then it's crucial to use the [[#ngx.req.discard_body|ngx.req.discard_body]] function to explicitly discard the request body, or you'll break HTTP 1.1 keepalive and HTTP 1.1 pipelining.
|
||||
|
||||
Here's a small example:
|
||||
|
||||
<geshi lang="lua">
|
||||
ngx.req.read_body()
|
||||
local args = ngx.req.get_post_args()
|
||||
</geshi>
|
||||
|
||||
This function was first introduced in the <code>v0.3.1rc17</code> release.
|
||||
|
||||
== ngx.req.discard_body ==
|
||||
|
@ -1893,32 +1987,38 @@ This is the UTC time.
|
|||
'''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*''
|
||||
|
||||
Returns a formated string can be used as the cookie expiration time. The parameter <code>sec</code> is the timestamp in seconds (like those returned from [[#ngx.time|ngx.time]]).
|
||||
|
||||
<geshi lang="nginx">
|
||||
ngx.say(ngx.cookie_time(1290079655))
|
||||
-- yields "Thu, 18-Nov-10 11:27:35 GMT"
|
||||
</geshi>
|
||||
|
||||
== ngx.http_time ==
|
||||
'''syntax:''' ''str = ngx.http_time(sec)''
|
||||
|
||||
'''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*''
|
||||
|
||||
Returns a formated string can be used as the http header time (for example, being used in <code>Last-Modified</code> header). The parameter <code>sec</code> is the timestamp in seconds (like those returned from [[#ngx.time|ngx.time]]).
|
||||
|
||||
<geshi lang="nginx">
|
||||
ngx.say(ngx.http_time(1290079655))
|
||||
-- yields "Thu, 18 Nov 10 11:27:35 GMT"
|
||||
</geshi>
|
||||
|
||||
== ngx.parse_http_time ==
|
||||
'''syntax:''' ''sec = ngx.parse_http_time(str)''
|
||||
|
||||
'''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*''
|
||||
|
||||
Parse the http time string (as returned by [[#ngx.http_time|ngx.http_time]]) into seconds. Returns the seconds or <code>nil</code> if the input string is in bad forms.
|
||||
|
||||
<geshi lang="nginx">
|
||||
local time = ngx.parse_http_time("Thu, 18 Nov 10 11:27:35 GMT")
|
||||
if time == nil then
|
||||
...
|
||||
end
|
||||
</geshi>
|
||||
|
||||
== ngx.is_subrequest ==
|
||||
'''syntax:''' ''value = ngx.is_subrequest''
|
||||
|
||||
|
@ -2273,10 +2373,11 @@ Alternatively, you can compile this module with nginx core's source by hand:
|
|||
# Download the latest version of the release tarball of the ngx_devel_kit (NDK) module from lua-nginx-module [http://github.com/simpl/ngx_devel_kit/tags file list].
|
||||
# Download the latest version of the release tarball of this module from lua-nginx-module [http://github.com/chaoslawful/lua-nginx-module/tags file list].
|
||||
# Grab the nginx source code from [http://nginx.org/ nginx.org], for example, the version 1.0.5 (see nginx compatibility), and then build the source with this module:
|
||||
|
||||
<geshi lang="bash">
|
||||
$ wget 'http://nginx.org/download/nginx-1.0.5.tar.gz'
|
||||
$ tar -xzvf nginx-1.0.5.tar.gz
|
||||
$ cd nginx-1.0.5/
|
||||
wget 'http://nginx.org/download/nginx-1.0.5.tar.gz'
|
||||
tar -xzvf nginx-1.0.5.tar.gz
|
||||
cd nginx-1.0.5/
|
||||
|
||||
# tell nginx's build system where to find lua:
|
||||
export LUA_LIB=/path/to/lua/lib
|
||||
|
@ -2287,12 +2388,12 @@ Alternatively, you can compile this module with nginx core's source by hand:
|
|||
# export LUAJIT_INC=/path/to/luajit/include/luajit-2.0
|
||||
|
||||
# Here we assume you would install you nginx under /opt/nginx/.
|
||||
$ ./configure --prefix=/opt/nginx \
|
||||
./configure --prefix=/opt/nginx \
|
||||
--add-module=/path/to/ngx_devel_kit \
|
||||
--add-module=/path/to/lua-nginx-module
|
||||
|
||||
$ make -j2
|
||||
$ make install
|
||||
make -j2
|
||||
make install
|
||||
</geshi>
|
||||
|
||||
= Compatibility =
|
||||
|
|
|
@ -121,7 +121,8 @@ ngx_http_lua_capture_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
}
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"lua capture body filter capturing response body, uri \"%V\"", &r->uri);
|
||||
"lua capture body filter capturing response body, uri \"%V\"",
|
||||
&r->uri);
|
||||
|
||||
rc = ngx_http_lua_add_copy_chain(r, pr_ctx, &ctx->body, in);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче