1 
2 /*
3  * Copyright (C) Xiaozhe Wang (chaoslawful)
4  * Copyright (C) Yichun Zhang (agentzh)
5  */
6 
7 
8 #ifndef DDEBUG
9 #define DDEBUG 0
10 #endif
11 #include "ddebug.h"
12 
13 
14 #include "ngx_http_lua_directive.h"
15 #include "ngx_http_lua_capturefilter.h"
16 #include "ngx_http_lua_contentby.h"
17 #include "ngx_http_lua_rewriteby.h"
18 #include "ngx_http_lua_accessby.h"
19 #include "ngx_http_lua_logby.h"
20 #include "ngx_http_lua_util.h"
21 #include "ngx_http_lua_headerfilterby.h"
22 #include "ngx_http_lua_bodyfilterby.h"
23 #include "ngx_http_lua_initby.h"
24 #include "ngx_http_lua_initworkerby.h"
25 #include "ngx_http_lua_exitworkerby.h"
26 #include "ngx_http_lua_probe.h"
27 #include "ngx_http_lua_semaphore.h"
28 #include "ngx_http_lua_balancer.h"
29 #include "ngx_http_lua_ssl_certby.h"
30 #include "ngx_http_lua_ssl_session_storeby.h"
31 #include "ngx_http_lua_ssl_session_fetchby.h"
32 #include "ngx_http_lua_headers.h"
33 #include "ngx_http_lua_pipe.h"
34 
35 
36 static void *ngx_http_lua_create_main_conf(ngx_conf_t *cf);
37 static char *ngx_http_lua_init_main_conf(ngx_conf_t *cf, void *conf);
38 static void *ngx_http_lua_create_srv_conf(ngx_conf_t *cf);
39 static char *ngx_http_lua_merge_srv_conf(ngx_conf_t *cf, void *parent,
40     void *child);
41 static void *ngx_http_lua_create_loc_conf(ngx_conf_t *cf);
42 
43 static char *ngx_http_lua_merge_loc_conf(ngx_conf_t *cf, void *parent,
44     void *child);
45 static ngx_int_t ngx_http_lua_init(ngx_conf_t *cf);
46 static char *ngx_http_lua_lowat_check(ngx_conf_t *cf, void *post, void *data);
47 #if (NGX_HTTP_SSL)
48 static ngx_int_t ngx_http_lua_set_ssl(ngx_conf_t *cf,
49     ngx_http_lua_loc_conf_t *llcf);
50 #endif
51 static char *ngx_http_lua_malloc_trim(ngx_conf_t *cf, ngx_command_t *cmd,
52     void *conf);
53 
54 
55 static ngx_conf_post_t  ngx_http_lua_lowat_post =
56     { ngx_http_lua_lowat_check };
57 
58 
59 static volatile ngx_cycle_t  *ngx_http_lua_prev_cycle = NULL;
60 
61 
62 #if (NGX_HTTP_SSL)
63 
64 static ngx_conf_bitmask_t  ngx_http_lua_ssl_protocols[] = {
65     { ngx_string("SSLv2"), NGX_SSL_SSLv2 },
66     { ngx_string("SSLv3"), NGX_SSL_SSLv3 },
67     { ngx_string("TLSv1"), NGX_SSL_TLSv1 },
68     { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 },
69     { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 },
70 #ifdef NGX_SSL_TLSv1_3
71     { ngx_string("TLSv1.3"), NGX_SSL_TLSv1_3 },
72 #endif
73     { ngx_null_string, 0 }
74 };
75 
76 #endif
77 
78 
79 static ngx_command_t ngx_http_lua_cmds[] = {
80 
81     { ngx_string("lua_load_resty_core"),
82       NGX_HTTP_MAIN_CONF|NGX_CONF_FLAG,
83       ngx_http_lua_load_resty_core,
84       NGX_HTTP_MAIN_CONF_OFFSET,
85       0,
86       NULL },
87 
88     { ngx_string("lua_thread_cache_max_entries"),
89       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
90       ngx_conf_set_num_slot,
91       NGX_HTTP_MAIN_CONF_OFFSET,
92       offsetof(ngx_http_lua_main_conf_t, lua_thread_cache_max_entries),
93       NULL },
94 
95     { ngx_string("lua_max_running_timers"),
96       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
97       ngx_conf_set_num_slot,
98       NGX_HTTP_MAIN_CONF_OFFSET,
99       offsetof(ngx_http_lua_main_conf_t, max_running_timers),
100       NULL },
101 
102     { ngx_string("lua_max_pending_timers"),
103       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
104       ngx_conf_set_num_slot,
105       NGX_HTTP_MAIN_CONF_OFFSET,
106       offsetof(ngx_http_lua_main_conf_t, max_pending_timers),
107       NULL },
108 
109     { ngx_string("lua_shared_dict"),
110       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE2,
111       ngx_http_lua_shared_dict,
112       0,
113       0,
114       NULL },
115 
116     { ngx_string("lua_capture_error_log"),
117       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
118       ngx_http_lua_capture_error_log,
119       0,
120       0,
121       NULL },
122 
123     { ngx_string("lua_sa_restart"),
124       NGX_HTTP_MAIN_CONF|NGX_CONF_FLAG,
125       ngx_conf_set_flag_slot,
126       NGX_HTTP_MAIN_CONF_OFFSET,
127       offsetof(ngx_http_lua_main_conf_t, set_sa_restart),
128       NULL },
129 
130     { ngx_string("lua_regex_cache_max_entries"),
131       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
132       ngx_http_lua_regex_cache_max_entries,
133       NGX_HTTP_MAIN_CONF_OFFSET,
134 #if (NGX_PCRE)
135       offsetof(ngx_http_lua_main_conf_t, regex_cache_max_entries),
136 #else
137       0,
138 #endif
139       NULL },
140 
141     { ngx_string("lua_regex_match_limit"),
142       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
143       ngx_http_lua_regex_match_limit,
144       NGX_HTTP_MAIN_CONF_OFFSET,
145 #if (NGX_PCRE)
146       offsetof(ngx_http_lua_main_conf_t, regex_match_limit),
147 #else
148       0,
149 #endif
150       NULL },
151 
152     { ngx_string("lua_package_cpath"),
153       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
154       ngx_http_lua_package_cpath,
155       NGX_HTTP_MAIN_CONF_OFFSET,
156       0,
157       NULL },
158 
159     { ngx_string("lua_package_path"),
160       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
161       ngx_http_lua_package_path,
162       NGX_HTTP_MAIN_CONF_OFFSET,
163       0,
164       NULL },
165 
166     { ngx_string("lua_code_cache"),
167       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
168                         |NGX_CONF_FLAG,
169       ngx_http_lua_code_cache,
170       NGX_HTTP_LOC_CONF_OFFSET,
171       offsetof(ngx_http_lua_loc_conf_t, enable_code_cache),
172       NULL },
173 
174     { ngx_string("lua_need_request_body"),
175       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
176                         |NGX_CONF_FLAG,
177       ngx_conf_set_flag_slot,
178       NGX_HTTP_LOC_CONF_OFFSET,
179       offsetof(ngx_http_lua_loc_conf_t, force_read_body),
180       NULL },
181 
182     { ngx_string("lua_transform_underscores_in_response_headers"),
183       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
184                         |NGX_CONF_FLAG,
185       ngx_conf_set_flag_slot,
186       NGX_HTTP_LOC_CONF_OFFSET,
187       offsetof(ngx_http_lua_loc_conf_t, transform_underscores_in_resp_headers),
188       NULL },
189 
190      { ngx_string("lua_socket_log_errors"),
191       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
192                         |NGX_CONF_FLAG,
193       ngx_conf_set_flag_slot,
194       NGX_HTTP_LOC_CONF_OFFSET,
195       offsetof(ngx_http_lua_loc_conf_t, log_socket_errors),
196       NULL },
197 
198     { ngx_string("init_by_lua_block"),
199       NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
200       ngx_http_lua_init_by_lua_block,
201       NGX_HTTP_MAIN_CONF_OFFSET,
202       0,
203       (void *) ngx_http_lua_init_by_inline },
204 
205     { ngx_string("init_by_lua"),
206       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
207       ngx_http_lua_init_by_lua,
208       NGX_HTTP_MAIN_CONF_OFFSET,
209       0,
210       (void *) ngx_http_lua_init_by_inline },
211 
212     { ngx_string("init_by_lua_file"),
213       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
214       ngx_http_lua_init_by_lua,
215       NGX_HTTP_MAIN_CONF_OFFSET,
216       0,
217       (void *) ngx_http_lua_init_by_file },
218 
219     { ngx_string("init_worker_by_lua_block"),
220       NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
221       ngx_http_lua_init_worker_by_lua_block,
222       NGX_HTTP_MAIN_CONF_OFFSET,
223       0,
224       (void *) ngx_http_lua_init_worker_by_inline },
225 
226     { ngx_string("init_worker_by_lua"),
227       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
228       ngx_http_lua_init_worker_by_lua,
229       NGX_HTTP_MAIN_CONF_OFFSET,
230       0,
231       (void *) ngx_http_lua_init_worker_by_inline },
232 
233     { ngx_string("init_worker_by_lua_file"),
234       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
235       ngx_http_lua_init_worker_by_lua,
236       NGX_HTTP_MAIN_CONF_OFFSET,
237       0,
238       (void *) ngx_http_lua_init_worker_by_file },
239 
240     { ngx_string("exit_worker_by_lua_block"),
241       NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
242       ngx_http_lua_exit_worker_by_lua_block,
243       NGX_HTTP_MAIN_CONF_OFFSET,
244       0,
245       (void *) ngx_http_lua_exit_worker_by_inline },
246 
247     { ngx_string("exit_worker_by_lua_file"),
248       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
249       ngx_http_lua_exit_worker_by_lua,
250       NGX_HTTP_MAIN_CONF_OFFSET,
251       0,
252       (void *) ngx_http_lua_exit_worker_by_file },
253 
254 #if defined(NDK) && NDK
255     /* set_by_lua_block $res { inline Lua code } */
256     { ngx_string("set_by_lua_block"),
257       NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
258                        |NGX_CONF_TAKE1|NGX_CONF_BLOCK,
259       ngx_http_lua_set_by_lua_block,
260       NGX_HTTP_LOC_CONF_OFFSET,
261       0,
262       (void *) ngx_http_lua_filter_set_by_lua_inline },
263 
264     /* set_by_lua $res <inline script> [$arg1 [$arg2 [...]]] */
265     { ngx_string("set_by_lua"),
266       NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
267                        |NGX_CONF_2MORE,
268       ngx_http_lua_set_by_lua,
269       NGX_HTTP_LOC_CONF_OFFSET,
270       0,
271       (void *) ngx_http_lua_filter_set_by_lua_inline },
272 
273     /* set_by_lua_file $res rel/or/abs/path/to/script [$arg1 [$arg2 [..]]] */
274     { ngx_string("set_by_lua_file"),
275       NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
276                        |NGX_CONF_2MORE,
277       ngx_http_lua_set_by_lua_file,
278       NGX_HTTP_LOC_CONF_OFFSET,
279       0,
280       (void *) ngx_http_lua_filter_set_by_lua_file },
281 #endif
282 
283     /* rewrite_by_lua "<inline script>" */
284     { ngx_string("rewrite_by_lua"),
285       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
286                         |NGX_CONF_TAKE1,
287       ngx_http_lua_rewrite_by_lua,
288       NGX_HTTP_LOC_CONF_OFFSET,
289       0,
290       (void *) ngx_http_lua_rewrite_handler_inline },
291 
292     /* rewrite_by_lua_block { <inline script> } */
293     { ngx_string("rewrite_by_lua_block"),
294       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
295                         |NGX_CONF_BLOCK|NGX_CONF_NOARGS,
296       ngx_http_lua_rewrite_by_lua_block,
297       NGX_HTTP_LOC_CONF_OFFSET,
298       0,
299       (void *) ngx_http_lua_rewrite_handler_inline },
300 
301     /* access_by_lua "<inline script>" */
302     { ngx_string("access_by_lua"),
303       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
304                         |NGX_CONF_TAKE1,
305       ngx_http_lua_access_by_lua,
306       NGX_HTTP_LOC_CONF_OFFSET,
307       0,
308       (void *) ngx_http_lua_access_handler_inline },
309 
310     /* access_by_lua_block { <inline script> } */
311     { ngx_string("access_by_lua_block"),
312       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
313                         |NGX_CONF_BLOCK|NGX_CONF_NOARGS,
314       ngx_http_lua_access_by_lua_block,
315       NGX_HTTP_LOC_CONF_OFFSET,
316       0,
317       (void *) ngx_http_lua_access_handler_inline },
318 
319     /* content_by_lua "<inline script>" */
320     { ngx_string("content_by_lua"),
321       NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
322       ngx_http_lua_content_by_lua,
323       NGX_HTTP_LOC_CONF_OFFSET,
324       0,
325       (void *) ngx_http_lua_content_handler_inline },
326 
327     /* content_by_lua_block { <inline script> } */
328     { ngx_string("content_by_lua_block"),
329       NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
330       ngx_http_lua_content_by_lua_block,
331       NGX_HTTP_LOC_CONF_OFFSET,
332       0,
333       (void *) ngx_http_lua_content_handler_inline },
334 
335     /* log_by_lua <inline script> */
336     { ngx_string("log_by_lua"),
337       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
338                         |NGX_CONF_TAKE1,
339       ngx_http_lua_log_by_lua,
340       NGX_HTTP_LOC_CONF_OFFSET,
341       0,
342       (void *) ngx_http_lua_log_handler_inline },
343 
344     /* log_by_lua_block { <inline script> } */
345     { ngx_string("log_by_lua_block"),
346       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
347                         |NGX_CONF_BLOCK|NGX_CONF_NOARGS,
348       ngx_http_lua_log_by_lua_block,
349       NGX_HTTP_LOC_CONF_OFFSET,
350       0,
351       (void *) ngx_http_lua_log_handler_inline },
352 
353     { ngx_string("rewrite_by_lua_file"),
354       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
355                         |NGX_CONF_TAKE1,
356       ngx_http_lua_rewrite_by_lua,
357       NGX_HTTP_LOC_CONF_OFFSET,
358       0,
359       (void *) ngx_http_lua_rewrite_handler_file },
360 
361     { ngx_string("rewrite_by_lua_no_postpone"),
362       NGX_HTTP_MAIN_CONF|NGX_CONF_FLAG,
363       ngx_conf_set_flag_slot,
364       NGX_HTTP_MAIN_CONF_OFFSET,
365       offsetof(ngx_http_lua_main_conf_t, postponed_to_rewrite_phase_end),
366       NULL },
367 
368     { ngx_string("access_by_lua_file"),
369       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
370                         |NGX_CONF_TAKE1,
371       ngx_http_lua_access_by_lua,
372       NGX_HTTP_LOC_CONF_OFFSET,
373       0,
374       (void *) ngx_http_lua_access_handler_file },
375 
376     { ngx_string("access_by_lua_no_postpone"),
377       NGX_HTTP_MAIN_CONF|NGX_CONF_FLAG,
378       ngx_conf_set_flag_slot,
379       NGX_HTTP_MAIN_CONF_OFFSET,
380       offsetof(ngx_http_lua_main_conf_t, postponed_to_access_phase_end),
381       NULL },
382 
383     /* content_by_lua_file rel/or/abs/path/to/script */
384     { ngx_string("content_by_lua_file"),
385       NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
386       ngx_http_lua_content_by_lua,
387       NGX_HTTP_LOC_CONF_OFFSET,
388       0,
389       (void *) ngx_http_lua_content_handler_file },
390 
391     { ngx_string("log_by_lua_file"),
392       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
393                         |NGX_CONF_TAKE1,
394       ngx_http_lua_log_by_lua,
395       NGX_HTTP_LOC_CONF_OFFSET,
396       0,
397       (void *) ngx_http_lua_log_handler_file },
398 
399     /* header_filter_by_lua <inline script> */
400     { ngx_string("header_filter_by_lua"),
401       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
402                         |NGX_CONF_TAKE1,
403       ngx_http_lua_header_filter_by_lua,
404       NGX_HTTP_LOC_CONF_OFFSET,
405       0,
406       (void *) ngx_http_lua_header_filter_inline },
407 
408     /* header_filter_by_lua_block { <inline script> } */
409     { ngx_string("header_filter_by_lua_block"),
410       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
411                         |NGX_CONF_BLOCK|NGX_CONF_NOARGS,
412       ngx_http_lua_header_filter_by_lua_block,
413       NGX_HTTP_LOC_CONF_OFFSET,
414       0,
415       (void *) ngx_http_lua_header_filter_inline },
416 
417     { ngx_string("header_filter_by_lua_file"),
418       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
419                         |NGX_CONF_TAKE1,
420       ngx_http_lua_header_filter_by_lua,
421       NGX_HTTP_LOC_CONF_OFFSET,
422       0,
423       (void *) ngx_http_lua_header_filter_file },
424 
425     { ngx_string("body_filter_by_lua"),
426       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
427                         |NGX_CONF_TAKE1,
428       ngx_http_lua_body_filter_by_lua,
429       NGX_HTTP_LOC_CONF_OFFSET,
430       0,
431       (void *) ngx_http_lua_body_filter_inline },
432 
433     /* body_filter_by_lua_block { <inline script> } */
434     { ngx_string("body_filter_by_lua_block"),
435       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
436                         |NGX_CONF_BLOCK|NGX_CONF_NOARGS,
437       ngx_http_lua_body_filter_by_lua_block,
438       NGX_HTTP_LOC_CONF_OFFSET,
439       0,
440       (void *) ngx_http_lua_body_filter_inline },
441 
442     { ngx_string("body_filter_by_lua_file"),
443       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
444                         |NGX_CONF_TAKE1,
445       ngx_http_lua_body_filter_by_lua,
446       NGX_HTTP_LOC_CONF_OFFSET,
447       0,
448       (void *) ngx_http_lua_body_filter_file },
449 
450     { ngx_string("balancer_by_lua_block"),
451       NGX_HTTP_UPS_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
452       ngx_http_lua_balancer_by_lua_block,
453       NGX_HTTP_SRV_CONF_OFFSET,
454       0,
455       (void *) ngx_http_lua_balancer_handler_inline },
456 
457     { ngx_string("balancer_by_lua_file"),
458       NGX_HTTP_UPS_CONF|NGX_CONF_TAKE1,
459       ngx_http_lua_balancer_by_lua,
460       NGX_HTTP_SRV_CONF_OFFSET,
461       0,
462       (void *) ngx_http_lua_balancer_handler_file },
463 
464     { ngx_string("lua_socket_keepalive_timeout"),
465       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF
466           |NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
467       ngx_conf_set_msec_slot,
468       NGX_HTTP_LOC_CONF_OFFSET,
469       offsetof(ngx_http_lua_loc_conf_t, keepalive_timeout),
470       NULL },
471 
472     { ngx_string("lua_socket_connect_timeout"),
473       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF
474           |NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
475       ngx_conf_set_msec_slot,
476       NGX_HTTP_LOC_CONF_OFFSET,
477       offsetof(ngx_http_lua_loc_conf_t, connect_timeout),
478       NULL },
479 
480     { ngx_string("lua_socket_send_timeout"),
481       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF
482           |NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
483       ngx_conf_set_msec_slot,
484       NGX_HTTP_LOC_CONF_OFFSET,
485       offsetof(ngx_http_lua_loc_conf_t, send_timeout),
486       NULL },
487 
488     { ngx_string("lua_socket_send_lowat"),
489       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF
490           |NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
491       ngx_conf_set_size_slot,
492       NGX_HTTP_LOC_CONF_OFFSET,
493       offsetof(ngx_http_lua_loc_conf_t, send_lowat),
494       &ngx_http_lua_lowat_post },
495 
496     { ngx_string("lua_socket_buffer_size"),
497       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF
498           |NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
499       ngx_conf_set_size_slot,
500       NGX_HTTP_LOC_CONF_OFFSET,
501       offsetof(ngx_http_lua_loc_conf_t, buffer_size),
502       NULL },
503 
504     { ngx_string("lua_socket_pool_size"),
505       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF
506                         |NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
507       ngx_conf_set_num_slot,
508       NGX_HTTP_LOC_CONF_OFFSET,
509       offsetof(ngx_http_lua_loc_conf_t, pool_size),
510       NULL },
511 
512     { ngx_string("lua_socket_read_timeout"),
513       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF
514           |NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
515       ngx_conf_set_msec_slot,
516       NGX_HTTP_LOC_CONF_OFFSET,
517       offsetof(ngx_http_lua_loc_conf_t, read_timeout),
518       NULL },
519 
520     { ngx_string("lua_http10_buffering"),
521       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
522                         |NGX_CONF_FLAG,
523       ngx_conf_set_flag_slot,
524       NGX_HTTP_LOC_CONF_OFFSET,
525       offsetof(ngx_http_lua_loc_conf_t, http10_buffering),
526       NULL },
527 
528     { ngx_string("lua_check_client_abort"),
529       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
530                         |NGX_CONF_FLAG,
531       ngx_conf_set_flag_slot,
532       NGX_HTTP_LOC_CONF_OFFSET,
533       offsetof(ngx_http_lua_loc_conf_t, check_client_abort),
534       NULL },
535 
536     { ngx_string("lua_use_default_type"),
537       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
538                         |NGX_CONF_FLAG,
539       ngx_conf_set_flag_slot,
540       NGX_HTTP_LOC_CONF_OFFSET,
541       offsetof(ngx_http_lua_loc_conf_t, use_default_type),
542       NULL },
543 
544 #if (NGX_HTTP_SSL)
545 
546     { ngx_string("lua_ssl_protocols"),
547       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
548       ngx_conf_set_bitmask_slot,
549       NGX_HTTP_LOC_CONF_OFFSET,
550       offsetof(ngx_http_lua_loc_conf_t, ssl_protocols),
551       &ngx_http_lua_ssl_protocols },
552 
553     { ngx_string("lua_ssl_ciphers"),
554       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
555       ngx_conf_set_str_slot,
556       NGX_HTTP_LOC_CONF_OFFSET,
557       offsetof(ngx_http_lua_loc_conf_t, ssl_ciphers),
558       NULL },
559 
560     { ngx_string("ssl_certificate_by_lua_block"),
561       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
562       ngx_http_lua_ssl_cert_by_lua_block,
563       NGX_HTTP_SRV_CONF_OFFSET,
564       0,
565       (void *) ngx_http_lua_ssl_cert_handler_inline },
566 
567     { ngx_string("ssl_certificate_by_lua_file"),
568       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
569       ngx_http_lua_ssl_cert_by_lua,
570       NGX_HTTP_SRV_CONF_OFFSET,
571       0,
572       (void *) ngx_http_lua_ssl_cert_handler_file },
573 
574     { ngx_string("ssl_session_store_by_lua_block"),
575       NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
576       ngx_http_lua_ssl_sess_store_by_lua_block,
577       NGX_HTTP_SRV_CONF_OFFSET,
578       0,
579       (void *) ngx_http_lua_ssl_sess_store_handler_inline },
580 
581     { ngx_string("ssl_session_store_by_lua_file"),
582       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
583       ngx_http_lua_ssl_sess_store_by_lua,
584       NGX_HTTP_SRV_CONF_OFFSET,
585       0,
586       (void *) ngx_http_lua_ssl_sess_store_handler_file },
587 
588     { ngx_string("ssl_session_fetch_by_lua_block"),
589       NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
590       ngx_http_lua_ssl_sess_fetch_by_lua_block,
591       NGX_HTTP_SRV_CONF_OFFSET,
592       0,
593       (void *) ngx_http_lua_ssl_sess_fetch_handler_inline },
594 
595     { ngx_string("ssl_session_fetch_by_lua_file"),
596       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
597       ngx_http_lua_ssl_sess_fetch_by_lua,
598       NGX_HTTP_SRV_CONF_OFFSET,
599       0,
600       (void *) ngx_http_lua_ssl_sess_fetch_handler_file },
601 
602     { ngx_string("lua_ssl_verify_depth"),
603       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
604       ngx_conf_set_num_slot,
605       NGX_HTTP_LOC_CONF_OFFSET,
606       offsetof(ngx_http_lua_loc_conf_t, ssl_verify_depth),
607       NULL },
608 
609     { ngx_string("lua_ssl_trusted_certificate"),
610       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
611       ngx_conf_set_str_slot,
612       NGX_HTTP_LOC_CONF_OFFSET,
613       offsetof(ngx_http_lua_loc_conf_t, ssl_trusted_certificate),
614       NULL },
615 
616     { ngx_string("lua_ssl_crl"),
617       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
618       ngx_conf_set_str_slot,
619       NGX_HTTP_LOC_CONF_OFFSET,
620       offsetof(ngx_http_lua_loc_conf_t, ssl_crl),
621       NULL },
622 
623 #endif  /* NGX_HTTP_SSL */
624 
625      { ngx_string("lua_malloc_trim"),
626       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
627       ngx_http_lua_malloc_trim,
628       NGX_HTTP_MAIN_CONF_OFFSET,
629       0,
630       NULL },
631 
632     ngx_null_command
633 };
634 
635 
636 static ngx_http_module_t ngx_http_lua_module_ctx = {
637     NULL,                             /*  preconfiguration */
638     ngx_http_lua_init,                /*  postconfiguration */
639 
640     ngx_http_lua_create_main_conf,    /*  create main configuration */
641     ngx_http_lua_init_main_conf,      /*  init main configuration */
642 
643     ngx_http_lua_create_srv_conf,     /*  create server configuration */
644     ngx_http_lua_merge_srv_conf,      /*  merge server configuration */
645 
646     ngx_http_lua_create_loc_conf,     /*  create location configuration */
647     ngx_http_lua_merge_loc_conf       /*  merge location configuration */
648 };
649 
650 
651 ngx_module_t ngx_http_lua_module = {
652     NGX_MODULE_V1,
653     &ngx_http_lua_module_ctx,   /*  module context */
654     ngx_http_lua_cmds,          /*  module directives */
655     NGX_HTTP_MODULE,            /*  module type */
656     NULL,                       /*  init master */
657     NULL,                       /*  init module */
658     ngx_http_lua_init_worker,   /*  init process */
659     NULL,                       /*  init thread */
660     NULL,                       /*  exit thread */
661     ngx_http_lua_exit_worker,   /*  exit process */
662     NULL,                       /*  exit master */
663     NGX_MODULE_V1_PADDING
664 };
665 
666 
667 static ngx_int_t
ngx_http_lua_init(ngx_conf_t * cf)668 ngx_http_lua_init(ngx_conf_t *cf)
669 {
670     int                         multi_http_blocks;
671     ngx_int_t                   rc;
672     ngx_array_t                *arr;
673     ngx_http_handler_pt        *h;
674     volatile ngx_cycle_t       *saved_cycle;
675     ngx_http_core_main_conf_t  *cmcf;
676     ngx_http_lua_main_conf_t   *lmcf;
677     ngx_pool_cleanup_t         *cln;
678     ngx_str_t                   name = ngx_string("host");
679 
680     if (ngx_process == NGX_PROCESS_SIGNALLER || ngx_test_config) {
681         return NGX_OK;
682     }
683 
684     lmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_lua_module);
685 
686     lmcf->host_var_index = ngx_http_get_variable_index(cf, &name);
687     if (lmcf->host_var_index == NGX_ERROR) {
688         return NGX_ERROR;
689     }
690 
691     if (ngx_http_lua_prev_cycle != ngx_cycle) {
692         ngx_http_lua_prev_cycle = ngx_cycle;
693         multi_http_blocks = 0;
694 
695     } else {
696         multi_http_blocks = 1;
697     }
698 
699     if (multi_http_blocks || lmcf->requires_capture_filter) {
700         rc = ngx_http_lua_capture_filter_init(cf);
701         if (rc != NGX_OK) {
702             return rc;
703         }
704     }
705 
706     if (lmcf->postponed_to_rewrite_phase_end == NGX_CONF_UNSET) {
707         lmcf->postponed_to_rewrite_phase_end = 0;
708     }
709 
710     if (lmcf->postponed_to_access_phase_end == NGX_CONF_UNSET) {
711         lmcf->postponed_to_access_phase_end = 0;
712     }
713 
714     cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
715 
716     if (lmcf->requires_rewrite) {
717         h = ngx_array_push(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers);
718         if (h == NULL) {
719             return NGX_ERROR;
720         }
721 
722         *h = ngx_http_lua_rewrite_handler;
723     }
724 
725     if (lmcf->requires_access) {
726         h = ngx_array_push(&cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers);
727         if (h == NULL) {
728             return NGX_ERROR;
729         }
730 
731         *h = ngx_http_lua_access_handler;
732     }
733 
734     dd("requires log: %d", (int) lmcf->requires_log);
735 
736     if (lmcf->requires_log) {
737         arr = &cmcf->phases[NGX_HTTP_LOG_PHASE].handlers;
738         h = ngx_array_push(arr);
739         if (h == NULL) {
740             return NGX_ERROR;
741         }
742 
743         if (arr->nelts > 1) {
744             h = arr->elts;
745             ngx_memmove(&h[1], h,
746                         (arr->nelts - 1) * sizeof(ngx_http_handler_pt));
747         }
748 
749         *h = ngx_http_lua_log_handler;
750     }
751 
752     if (multi_http_blocks || lmcf->requires_header_filter) {
753         rc = ngx_http_lua_header_filter_init();
754         if (rc != NGX_OK) {
755             return rc;
756         }
757     }
758 
759     if (multi_http_blocks || lmcf->requires_body_filter) {
760         rc = ngx_http_lua_body_filter_init();
761         if (rc != NGX_OK) {
762             return rc;
763         }
764     }
765 
766     /* add the cleanup of semaphores after the lua_close */
767     cln = ngx_pool_cleanup_add(cf->pool, 0);
768     if (cln == NULL) {
769         return NGX_ERROR;
770     }
771 
772     cln->data = lmcf;
773     cln->handler = ngx_http_lua_sema_mm_cleanup;
774 
775 #ifdef HAVE_NGX_LUA_PIPE
776     ngx_http_lua_pipe_init();
777 #endif
778 
779 #if (nginx_version >= 1011011)
780     cln = ngx_pool_cleanup_add(cf->pool, 0);
781     if (cln == NULL) {
782         return NGX_ERROR;
783     }
784 
785     cln->data = lmcf;
786     cln->handler = ngx_http_lua_ngx_raw_header_cleanup;
787 #endif
788 
789     if (lmcf->lua == NULL) {
790         dd("initializing lua vm");
791 
792 #ifndef OPENRESTY_LUAJIT
793         if (ngx_process != NGX_PROCESS_SIGNALLER && !ngx_test_config) {
794             ngx_log_error(NGX_LOG_ALERT, cf->log, 0,
795                           "detected a LuaJIT version which is not OpenResty's"
796                           "; many optimizations will be disabled and "
797                           "performance will be compromised (see "
798                           "https://github.com/openresty/luajit2 for "
799                           "OpenResty's LuaJIT or, even better, consider using "
800                           "the OpenResty releases from https://openresty.org/"
801                           "en/download.html)");
802         }
803 #else
804 #   if !defined(HAVE_LUA_RESETTHREAD)
805         ngx_log_error(NGX_LOG_ALERT, cf->log, 0,
806                       "detected an old version of OpenResty's LuaJIT missing "
807                       "the lua_resetthread API and thus the "
808                       "performance will be compromised; please upgrade to the "
809                       "latest version of OpenResty's LuaJIT: "
810                       "https://github.com/openresty/luajit2");
811 #   endif
812 #   if !defined(HAVE_LUA_EXDATA2)
813         ngx_log_error(NGX_LOG_ALERT, cf->log, 0,
814                       "detected an old version of OpenResty's LuaJIT missing "
815                       "the exdata2 API and thus the "
816                       "performance will be compromised; please upgrade to the "
817                       "latest version of OpenResty's LuaJIT: "
818                       "https://github.com/openresty/luajit2");
819 #   endif
820 #endif
821 
822         ngx_http_lua_content_length_hash =
823                                   ngx_http_lua_hash_literal("content-length");
824         ngx_http_lua_location_hash = ngx_http_lua_hash_literal("location");
825 
826         rc = ngx_http_lua_init_vm(&lmcf->lua, NULL, cf->cycle, cf->pool,
827                                   lmcf, cf->log, NULL);
828         if (rc != NGX_OK) {
829             if (rc == NGX_DECLINED) {
830                 ngx_http_lua_assert(lmcf->lua != NULL);
831 
832                 ngx_conf_log_error(NGX_LOG_ALERT, cf, 0,
833                                    "failed to load the 'resty.core' module "
834                                    "(https://github.com/openresty/lua-resty"
835                                    "-core); ensure you are using an OpenResty "
836                                    "release from https://openresty.org/en/"
837                                    "download.html (reason: %s)",
838                                    lua_tostring(lmcf->lua, -1));
839 
840             } else {
841                 /* rc == NGX_ERROR */
842                 ngx_conf_log_error(NGX_LOG_ALERT, cf, 0,
843                                    "failed to initialize Lua VM");
844             }
845 
846             return NGX_ERROR;
847         }
848 
849         /* rc == NGX_OK */
850 
851         ngx_http_lua_assert(lmcf->lua != NULL);
852 
853         if (!lmcf->requires_shm && lmcf->init_handler) {
854             saved_cycle = ngx_cycle;
855             ngx_cycle = cf->cycle;
856 
857             rc = lmcf->init_handler(cf->log, lmcf, lmcf->lua);
858 
859             ngx_cycle = saved_cycle;
860 
861             if (rc != NGX_OK) {
862                 /* an error happened */
863                 return NGX_ERROR;
864             }
865         }
866 
867         dd("Lua VM initialized!");
868     }
869 
870     return NGX_OK;
871 }
872 
873 
874 static char *
ngx_http_lua_lowat_check(ngx_conf_t * cf,void * post,void * data)875 ngx_http_lua_lowat_check(ngx_conf_t *cf, void *post, void *data)
876 {
877 #if (NGX_FREEBSD)
878     ssize_t *np = data;
879 
880     if ((u_long) *np >= ngx_freebsd_net_inet_tcp_sendspace) {
881         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
882                            "\"lua_send_lowat\" must be less than %d "
883                            "(sysctl net.inet.tcp.sendspace)",
884                            ngx_freebsd_net_inet_tcp_sendspace);
885 
886         return NGX_CONF_ERROR;
887     }
888 
889 #elif !(NGX_HAVE_SO_SNDLOWAT)
890     ssize_t *np = data;
891 
892     ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
893                        "\"lua_send_lowat\" is not supported, ignored");
894 
895     *np = 0;
896 
897 #endif
898 
899     return NGX_CONF_OK;
900 }
901 
902 
903 static void *
ngx_http_lua_create_main_conf(ngx_conf_t * cf)904 ngx_http_lua_create_main_conf(ngx_conf_t *cf)
905 {
906     ngx_int_t       rc;
907 
908     ngx_http_lua_main_conf_t    *lmcf;
909 
910     lmcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_lua_main_conf_t));
911     if (lmcf == NULL) {
912         return NULL;
913     }
914 
915     /* set by ngx_pcalloc:
916      *      lmcf->lua = NULL;
917      *      lmcf->lua_path = { 0, NULL };
918      *      lmcf->lua_cpath = { 0, NULL };
919      *      lmcf->pending_timers = 0;
920      *      lmcf->running_timers = 0;
921      *      lmcf->watcher = NULL;
922      *      lmcf->regex_cache_entries = 0;
923      *      lmcf->jit_stack = NULL;
924      *      lmcf->shm_zones = NULL;
925      *      lmcf->init_handler = NULL;
926      *      lmcf->init_src = { 0, NULL };
927      *      lmcf->shm_zones_inited = 0;
928      *      lmcf->shdict_zones = NULL;
929      *      lmcf->preload_hooks = NULL;
930      *      lmcf->requires_header_filter = 0;
931      *      lmcf->requires_body_filter = 0;
932      *      lmcf->requires_capture_filter = 0;
933      *      lmcf->requires_rewrite = 0;
934      *      lmcf->requires_access = 0;
935      *      lmcf->requires_log = 0;
936      *      lmcf->requires_shm = 0;
937      */
938 
939     lmcf->pool = cf->pool;
940     lmcf->max_pending_timers = NGX_CONF_UNSET;
941     lmcf->max_running_timers = NGX_CONF_UNSET;
942     lmcf->lua_thread_cache_max_entries = NGX_CONF_UNSET;
943 #if (NGX_PCRE)
944     lmcf->regex_cache_max_entries = NGX_CONF_UNSET;
945     lmcf->regex_match_limit = NGX_CONF_UNSET;
946 #endif
947     lmcf->postponed_to_rewrite_phase_end = NGX_CONF_UNSET;
948     lmcf->postponed_to_access_phase_end = NGX_CONF_UNSET;
949 
950     lmcf->set_sa_restart = NGX_CONF_UNSET;
951 
952 #if (NGX_HTTP_LUA_HAVE_MALLOC_TRIM)
953     lmcf->malloc_trim_cycle = NGX_CONF_UNSET_UINT;
954 #endif
955 
956     rc = ngx_http_lua_sema_mm_init(cf, lmcf);
957     if (rc != NGX_OK) {
958         return NULL;
959     }
960 
961     dd("nginx Lua module main config structure initialized!");
962 
963     return lmcf;
964 }
965 
966 
967 static char *
ngx_http_lua_init_main_conf(ngx_conf_t * cf,void * conf)968 ngx_http_lua_init_main_conf(ngx_conf_t *cf, void *conf)
969 {
970 #ifdef HAVE_LUA_RESETTHREAD
971     ngx_int_t                    i, n;
972     ngx_http_lua_thread_ref_t   *trefs;
973 #endif
974 
975     ngx_http_lua_main_conf_t     *lmcf = conf;
976 
977     if (lmcf->lua_thread_cache_max_entries < 0) {
978         lmcf->lua_thread_cache_max_entries = 1024;
979 
980 #ifndef HAVE_LUA_RESETTHREAD
981 
982     } else if (lmcf->lua_thread_cache_max_entries > 0) {
983         ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
984                       "lua_thread_cache_max_entries has no effect when "
985                       "LuaJIT has no support for the lua_resetthread API "
986                       "(you forgot to use OpenResty's LuaJIT?)");
987         return NGX_CONF_ERROR;
988 
989 #endif
990     }
991 
992 #if (NGX_PCRE)
993     if (lmcf->regex_cache_max_entries == NGX_CONF_UNSET) {
994         lmcf->regex_cache_max_entries = 1024;
995     }
996 
997     if (lmcf->regex_match_limit == NGX_CONF_UNSET) {
998         lmcf->regex_match_limit = 0;
999     }
1000 #endif
1001 
1002     if (lmcf->max_pending_timers == NGX_CONF_UNSET) {
1003         lmcf->max_pending_timers = 1024;
1004     }
1005 
1006     if (lmcf->max_running_timers == NGX_CONF_UNSET) {
1007         lmcf->max_running_timers = 256;
1008     }
1009 
1010 #if (NGX_HTTP_LUA_HAVE_SA_RESTART)
1011     if (lmcf->set_sa_restart == NGX_CONF_UNSET) {
1012         lmcf->set_sa_restart = 1;
1013     }
1014 #endif
1015 
1016 #if (NGX_HTTP_LUA_HAVE_MALLOC_TRIM)
1017     if (lmcf->malloc_trim_cycle == NGX_CONF_UNSET_UINT) {
1018         lmcf->malloc_trim_cycle = 1000;  /* number of reqs */
1019     }
1020 #endif
1021 
1022     lmcf->cycle = cf->cycle;
1023 
1024     ngx_queue_init(&lmcf->free_lua_threads);
1025     ngx_queue_init(&lmcf->cached_lua_threads);
1026 
1027 #ifdef HAVE_LUA_RESETTHREAD
1028     n = lmcf->lua_thread_cache_max_entries;
1029 
1030     if (n > 0) {
1031         trefs = ngx_palloc(cf->pool, n * sizeof(ngx_http_lua_thread_ref_t));
1032         if (trefs == NULL) {
1033             return NGX_CONF_ERROR;
1034         }
1035 
1036         for (i = 0; i < n; i++) {
1037             trefs[i].ref = LUA_NOREF;
1038             trefs[i].co = NULL;
1039             ngx_queue_insert_head(&lmcf->free_lua_threads, &trefs[i].queue);
1040         }
1041     }
1042 #endif
1043 
1044     return NGX_CONF_OK;
1045 }
1046 
1047 
1048 static void *
ngx_http_lua_create_srv_conf(ngx_conf_t * cf)1049 ngx_http_lua_create_srv_conf(ngx_conf_t *cf)
1050 {
1051     ngx_http_lua_srv_conf_t     *lscf;
1052 
1053     lscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_lua_srv_conf_t));
1054     if (lscf == NULL) {
1055         return NULL;
1056     }
1057 
1058     /* set by ngx_pcalloc:
1059      *      lscf->srv.ssl_cert_handler = NULL;
1060      *      lscf->srv.ssl_cert_src = { 0, NULL };
1061      *      lscf->srv.ssl_cert_src_key = NULL;
1062      *
1063      *      lscf->srv.ssl_session_store_handler = NULL;
1064      *      lscf->srv.ssl_session_store_src = { 0, NULL };
1065      *      lscf->srv.ssl_session_store_src_key = NULL;
1066      *
1067      *      lscf->srv.ssl_session_fetch_handler = NULL;
1068      *      lscf->srv.ssl_session_fetch_src = { 0, NULL };
1069      *      lscf->srv.ssl_session_fetch_src_key = NULL;
1070      *
1071      *      lscf->balancer.handler = NULL;
1072      *      lscf->balancer.src = { 0, NULL };
1073      *      lscf->balancer.src_key = NULL;
1074      */
1075 
1076 #if (NGX_HTTP_SSL)
1077     lscf->srv.ssl_cert_src_ref = LUA_REFNIL;
1078     lscf->srv.ssl_sess_store_src_ref = LUA_REFNIL;
1079     lscf->srv.ssl_sess_fetch_src_ref = LUA_REFNIL;
1080 #endif
1081 
1082     lscf->balancer.src_ref = LUA_REFNIL;
1083 
1084     return lscf;
1085 }
1086 
1087 
1088 static char *
ngx_http_lua_merge_srv_conf(ngx_conf_t * cf,void * parent,void * child)1089 ngx_http_lua_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
1090 {
1091 #if (NGX_HTTP_SSL)
1092 
1093     ngx_http_lua_srv_conf_t *prev = parent;
1094     ngx_http_lua_srv_conf_t *conf = child;
1095     ngx_http_ssl_srv_conf_t *sscf;
1096 
1097     dd("merge srv conf");
1098 
1099     if (conf->srv.ssl_cert_src.len == 0) {
1100         conf->srv.ssl_cert_src = prev->srv.ssl_cert_src;
1101         conf->srv.ssl_cert_src_ref = prev->srv.ssl_cert_src_ref;
1102         conf->srv.ssl_cert_src_key = prev->srv.ssl_cert_src_key;
1103         conf->srv.ssl_cert_handler = prev->srv.ssl_cert_handler;
1104     }
1105 
1106     if (conf->srv.ssl_cert_src.len) {
1107         sscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_ssl_module);
1108         if (sscf == NULL || sscf->ssl.ctx == NULL) {
1109             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
1110                           "no ssl configured for the server");
1111 
1112             return NGX_CONF_ERROR;
1113         }
1114 
1115 #ifdef LIBRESSL_VERSION_NUMBER
1116 
1117         ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
1118                       "LibreSSL is not supported by ssl_certificate_by_lua*");
1119         return NGX_CONF_ERROR;
1120 
1121 #else
1122 
1123 #   if OPENSSL_VERSION_NUMBER >= 0x1000205fL
1124 
1125         SSL_CTX_set_cert_cb(sscf->ssl.ctx, ngx_http_lua_ssl_cert_handler, NULL);
1126 
1127 #   else
1128 
1129         ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
1130                       "OpenSSL too old to support ssl_certificate_by_lua*");
1131         return NGX_CONF_ERROR;
1132 
1133 #   endif
1134 
1135 #endif
1136     }
1137 
1138     if (conf->srv.ssl_sess_store_src.len == 0) {
1139         conf->srv.ssl_sess_store_src = prev->srv.ssl_sess_store_src;
1140         conf->srv.ssl_sess_store_src_ref = prev->srv.ssl_sess_store_src_ref;
1141         conf->srv.ssl_sess_store_src_key = prev->srv.ssl_sess_store_src_key;
1142         conf->srv.ssl_sess_store_handler = prev->srv.ssl_sess_store_handler;
1143     }
1144 
1145     if (conf->srv.ssl_sess_store_src.len) {
1146         sscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_ssl_module);
1147         if (sscf && sscf->ssl.ctx) {
1148 #ifdef LIBRESSL_VERSION_NUMBER
1149             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
1150                           "LibreSSL is not supported by "
1151                           "ssl_session_store_by_lua*");
1152 
1153             return NGX_CONF_ERROR;
1154 #else
1155             SSL_CTX_sess_set_new_cb(sscf->ssl.ctx,
1156                                     ngx_http_lua_ssl_sess_store_handler);
1157 #endif
1158         }
1159     }
1160 
1161     if (conf->srv.ssl_sess_fetch_src.len == 0) {
1162         conf->srv.ssl_sess_fetch_src = prev->srv.ssl_sess_fetch_src;
1163         conf->srv.ssl_sess_fetch_src_ref = prev->srv.ssl_sess_fetch_src_ref;
1164         conf->srv.ssl_sess_fetch_src_key = prev->srv.ssl_sess_fetch_src_key;
1165         conf->srv.ssl_sess_fetch_handler = prev->srv.ssl_sess_fetch_handler;
1166     }
1167 
1168     if (conf->srv.ssl_sess_fetch_src.len) {
1169         sscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_ssl_module);
1170         if (sscf && sscf->ssl.ctx) {
1171 #ifdef LIBRESSL_VERSION_NUMBER
1172             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
1173                           "LibreSSL is not supported by "
1174                           "ssl_session_fetch_by_lua*");
1175 
1176             return NGX_CONF_ERROR;
1177 #else
1178             SSL_CTX_sess_set_get_cb(sscf->ssl.ctx,
1179                                     ngx_http_lua_ssl_sess_fetch_handler);
1180 #endif
1181         }
1182     }
1183 
1184 #endif  /* NGX_HTTP_SSL */
1185     return NGX_CONF_OK;
1186 }
1187 
1188 
1189 static void *
ngx_http_lua_create_loc_conf(ngx_conf_t * cf)1190 ngx_http_lua_create_loc_conf(ngx_conf_t *cf)
1191 {
1192     ngx_http_lua_loc_conf_t *conf;
1193 
1194     conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_lua_loc_conf_t));
1195     if (conf == NULL) {
1196         return NULL;
1197     }
1198 
1199     /* set by ngx_pcalloc:
1200      *      conf->access_src  = {{ 0, NULL }, NULL, NULL, NULL};
1201      *      conf->access_src_key = NULL
1202      *      conf->rewrite_src = {{ 0, NULL }, NULL, NULL, NULL};
1203      *      conf->rewrite_src_key = NULL;
1204      *      conf->rewrite_handler = NULL;
1205      *
1206      *      conf->content_src = {{ 0, NULL }, NULL, NULL, NULL};
1207      *      conf->content_src_key = NULL;
1208      *      conf->content_handler = NULL;
1209      *
1210      *      conf->log_src = {{ 0, NULL }, NULL, NULL, NULL};
1211      *      conf->log_src_key = NULL;
1212      *      conf->log_handler = NULL;
1213      *
1214      *      conf->header_filter_src = {{ 0, NULL }, NULL, NULL, NULL};
1215      *      conf->header_filter_src_key = NULL;
1216      *      conf->header_filter_handler = NULL;
1217      *
1218      *      conf->body_filter_src = {{ 0, NULL }, NULL, NULL, NULL};
1219      *      conf->body_filter_src_key = NULL;
1220      *      conf->body_filter_handler = NULL;
1221      *
1222      *      conf->ssl = 0;
1223      *      conf->ssl_protocols = 0;
1224      *      conf->ssl_ciphers = { 0, NULL };
1225      *      conf->ssl_trusted_certificate = { 0, NULL };
1226      *      conf->ssl_crl = { 0, NULL };
1227      */
1228 
1229     conf->force_read_body    = NGX_CONF_UNSET;
1230     conf->enable_code_cache  = NGX_CONF_UNSET;
1231     conf->http10_buffering   = NGX_CONF_UNSET;
1232     conf->check_client_abort = NGX_CONF_UNSET;
1233     conf->use_default_type   = NGX_CONF_UNSET;
1234 
1235     conf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
1236     conf->connect_timeout = NGX_CONF_UNSET_MSEC;
1237     conf->send_timeout = NGX_CONF_UNSET_MSEC;
1238     conf->read_timeout = NGX_CONF_UNSET_MSEC;
1239     conf->send_lowat = NGX_CONF_UNSET_SIZE;
1240     conf->buffer_size = NGX_CONF_UNSET_SIZE;
1241     conf->pool_size = NGX_CONF_UNSET_UINT;
1242 
1243     conf->transform_underscores_in_resp_headers = NGX_CONF_UNSET;
1244     conf->log_socket_errors = NGX_CONF_UNSET;
1245 
1246     conf->rewrite_src_ref = LUA_REFNIL;
1247     conf->access_src_ref = LUA_REFNIL;
1248     conf->content_src_ref = LUA_REFNIL;
1249     conf->header_filter_src_ref = LUA_REFNIL;
1250     conf->body_filter_src_ref = LUA_REFNIL;
1251     conf->log_src_ref = LUA_REFNIL;
1252 
1253 #if (NGX_HTTP_SSL)
1254     conf->ssl_verify_depth = NGX_CONF_UNSET_UINT;
1255 #endif
1256 
1257     return conf;
1258 }
1259 
1260 
1261 static char *
ngx_http_lua_merge_loc_conf(ngx_conf_t * cf,void * parent,void * child)1262 ngx_http_lua_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
1263 {
1264     ngx_http_lua_loc_conf_t *prev = parent;
1265     ngx_http_lua_loc_conf_t *conf = child;
1266 
1267     if (conf->rewrite_src.value.len == 0) {
1268         conf->rewrite_src = prev->rewrite_src;
1269         conf->rewrite_handler = prev->rewrite_handler;
1270         conf->rewrite_src_ref = prev->rewrite_src_ref;
1271         conf->rewrite_src_key = prev->rewrite_src_key;
1272         conf->rewrite_chunkname = prev->rewrite_chunkname;
1273     }
1274 
1275     if (conf->access_src.value.len == 0) {
1276         conf->access_src = prev->access_src;
1277         conf->access_handler = prev->access_handler;
1278         conf->access_src_ref = prev->access_src_ref;
1279         conf->access_src_key = prev->access_src_key;
1280         conf->access_chunkname = prev->access_chunkname;
1281     }
1282 
1283     if (conf->content_src.value.len == 0) {
1284         conf->content_src = prev->content_src;
1285         conf->content_handler = prev->content_handler;
1286         conf->content_src_ref = prev->content_src_ref;
1287         conf->content_src_key = prev->content_src_key;
1288         conf->content_chunkname = prev->content_chunkname;
1289     }
1290 
1291     if (conf->log_src.value.len == 0) {
1292         conf->log_src = prev->log_src;
1293         conf->log_handler = prev->log_handler;
1294         conf->log_src_ref = prev->log_src_ref;
1295         conf->log_src_key = prev->log_src_key;
1296         conf->log_chunkname = prev->log_chunkname;
1297     }
1298 
1299     if (conf->header_filter_src.value.len == 0) {
1300         conf->header_filter_src = prev->header_filter_src;
1301         conf->header_filter_handler = prev->header_filter_handler;
1302         conf->header_filter_src_ref = prev->header_filter_src_ref;
1303         conf->header_filter_src_key = prev->header_filter_src_key;
1304     }
1305 
1306     if (conf->body_filter_src.value.len == 0) {
1307         conf->body_filter_src = prev->body_filter_src;
1308         conf->body_filter_handler = prev->body_filter_handler;
1309         conf->body_filter_src_ref = prev->body_filter_src_ref;
1310         conf->body_filter_src_key = prev->body_filter_src_key;
1311     }
1312 
1313 #if (NGX_HTTP_SSL)
1314 
1315     ngx_conf_merge_bitmask_value(conf->ssl_protocols, prev->ssl_protocols,
1316                                  (NGX_CONF_BITMASK_SET|NGX_SSL_SSLv3
1317                                   |NGX_SSL_TLSv1|NGX_SSL_TLSv1_1
1318                                   |NGX_SSL_TLSv1_2));
1319 
1320     ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers,
1321                              "DEFAULT");
1322 
1323     ngx_conf_merge_uint_value(conf->ssl_verify_depth,
1324                               prev->ssl_verify_depth, 1);
1325     ngx_conf_merge_str_value(conf->ssl_trusted_certificate,
1326                              prev->ssl_trusted_certificate, "");
1327     ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, "");
1328 
1329     if (ngx_http_lua_set_ssl(cf, conf) != NGX_OK) {
1330         return NGX_CONF_ERROR;
1331     }
1332 
1333 #endif
1334 
1335     ngx_conf_merge_value(conf->force_read_body, prev->force_read_body, 0);
1336     ngx_conf_merge_value(conf->enable_code_cache, prev->enable_code_cache, 1);
1337     ngx_conf_merge_value(conf->http10_buffering, prev->http10_buffering, 1);
1338     ngx_conf_merge_value(conf->check_client_abort, prev->check_client_abort, 0);
1339     ngx_conf_merge_value(conf->use_default_type, prev->use_default_type, 1);
1340 
1341     ngx_conf_merge_msec_value(conf->keepalive_timeout,
1342                               prev->keepalive_timeout, 60000);
1343 
1344     ngx_conf_merge_msec_value(conf->connect_timeout,
1345                               prev->connect_timeout, 60000);
1346 
1347     ngx_conf_merge_msec_value(conf->send_timeout,
1348                               prev->send_timeout, 60000);
1349 
1350     ngx_conf_merge_msec_value(conf->read_timeout,
1351                               prev->read_timeout, 60000);
1352 
1353     ngx_conf_merge_size_value(conf->send_lowat,
1354                               prev->send_lowat, 0);
1355 
1356     ngx_conf_merge_size_value(conf->buffer_size,
1357                               prev->buffer_size,
1358                               (size_t) ngx_pagesize);
1359 
1360     ngx_conf_merge_uint_value(conf->pool_size, prev->pool_size, 30);
1361 
1362     ngx_conf_merge_value(conf->transform_underscores_in_resp_headers,
1363                          prev->transform_underscores_in_resp_headers, 1);
1364 
1365     ngx_conf_merge_value(conf->log_socket_errors, prev->log_socket_errors, 1);
1366 
1367     return NGX_CONF_OK;
1368 }
1369 
1370 
1371 #if (NGX_HTTP_SSL)
1372 
1373 static ngx_int_t
ngx_http_lua_set_ssl(ngx_conf_t * cf,ngx_http_lua_loc_conf_t * llcf)1374 ngx_http_lua_set_ssl(ngx_conf_t *cf, ngx_http_lua_loc_conf_t *llcf)
1375 {
1376     ngx_pool_cleanup_t  *cln;
1377 
1378     llcf->ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
1379     if (llcf->ssl == NULL) {
1380         return NGX_ERROR;
1381     }
1382 
1383     llcf->ssl->log = cf->log;
1384 
1385     if (ngx_ssl_create(llcf->ssl, llcf->ssl_protocols, NULL) != NGX_OK) {
1386         return NGX_ERROR;
1387     }
1388 
1389     cln = ngx_pool_cleanup_add(cf->pool, 0);
1390     if (cln == NULL) {
1391         return NGX_ERROR;
1392     }
1393 
1394     cln->handler = ngx_ssl_cleanup_ctx;
1395     cln->data = llcf->ssl;
1396 
1397     if (SSL_CTX_set_cipher_list(llcf->ssl->ctx,
1398                                 (const char *) llcf->ssl_ciphers.data)
1399         == 0)
1400     {
1401         ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0,
1402                       "SSL_CTX_set_cipher_list(\"%V\") failed",
1403                       &llcf->ssl_ciphers);
1404         return NGX_ERROR;
1405     }
1406 
1407     if (llcf->ssl_trusted_certificate.len
1408         && ngx_ssl_trusted_certificate(cf, llcf->ssl,
1409                                        &llcf->ssl_trusted_certificate,
1410                                        llcf->ssl_verify_depth)
1411         != NGX_OK)
1412     {
1413         return NGX_ERROR;
1414     }
1415 
1416     dd("ssl crl: %.*s", (int) llcf->ssl_crl.len, llcf->ssl_crl.data);
1417 
1418     if (ngx_ssl_crl(cf, llcf->ssl, &llcf->ssl_crl) != NGX_OK) {
1419         return NGX_ERROR;
1420     }
1421 
1422     return NGX_OK;
1423 }
1424 
1425 #endif  /* NGX_HTTP_SSL */
1426 
1427 
1428 static char *
ngx_http_lua_malloc_trim(ngx_conf_t * cf,ngx_command_t * cmd,void * conf)1429 ngx_http_lua_malloc_trim(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1430 {
1431 #if (NGX_HTTP_LUA_HAVE_MALLOC_TRIM)
1432 
1433     ngx_int_t       nreqs;
1434     ngx_str_t      *value;
1435 
1436     ngx_http_lua_main_conf_t    *lmcf = conf;
1437 
1438     value = cf->args->elts;
1439 
1440     nreqs = ngx_atoi(value[1].data, value[1].len);
1441     if (nreqs == NGX_ERROR) {
1442         return "invalid number in the 1st argument";
1443     }
1444 
1445     lmcf->malloc_trim_cycle = (ngx_uint_t) nreqs;
1446 
1447     if (nreqs == 0) {
1448         return NGX_CONF_OK;
1449     }
1450 
1451     lmcf->requires_log = 1;
1452 
1453 #else
1454 
1455     ngx_conf_log_error(NGX_LOG_WARN, cf, 0, "lua_malloc_trim is not supported "
1456                        "on this platform, ignored");
1457 
1458 #endif
1459     return NGX_CONF_OK;
1460 }
1461 
1462 /* vi:set ft=c ts=4 sw=4 et fdm=marker: */
1463