1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
|
/*
* !!! DO NOT EDIT DIRECTLY !!!
* This file was automatically generated from the following template:
*
* src/subsys/ngx_subsys_lua_common.h.tt2
*/
/*
* Copyright (C) Xiaozhe Wang (chaoslawful)
* Copyright (C) Yichun Zhang (agentzh)
*/
#ifndef _NGX_STREAM_LUA_COMMON_H_INCLUDED_
#define _NGX_STREAM_LUA_COMMON_H_INCLUDED_
#include "ngx_stream_lua_autoconf.h"
#include <nginx.h>
#include <ngx_core.h>
#include <ngx_stream.h>
#include <ngx_md5.h>
#include <setjmp.h>
#include <stdint.h>
#include <luajit.h>
#include <lualib.h>
#include <lauxlib.h>
#include "ngx_stream_lua_request.h"
#if (NGX_PCRE)
# if (NGX_PCRE2)
# define LUA_HAVE_PCRE_JIT 1
# else
#include <pcre.h>
# if (PCRE_MAJOR > 8) || (PCRE_MAJOR == 8 && PCRE_MINOR >= 21)
# define LUA_HAVE_PCRE_JIT 1
# else
# define LUA_HAVE_PCRE_JIT 0
# endif
# endif
#endif
#if !defined(nginx_version) || nginx_version < 1013006
#error at least nginx 1.13.6 is required but found an older version
#endif
#if LUA_VERSION_NUM != 501
# error unsupported Lua language version
#endif
#if !defined(LUAJIT_VERSION_NUM) || (LUAJIT_VERSION_NUM < 20000)
# error unsupported LuaJIT version
#endif
#if (!defined OPENSSL_NO_OCSP && defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB)
# define NGX_STREAM_LUA_USE_OCSP 1
#endif
#ifndef NGX_HAVE_SHA1
# if defined(nginx_version) && nginx_version >= 1011002
# define NGX_HAVE_SHA1 1
# endif
#endif
#ifndef MD5_DIGEST_LENGTH
#define MD5_DIGEST_LENGTH 16
#endif
#ifdef NGX_LUA_USE_ASSERT
# include <assert.h>
# define ngx_stream_lua_assert(a) assert(a)
#else
# define ngx_stream_lua_assert(a)
#endif
/* Nginx HTTP Lua Inline tag prefix */
#define NGX_STREAM_LUA_INLINE_TAG "nhli_"
#define NGX_STREAM_LUA_INLINE_TAG_LEN \
(sizeof(NGX_STREAM_LUA_INLINE_TAG) - 1)
#define NGX_STREAM_LUA_INLINE_KEY_LEN \
(NGX_STREAM_LUA_INLINE_TAG_LEN + 2 * MD5_DIGEST_LENGTH)
/* Nginx HTTP Lua File tag prefix */
#define NGX_STREAM_LUA_FILE_TAG "nhlf_"
#define NGX_STREAM_LUA_FILE_TAG_LEN \
(sizeof(NGX_STREAM_LUA_FILE_TAG) - 1)
#define NGX_STREAM_LUA_FILE_KEY_LEN \
(NGX_STREAM_LUA_FILE_TAG_LEN + 2 * MD5_DIGEST_LENGTH)
#define NGX_STREAM_CLIENT_CLOSED_REQUEST 499
#ifndef NGX_STREAM_LUA_MAX_ARGS
#define NGX_STREAM_LUA_MAX_ARGS 100
#endif
/* must be within 16 bit */
#define NGX_STREAM_LUA_CONTEXT_CONTENT 0x0001
#define NGX_STREAM_LUA_CONTEXT_LOG 0x0002
#define NGX_STREAM_LUA_CONTEXT_TIMER 0x0004
#define NGX_STREAM_LUA_CONTEXT_INIT_WORKER 0x0008
#define NGX_STREAM_LUA_CONTEXT_BALANCER 0x0010
#define NGX_STREAM_LUA_CONTEXT_PREREAD 0x0020
#define NGX_STREAM_LUA_CONTEXT_SSL_CERT 0x0040
#define NGX_STREAM_LUA_CONTEXT_SSL_CLIENT_HELLO 0x0080
#define NGX_STREAM_LUA_FFI_NO_REQ_CTX -100
#define NGX_STREAM_LUA_FFI_BAD_CONTEXT -101
#if (NGX_PTR_SIZE >= 8 && !defined(_WIN64))
#define ngx_stream_lua_lightudata_mask(ludata) \
((void *) ((uintptr_t) (&ngx_stream_lua_##ludata) & ((1UL << 47) - 1)))
#else
#define ngx_stream_lua_lightudata_mask(ludata) \
(&ngx_stream_lua_##ludata)
#endif
typedef struct ngx_stream_lua_main_conf_s ngx_stream_lua_main_conf_t;
typedef struct ngx_stream_lua_srv_conf_s ngx_stream_lua_srv_conf_t;
typedef struct ngx_stream_lua_balancer_peer_data_s
ngx_stream_lua_balancer_peer_data_t;
typedef struct ngx_stream_lua_sema_mm_s ngx_stream_lua_sema_mm_t;
typedef ngx_int_t (*ngx_stream_lua_main_conf_handler_pt)(ngx_log_t *log,
ngx_stream_lua_main_conf_t *lmcf, lua_State *L);
typedef ngx_int_t (*ngx_stream_lua_srv_conf_handler_pt)(
ngx_stream_lua_request_t *r, ngx_stream_lua_srv_conf_t *lscf, lua_State *L);
typedef struct {
u_char *package;
lua_CFunction loader;
} ngx_stream_lua_preload_hook_t;
struct ngx_stream_lua_main_conf_s {
lua_State *lua;
ngx_pool_cleanup_t *vm_cleanup;
ngx_str_t lua_path;
ngx_str_t lua_cpath;
ngx_cycle_t *cycle;
ngx_pool_t *pool;
ngx_int_t max_pending_timers;
ngx_int_t pending_timers;
ngx_int_t max_running_timers;
ngx_int_t running_timers;
ngx_connection_t *watcher; /* for watching the process exit event */
#if (NGX_PCRE)
ngx_int_t regex_cache_entries;
ngx_int_t regex_cache_max_entries;
ngx_int_t regex_match_limit;
#endif
#if (LUA_HAVE_PCRE_JIT)
#if (NGX_PCRE2)
pcre2_jit_stack *jit_stack;
#else
pcre_jit_stack *jit_stack;
#endif
#endif
ngx_array_t *shm_zones; /* of ngx_shm_zone_t* */
ngx_array_t *shdict_zones; /* shm zones of "shdict" */
ngx_array_t *preload_hooks; /* of ngx_stream_lua_preload_hook_t */
ngx_flag_t postponed_to_preread_phase_end;
ngx_stream_lua_main_conf_handler_pt init_handler;
ngx_str_t init_src;
ngx_stream_lua_main_conf_handler_pt init_worker_handler;
ngx_str_t init_worker_src;
ngx_stream_lua_balancer_peer_data_t *balancer_peer_data;
/* neither yielding nor recursion is possible in
* balancer_by_lua*, so there cannot be any races among
* concurrent requests and it is safe to store the peer
* data pointer in the main conf.
*/
ngx_uint_t shm_zones_inited;
ngx_stream_lua_sema_mm_t *sema_mm;
ngx_uint_t malloc_trim_cycle; /* a cycle is defined as the number
of reqeusts */
ngx_uint_t malloc_trim_req_count;
ngx_flag_t set_sa_restart;
unsigned requires_preread:1;
unsigned requires_log:1;
unsigned requires_shm:1;
unsigned requires_capture_log:1;
};
struct ngx_stream_lua_srv_conf_s {
#if (NGX_STREAM_SSL)
ngx_ssl_t *ssl; /* shared by SSL cosockets */
ngx_array_t *ssl_certificates;
ngx_array_t *ssl_certificate_keys;
ngx_uint_t ssl_protocols;
ngx_str_t ssl_ciphers;
ngx_uint_t ssl_verify_depth;
ngx_str_t ssl_trusted_certificate;
ngx_str_t ssl_crl;
#if (nginx_version >= 1019004)
ngx_array_t *ssl_conf_commands;
#endif
struct {
ngx_stream_lua_srv_conf_handler_pt ssl_cert_handler;
ngx_str_t ssl_cert_src;
u_char *ssl_cert_src_key;
ngx_stream_lua_srv_conf_handler_pt ssl_client_hello_handler;
ngx_str_t ssl_client_hello_src;
u_char *ssl_client_hello_src_key;
} srv;
#endif
ngx_flag_t enable_code_cache; /* whether to enable
code cache */
ngx_stream_lua_handler_pt preread_handler;
ngx_stream_lua_handler_pt content_handler;
ngx_stream_lua_handler_pt log_handler;
u_char *preread_chunkname;
ngx_stream_complex_value_t preread_src; /* access_by_lua
inline script/script
file path */
u_char *preread_src_key; /* cached key for access_src */
u_char *content_chunkname;
ngx_stream_complex_value_t content_src;
/* content_by_lua
* inline script/script
* file path */
u_char *content_src_key; /* cached key for content_src */
u_char *log_chunkname;
ngx_stream_complex_value_t log_src;
/* log_by_lua inline script/script
* file path */
u_char *log_src_key;
/* cached key for log_src */
ngx_msec_t keepalive_timeout;
ngx_msec_t connect_timeout;
ngx_msec_t send_timeout;
ngx_msec_t read_timeout;
size_t send_lowat;
size_t buffer_size;
ngx_uint_t pool_size;
ngx_flag_t log_socket_errors;
ngx_flag_t check_client_abort;
struct {
ngx_str_t src;
u_char *src_key;
ngx_stream_lua_srv_conf_handler_pt handler;
} balancer;
};
typedef ngx_stream_lua_srv_conf_t ngx_stream_lua_loc_conf_t;
typedef enum {
NGX_STREAM_LUA_USER_CORO_NOP = 0,
NGX_STREAM_LUA_USER_CORO_RESUME = 1,
NGX_STREAM_LUA_USER_CORO_YIELD = 2,
NGX_STREAM_LUA_USER_THREAD_RESUME = 3
} ngx_stream_lua_user_coro_op_t;
typedef enum {
NGX_STREAM_LUA_CO_RUNNING = 0, /* coroutine running */
NGX_STREAM_LUA_CO_SUSPENDED = 1, /* coroutine suspended */
NGX_STREAM_LUA_CO_NORMAL = 2, /* coroutine normal */
NGX_STREAM_LUA_CO_DEAD = 3, /* coroutine dead */
NGX_STREAM_LUA_CO_ZOMBIE = 4, /* coroutine zombie */
} ngx_stream_lua_co_status_t;
typedef struct ngx_stream_lua_co_ctx_s ngx_stream_lua_co_ctx_t;
typedef struct ngx_stream_lua_posted_thread_s ngx_stream_lua_posted_thread_t;
struct ngx_stream_lua_posted_thread_s {
ngx_stream_lua_co_ctx_t *co_ctx;
ngx_stream_lua_posted_thread_t *next;
};
struct ngx_stream_lua_co_ctx_s {
void *data; /* user state for cosockets */
lua_State *co;
ngx_stream_lua_co_ctx_t *parent_co_ctx;
ngx_stream_lua_posted_thread_t *zombie_child_threads;
ngx_stream_lua_cleanup_pt cleanup;
ngx_event_t sleep; /* used for ngx.sleep */
ngx_queue_t sem_wait_queue;
#ifdef NGX_LUA_USE_ASSERT
int co_top; /* stack top after yielding/creation,
only for sanity checks */
#endif
int co_ref; /* reference to anchor the thread
coroutines (entry coroutine and user
threads) in the Lua registry,
preventing the thread coroutine
from beging collected by the
Lua GC */
unsigned waited_by_parent:1; /* whether being waited by
a parent coroutine */
unsigned co_status:3; /* the current coroutine's status */
unsigned flushing:1; /* indicates whether the current
coroutine is waiting for
ngx.flush(true) */
unsigned is_uthread:1; /* whether the current coroutine is
a user thread */
unsigned thread_spawn_yielded:1; /* yielded from
the ngx.thread.spawn()
call */
unsigned sem_resume_status:1;
unsigned is_wrap:1; /* set when creating coroutines via
coroutine.wrap */
unsigned propagate_error:1; /* set when propagating an error
from a coroutine to its
parent */
};
typedef struct {
lua_State *vm;
ngx_int_t count;
} ngx_stream_lua_vm_state_t;
typedef struct ngx_stream_lua_ctx_s {
/* for lua_coce_cache off: */
ngx_stream_lua_vm_state_t *vm_state;
ngx_stream_lua_request_t *request;
ngx_stream_lua_handler_pt resume_handler;
ngx_stream_lua_co_ctx_t *cur_co_ctx;
/* co ctx for the current coroutine */
/* FIXME: we should use rbtree here to prevent O(n) lookup overhead */
ngx_list_t *user_co_ctx; /* coroutine contexts for user
coroutines */
ngx_stream_lua_co_ctx_t entry_co_ctx; /* coroutine context for the
entry coroutine */
ngx_stream_lua_co_ctx_t *on_abort_co_ctx; /* coroutine context for the
on_abort thread */
int ctx_ref; /* reference to anchor
request ctx data in lua
registry */
unsigned flushing_coros; /* number of coroutines waiting on
ngx.flush(true) */
ngx_chain_t *out; /* buffered output chain for HTTP 1.0 */
ngx_chain_t *free_bufs;
ngx_chain_t *busy_bufs;
ngx_chain_t *free_recv_bufs;
ngx_stream_lua_cleanup_pt *cleanup;
ngx_stream_lua_cleanup_t *free_cleanup; /* free list of cleanup records */
ngx_int_t exit_code;
void *downstream;
/* can be either
* ngx_stream_lua_socket_tcp_upstream_t
* or ngx_stream_lua_co_ctx_t */
ngx_stream_lua_posted_thread_t *posted_threads;
int uthreads; /* number of active user threads */
uint16_t context; /* the current running directive context
(or running phase) for the current
Lua chunk */
unsigned waiting_more_body:1; /* 1: waiting for more
request body data;
0: no need to wait */
unsigned co_op:2; /* coroutine API operation */
unsigned exited:1;
unsigned eof:1; /* 1: last_buf has been sent;
0: last_buf not sent yet */
unsigned capture:1; /* 1: response body of current request
is to be captured by the lua
capture filter,
0: not to be captured */
unsigned read_body_done:1; /* 1: request body has been all
read; 0: body has not been
all read */
unsigned headers_set:1; /* whether the user has set custom
response headers */
unsigned entered_preread_phase:1;
unsigned entered_content_phase:1;
unsigned buffering:1; /* HTTP 1.0 response body buffering flag */
unsigned no_abort:1; /* prohibit "world abortion" via ngx.exit()
and etc */
unsigned header_sent:1; /* r->header_sent is not sufficient for
* this because special header filters
* like ngx_image_filter may intercept
* the header. so we should always test
* both flags. see the test case in
* t/020-subrequest.t */
unsigned seen_last_in_filter:1; /* used by body_filter_by_lua* */
unsigned seen_last_for_subreq:1; /* used by body capture filter */
unsigned writing_raw_req_socket:1; /* used by raw downstream
socket */
unsigned acquired_raw_req_socket:1; /* whether a raw req socket
is acquired */
unsigned seen_body_data:1;
unsigned peek_needs_more_data:1; /* whether req socket is waiting
for more data in preread buf */
} ngx_stream_lua_ctx_t;
extern ngx_module_t ngx_stream_lua_module;
#endif /* _NGX_STREAM_LUA_COMMON_H_INCLUDED_ */
/* vi:set ft=c ts=4 sw=4 et fdm=marker: */
|