Skip to content

Commit c1cd173

Browse files
committed
feature: added new Lua API, ngx.get_phase(), for fetching the name of the current running phase from within Lua. possible return values are "set", "rewrite", "access", "content", "log", "header_filter", "body_filter", and "init". thanks James Hurst for the patch.
1 parent bd66f77 commit c1cd173

File tree

5 files changed

+238
-0
lines changed

5 files changed

+238
-0
lines changed

config

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ NGX_ADDON_SRCS="$NGX_ADDON_SRCS \
183183
$ngx_addon_dir/src/ngx_http_lua_initby.c \
184184
$ngx_addon_dir/src/ngx_http_lua_socket_udp.c \
185185
$ngx_addon_dir/src/ngx_http_lua_req_method.c \
186+
$ngx_addon_dir/src/ngx_http_lua_phase.c \
186187
"
187188

188189
NGX_ADDON_DEPS="$NGX_ADDON_DEPS \
@@ -229,6 +230,7 @@ NGX_ADDON_DEPS="$NGX_ADDON_DEPS \
229230
$ngx_addon_dir/src/ngx_http_lua_initby.h \
230231
$ngx_addon_dir/src/ngx_http_lua_socket_udp.h \
231232
$ngx_addon_dir/src/ngx_http_lua_req_method.h \
233+
$ngx_addon_dir/src/ngx_http_lua_phase.h \
232234
"
233235

234236
CFLAGS="$CFLAGS -DNDK_SET_VAR"

src/ngx_http_lua_phase.c

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#ifndef DDEBUG
2+
#define DDEBUG 0
3+
#endif
4+
#include "ddebug.h"
5+
6+
7+
#include "ngx_http_lua_phase.h"
8+
#include "ngx_http_lua_util.h"
9+
#include "ngx_http_lua_ctx.h"
10+
11+
12+
static int ngx_http_lua_ngx_get_phase(lua_State *L);
13+
14+
15+
static int
16+
ngx_http_lua_ngx_get_phase(lua_State *L)
17+
{
18+
ngx_http_request_t *r;
19+
ngx_http_lua_ctx_t *ctx;
20+
21+
lua_pushlightuserdata(L, &ngx_http_lua_request_key);
22+
lua_rawget(L, LUA_GLOBALSINDEX);
23+
r = lua_touserdata(L, -1);
24+
lua_pop(L, 1);
25+
26+
/* If we have no request object, assume we are called from the "init"
27+
* phase. */
28+
29+
if (r == NULL) {
30+
lua_pushlstring(L, (char *) "init", sizeof("init") - 1);
31+
return 1;
32+
}
33+
34+
ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
35+
if (ctx == NULL) {
36+
return luaL_error(L, "no request ctx found");
37+
}
38+
39+
switch (ctx->context) {
40+
case NGX_HTTP_LUA_CONTEXT_SET:
41+
lua_pushliteral(L, "set");
42+
break;
43+
44+
case NGX_HTTP_LUA_CONTEXT_REWRITE:
45+
lua_pushliteral(L, "rewrite");
46+
break;
47+
48+
case NGX_HTTP_LUA_CONTEXT_ACCESS:
49+
lua_pushliteral(L, "access");
50+
break;
51+
52+
case NGX_HTTP_LUA_CONTEXT_CONTENT:
53+
lua_pushliteral(L, "content");
54+
break;
55+
56+
case NGX_HTTP_LUA_CONTEXT_LOG:
57+
lua_pushliteral(L, "log");
58+
break;
59+
60+
case NGX_HTTP_LUA_CONTEXT_HEADER_FILTER:
61+
lua_pushliteral(L, "header_filter");
62+
break;
63+
64+
case NGX_HTTP_LUA_CONTEXT_BODY_FILTER:
65+
lua_pushliteral(L, "body_filter");
66+
break;
67+
68+
default:
69+
luaL_error(L, "unknown phase: %d", ctx->context);
70+
}
71+
72+
return 1;
73+
}
74+
75+
76+
void
77+
ngx_http_lua_inject_phase_api(lua_State *L)
78+
{
79+
lua_pushcfunction(L, ngx_http_lua_ngx_get_phase);
80+
lua_setfield(L, -2, "get_phase");
81+
}
82+

src/ngx_http_lua_phase.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#ifndef NGX_HTTP_LUA_PHASE_H
2+
#define NGX_HTTP_LUA_PHASE_H
3+
4+
5+
#include "ngx_http_lua_common.h"
6+
7+
8+
void ngx_http_lua_inject_phase_api(lua_State *L);
9+
10+
11+
#endif /* NGX_HTTP_LUA_PHASE_H */

src/ngx_http_lua_util.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "ngx_http_lua_headerfilterby.h"
3636
#include "ngx_http_lua_bodyfilterby.h"
3737
#include "ngx_http_lua_logby.h"
38+
#include "ngx_http_lua_phase.h"
3839

3940

4041
char ngx_http_lua_code_cache_key;
@@ -587,9 +588,12 @@ ngx_http_lua_inject_ngx_api(ngx_conf_t *cf, lua_State *L)
587588
ngx_http_lua_inject_control_api(cf->log, L);
588589
ngx_http_lua_inject_subrequest_api(L);
589590
ngx_http_lua_inject_sleep_api(L);
591+
ngx_http_lua_inject_phase_api(L);
592+
590593
#if (NGX_PCRE)
591594
ngx_http_lua_inject_regex_api(L);
592595
#endif
596+
593597
ngx_http_lua_inject_req_api(cf->log, L);
594598
ngx_http_lua_inject_resp_header_api(L);
595599
ngx_http_lua_inject_variable_api(L);

t/089-phase.t

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# vim:set ft= ts=4 sw=4 et fdm=marker:
2+
use lib 'lib';
3+
use Test::Nginx::Socket;
4+
5+
#worker_connections(1014);
6+
#master_process_enabled(1);
7+
log_level('warn');
8+
9+
repeat_each(2);
10+
#repeat_each(1);
11+
12+
plan tests => repeat_each() * (blocks() * 2) - 2;
13+
14+
#no_diff();
15+
#no_long_string();
16+
run_tests();
17+
18+
__DATA__
19+
20+
=== TEST 1: get_phase in init_by_lua
21+
--- http_config
22+
init_by_lua 'phase = ngx.get_phase()';
23+
--- config
24+
location /lua {
25+
content_by_lua '
26+
ngx.say(phase)
27+
';
28+
}
29+
--- request
30+
GET /lua
31+
--- response_body
32+
init
33+
34+
35+
36+
=== TEST 2: get_phase in set_by_lua
37+
--- config
38+
set_by_lua $phase 'return ngx.get_phase()';
39+
location /lua {
40+
content_by_lua '
41+
ngx.say(ngx.var.phase)
42+
';
43+
}
44+
--- request
45+
GET /lua
46+
--- response_body
47+
set
48+
49+
50+
51+
=== TEST 3: get_phase in rewrite_by_lua
52+
--- config
53+
location /lua {
54+
rewrite_by_lua '
55+
ngx.say(ngx.get_phase())
56+
ngx.exit(200)
57+
';
58+
}
59+
--- request
60+
GET /lua
61+
--- response_body
62+
rewrite
63+
64+
65+
66+
=== TEST 4: get_phase in access_by_lua
67+
--- config
68+
location /lua {
69+
access_by_lua '
70+
ngx.say(ngx.get_phase())
71+
ngx.exit(200)
72+
';
73+
}
74+
--- request
75+
GET /lua
76+
--- response_body
77+
access
78+
79+
80+
81+
=== TEST 5: get_phase in content_by_lua
82+
--- config
83+
location /lua {
84+
content_by_lua '
85+
ngx.say(ngx.get_phase())
86+
';
87+
}
88+
--- request
89+
GET /lua
90+
--- response_body
91+
content
92+
93+
94+
95+
=== TEST 6: get_phase in header_filter_by_lua
96+
--- config
97+
location /lua {
98+
echo "OK";
99+
header_filter_by_lua '
100+
ngx.header.Phase = ngx.get_phase()
101+
';
102+
}
103+
--- request
104+
GET /lua
105+
--- response_header
106+
Phase: header_filter
107+
108+
109+
110+
=== TEST 7: get_phase in body_filter_by_lua
111+
--- config
112+
location /lua {
113+
content_by_lua '
114+
ngx.exit(200)
115+
';
116+
body_filter_by_lua '
117+
ngx.arg[1] = ngx.get_phase()
118+
';
119+
}
120+
--- request
121+
GET /lua
122+
--- response_body chop
123+
body_filter
124+
125+
126+
127+
=== TEST 8: get_phase in log_by_lua
128+
--- config
129+
location /lua {
130+
echo "OK";
131+
log_by_lua '
132+
ngx.log(ngx.ERR, ngx.get_phase())
133+
';
134+
}
135+
--- request
136+
GET /lua
137+
--- error_log
138+
log
139+

0 commit comments

Comments
 (0)