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: */
0 commit comments