access_by_lua and access_by_lua_file are passing tests now.
This commit is contained in:
Родитель
2606b2f2fd
Коммит
20e919d612
|
@ -101,3 +101,5 @@ src/headers.c
|
|||
src/headers.h
|
||||
go
|
||||
all.sh
|
||||
src/accessby.[ch]
|
||||
src/rewriteby.[ch]
|
||||
|
|
180
README.markdown
180
README.markdown
|
@ -253,7 +253,7 @@ content.
|
|||
This hook uses exactly the same mechamism as `content_by_lua` so all the nginx APIs defined there
|
||||
are also available here.
|
||||
|
||||
Note that this handler always runs *after* the standard nginx rewrite module. So the following will work as expected:
|
||||
Note that this handler always runs *after* the standard nginx rewrite module ( http://wiki.nginx.org/NginxHttpRewriteModule ). So the following will work as expected:
|
||||
|
||||
location /foo {
|
||||
set $a 12; # create and initialize $a
|
||||
|
@ -295,8 +295,110 @@ The right way of doing this is as follows:
|
|||
echo "res = $b";
|
||||
}
|
||||
|
||||
It's worth mentioning that, the `ngx_eval` module can be
|
||||
approximately implemented by `rewrite_by_lua`. For example,
|
||||
|
||||
location / {
|
||||
eval $res {
|
||||
proxy_pass http://foo.com/check-spam;
|
||||
}
|
||||
if ($res = 'spam') {
|
||||
rewrite ^ /terms-of-use.html redirect;
|
||||
}
|
||||
|
||||
fastcgi_pass ...;
|
||||
}
|
||||
|
||||
can be implemented in terms of `ngx_lua` like this
|
||||
|
||||
location = /check-spam {
|
||||
internal;
|
||||
proxy_pass http://foo.com/check-spam;
|
||||
}
|
||||
|
||||
location / {
|
||||
rewrite_by_lua '
|
||||
local res = ngx.location.capture("/check-spam")
|
||||
if res.body == "spam" then
|
||||
ngx.redirect("/terms-of-use.html")
|
||||
end
|
||||
';
|
||||
|
||||
fastcgi_pass ...;
|
||||
}
|
||||
|
||||
Just as any other rewrite-phase handlers, `rewrite_by_lua` also runs in subrequests.
|
||||
|
||||
This directive won't work properly with nginx 0.7.x.
|
||||
|
||||
access_by_lua
|
||||
--------------
|
||||
|
||||
* **Syntax:** `access_by_lua <lua-script-str>`
|
||||
* **Context:** `location | lif`
|
||||
* **Phase:** `access tail`
|
||||
|
||||
Act as an access phase handler and execute user code specified by `<lua-script-str>`
|
||||
for every request. The user code may call predefined APIs to generate response
|
||||
content.
|
||||
|
||||
This hook uses exactly the same mechamism as `content_by_lua`
|
||||
so all the nginx APIs defined there
|
||||
are also available here.
|
||||
|
||||
Note that this handler always runs *after* the standard nginx
|
||||
access module ( http://wiki.nginx.org/NginxHttpAccessModule ).
|
||||
So the following will work as expected:
|
||||
|
||||
location / {
|
||||
deny 192.168.1.1;
|
||||
allow 192.168.1.0/24;
|
||||
allow 10.1.1.0/16;
|
||||
deny all;
|
||||
|
||||
access_by_lua '
|
||||
local res = ngx.location.capture("/mysql", { ... })
|
||||
...
|
||||
';
|
||||
|
||||
# proxy_pass/fastcgi_pass/...
|
||||
}
|
||||
|
||||
That is, if a client address appears in the blacklist, then
|
||||
we don't have to bother sending a mysql query to do more
|
||||
advanced authentication in `access_by_lua`.
|
||||
|
||||
It's worth mentioning that, the `ngx_auth_request` module can be
|
||||
approximately implemented by `access_by_lua`. For example,
|
||||
|
||||
location / {
|
||||
auth_request /auth;
|
||||
|
||||
...
|
||||
}
|
||||
|
||||
can be implemented in terms of `ngx_lua` like this
|
||||
|
||||
location / {
|
||||
access_by_lua '
|
||||
local res = ngx.location.capture("/auth")
|
||||
|
||||
if res.status == ngx.HTTP_OK then
|
||||
return
|
||||
end
|
||||
|
||||
if res.status == ngx.HTTP_FORBIDDEN then
|
||||
ngx.exit(res.status)
|
||||
end
|
||||
|
||||
ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
|
||||
';
|
||||
|
||||
...
|
||||
}
|
||||
|
||||
Just as any other access-phase handlers, `access_by_lua` will NOT run in subrequests.
|
||||
|
||||
content_by_lua_file
|
||||
-------------------
|
||||
|
||||
|
@ -322,6 +424,16 @@ the file specified by `<path-lua-script>`.
|
|||
|
||||
This directive won't work properly with nginx 0.7.x.
|
||||
|
||||
access_by_lua_file
|
||||
-------------------
|
||||
|
||||
* **Syntax:** `access_by_lua_file <path-to-lua-script>`
|
||||
* **Context:** `location | lif`
|
||||
* **Phase:** `access tail`
|
||||
|
||||
Same as `access_by_lua`, except the code to be executed is in
|
||||
the file specified by `<path-lua-script>`.
|
||||
|
||||
lua_need_request_body
|
||||
---------------------
|
||||
|
||||
|
@ -374,7 +486,7 @@ that outputs 88, the sum of 32 and 56.
|
|||
|
||||
Read and write Nginx variables
|
||||
------------------------------
|
||||
* **Context:** `set_by_lua*`, `rewrite_by_lua*`, `content_by_lua*`
|
||||
* **Context:** `set_by_lua*`, `rewrite_by_lua*`, `access_by_lua*`, `content_by_lua*`
|
||||
|
||||
value = ngx.var.some_nginx_variable_name
|
||||
ngx.var.some_nginx_variable_name = value
|
||||
|
@ -394,7 +506,7 @@ That is, nginx variables cannot be created on-the-fly.
|
|||
|
||||
Core constants
|
||||
---------------------
|
||||
* **Context:** `rewrite_by_lua*`, `content_by_lua*`
|
||||
* **Context:** `rewrite_by_lua*`, `access_by_lua*`, `content_by_lua*`
|
||||
|
||||
ngx.OK
|
||||
ngx.DONE
|
||||
|
@ -403,7 +515,7 @@ Core constants
|
|||
|
||||
HTTP method constants
|
||||
---------------------
|
||||
* **Context:** `rewrite_by_lua*`, `content_by_lua*`
|
||||
* **Context:** `rewrite_by_lua*`, `access_by_lua*`, `content_by_lua*`
|
||||
|
||||
value = ngx.HTTP_GET
|
||||
value = ngx.HTTP_HEAD
|
||||
|
@ -413,7 +525,7 @@ HTTP method constants
|
|||
|
||||
HTTP status constants
|
||||
---------------------
|
||||
* **Context:** `rewrite_by_lua*`, `content_by_lua*`
|
||||
* **Context:** `rewrite_by_lua*`, `access_by_lua*`, `content_by_lua*`
|
||||
|
||||
value = ngx.HTTP_OK
|
||||
value = ngx.HTTP_CREATED
|
||||
|
@ -430,7 +542,7 @@ HTTP status constants
|
|||
|
||||
Nginx log level constants
|
||||
-------------------------
|
||||
* **Context:** `rewrite_by_lua*`, `content_by_lua*`
|
||||
* **Context:** `rewrite_by_lua*`, `access_by_lua*`, `content_by_lua*`
|
||||
|
||||
log_level = ngx.STDERR
|
||||
log_level = ngx.EMERG
|
||||
|
@ -444,7 +556,7 @@ Nginx log level constants
|
|||
|
||||
print(a, b, ...)
|
||||
----------------
|
||||
* **Context:** `set_by_lua*`, `rewrite_by_lua*`, `content_by_lua*`
|
||||
* **Context:** `set_by_lua*`, `rewrite_by_lua*`, `access_by_lua*`, `content_by_lua*`
|
||||
|
||||
Emit args concatenated to `error.log`, with log level `ngx.NOTICE` and prefix `lua print: `.
|
||||
|
||||
|
@ -456,7 +568,7 @@ Nil arguments are accepted and result in literal "nil".
|
|||
|
||||
ngx.location.capture(uri, options?)
|
||||
-----------------------------------
|
||||
* **Context:** `rewrite_by_lua*`, `content_by_lua*`
|
||||
* **Context:** `rewrite_by_lua*`, `access_by_lua*`, `content_by_lua*`
|
||||
|
||||
Issue a synchronous but still non-blocking "nginx subrequest" using `uri`.
|
||||
|
||||
|
@ -538,7 +650,7 @@ This is functionally identical to the previous examples.
|
|||
|
||||
ngx.status
|
||||
----------
|
||||
* **Context:** `rewrite_by_lua*`, `content_by_lua*`
|
||||
* **Context:** `rewrite_by_lua*`, `access_by_lua*`, `content_by_lua*`
|
||||
|
||||
Read and write the response status. This should be called
|
||||
before sending out the response headers.
|
||||
|
@ -548,7 +660,7 @@ before sending out the response headers.
|
|||
|
||||
ngx.header.HEADER
|
||||
-----------------------
|
||||
* **Context:** `rewrite_by_lua*`, `content_by_lua*`
|
||||
* **Context:** `rewrite_by_lua*`, `access_by_lua*`, `content_by_lua*`
|
||||
|
||||
Set/add/clear response headers. Underscores (_) in the header names will be replaced by dashes (-) and the header names will be matched case-insentively.
|
||||
|
||||
|
@ -597,7 +709,7 @@ shouldn't need it.
|
|||
|
||||
ngx.exec(uri, args)
|
||||
-------------------
|
||||
* **Context:** `rewrite_by_lua*`, `content_by_lua*`
|
||||
* **Context:** `rewrite_by_lua*`, `access_by_lua*`, `content_by_lua*`
|
||||
|
||||
Does an internal redirect to uri with args.
|
||||
|
||||
|
@ -630,7 +742,7 @@ directive in the ngx_echo module.
|
|||
|
||||
ngx.redirect(uri, status?)
|
||||
--------------------------
|
||||
* **Context:** `rewrite_by_lua*`, `content_by_lua*`
|
||||
* **Context:** `rewrite_by_lua*`, `access_by_lua*`, `content_by_lua*`
|
||||
|
||||
Issue an HTTP 301 or 302 redirection to `uri`.
|
||||
|
||||
|
@ -671,7 +783,7 @@ is equivalent to
|
|||
|
||||
ngx.send_headers()
|
||||
------------------
|
||||
* **Context:** `rewrite_by_lua*`, `content_by_lua*`
|
||||
* **Context:** `rewrite_by_lua*`, `access_by_lua*`, `content_by_lua*`
|
||||
|
||||
Explicitly send out the response headers.
|
||||
|
||||
|
@ -683,7 +795,7 @@ Headers will also be sent automatically when `content_by_lua` exits normally.
|
|||
|
||||
ngx.print(a, b, ...)
|
||||
--------------------
|
||||
* **Context:** `rewrite_by_lua*`, `content_by_lua*`
|
||||
* **Context:** `rewrite_by_lua*`, `access_by_lua*`, `content_by_lua*`
|
||||
|
||||
Emit args concatenated to the HTTP client (as response body).
|
||||
|
||||
|
@ -691,7 +803,7 @@ Nil arguments are not allowed.
|
|||
|
||||
ngx.say(a, b, ...)
|
||||
------------------
|
||||
* **Context:** `rewrite_by_lua*`, `content_by_lua*`
|
||||
* **Context:** `rewrite_by_lua*`, `access_by_lua*`, `content_by_lua*`
|
||||
|
||||
Just as `ngx.print` but also emit a trailing newline.
|
||||
|
||||
|
@ -699,7 +811,7 @@ Nil arguments are not allowed.
|
|||
|
||||
ngx.log(log_level, ...)
|
||||
-----------------------
|
||||
* **Context:** `rewrite_by_lua*`, `content_by_lua*`
|
||||
* **Context:** `rewrite_by_lua*`, `access_by_lua*`, `content_by_lua*`
|
||||
|
||||
Log args concatenated to error.log with the given logging level.
|
||||
|
||||
|
@ -707,13 +819,13 @@ Nil arguments are accepted and result in literal "nil".
|
|||
|
||||
ngx.flush()
|
||||
-----------
|
||||
* **Context:** `rewrite_by_lua*`, `content_by_lua*`
|
||||
* **Context:** `rewrite_by_lua*`, `access_by_lua*`, `content_by_lua*`
|
||||
|
||||
Force flushing the response outputs.
|
||||
|
||||
ngx.exit(status)
|
||||
----------------
|
||||
* **Context:** `rewrite_by_lua*`, `content_by_lua*`
|
||||
* **Context:** `rewrite_by_lua*`, `access_by_lua*`, `content_by_lua*`
|
||||
|
||||
Interrupts the execution of the current Lua thread and returns
|
||||
status code to nginx.
|
||||
|
@ -724,13 +836,13 @@ or other HTTP status numbers.
|
|||
|
||||
ngx.eof()
|
||||
---------
|
||||
* **Context:** `rewrite_by_lua*`, `content_by_lua*`
|
||||
* **Context:** `rewrite_by_lua*`, `access_by_lua*`, `content_by_lua*`
|
||||
|
||||
Explicitly specify the end of the response output stream.
|
||||
|
||||
ngx.escape_uri(str)
|
||||
-------------------
|
||||
* **Context:** `set_by_lua*`, `rewrite_by_lua*`, `content_by_lua*`
|
||||
* **Context:** `set_by_lua*`, `rewrite_by_lua*`, `access_by_lua*`, `content_by_lua*`
|
||||
|
||||
Escape `str` as a URI component.
|
||||
|
||||
|
@ -738,7 +850,7 @@ Escape `str` as a URI component.
|
|||
|
||||
ngx.unescape_uri(str)
|
||||
---------------------
|
||||
* **Context:** `set_by_lua*`, `rewrite_by_lua*`, `content_by_lua*`
|
||||
* **Context:** `set_by_lua*`, `rewrite_by_lua*`, `access_by_lua*`, `content_by_lua*`
|
||||
|
||||
Unescape `str` as a escaped URI component.
|
||||
|
||||
|
@ -746,7 +858,7 @@ Unescape `str` as a escaped URI component.
|
|||
|
||||
ngx.encode_base64(str)
|
||||
----------------------
|
||||
* **Context:** `set_by_lua*`, `rewrite_by_lua*`, `content_by_lua*`
|
||||
* **Context:** `set_by_lua*`, `rewrite_by_lua*`, `access_by_lua*`, `content_by_lua*`
|
||||
|
||||
Encode `str` to a base64 digest
|
||||
|
||||
|
@ -754,7 +866,7 @@ Encode `str` to a base64 digest
|
|||
|
||||
ngx.decode_base64(str)
|
||||
----------------------
|
||||
* **Context:** `set_by_lua*`, `rewrite_by_lua*`, `content_by_lua*`
|
||||
* **Context:** `set_by_lua*`, `rewrite_by_lua*`, `access_by_lua*`, `content_by_lua*`
|
||||
|
||||
Decode `str` as a base64 digest to the raw form
|
||||
|
||||
|
@ -762,7 +874,7 @@ Decode `str` as a base64 digest to the raw form
|
|||
|
||||
ngx.today()
|
||||
---------------
|
||||
* **Context:** `set_by_lua*`, `rewrite_by_lua*`, `content_by_lua*`
|
||||
* **Context:** `set_by_lua*`, `rewrite_by_lua*`, `access_by_lua*`, `content_by_lua*`
|
||||
|
||||
Returns today's date (in the format `yyyy-mm-dd`) from nginx cached time (no syscall involved unlike Lua's date library).
|
||||
.
|
||||
|
@ -771,13 +883,13 @@ This is the local time.
|
|||
|
||||
ngx.time()
|
||||
-------------
|
||||
* **Context:** `set_by_lua*`, `rewrite_by_lua*`, `content_by_lua*`
|
||||
* **Context:** `set_by_lua*`, `rewrite_by_lua*`, `access_by_lua*`, `content_by_lua*`
|
||||
|
||||
Returns the elapsed seconds from the epoch for the current timestamp from the nginx cached time (no syscall involved unlike Lua's date library).
|
||||
|
||||
ngx.localtime()
|
||||
---------------
|
||||
* **Context:** `set_by_lua*`, `rewrite_by_lua*`, `content_by_lua*`
|
||||
* **Context:** `set_by_lua*`, `rewrite_by_lua*`, `access_by_lua*`, `content_by_lua*`
|
||||
|
||||
Returns the current timestamp (in the format `yyyy-mm-dd hh:mm:ss`) of the nginx cached time (no syscall involved unlike Lua's date library).
|
||||
|
||||
|
@ -785,7 +897,7 @@ This is the local time.
|
|||
|
||||
ngx.utctime()
|
||||
-------------
|
||||
* **Context:** `set_by_lua*`, `rewrite_by_lua*`, `content_by_lua*`
|
||||
* **Context:** `set_by_lua*`, `rewrite_by_lua*`, `access_by_lua*`, `content_by_lua*`
|
||||
|
||||
Returns the current timestamp (in the format `yyyy-mm-dd hh:mm:ss`) of the nginx cached time (no syscall involved unlike Lua's date library).
|
||||
|
||||
|
@ -793,7 +905,7 @@ This is the UTC time.
|
|||
|
||||
ngx.cookie_time(sec)
|
||||
--------------------
|
||||
* **Context:** `set_by_lua*`, `rewrite_by_lua*`, `content_by_lua*`
|
||||
* **Context:** `set_by_lua*`, `rewrite_by_lua*`, `access_by_lua*`, `content_by_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`).
|
||||
|
||||
|
@ -802,7 +914,7 @@ Returns a formated string can be used as the cookie expiration time. The paramet
|
|||
|
||||
ndk.set_var.DIRECTIVE
|
||||
---------------------
|
||||
* **Context:** `rewrite_by_lua*`, `content_by_lua*`
|
||||
* **Context:** `rewrite_by_lua*`, `access_by_lua*`, `content_by_lua*`
|
||||
|
||||
This mechanism allows calling other nginx C modules' directives that are
|
||||
implemented by Nginx Devel Kit (NDK)'s set_var submodule's ndk_set_var_value.
|
||||
|
@ -836,12 +948,12 @@ Lua can be obtained freely from its project [homepage](http://www.lua.org/).
|
|||
lua-nginx-module [file list](http://github.com/chaoslawful/lua-nginx-module/downloads).
|
||||
|
||||
1. Grab the nginx source code from [nginx.net](http://nginx.net/), for example,
|
||||
the version 0.8.53 (see nginx compatibility), and then build the source with
|
||||
the version 0.8.54 (see nginx compatibility), and then build the source with
|
||||
this module:
|
||||
|
||||
$ wget 'http://sysoev.ru/nginx/nginx-0.8.53.tar.gz'
|
||||
$ tar -xzvf nginx-0.8.53.tar.gz
|
||||
$ cd nginx-0.8.53/
|
||||
$ wget 'http://sysoev.ru/nginx/nginx-0.8.54.tar.gz'
|
||||
$ tar -xzvf nginx-0.8.54.tar.gz
|
||||
$ cd nginx-0.8.54/
|
||||
|
||||
# tell nginx's build system where to find lua:
|
||||
export LUA_LIB=/path/to/lua/lib
|
||||
|
@ -865,7 +977,7 @@ Compatibility
|
|||
The following versions of Nginx should work with this module:
|
||||
|
||||
* 0.9.x (last tested: 0.9.3)
|
||||
* 0.8.x (last tested: 0.8.53)
|
||||
* 0.8.x (last tested: 0.8.54)
|
||||
* 0.7.x >= 0.7.46 (last tested: 0.7.68)
|
||||
|
||||
Earlier versions of Nginx like 0.6.x and 0.5.x will **not** work.
|
||||
|
|
4
config
4
config
|
@ -123,8 +123,8 @@ fi
|
|||
|
||||
ngx_addon_name=ngx_http_lua_module
|
||||
HTTP_AUX_FILTER_MODULES="$HTTP_AUX_FILTER_MODULES ngx_http_lua_module"
|
||||
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/src/ngx_http_lua_module.c $ngx_addon_dir/src/ngx_http_lua_headers.c $ngx_addon_dir/src/ngx_http_lua_directive.c $ngx_addon_dir/src/ngx_http_lua_hook.c $ngx_addon_dir/src/ngx_http_lua_util.c $ngx_addon_dir/src/ngx_http_lua_cache.c $ngx_addon_dir/src/ngx_http_lua_conf.c $ngx_addon_dir/src/ngx_http_lua_contentby.c $ngx_addon_dir/src/ngx_http_lua_rewriteby.c $ngx_addon_dir/src/ngx_http_lua_setby.c $ngx_addon_dir/src/ngx_http_lua_filter.c $ngx_addon_dir/src/ngx_http_lua_clfactory.c"
|
||||
NGX_ADDON_DEPS="$NGX_ADDON_DEPS $ngx_addon_dir/src/ddebug.h $ngx_addon_dir/src/ngx_http_lua_common.h $ngx_addon_dir/src/ngx_http_lua_directive.h $ngx_addon_dir/src/ngx_http_lua_headers.h $ngx_addon_dir/src/ngx_http_lua_hook.h $ngx_addon_dir/src/ngx_http_lua_util.h $ngx_addon_dir/src/ngx_http_lua_cache.h $ngx_addon_dir/src/ngx_http_lua_conf.h $ngx_addon_dir/src/ngx_http_lua_contentby.h $ngx_addon_dir/src/ngx_http_lua_rewriteby.h $ngx_addon_dir/src/ngx_http_lua_setby.h $ngx_addon_dir/src/ngx_http_lua_filter.h $ngx_addon_dir/src/ngx_http_lua_clfactory.h"
|
||||
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/src/ngx_http_lua_module.c $ngx_addon_dir/src/ngx_http_lua_headers.c $ngx_addon_dir/src/ngx_http_lua_directive.c $ngx_addon_dir/src/ngx_http_lua_hook.c $ngx_addon_dir/src/ngx_http_lua_util.c $ngx_addon_dir/src/ngx_http_lua_cache.c $ngx_addon_dir/src/ngx_http_lua_conf.c $ngx_addon_dir/src/ngx_http_lua_contentby.c $ngx_addon_dir/src/ngx_http_lua_rewriteby.c $ngx_addon_dir/src/ngx_http_lua_accessby.c $ngx_addon_dir/src/ngx_http_lua_setby.c $ngx_addon_dir/src/ngx_http_lua_filter.c $ngx_addon_dir/src/ngx_http_lua_clfactory.c"
|
||||
NGX_ADDON_DEPS="$NGX_ADDON_DEPS $ngx_addon_dir/src/ddebug.h $ngx_addon_dir/src/ngx_http_lua_common.h $ngx_addon_dir/src/ngx_http_lua_directive.h $ngx_addon_dir/src/ngx_http_lua_headers.h $ngx_addon_dir/src/ngx_http_lua_hook.h $ngx_addon_dir/src/ngx_http_lua_util.h $ngx_addon_dir/src/ngx_http_lua_cache.h $ngx_addon_dir/src/ngx_http_lua_conf.h $ngx_addon_dir/src/ngx_http_lua_contentby.h $ngx_addon_dir/src/ngx_http_lua_rewriteby.h $ngx_addon_dir/src/ngx_http_lua_accessby.h $ngx_addon_dir/src/ngx_http_lua_setby.h $ngx_addon_dir/src/ngx_http_lua_filter.h $ngx_addon_dir/src/ngx_http_lua_clfactory.h"
|
||||
CFLAGS="$CFLAGS -DNDK_SET_VAR -DNGX_OPENSSL_MD5 -DNGX_HAVE_OPENSSL_MD5_H -DNGX_HAVE_OPENSSL_SHA1_H -DNDK_SET_VAR -DNDK_HASH -DNDK_SHA1 -DNDK_MD5"
|
||||
CORE_LIBS="-Wl,-E $CORE_LIBS"
|
||||
|
||||
|
|
|
@ -0,0 +1,300 @@
|
|||
/* vim:set ft=c ts=4 sw=4 et fdm=marker: */
|
||||
|
||||
#define DDEBUG 0
|
||||
|
||||
#include "nginx.h"
|
||||
#include "ngx_http_lua_accessby.h"
|
||||
#include "ngx_http_lua_util.h"
|
||||
#include "ngx_http_lua_hook.h"
|
||||
#include "ngx_http_lua_cache.h"
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_lua_access_by_chunk(lua_State *L, ngx_http_request_t *r)
|
||||
{
|
||||
int cc_ref;
|
||||
lua_State *cc;
|
||||
ngx_http_lua_ctx_t *ctx;
|
||||
ngx_http_cleanup_t *cln;
|
||||
|
||||
/* {{{ new coroutine to handle request */
|
||||
cc = ngx_http_lua_new_thread(r, L, &cc_ref);
|
||||
|
||||
if (cc == NULL) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"(lua-content-by-chunk) failed to create new coroutine "
|
||||
"to handle request");
|
||||
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
/* move code closure to new coroutine */
|
||||
lua_xmove(L, cc, 1);
|
||||
|
||||
/* set closure's env table to new coroutine's globals table */
|
||||
lua_pushvalue(cc, LUA_GLOBALSINDEX);
|
||||
lua_setfenv(cc, -2);
|
||||
|
||||
/* save reference of code to ease forcing stopping */
|
||||
lua_pushvalue(cc, -1);
|
||||
lua_setglobal(cc, GLOBALS_SYMBOL_RUNCODE);
|
||||
|
||||
/* save nginx request in coroutine globals table */
|
||||
lua_pushlightuserdata(cc, r);
|
||||
lua_setglobal(cc, GLOBALS_SYMBOL_REQUEST);
|
||||
/* }}} */
|
||||
|
||||
/* {{{ initialize request context */
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
|
||||
|
||||
dd("ctx = %p", ctx);
|
||||
|
||||
if (ctx == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_http_lua_reset_ctx(r, L, ctx);
|
||||
|
||||
ctx->entered_access_phase = 1;
|
||||
|
||||
ctx->cc = cc;
|
||||
ctx->cc_ref = cc_ref;
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ register request cleanup hooks */
|
||||
if (ctx->cleanup == NULL) {
|
||||
cln = ngx_http_cleanup_add(r, 0);
|
||||
if (cln == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
cln->handler = ngx_http_lua_request_cleanup;
|
||||
cln->data = r;
|
||||
ctx->cleanup = &cln->handler;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
return ngx_http_lua_run_thread(L, r, ctx, 0);
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_lua_access_handler_file(ngx_http_request_t *r)
|
||||
{
|
||||
lua_State *L;
|
||||
ngx_int_t rc;
|
||||
u_char *script_path;
|
||||
ngx_http_lua_main_conf_t *lmcf;
|
||||
ngx_http_lua_loc_conf_t *llcf;
|
||||
char *err;
|
||||
|
||||
llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module);
|
||||
|
||||
script_path = ngx_http_lua_rebase_path(r->pool, llcf->access_src.data,
|
||||
llcf->access_src.len);
|
||||
|
||||
if (script_path == NULL) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"Failed to allocate memory to store absolute path: raw path='%v'",
|
||||
&(llcf->access_src));
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);
|
||||
L = lmcf->lua;
|
||||
|
||||
/* load Lua script file (w/ cache) sp = 1 */
|
||||
rc = ngx_http_lua_cache_loadfile(L, (char *) script_path, &err);
|
||||
|
||||
if (rc != NGX_OK) {
|
||||
if (err == NULL) {
|
||||
err = "unknown error";
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"Failed to load Lua inlined code: %s", err);
|
||||
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
/* make sure we have a valid code chunk */
|
||||
assert(lua_isfunction(L, -1));
|
||||
|
||||
rc = ngx_http_lua_access_by_chunk(L, r);
|
||||
|
||||
if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (rc == NGX_DONE) {
|
||||
return NGX_DONE;
|
||||
}
|
||||
|
||||
if (rc == NGX_AGAIN) {
|
||||
return NGX_DONE;
|
||||
}
|
||||
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_lua_access_handler(ngx_http_request_t *r)
|
||||
{
|
||||
ngx_http_lua_loc_conf_t *llcf;
|
||||
ngx_http_lua_ctx_t *ctx;
|
||||
ngx_int_t rc;
|
||||
ngx_http_lua_main_conf_t *lmcf;
|
||||
|
||||
dd("in access handler: %.*s", (int) r->uri.len, r->uri.data);
|
||||
|
||||
lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);
|
||||
|
||||
if (! lmcf->postponed_to_access_phase_end) {
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
ngx_http_phase_handler_t tmp;
|
||||
ngx_http_phase_handler_t *ph;
|
||||
ngx_http_phase_handler_t *cur_ph;
|
||||
ngx_http_phase_handler_t *last_ph;
|
||||
|
||||
lmcf->postponed_to_access_phase_end = 1;
|
||||
|
||||
cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
|
||||
|
||||
ph = cmcf->phase_engine.handlers;
|
||||
cur_ph = &ph[r->phase_handler];
|
||||
last_ph = &ph[cur_ph->next - 1];
|
||||
|
||||
#if 0
|
||||
if (cur_ph == last_ph) {
|
||||
dd("XXX our handler is already the last access phase handler");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cur_ph < last_ph) {
|
||||
dd("swaping the contents of cur_ph and last_ph...");
|
||||
|
||||
tmp = *cur_ph;
|
||||
|
||||
memmove(cur_ph, cur_ph + 1,
|
||||
(last_ph - cur_ph) * sizeof (ngx_http_phase_handler_t));
|
||||
|
||||
*last_ph = tmp;
|
||||
|
||||
r->phase_handler--; /* redo the current ph */
|
||||
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
}
|
||||
|
||||
llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module);
|
||||
|
||||
if (llcf->access_handler == NULL) {
|
||||
dd("no access handler found");
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
|
||||
|
||||
dd("ctx = %p", ctx);
|
||||
|
||||
if (ctx == NULL) {
|
||||
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_lua_ctx_t));
|
||||
if (ctx == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
dd("setting new ctx: ctx = %p", ctx);
|
||||
|
||||
ctx->cc_ref = LUA_NOREF;
|
||||
|
||||
ngx_http_set_ctx(r, ctx, ngx_http_lua_module);
|
||||
}
|
||||
|
||||
dd("entered? %d", (int) ctx->entered_access_phase);
|
||||
|
||||
if (ctx->waiting_more_body) {
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
if (ctx->entered_access_phase) {
|
||||
dd("calling wev handler");
|
||||
rc = ngx_http_lua_wev_handler(r);
|
||||
dd("wev handler returns %d", (int) rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (llcf->force_read_body &&
|
||||
! ctx->read_body_done &&
|
||||
((r->method & NGX_HTTP_POST) || (r->method & NGX_HTTP_PUT)))
|
||||
{
|
||||
rc = ngx_http_read_client_request_body(r,
|
||||
ngx_http_lua_generic_phase_post_read);
|
||||
|
||||
if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (rc == NGX_AGAIN) {
|
||||
ctx->waiting_more_body = 1;
|
||||
return NGX_DONE;
|
||||
}
|
||||
}
|
||||
|
||||
dd("calling access handler");
|
||||
return llcf->access_handler(r);
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_lua_access_handler_inline(ngx_http_request_t *r)
|
||||
{
|
||||
lua_State *L;
|
||||
ngx_int_t rc;
|
||||
ngx_http_lua_main_conf_t *lmcf;
|
||||
ngx_http_lua_loc_conf_t *llcf;
|
||||
char *err;
|
||||
|
||||
dd("HERE");
|
||||
|
||||
llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module);
|
||||
lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);
|
||||
|
||||
L = lmcf->lua;
|
||||
|
||||
/* load Lua inline script (w/ cache) sp = 1 */
|
||||
rc = ngx_http_lua_cache_loadbuffer(L, llcf->access_src.data,
|
||||
llcf->access_src.len, "access_by_lua", &err);
|
||||
|
||||
if (rc != NGX_OK) {
|
||||
if (err == NULL) {
|
||||
err = "unknown error";
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"Failed to load Lua inlined code: %s", err);
|
||||
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
rc = ngx_http_lua_access_by_chunk(L, r);
|
||||
|
||||
dd("access by chunk returns %d", (int) rc);
|
||||
|
||||
if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (rc == NGX_DONE) {
|
||||
return NGX_DONE;
|
||||
}
|
||||
|
||||
if (rc == NGX_AGAIN) {
|
||||
return NGX_DONE;
|
||||
}
|
||||
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
/* vim:set ft=c ts=4 sw=4 et fdm=marker: */
|
||||
|
||||
#ifndef NGX_HTTP_LUA_ACCESS_BY_H__
|
||||
#define NGX_HTTP_LUA_ACCESS_BY_H__
|
||||
|
||||
|
||||
#include "ngx_http_lua_common.h"
|
||||
|
||||
|
||||
ngx_int_t ngx_http_lua_access_by_chunk(lua_State *L, ngx_http_request_t *r);
|
||||
ngx_int_t ngx_http_lua_access_handler(ngx_http_request_t *r);
|
||||
ngx_int_t ngx_http_lua_access_handler_inline(ngx_http_request_t *r);
|
||||
ngx_int_t ngx_http_lua_access_handler_file(ngx_http_request_t *r);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -26,7 +26,7 @@ typedef struct {
|
|||
ngx_str_t lua_cpath;
|
||||
|
||||
unsigned postponed_to_rewrite_phase_end:1;
|
||||
unsigned postponed_to_access_phase_end:1; /* TODO */
|
||||
unsigned postponed_to_access_phase_end:1;
|
||||
|
||||
} ngx_http_lua_main_conf_t;
|
||||
|
||||
|
@ -35,11 +35,12 @@ typedef struct {
|
|||
0: don't force reading request body */
|
||||
|
||||
ngx_http_handler_pt rewrite_handler;
|
||||
ngx_http_handler_pt access_handler;
|
||||
ngx_http_handler_pt content_handler;
|
||||
|
||||
ngx_str_t rewrite_src; /* rewrite_by_lua
|
||||
inline script/script file path */
|
||||
|
||||
ngx_str_t access_src;
|
||||
ngx_str_t content_src; /* content_by_lua
|
||||
inline script/script file path */
|
||||
|
||||
|
@ -87,8 +88,9 @@ typedef struct {
|
|||
0: no need to wait */
|
||||
|
||||
unsigned headers_set:1;
|
||||
unsigned entered_content_phase:1;
|
||||
unsigned entered_rewrite_phase:1;
|
||||
unsigned entered_access_phase:1;
|
||||
unsigned entered_content_phase:1;
|
||||
|
||||
ngx_http_cleanup_pt *cleanup;
|
||||
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
#include "ngx_http_lua_contentby.h"
|
||||
|
||||
|
||||
ngx_flag_t ngx_http_lua_requires_rewrite = 0;
|
||||
unsigned ngx_http_lua_requires_rewrite = 0;
|
||||
unsigned ngx_http_lua_requires_access = 0;
|
||||
|
||||
|
||||
char *
|
||||
|
@ -227,6 +228,62 @@ ngx_http_lua_rewrite_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
}
|
||||
|
||||
|
||||
char *
|
||||
ngx_http_lua_access_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_str_t *args;
|
||||
ngx_http_lua_loc_conf_t *llcf = conf;
|
||||
|
||||
dd("enter");
|
||||
|
||||
/* must specifiy a content handler */
|
||||
if (cmd->post == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (llcf->access_handler) {
|
||||
return "is duplicate";
|
||||
}
|
||||
|
||||
/* update lua script data */
|
||||
/*
|
||||
* args[0] = "content_by_lua"
|
||||
* args[1] = lua script to be executed
|
||||
* */
|
||||
args = cf->args->elts;
|
||||
|
||||
/* prevent variable appearing in Lua inline script/file path */
|
||||
|
||||
#if 0
|
||||
if (ngx_http_lua_has_inline_var(&args[1])) {
|
||||
ngx_conf_log_error(NGX_LOG_ERR, cf, 0,
|
||||
"Lua inline script or file path should not has inline "
|
||||
"variable: %V",
|
||||
&args[1]);
|
||||
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (args[1].len == 0) {
|
||||
/* Oops...Invalid location conf */
|
||||
ngx_conf_log_error(NGX_LOG_ERR, cf, 0,
|
||||
"Invalid location config: no runnable Lua code");
|
||||
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
llcf->access_src = args[1];
|
||||
llcf->access_handler = cmd->post;
|
||||
|
||||
if (! ngx_http_lua_requires_access) {
|
||||
ngx_http_lua_requires_access = 1;
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
ngx_http_lua_content_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
#include "ngx_http_lua_common.h"
|
||||
|
||||
|
||||
extern ngx_flag_t ngx_http_lua_requires_rewrite;
|
||||
extern unsigned ngx_http_lua_requires_rewrite;
|
||||
extern unsigned ngx_http_lua_requires_access;
|
||||
|
||||
|
||||
char * ngx_http_lua_package_cpath(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
|
@ -18,7 +19,8 @@ char * ngx_http_lua_content_by_lua(ngx_conf_t *cf, ngx_command_t *cmd,
|
|||
void *conf);
|
||||
char * ngx_http_lua_rewrite_by_lua(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
ngx_int_t ngx_http_lua_rewrite_handler_file(ngx_http_request_t *r);
|
||||
char * ngx_http_lua_access_by_lua(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
ngx_int_t ngx_http_lua_filter_set_by_lua_inline(ngx_http_request_t *r,
|
||||
ngx_str_t *val, ngx_http_variable_value_t *v, void *data);
|
||||
ngx_int_t ngx_http_lua_filter_set_by_lua_file(ngx_http_request_t *r,
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "ngx_http_lua_filter.h"
|
||||
#include "ngx_http_lua_contentby.h"
|
||||
#include "ngx_http_lua_rewriteby.h"
|
||||
#include "ngx_http_lua_accessby.h"
|
||||
|
||||
|
||||
static ngx_int_t ngx_http_lua_init(ngx_conf_t *cf);
|
||||
|
@ -72,6 +73,16 @@ static ngx_command_t ngx_http_lua_cmds[] = {
|
|||
ngx_http_lua_rewrite_handler_inline
|
||||
},
|
||||
|
||||
/* access_by_lua <inline script> */
|
||||
{
|
||||
ngx_string("access_by_lua"),
|
||||
NGX_HTTP_LOC_CONF | NGX_HTTP_LIF_CONF | NGX_CONF_TAKE1,
|
||||
ngx_http_lua_access_by_lua,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
0,
|
||||
ngx_http_lua_access_handler_inline
|
||||
},
|
||||
|
||||
/* content_by_lua <inline script> */
|
||||
{
|
||||
ngx_string("content_by_lua"),
|
||||
|
@ -91,6 +102,15 @@ static ngx_command_t ngx_http_lua_cmds[] = {
|
|||
ngx_http_lua_rewrite_handler_file
|
||||
},
|
||||
|
||||
{
|
||||
ngx_string("access_by_lua_file"),
|
||||
NGX_HTTP_LOC_CONF | NGX_HTTP_LIF_CONF | NGX_CONF_TAKE1,
|
||||
ngx_http_lua_access_by_lua,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
0,
|
||||
ngx_http_lua_access_handler_file
|
||||
},
|
||||
|
||||
/* content_by_lua_file rel/or/abs/path/to/script */
|
||||
{
|
||||
ngx_string("content_by_lua_file"),
|
||||
|
@ -146,9 +166,9 @@ ngx_http_lua_init(ngx_conf_t *cf)
|
|||
return rc;
|
||||
}
|
||||
|
||||
if (ngx_http_lua_requires_rewrite) {
|
||||
cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
|
||||
cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
|
||||
|
||||
if (ngx_http_lua_requires_rewrite) {
|
||||
h = ngx_array_push(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers);
|
||||
if (h == NULL) {
|
||||
return NGX_ERROR;
|
||||
|
@ -157,6 +177,15 @@ ngx_http_lua_init(ngx_conf_t *cf)
|
|||
*h = ngx_http_lua_rewrite_handler;
|
||||
}
|
||||
|
||||
if (ngx_http_lua_requires_access) {
|
||||
h = ngx_array_push(&cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers);
|
||||
if (h == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*h = ngx_http_lua_access_handler;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,9 +53,9 @@ ngx_http_lua_rewrite_by_chunk(lua_State *L, ngx_http_request_t *r)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
#if 0
|
||||
ngx_http_lua_reset_ctx(r, L, ctx);
|
||||
#endif
|
||||
|
||||
ctx->entered_rewrite_phase = 1;
|
||||
|
||||
ctx->cc = cc;
|
||||
ctx->cc_ref = cc_ref;
|
||||
|
@ -243,10 +243,6 @@ ngx_http_lua_rewrite_handler(ngx_http_request_t *r)
|
|||
}
|
||||
}
|
||||
|
||||
dd("setting entered");
|
||||
|
||||
ctx->entered_rewrite_phase = 1;
|
||||
|
||||
dd("calling rewrite handler");
|
||||
return llcf->rewrite_handler(r);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
ngx_int_t ngx_http_lua_rewrite_by_chunk(lua_State *L, ngx_http_request_t *r);
|
||||
ngx_int_t ngx_http_lua_rewrite_handler(ngx_http_request_t *r);
|
||||
ngx_int_t ngx_http_lua_rewrite_handler_inline(ngx_http_request_t *r);
|
||||
ngx_int_t ngx_http_lua_rewrite_handler_file(ngx_http_request_t *r);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -807,6 +807,7 @@ ngx_http_lua_reset_ctx(ngx_http_request_t *r, lua_State *L,
|
|||
ctx->waiting = 0;
|
||||
ctx->done = 0;
|
||||
ctx->entered_rewrite_phase = 0;
|
||||
ctx->entered_access_phase = 0;
|
||||
ctx->exit_code = 0;
|
||||
ctx->exited = 0;
|
||||
ctx->exec_uri.data = NULL;
|
||||
|
|
Загрузка…
Ссылка в новой задаче