Strange rewrite_by_lua outcome

agentzh agentzh at gmail.com
Mon Oct 17 00:55:54 UTC 2011


On Mon, Oct 17, 2011 at 4:11 AM, Nginx User <nginx at nginxuser.net> wrote:
>
> This produces a 500 Internal server error instead:
> #GET /submit_links/
> rewrite_by_lua '
>        local request_uri = ngx.re.match(ngx.var.request_uri,
> "\:|\[|\]|\-\-|\@|\^|\{|\}|\~|\<|\>|\.\.|\+\+|//|\%0|\%A|\%B|\%C|\%D|\%E|\%F|\%22|\%27|\%28|\%29|\%3C|\%3E|\%5C|\%7B|\%7C|\%7D|select(\s*)\(|convert(\s*)\(|/query/|function\.|remoteFile|servername|\&rptmode\=|/\(null\)/|(maincore|authorize|macromates|head_auth|submit_links|change_action|admin_db_utilities|admin\.webring\.docs|Table/Latest/index)\.|w00t|MNG/LIVE|/x[0-9][0-9]|\\x[0-9][0-9]|/(cgi|https?)/|\.css\(|\)\+|/\,/|\{0\}|eval\(|\_vti\_|\(null\)|echo.*kae|function(\.array\-rand|\(\))",
> "io")

I think you should escape "\" here according to nginx's string literal
syntax (you do not need to escape "\" in your previous "if" example
because Nginx uses special regex syntax in that regex context. You'll
also have to escape the "\" according to Lua string escaping rules
too. That is, escaping "\" *twice*.

>
> Line 62: "23388#0: *258 Failed to load Lua inlined code: [string
> "rewrite_by_lua"]:24: ')' expected near '|', client: xx.xxx.xx.xx,
> server: testsite.com, request: "GET /submit_links HTTP/1.1", host:
> "testsite.com""
> http://pastebin.com/XYNwEciX
>

The error message indicates a Lua syntax error in your Lua source
code. A quick solution to this is to put your code into a separate
.lua file and use rewrite_by_lua_file instead such that you do not
have to escape "\" twice (once for Nginx string escaping rules and
another for Lua string escaping rules).

Here's an example:
    # nginx.conf
    location /foo {
        rewrite_by_lua 'ngx.re.match("\\\\d+", ngx.var.uri)';  # we're
using \d+ here but requires twice escaping
    }

And to use external .lua file:

    # nginx.conf
    location /foo {
        rewrite_by_lua_file conf/my.lua;
    }

    # conf/my.lua
    ngx.re.match("\\d+", ngx.var.uri)

We can see that in the first example, we need to escape "\" for Nginx
string literals (so it becomes "\\") and then escape each of these two
back-slashes again according for Lua string literals and thus got
"\\\\" at last.

But in the second example, we only need to esacpe "\" once according
to Lua string literal syntax, which is a bit better looking :)

This gotcha is documented in ngx_lua's wiki page here:

    http://wiki.nginx.org/HttpLuaModule#ngx.re.match

Best,
-agentzh



More information about the nginx mailing list