Skip to content

Commit 0e2e7b3

Browse files
committed
Add access_by_lua(_block/_file) and access_by_lua_no_postpone
Some rudimentary tests Requested cleanup of `#if 1` Try fixing tests
1 parent 7566e50 commit 0e2e7b3

22 files changed

+754
-36
lines changed

README.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,9 @@ behavior.
141141
* [init_worker_by_lua_file](https://github.com/openresty/lua-nginx-module#init_worker_by_lua_file)
142142
* [preread_by_lua_block](#preread_by_lua_block)
143143
* [preread_by_lua_file](#preread_by_lua_file)
144+
* [access_by_lua](https://github.com/openresty/lua-nginx-module#access_by_lua)
145+
* [access_by_lua_block](https://github.com/openresty/lua-nginx-module#access_by_lua_block)
146+
* [access_by_lua_file](https://github.com/openresty/lua-nginx-module#access_by_lua_file)
144147
* [content_by_lua_block](https://github.com/openresty/lua-nginx-module#content_by_lua_block)
145148
* [content_by_lua_file](https://github.com/openresty/lua-nginx-module#content_by_lua_file)
146149
* [balancer_by_lua_block](https://github.com/openresty/lua-nginx-module#balancer_by_lua_block)
@@ -170,6 +173,7 @@ behavior.
170173
* [lua_add_variable](#lua_add_variable)
171174
* [lua_capture_error_log](https://github.com/openresty/lua-nginx-module#lua_capture_error_log)
172175
* [preread_by_lua_no_postpone](#preread_by_lua_no_postpone)
176+
* [access_by_lua_no_postpone](https://github.com/openresty/lua-nginx-module#access_by_lua_no_postpone)
173177

174178
The [send_timeout](https://nginx.org/r/send_timeout) directive in the Nginx
175179
"http" subsystem is missing in the "stream" subsystem. As such,
@@ -527,7 +531,6 @@ output to be completely flushed out (to the system socket send buffers).
527531
TODO
528532
====
529533

530-
* Add new directives `access_by_lua_block` and `access_by_lua_file`.
531534
* Add `lua_postpone_output` to emulate the [postpone_output](https://nginx.org/r/postpone_output) directive.
532535

533536
[Back to TOC](#table-of-contents)

config

+2
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ STREAM_LUA_SRCS=" \
280280
$ngx_addon_dir/src/ngx_stream_lua_ssl_certby.c \
281281
$ngx_addon_dir/src/ngx_stream_lua_log_ringbuf.c \
282282
$ngx_addon_dir/src/ngx_stream_lua_input_filters.c \
283+
$ngx_addon_dir/src/ngx_stream_lua_accessby.c \
283284
"
284285

285286
STREAM_LUA_DEPS=" \
@@ -324,6 +325,7 @@ STREAM_LUA_DEPS=" \
324325
$ngx_addon_dir/src/ngx_stream_lua_ssl_certby.h \
325326
$ngx_addon_dir/src/ngx_stream_lua_log_ringbuf.h \
326327
$ngx_addon_dir/src/ngx_stream_lua_input_filters.h \
328+
$ngx_addon_dir/src/ngx_stream_lua_accessby.h \
327329
"
328330

329331
# ----------------------------------------

src/ngx_stream_lua_accessby.c

+320
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,320 @@
1+
2+
/*
3+
* Copyright (C) Xiaozhe Wang (chaoslawful)
4+
* Copyright (C) Yichun Zhang (agentzh)
5+
* Copyright (C) Arcadiy Ivanov (arcivanov)
6+
*/
7+
8+
9+
#ifndef DDEBUG
10+
#define DDEBUG 0
11+
#endif
12+
#include "ddebug.h"
13+
14+
15+
#include <nginx.h>
16+
#include "ngx_stream_lua_accessby.h"
17+
#include "ngx_stream_lua_util.h"
18+
#include "ngx_stream_lua_exception.h"
19+
#include "ngx_stream_lua_cache.h"
20+
21+
22+
static ngx_int_t ngx_stream_lua_access_by_chunk(lua_State *L,
23+
ngx_stream_lua_request_t *r);
24+
25+
26+
ngx_int_t
27+
ngx_stream_lua_access_handler(ngx_stream_session_t *s)
28+
{
29+
ngx_int_t rc;
30+
ngx_stream_lua_ctx_t *ctx;
31+
ngx_stream_lua_srv_conf_t *lscf;
32+
ngx_stream_lua_main_conf_t *lmcf;
33+
ngx_stream_lua_request_t *r;
34+
35+
dd("entered");
36+
37+
ngx_log_debug0(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
38+
"lua access handler");
39+
40+
lmcf = ngx_stream_get_module_main_conf(s, ngx_stream_lua_module);
41+
42+
if (!lmcf->postponed_to_access_phase_end) {
43+
ngx_stream_phase_handler_t tmp, *ph, *cur_ph, *last_ph;
44+
ngx_stream_core_main_conf_t *cmcf;
45+
lmcf->postponed_to_access_phase_end = 1;
46+
47+
cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module);
48+
49+
ph = cmcf->phase_engine.handlers;
50+
cur_ph = &ph[s->phase_handler];
51+
/* we should skip the post_access phase handler here too */
52+
last_ph = &ph[cur_ph->next - 2];
53+
54+
dd("ph cur: %d, ph next: %d", (int) s->phase_handler,
55+
(int) (cur_ph->next - 2));
56+
57+
if (cur_ph < last_ph) {
58+
dd("swapping the contents of cur_ph and last_ph...");
59+
60+
tmp = *cur_ph;
61+
62+
memmove(cur_ph, cur_ph + 1,
63+
(last_ph - cur_ph) * sizeof (ngx_stream_phase_handler_t));
64+
65+
*last_ph = tmp;
66+
67+
s->phase_handler--; /* redo the current ph */
68+
69+
return NGX_DECLINED;
70+
}
71+
}
72+
73+
lscf = ngx_stream_get_module_srv_conf(s, ngx_stream_lua_module);
74+
75+
if (lscf->access_handler == NULL) {
76+
dd("no access handler found");
77+
return NGX_DECLINED;
78+
}
79+
80+
ctx = ngx_stream_get_module_ctx(s, ngx_stream_lua_module);
81+
82+
dd("ctx = %p", ctx);
83+
84+
if (ctx == NULL) {
85+
ctx = ngx_stream_lua_create_ctx(s);
86+
if (ctx == NULL) {
87+
return NGX_STREAM_INTERNAL_SERVER_ERROR;
88+
}
89+
}
90+
91+
r = ctx->request;
92+
93+
dd("entered? %d", (int) ctx->entered_access_phase);
94+
95+
if (ctx->entered_access_phase) {
96+
dd("calling wev handler");
97+
rc = ctx->resume_handler(r);
98+
dd("wev handler returns %d", (int) rc);
99+
100+
if (rc == NGX_ERROR || rc == NGX_DONE || rc == NGX_OK || rc > NGX_OK) {
101+
return rc;
102+
}
103+
104+
return NGX_DECLINED;
105+
}
106+
107+
dd("calling access handler");
108+
return lscf->access_handler(r);
109+
}
110+
111+
112+
ngx_int_t
113+
ngx_stream_lua_access_handler_inline(ngx_stream_lua_request_t *r)
114+
{
115+
ngx_int_t rc;
116+
lua_State *L;
117+
ngx_stream_lua_srv_conf_t *lscf;
118+
119+
dd("entered");
120+
121+
lscf = ngx_stream_lua_get_module_srv_conf(r, ngx_stream_lua_module);
122+
123+
L = ngx_stream_lua_get_lua_vm(r, NULL);
124+
125+
/* load Lua inline script (w/ cache) sp = 1 */
126+
rc = ngx_stream_lua_cache_loadbuffer(r->connection->log, L,
127+
lscf->access_src.value.data,
128+
lscf->access_src.value.len,
129+
lscf->access_src_key,
130+
(const char *) lscf->access_chunkname);
131+
132+
if (rc != NGX_OK) {
133+
return NGX_STREAM_INTERNAL_SERVER_ERROR;
134+
}
135+
136+
return ngx_stream_lua_access_by_chunk(L, r);
137+
}
138+
139+
140+
ngx_int_t
141+
ngx_stream_lua_access_handler_file(ngx_stream_lua_request_t *r)
142+
{
143+
u_char *script_path;
144+
ngx_int_t rc;
145+
ngx_str_t eval_src;
146+
lua_State *L;
147+
ngx_stream_lua_srv_conf_t *lscf;
148+
149+
dd("entered");
150+
151+
lscf = ngx_stream_lua_get_module_srv_conf(r, ngx_stream_lua_module);
152+
153+
/* Eval nginx variables in code path string first */
154+
if (ngx_stream_complex_value(r->session, &lscf->access_src, &eval_src) != NGX_OK) {
155+
return NGX_ERROR;
156+
}
157+
158+
script_path = ngx_stream_lua_rebase_path(r->pool, eval_src.data,
159+
eval_src.len);
160+
161+
if (script_path == NULL) {
162+
return NGX_ERROR;
163+
}
164+
165+
L = ngx_stream_lua_get_lua_vm(r, NULL);
166+
167+
/* load Lua script file (w/ cache) sp = 1 */
168+
rc = ngx_stream_lua_cache_loadfile(r->connection->log, L, script_path,
169+
lscf->access_src_key);
170+
if (rc != NGX_OK) {
171+
if (rc < NGX_STREAM_SPECIAL_RESPONSE) {
172+
return NGX_STREAM_INTERNAL_SERVER_ERROR;
173+
}
174+
175+
return rc;
176+
}
177+
178+
/* make sure we have a valid code chunk */
179+
ngx_stream_lua_assert(lua_isfunction(L, -1));
180+
181+
return ngx_stream_lua_access_by_chunk(L, r);
182+
}
183+
184+
185+
static ngx_int_t
186+
ngx_stream_lua_access_by_chunk(lua_State *L, ngx_stream_lua_request_t *r)
187+
{
188+
int co_ref;
189+
ngx_int_t rc;
190+
lua_State *co;
191+
ngx_event_t *rev;
192+
ngx_connection_t *c;
193+
ngx_stream_lua_ctx_t *ctx;
194+
ngx_stream_lua_cleanup_t *cln;
195+
196+
ngx_stream_lua_srv_conf_t *lscf;
197+
198+
/* {{{ new coroutine to handle request */
199+
co = ngx_stream_lua_new_thread(r, L, &co_ref);
200+
201+
if (co == NULL) {
202+
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
203+
"lua: failed to create new coroutine "
204+
"to handle request");
205+
206+
return NGX_STREAM_INTERNAL_SERVER_ERROR;
207+
}
208+
209+
/* move code closure to new coroutine */
210+
lua_xmove(L, co, 1);
211+
212+
#ifndef OPENRESTY_LUAJIT
213+
/* set closure's env table to new coroutine's globals table */
214+
ngx_stream_lua_get_globals_table(co);
215+
lua_setfenv(co, -2);
216+
#endif
217+
218+
/* save nginx request in coroutine globals table */
219+
ngx_stream_lua_set_req(co, r);
220+
221+
/* {{{ initialize request context */
222+
ctx = ngx_stream_lua_get_module_ctx(r, ngx_stream_lua_module);
223+
224+
dd("ctx = %p", ctx);
225+
226+
if (ctx == NULL) {
227+
return NGX_ERROR;
228+
}
229+
230+
ngx_stream_lua_reset_ctx(r, L, ctx);
231+
232+
ctx->entered_access_phase = 1;
233+
234+
ctx->cur_co_ctx = &ctx->entry_co_ctx;
235+
ctx->cur_co_ctx->co = co;
236+
ctx->cur_co_ctx->co_ref = co_ref;
237+
#ifdef NGX_LUA_USE_ASSERT
238+
ctx->cur_co_ctx->co_top = 1;
239+
#endif
240+
241+
// ngx_stream_lua_attach_co_ctx_to_L(co, ctx->cur_co_ctx);
242+
243+
/* }}} */
244+
245+
/* {{{ register request cleanup hooks */
246+
if (ctx->cleanup == NULL) {
247+
cln = ngx_stream_lua_cleanup_add(r, 0);
248+
if (cln == NULL) {
249+
return NGX_STREAM_INTERNAL_SERVER_ERROR;
250+
}
251+
252+
cln->handler = ngx_stream_lua_request_cleanup_handler;
253+
cln->data = ctx;
254+
ctx->cleanup = &cln->handler;
255+
}
256+
/* }}} */
257+
258+
ctx->context = NGX_STREAM_LUA_CONTEXT_ACCESS;
259+
260+
lscf = ngx_stream_lua_get_module_srv_conf(r, ngx_stream_lua_module);
261+
262+
if (lscf->check_client_abort) {
263+
r->read_event_handler = ngx_stream_lua_rd_check_broken_connection;
264+
265+
rev = r->connection->read;
266+
267+
if (!rev->active) {
268+
if (ngx_add_event(rev, NGX_READ_EVENT, 0) != NGX_OK) {
269+
return NGX_ERROR;
270+
}
271+
}
272+
273+
} else {
274+
r->read_event_handler = ngx_stream_lua_block_reading;
275+
}
276+
277+
rc = ngx_stream_lua_run_thread(L, r, ctx, 0);
278+
279+
ngx_log_debug1(NGX_LOG_DEBUG_STREAM, r->connection->log, 0,
280+
"access run thread returned %d", (int) rc);
281+
282+
if (rc == NGX_ERROR || rc > NGX_OK) {
283+
return rc;
284+
}
285+
286+
c = r->connection;
287+
288+
if (rc == NGX_AGAIN) {
289+
rc = ngx_stream_lua_run_posted_threads(c, L, r, ctx, 0);
290+
291+
if (rc == NGX_ERROR || rc == NGX_DONE || rc > NGX_OK) {
292+
return rc;
293+
}
294+
295+
if (rc != NGX_OK) {
296+
return NGX_DECLINED;
297+
}
298+
299+
} else if (rc == NGX_DONE) {
300+
ngx_stream_lua_finalize_request(r, NGX_DONE);
301+
302+
rc = ngx_stream_lua_run_posted_threads(c, L, r, ctx, 0);
303+
304+
if (rc == NGX_ERROR || rc == NGX_DONE || rc > NGX_OK) {
305+
return rc;
306+
}
307+
308+
if (rc != NGX_OK) {
309+
return NGX_DECLINED;
310+
}
311+
}
312+
313+
if (rc == NGX_OK) {
314+
return NGX_OK;
315+
}
316+
317+
return NGX_DECLINED;
318+
}
319+
320+
/* vi:set ft=c ts=4 sw=4 et fdm=marker: */

src/ngx_stream_lua_accessby.h

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
/*
3+
* Copyright (C) Xiaozhe Wang (chaoslawful)
4+
* Copyright (C) Yichun Zhang (agentzh)
5+
*/
6+
7+
8+
#ifndef _NGX_STREAM_LUA_ACCESSBY_H_INCLUDED_
9+
#define _NGX_STREAM_LUA_ACCESSBY_H_INCLUDED_
10+
11+
12+
#include "ngx_stream_lua_common.h"
13+
14+
15+
ngx_int_t ngx_stream_lua_access_handler(ngx_stream_session_t *s);
16+
ngx_int_t ngx_stream_lua_access_handler_inline(ngx_stream_lua_request_t *r);
17+
ngx_int_t ngx_stream_lua_access_handler_file(ngx_stream_lua_request_t *r);
18+
19+
20+
#endif /* _NGX_STREAM_LUA_ACCESSBY_H_INCLUDED_ */
21+
22+
/* vi:set ft=c ts=4 sw=4 et fdm=marker: */

0 commit comments

Comments
 (0)