0%

Nginx rewrite & OpenResty rewrite_by_lua*

Module ngx_http_rewrite_module

1.Directives

  • break
  • return
  • set
  • return
  • if
  • rewrite
  • rewrite_log
  • uninitialized_variable_warn

2. 执行顺序

  1. server level 的 rewrite 模块代码
    (break, return, set … 等按出现顺序依次执行,无优先级区别)
  2. 根据当前 URI 选择一个合适的 location,进入其中
  3. 顺序执行 location level 的 rewrite 模块代码
  4. 若在此过程中 URI 被重定向(rewritten), 返回 2. 再次执行(注: 此处不是返回 1.)
    (2. - 4. 过程最多重复10次,再多Nginx报错)

3. rewrite 命令

1
2
3
Syntax:	rewrite regex replacement [flag];
Default: —
Context: server, location, if

用于对当前的 URI 进行重定向。

flag
  • (default)
    当前 URI 被修改,但是代码会继续向下执行,直到执行完 rewrite phase
  • last
    当前 URI 被修改,暂停当前代码执行,暂停当前 rewrite phase 代码执行,直接跳转去匹配下一个 location
  • break
    当前 URI 被修改,暂停当前 rewrite phase 代码执行,接着执行下一个 phase,(不改变location)
  • redirect
    暂停当前代码执行,暂停当前 rewrite phase 代码执行,返回 302 给客户端

    returns a temporary redirect with the 302 code; used if a replacement string does not start with “http://”, “https://”, or “$scheme”;

    疑问:此处 replacement 是否以 $scheme 开头好像都可以使浏览器发生跳转,没理解这里说的是什么意思。

  • permanent
    暂停当前代码执行,暂停当前 rewrite phase 代码执行,返回 301 给客户端

3. rewrite_by_lua

rewrite_by_lua 是运行在 rewrite phase 结尾。
例如:

1
2
3
4
5
6
7
8
location / {
set $a 1;
rewrite_by_lua '
ngx.var.a = ngx.var.a + 1;
';

echo $a;
}

输出:

1
2

测试时发现:

1
2
3
4
5
6
7
8
9
10
11
12
location / {
set $a 2048;
rewrite ^ /test;

rewrite_by_lua '
ngx.var.a = ngx.var.a + 1;
';
}

location /test {
echo $a;
}

输出:

1
2048

没有在rewrite 时使用last, redirect, permanent, 按理rewrite_by_lua里面的代码应该被执行,但是缺没有。
openresty/lua-nginx-module 有这样一段话

If the ngx_http_rewrite_module’s rewrite directive is used to change the URI and initiate location re-lookups (internal redirections), then any rewrite_by_lua or rewrite_by_lua_file code sequences within the current location will not be executed.

当发生重定向后,rewrite_by_lua 中的代码不会被执行。

Reference 参考并感谢作者 Thanks