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 1
314+ if (rc == NGX_OK ) {
315+ return NGX_OK ;
316+ }
317+ #endif
318+
319+ return NGX_DECLINED ;
320+ }
321+
322+ /* vi:set ft=c ts=4 sw=4 et fdm=marker: */
0 commit comments