Skip to content

Commit 5078b14

Browse files
committed
bugfix: the ngx.arg API was not usable within external lua module files in set_by_lua*. diagnosis: now we issue user-friendly error messages when the nginx lua APIs are used in the wrong directive contexts (e.g., using ngx.location.capture in set_by_lua*).
1 parent 4e4e0b3 commit 5078b14

23 files changed

+1059
-352
lines changed

src/ngx_http_lua_accessby.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,8 @@ ngx_http_lua_access_by_chunk(lua_State *L, ngx_http_request_t *r)
281281
}
282282
/* }}} */
283283

284+
ctx->context = NGX_HTTP_LUA_CONTEXT_ACCESS;
285+
284286
rc = ngx_http_lua_run_thread(L, r, ctx, 0);
285287

286288
dd("returned %d", (int) rc);

src/ngx_http_lua_common.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,15 @@ typedef struct {
6969
#endif
7070

7171

72+
#define NGX_HTTP_LUA_CONTEXT_SET 0x01
73+
#define NGX_HTTP_LUA_CONTEXT_REWRITE 0x02
74+
#define NGX_HTTP_LUA_CONTEXT_ACCESS 0x04
75+
#define NGX_HTTP_LUA_CONTEXT_CONTENT 0x08
76+
#define NGX_HTTP_LUA_CONTEXT_LOG 0x10
77+
#define NGX_HTTP_LUA_CONTEXT_HEADER_FILTER 0x20
78+
#define NGX_HTTP_LUA_CONTEXT_BODY_FILTER 0x40
79+
80+
7281
typedef struct {
7382
lua_State *lua;
7483

@@ -158,6 +167,8 @@ typedef struct {
158167
typedef struct {
159168
void *data;
160169

170+
uint8_t context;
171+
161172
lua_State *cc; /* coroutine to handle request */
162173

163174
int cc_ref; /* reference to anchor coroutine in

src/ngx_http_lua_contentby.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ ngx_http_lua_content_by_chunk(lua_State *L, ngx_http_request_t *r)
8787
}
8888
/* }}} */
8989

90+
ctx->context = NGX_HTTP_LUA_CONTEXT_CONTENT;
91+
9092
return ngx_http_lua_run_thread(L, r, ctx, 0);
9193
}
9294

src/ngx_http_lua_control.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,13 @@ ngx_http_lua_ngx_exec(lua_State *L)
138138
uri.len = len;
139139

140140
ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
141+
if (ctx == NULL) {
142+
return luaL_error(L, "no ctx found");
143+
}
144+
145+
ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE
146+
| NGX_HTTP_LUA_CONTEXT_ACCESS
147+
| NGX_HTTP_LUA_CONTEXT_CONTENT);
141148

142149
if (ngx_http_parse_unsafe_uri(r, &uri, &args, &flags)
143150
!= NGX_OK)
@@ -263,6 +270,10 @@ ngx_http_lua_ngx_redirect(lua_State *L)
263270
return luaL_error(L, "no request ctx found");
264271
}
265272

273+
ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE
274+
| NGX_HTTP_LUA_CONTEXT_ACCESS
275+
| NGX_HTTP_LUA_CONTEXT_CONTENT);
276+
266277
if (ctx->headers_sent) {
267278
return luaL_error(L, "attempt to call ngx.redirect after sending out "
268279
"the headers");
@@ -333,6 +344,10 @@ ngx_http_lua_ngx_exit(lua_State *L)
333344
return luaL_error(L, "no request ctx found");
334345
}
335346

347+
ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE
348+
| NGX_HTTP_LUA_CONTEXT_ACCESS
349+
| NGX_HTTP_LUA_CONTEXT_CONTENT);
350+
336351
rc = (ngx_int_t) luaL_checkinteger(L, 1);
337352

338353
if (rc >= NGX_HTTP_SPECIAL_RESPONSE && ctx->headers_sent) {

src/ngx_http_lua_headerfilterby.c

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ ngx_http_lua_header_filter(ngx_http_request_t *r)
240240
ngx_http_lua_ctx_t *ctx;
241241
ngx_int_t rc;
242242
ngx_http_cleanup_t *cln;
243+
uint8_t old_context;
243244

244245
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
245246
"lua header filter for user lua code, uri \"%V\"", &r->uri);
@@ -280,8 +281,14 @@ ngx_http_lua_header_filter(ngx_http_request_t *r)
280281
ctx->cleanup = &cln->handler;
281282
}
282283

284+
old_context = ctx->context;
285+
ctx->context = NGX_HTTP_LUA_CONTEXT_HEADER_FILTER;
286+
283287
dd("calling header filter handler");
284288
rc = llcf->header_filter_handler(r);
289+
290+
ctx->context = old_context;
291+
285292
if (rc != NGX_OK) {
286293
dd("calling header filter handler rc %d", (int)rc);
287294
return NGX_ERROR;
@@ -301,32 +308,3 @@ ngx_http_lua_header_filter_init()
301308
return NGX_OK;
302309
}
303310

304-
305-
void
306-
ngx_http_lua_inject_headerfilterby_ngx_api(ngx_conf_t *cf, lua_State *L)
307-
{
308-
ngx_http_lua_main_conf_t *lmcf;
309-
310-
lmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_lua_module);
311-
312-
lua_pushlightuserdata(L, &ngx_http_lua_headerfilterby_ngx_key);
313-
lua_createtable(L, 0 /* narr */, 69 /* nrec */); /* ngx.* */
314-
315-
ngx_http_lua_inject_http_consts(L);
316-
ngx_http_lua_inject_core_consts(L);
317-
318-
ngx_http_lua_inject_log_api(L);
319-
ngx_http_lua_inject_time_api(L);
320-
ngx_http_lua_inject_string_api(L);
321-
#if (NGX_PCRE)
322-
ngx_http_lua_inject_regex_api(L);
323-
#endif
324-
ngx_http_lua_inject_req_api_no_io(cf->log, L);
325-
ngx_http_lua_inject_resp_header_api(L);
326-
ngx_http_lua_inject_variable_api(L);
327-
ngx_http_lua_inject_shdict_api(lmcf, L);
328-
ngx_http_lua_inject_misc_api(L);
329-
330-
lua_rawset(L, LUA_REGISTRYINDEX);
331-
}
332-

src/ngx_http_lua_headerfilterby.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ ngx_int_t ngx_http_lua_header_filter_inline(ngx_http_request_t *r);
1919

2020
ngx_int_t ngx_http_lua_header_filter_file(ngx_http_request_t *r);
2121

22-
void ngx_http_lua_inject_headerfilterby_ngx_api(ngx_conf_t *cf, lua_State *L);
23-
2422

2523
#endif /* NGX_HTTP_LUA_HEADERFILTERBY_H */
2624

src/ngx_http_lua_logby.c

Lines changed: 2 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,6 @@
2525
static ngx_int_t ngx_http_lua_log_by_chunk(lua_State *L, ngx_http_request_t *r);
2626

2727

28-
/* light user data key for the "ngx" table in the Lua VM regsitry */
29-
static char ngx_http_lua_logby_ngx_key;
30-
31-
3228
static void
3329
ngx_http_lua_log_by_lua_env(lua_State *L, ngx_http_request_t *r)
3430
{
@@ -52,12 +48,6 @@ ngx_http_lua_log_by_lua_env(lua_State *L, ngx_http_request_t *r)
5248
* */
5349
ngx_http_lua_create_new_global_table(L, 0 /* narr */, 1 /* nrec */);
5450

55-
/* {{{ initialize ngx.* namespace */
56-
lua_pushlightuserdata(L, &ngx_http_lua_logby_ngx_key);
57-
lua_rawget(L, LUA_REGISTRYINDEX);
58-
lua_setfield(L, -2, "ngx");
59-
/* }}} */
60-
6151
/* {{{ make new env inheriting main thread's globals table */
6252
lua_newtable(L); /* the metatable for the new env */
6353
lua_pushvalue(L, LUA_GLOBALSINDEX);
@@ -69,36 +59,6 @@ ngx_http_lua_log_by_lua_env(lua_State *L, ngx_http_request_t *r)
6959
}
7060

7161

72-
void
73-
ngx_http_lua_inject_logby_ngx_api(ngx_conf_t *cf, lua_State *L)
74-
{
75-
ngx_http_lua_main_conf_t *lmcf;
76-
77-
lmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_lua_module);
78-
79-
lua_pushlightuserdata(L, &ngx_http_lua_logby_ngx_key);
80-
81-
lua_createtable(L, 0 /* narr */, 69 /* nrec */); /* ngx.* */
82-
83-
ngx_http_lua_inject_http_consts(L);
84-
ngx_http_lua_inject_core_consts(L);
85-
86-
ngx_http_lua_inject_log_api(L);
87-
ngx_http_lua_inject_time_api(L);
88-
ngx_http_lua_inject_string_api(L);
89-
#if (NGX_PCRE)
90-
ngx_http_lua_inject_regex_api(L);
91-
#endif
92-
ngx_http_lua_inject_req_api_no_io(cf->log, L);
93-
ngx_http_lua_inject_resp_header_api(L);
94-
ngx_http_lua_inject_variable_api(L);
95-
ngx_http_lua_inject_shdict_api(lmcf, L);
96-
ngx_http_lua_inject_misc_api(L);
97-
98-
lua_rawset(L, LUA_REGISTRYINDEX);
99-
}
100-
101-
10262
ngx_int_t
10363
ngx_http_lua_log_handler(ngx_http_request_t *r)
10464
{
@@ -136,6 +96,8 @@ ngx_http_lua_log_handler(ngx_http_request_t *r)
13696
ngx_http_set_ctx(r, ctx, ngx_http_lua_module);
13797
}
13898

99+
ctx->context = NGX_HTTP_LUA_CONTEXT_LOG;
100+
139101
dd("calling log handler");
140102
rc = llcf->log_handler(r);
141103

src/ngx_http_lua_output.c

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ ngx_http_lua_ngx_echo(lua_State *L, unsigned newline)
6565
return luaL_error(L, "no request ctx found");
6666
}
6767

68+
ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE
69+
| NGX_HTTP_LUA_CONTEXT_ACCESS
70+
| NGX_HTTP_LUA_CONTEXT_CONTENT);
71+
6872
if (r->header_only) {
6973
return 0;
7074
}
@@ -458,6 +462,10 @@ ngx_http_lua_ngx_flush(lua_State *L)
458462
return luaL_error(L, "no request ctx found");
459463
}
460464

465+
ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE
466+
| NGX_HTTP_LUA_CONTEXT_ACCESS
467+
| NGX_HTTP_LUA_CONTEXT_CONTENT);
468+
461469
if (r->header_only) {
462470
return 0;
463471
}
@@ -567,6 +575,13 @@ ngx_http_lua_ngx_eof(lua_State *L)
567575
}
568576

569577
ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
578+
if (ctx == NULL) {
579+
return luaL_error(L, "no ctx found");
580+
}
581+
582+
ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE
583+
| NGX_HTTP_LUA_CONTEXT_ACCESS
584+
| NGX_HTTP_LUA_CONTEXT_CONTENT);
570585

571586
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
572587
"lua send eof");
@@ -615,20 +630,25 @@ ngx_http_lua_ngx_send_headers(lua_State *L)
615630
r = lua_touserdata(L, -1);
616631
lua_pop(L, 1);
617632

618-
if (r) {
619-
ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
633+
if (r == NULL) {
634+
return luaL_error(L, "no request found");
635+
}
620636

621-
if (ctx && ctx->headers_sent == 0) {
622-
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
623-
"lua send headers");
637+
ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
638+
if (ctx == NULL) {
639+
return luaL_error(L, "no ctx found");
640+
}
624641

625-
ngx_http_lua_send_header_if_needed(r, ctx);
626-
}
642+
ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE
643+
| NGX_HTTP_LUA_CONTEXT_ACCESS
644+
| NGX_HTTP_LUA_CONTEXT_CONTENT);
627645

628-
return 0;
629-
}
646+
if (!ctx->headers_sent) {
647+
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
648+
"lua send headers");
630649

631-
dd("(lua-ngx-send-headers) can't find nginx request object!");
650+
ngx_http_lua_send_header_if_needed(r, ctx);
651+
}
632652

633653
return 0;
634654
}

src/ngx_http_lua_req_body.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ ngx_http_lua_ngx_req_read_body(lua_State *L)
7575
return luaL_error(L, "request context is null");
7676
}
7777

78+
ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE
79+
| NGX_HTTP_LUA_CONTEXT_ACCESS
80+
| NGX_HTTP_LUA_CONTEXT_CONTENT);
81+
7882
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
7983
"lua start to read buffered request body");
8084

src/ngx_http_lua_rewriteby.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,8 @@ ngx_http_lua_rewrite_by_chunk(lua_State *L, ngx_http_request_t *r)
282282
}
283283
/* }}} */
284284

285+
ctx->context = NGX_HTTP_LUA_CONTEXT_REWRITE;
286+
285287
rc = ngx_http_lua_run_thread(L, r, ctx, 0);
286288

287289
if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) {

0 commit comments

Comments
 (0)