Ticket #688: Configuration.c

File Configuration.c, 36.1 KB (added by electron17.ya.ru, 12 years ago)

Файл конфигурации из ошибки

Line 
1/*
2 * Copyright (C) Igor Sysoev
3 * Copyright (C) 2007 Manlio Perillo (manlio.perillo@gmail.com)
4 * Copyright (C) 2010-2013 Phusion
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <ngx_config.h>
29#include <ngx_core.h>
30#include <ngx_http.h>
31
32#include <sys/types.h>
33#include <pwd.h>
34
35#include "ngx_http_passenger_module.h"
36#include "Configuration.h"
37#include "ContentHandler.h"
38#include "common/Constants.h"
39#include "common/agents/LoggingAgent/FilterSupport.h"
40
41
42static ngx_str_t headers_to_hide[] = {
43 /* NOTE: Do not hide the "Status" header; some broken HTTP clients
44 * expect this header. http://code.google.com/p/phusion-passenger/issues/detail?id=177
45 */
46 ngx_string("X-Accel-Expires"),
47 ngx_string("X-Accel-Redirect"),
48 ngx_string("X-Accel-Limit-Rate"),
49 ngx_string("X-Accel-Buffering"),
50 ngx_null_string
51};
52
53passenger_main_conf_t passenger_main_conf;
54
55static ngx_path_init_t ngx_http_proxy_temp_path = {
56 ngx_string(NGX_HTTP_PROXY_TEMP_PATH), { 1, 2, 0 }
57};
58
59
60void *
61passenger_create_main_conf(ngx_conf_t *cf)
62{
63 passenger_main_conf_t *conf;
64
65 conf = ngx_pcalloc(cf->pool, sizeof(passenger_main_conf_t));
66 if (conf == NULL) {
67 return NGX_CONF_ERROR;
68 }
69
70 conf->ctl = ngx_array_create(cf->pool, 1, sizeof(ngx_keyval_t));
71 if (conf->ctl == NULL) {
72 return NGX_CONF_ERROR;
73 }
74 conf->default_ruby.data = NULL;
75 conf->default_ruby.len = 0;
76 conf->log_level = (ngx_int_t) NGX_CONF_UNSET;
77 conf->debug_log_file.data = NULL;
78 conf->debug_log_file.len = 0;
79 conf->abort_on_startup_error = NGX_CONF_UNSET;
80 conf->max_pool_size = (ngx_uint_t) NGX_CONF_UNSET;
81 conf->pool_idle_time = (ngx_uint_t) NGX_CONF_UNSET;
82 conf->user_switching = NGX_CONF_UNSET;
83 conf->default_user.data = NULL;
84 conf->default_user.len = 0;
85 conf->default_group.data = NULL;
86 conf->default_group.len = 0;
87 conf->analytics_log_user.data = NULL;
88 conf->analytics_log_user.len = 0;
89 conf->analytics_log_group.data = NULL;
90 conf->analytics_log_group.len = 0;
91 conf->union_station_gateway_address.data = NULL;
92 conf->union_station_gateway_address.len = 0;
93 conf->union_station_gateway_port = (ngx_uint_t) NGX_CONF_UNSET;
94 conf->union_station_gateway_cert.data = NULL;
95 conf->union_station_gateway_cert.len = 0;
96 conf->union_station_proxy_address.data = NULL;
97 conf->union_station_proxy_address.len = 0;
98
99 conf->prestart_uris = ngx_array_create(cf->pool, 1, sizeof(ngx_str_t));
100 if (conf->prestart_uris == NULL) {
101 return NGX_CONF_ERROR;
102 }
103
104 return conf;
105}
106
107char *
108passenger_init_main_conf(ngx_conf_t *cf, void *conf_pointer)
109{
110 passenger_main_conf_t *conf;
111 struct passwd *user_entry;
112 struct group *group_entry;
113 char buf[128];
114
115 conf = &passenger_main_conf;
116 *conf = *((passenger_main_conf_t *) conf_pointer);
117
118 if (conf->default_ruby.len == 0) {
119 conf->default_ruby.data = (u_char *) DEFAULT_RUBY;
120 conf->default_ruby.len = strlen(DEFAULT_RUBY);
121 }
122
123 if (conf->log_level == (ngx_int_t) NGX_CONF_UNSET) {
124 conf->log_level = DEFAULT_LOG_LEVEL;
125 }
126
127 if (conf->debug_log_file.len == 0) {
128 conf->debug_log_file.data = (u_char *) "";
129 }
130
131 if (conf->abort_on_startup_error == NGX_CONF_UNSET) {
132 conf->abort_on_startup_error = 0;
133 }
134
135 if (conf->max_pool_size == (ngx_uint_t) NGX_CONF_UNSET) {
136 conf->max_pool_size = DEFAULT_MAX_POOL_SIZE;
137 }
138
139 if (conf->pool_idle_time == (ngx_uint_t) NGX_CONF_UNSET) {
140 conf->pool_idle_time = DEFAULT_POOL_IDLE_TIME;
141 }
142
143 if (conf->user_switching == NGX_CONF_UNSET) {
144 conf->user_switching = 1;
145 }
146
147 if (conf->default_user.len == 0) {
148 conf->default_user.len = sizeof(DEFAULT_WEB_APP_USER) - 1;
149 conf->default_user.data = (u_char *) DEFAULT_WEB_APP_USER;
150 }
151 if (conf->default_user.len > sizeof(buf) - 1) {
152 return "Value for 'default_user' is too long.";
153 }
154 memcpy(buf, conf->default_user.data, conf->default_user.len);
155 buf[conf->default_user.len] = '\0';
156 user_entry = getpwnam(buf);
157 if (user_entry == NULL) {
158 return "The user specified by the 'default_user' option does not exist.";
159 }
160
161 if (conf->default_group.len > 0) {
162 if (conf->default_group.len > sizeof(buf) - 1) {
163 return "Value for 'default_group' is too long.";
164 }
165 memcpy(buf, conf->default_group.data, conf->default_group.len);
166 buf[conf->default_group.len] = '\0';
167 group_entry = getgrnam(buf);
168 if (group_entry == NULL) {
169 return "The group specified by the 'default_group' option does not exist.";
170 }
171 }
172
173 if (conf->analytics_log_user.len == 0) {
174 conf->analytics_log_user.len = sizeof(DEFAULT_ANALYTICS_LOG_USER) - 1;
175 conf->analytics_log_user.data = (u_char *) DEFAULT_ANALYTICS_LOG_USER;
176 }
177
178 if (conf->analytics_log_group.len == 0) {
179 conf->analytics_log_group.len = sizeof(DEFAULT_ANALYTICS_LOG_GROUP) - 1;
180 conf->analytics_log_group.data = (u_char *) DEFAULT_ANALYTICS_LOG_GROUP;
181 }
182
183 if (conf->union_station_gateway_address.len == 0) {
184 conf->union_station_gateway_address.len = sizeof(DEFAULT_UNION_STATION_GATEWAY_ADDRESS) - 1;
185 conf->union_station_gateway_address.data = (u_char *) DEFAULT_UNION_STATION_GATEWAY_ADDRESS;
186 }
187
188 if (conf->union_station_gateway_port == (ngx_uint_t) NGX_CONF_UNSET) {
189 conf->union_station_gateway_port = DEFAULT_UNION_STATION_GATEWAY_PORT;
190 }
191
192 if (conf->union_station_gateway_cert.len == 0) {
193 conf->union_station_gateway_cert.data = (u_char *) "";
194 }
195
196 if (conf->union_station_proxy_address.len == 0) {
197 conf->union_station_proxy_address.data = (u_char *) "";
198 }
199
200 return NGX_CONF_OK;
201}
202
203void *
204passenger_create_loc_conf(ngx_conf_t *cf)
205{
206 passenger_loc_conf_t *conf;
207 ngx_keyval_t *kv;
208
209 conf = ngx_pcalloc(cf->pool, sizeof(passenger_loc_conf_t));
210 if (conf == NULL) {
211 return NGX_CONF_ERROR;
212 }
213
214 /*
215 * set by ngx_pcalloc():
216 *
217 * conf->upstream_config.bufs.num = 0;
218 * conf->upstream_config.next_upstream = 0;
219 * conf->upstream_config.temp_path = NULL;
220 * conf->upstream_config.hide_headers_hash = { NULL, 0 };
221 * conf->upstream_config.hide_headers = NULL;
222 * conf->upstream_config.pass_headers = NULL;
223 * conf->upstream_config.uri = { 0, NULL };
224 * conf->upstream_config.location = NULL;
225 * conf->upstream_config.store_lengths = NULL;
226 * conf->upstream_config.store_values = NULL;
227 */
228
229 #include "CreateLocationConfig.c"
230
231 /******************************/
232 /******************************/
233
234 conf->upstream_config.pass_headers = NGX_CONF_UNSET_PTR;
235 conf->upstream_config.hide_headers = NGX_CONF_UNSET_PTR;
236
237 conf->upstream_config.store = NGX_CONF_UNSET;
238 conf->upstream_config.store_access = NGX_CONF_UNSET_UINT;
239 conf->upstream_config.buffering = NGX_CONF_UNSET;
240 conf->upstream_config.ignore_client_abort = NGX_CONF_UNSET;
241
242 conf->upstream_config.local = NGX_CONF_UNSET_PTR;
243
244 conf->upstream_config.connect_timeout = NGX_CONF_UNSET_MSEC;
245 conf->upstream_config.send_timeout = NGX_CONF_UNSET_MSEC;
246 conf->upstream_config.read_timeout = NGX_CONF_UNSET_MSEC;
247
248 conf->upstream_config.send_lowat = NGX_CONF_UNSET_SIZE;
249 conf->upstream_config.buffer_size = NGX_CONF_UNSET_SIZE;
250
251 conf->upstream_config.busy_buffers_size_conf = NGX_CONF_UNSET_SIZE;
252 conf->upstream_config.max_temp_file_size_conf = NGX_CONF_UNSET_SIZE;
253 conf->upstream_config.temp_file_write_size_conf = NGX_CONF_UNSET_SIZE;
254
255 conf->upstream_config.pass_request_headers = NGX_CONF_UNSET;
256 conf->upstream_config.pass_request_body = NGX_CONF_UNSET;
257
258#if (NGX_HTTP_CACHE)
259 conf->upstream_config.cache = NGX_CONF_UNSET_PTR;
260 conf->upstream_config.cache_min_uses = NGX_CONF_UNSET_UINT;
261 conf->upstream_config.cache_bypass = NGX_CONF_UNSET_PTR;
262 conf->upstream_config.no_cache = NGX_CONF_UNSET_PTR;
263 conf->upstream_config.cache_valid = NGX_CONF_UNSET_PTR;
264 #if NGINX_VERSION_NUM >= 1002000
265 conf->upstream_config.cache_lock = NGX_CONF_UNSET;
266 conf->upstream_config.cache_lock_timeout = NGX_CONF_UNSET_MSEC;
267 #endif
268#endif
269
270 conf->upstream_config.intercept_errors = NGX_CONF_UNSET;
271
272 conf->upstream_config.cyclic_temp_file = 0;
273 conf->upstream_config.change_buffering = 1;
274
275 #define DEFINE_VAR_TO_PASS(header_name, var_name) \
276 kv = ngx_array_push(conf->vars_source); \
277 kv->key.data = (u_char *) header_name; \
278 kv->key.len = strlen(header_name) + 1; \
279 kv->value.data = (u_char *) var_name; \
280 kv->value.len = strlen(var_name) + 1
281
282 conf->vars_source = ngx_array_create(cf->pool, 4, sizeof(ngx_keyval_t));
283 if (conf->vars_source == NULL) {
284 return NGX_CONF_ERROR;
285 }
286
287 DEFINE_VAR_TO_PASS("SCGI", "1");
288 DEFINE_VAR_TO_PASS("QUERY_STRING", "$query_string");
289 DEFINE_VAR_TO_PASS("REQUEST_METHOD", "$request_method");
290 DEFINE_VAR_TO_PASS("SERVER_PROTOCOL", "$server_protocol");
291 DEFINE_VAR_TO_PASS("SERVER_SOFTWARE", "nginx/$nginx_version");
292 DEFINE_VAR_TO_PASS("REMOTE_ADDR", "$remote_addr");
293 DEFINE_VAR_TO_PASS("REMOTE_PORT", "$remote_port");
294 DEFINE_VAR_TO_PASS("SERVER_ADDR", "$server_addr");
295 DEFINE_VAR_TO_PASS("SERVER_PORT", "$server_port");
296
297#if NGINX_VERSION_NUM >= 1000010
298 ngx_str_set(&conf->upstream_config.module, "passenger");
299#endif
300
301 return conf;
302}
303
304static void
305cache_loc_conf_options(ngx_conf_t *cf, passenger_loc_conf_t *conf)
306{
307 #include "CacheLocationConfig.c"
308}
309
310char *
311passenger_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
312{
313 passenger_loc_conf_t *prev = parent;
314 passenger_loc_conf_t *conf = child;
315
316 u_char *p;
317 size_t size;
318 uintptr_t *code;
319 ngx_uint_t i;
320 ngx_str_t *prev_base_uris, *base_uri;
321 ngx_str_t *prev_union_station_filters, *union_station_filter;
322 ngx_keyval_t *src;
323 ngx_hash_init_t hash;
324 ngx_http_script_compile_t sc;
325 ngx_http_script_copy_code_t *copy;
326
327 #include "MergeLocationConfig.c"
328 if (prev->options_cache.data == NULL) {
329 cache_loc_conf_options(cf, prev);
330 }
331 cache_loc_conf_options(cf, conf);
332
333 if (prev->base_uris != NGX_CONF_UNSET_PTR) {
334 if (conf->base_uris == NGX_CONF_UNSET_PTR) {
335 conf->base_uris = ngx_array_create(cf->pool, 4, sizeof(ngx_str_t));
336 if (conf->base_uris == NULL) {
337 return NGX_CONF_ERROR;
338 }
339 }
340
341 prev_base_uris = (ngx_str_t *) prev->base_uris->elts;
342 for (i = 0; i < prev->base_uris->nelts; i++) {
343 base_uri = (ngx_str_t *) ngx_array_push(conf->base_uris);
344 if (base_uri == NULL) {
345 return NGX_CONF_ERROR;
346 }
347 *base_uri = prev_base_uris[i];
348 }
349 }
350
351 if (prev->union_station_filters != NGX_CONF_UNSET_PTR) {
352 if (conf->union_station_filters == NGX_CONF_UNSET_PTR) {
353 conf->union_station_filters = ngx_array_create(cf->pool, 4, sizeof(ngx_str_t));
354 if (conf->union_station_filters == NULL) {
355 return NGX_CONF_ERROR;
356 }
357 }
358
359 prev_union_station_filters = (ngx_str_t *) prev->union_station_filters->elts;
360 for (i = 0; i < prev->union_station_filters->nelts; i++) {
361 union_station_filter = (ngx_str_t *) ngx_array_push(conf->union_station_filters);
362 if (union_station_filter == NULL) {
363 return NGX_CONF_ERROR;
364 }
365 *union_station_filter = prev_union_station_filters[i];
366 }
367 }
368
369 /******************************/
370 /******************************/
371
372 if (conf->upstream_config.store != 0) {
373 ngx_conf_merge_value(conf->upstream_config.store,
374 prev->upstream_config.store, 0);
375
376 if (conf->upstream_config.store_lengths == NULL) {
377 conf->upstream_config.store_lengths = prev->upstream_config.store_lengths;
378 conf->upstream_config.store_values = prev->upstream_config.store_values;
379 }
380 }
381
382 ngx_conf_merge_uint_value(conf->upstream_config.store_access,
383 prev->upstream_config.store_access, 0600);
384
385 ngx_conf_merge_value(conf->upstream_config.buffering,
386 prev->upstream_config.buffering, 0);
387
388 ngx_conf_merge_value(conf->upstream_config.ignore_client_abort,
389 prev->upstream_config.ignore_client_abort, 0);
390
391 ngx_conf_merge_ptr_value(conf->upstream_config.local,
392 prev->upstream_config.local, NULL);
393
394 ngx_conf_merge_msec_value(conf->upstream_config.connect_timeout,
395 prev->upstream_config.connect_timeout, 12000000);
396
397 ngx_conf_merge_msec_value(conf->upstream_config.send_timeout,
398 prev->upstream_config.send_timeout, 12000000);
399
400 ngx_conf_merge_msec_value(conf->upstream_config.read_timeout,
401 prev->upstream_config.read_timeout, 12000000);
402
403 ngx_conf_merge_size_value(conf->upstream_config.send_lowat,
404 prev->upstream_config.send_lowat, 0);
405
406 ngx_conf_merge_size_value(conf->upstream_config.buffer_size,
407 prev->upstream_config.buffer_size,
408 16 * 1024);
409
410
411 ngx_conf_merge_bufs_value(conf->upstream_config.bufs, prev->upstream_config.bufs,
412 8, 16 * 1024);
413
414 if (conf->upstream_config.bufs.num < 2) {
415 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
416 "there must be at least 2 \"passenger_buffers\"");
417 return NGX_CONF_ERROR;
418 }
419
420
421 size = conf->upstream_config.buffer_size;
422 if (size < conf->upstream_config.bufs.size) {
423 size = conf->upstream_config.bufs.size;
424 }
425
426
427 ngx_conf_merge_size_value(conf->upstream_config.busy_buffers_size_conf,
428 prev->upstream_config.busy_buffers_size_conf,
429 NGX_CONF_UNSET_SIZE);
430
431 if (conf->upstream_config.busy_buffers_size_conf == NGX_CONF_UNSET_SIZE) {
432 conf->upstream_config.busy_buffers_size = 2 * size;
433 } else {
434 conf->upstream_config.busy_buffers_size =
435 conf->upstream_config.busy_buffers_size_conf;
436 }
437
438 if (conf->upstream_config.busy_buffers_size < size) {
439 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
440 "\"passenger_busy_buffers_size\" must be equal to or greater "
441 "than the maximum of the value of \"passenger_buffer_size\" and "
442 "one of the \"passenger_buffers\"");
443
444 return NGX_CONF_ERROR;
445 }
446
447 if (conf->upstream_config.busy_buffers_size
448 > (conf->upstream_config.bufs.num - 1) * conf->upstream_config.bufs.size)
449 {
450 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
451 "\"passenger_busy_buffers_size\" must be less than "
452 "the size of all \"passenger_buffers\" minus one buffer");
453
454 return NGX_CONF_ERROR;
455 }
456
457
458 ngx_conf_merge_size_value(conf->upstream_config.temp_file_write_size_conf,
459 prev->upstream_config.temp_file_write_size_conf,
460 NGX_CONF_UNSET_SIZE);
461
462 if (conf->upstream_config.temp_file_write_size_conf == NGX_CONF_UNSET_SIZE) {
463 conf->upstream_config.temp_file_write_size = 2 * size;
464 } else {
465 conf->upstream_config.temp_file_write_size =
466 conf->upstream_config.temp_file_write_size_conf;
467 }
468
469 if (conf->upstream_config.temp_file_write_size < size) {
470 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
471 "\"passenger_temp_file_write_size\" must be equal to or greater than "
472 "the maximum of the value of \"passenger_buffer_size\" and "
473 "one of the \"passenger_buffers\"");
474
475 return NGX_CONF_ERROR;
476 }
477
478
479 ngx_conf_merge_size_value(conf->upstream_config.max_temp_file_size_conf,
480 prev->upstream_config.max_temp_file_size_conf,
481 NGX_CONF_UNSET_SIZE);
482
483 if (conf->upstream_config.max_temp_file_size_conf == NGX_CONF_UNSET_SIZE) {
484 conf->upstream_config.max_temp_file_size = 1024 * 1024 * 1024;
485 } else {
486 conf->upstream_config.max_temp_file_size =
487 conf->upstream_config.max_temp_file_size_conf;
488 }
489
490 if (conf->upstream_config.max_temp_file_size != 0
491 && conf->upstream_config.max_temp_file_size < size)
492 {
493 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
494 "\"passenger_max_temp_file_size\" must be equal to zero to disable "
495 "temporary files usage or must be equal to or greater than "
496 "the maximum of the value of \"passenger_buffer_size\" and "
497 "one of the \"passenger_buffers\"");
498
499 return NGX_CONF_ERROR;
500 }
501
502 ngx_conf_merge_bitmask_value(conf->upstream_config.ignore_headers,
503 prev->upstream_config.ignore_headers,
504 NGX_CONF_BITMASK_SET);
505
506 ngx_conf_merge_bitmask_value(conf->upstream_config.next_upstream,
507 prev->upstream_config.next_upstream,
508 (NGX_CONF_BITMASK_SET
509 |NGX_HTTP_UPSTREAM_FT_ERROR
510 |NGX_HTTP_UPSTREAM_FT_TIMEOUT));
511
512 if (conf->upstream_config.next_upstream & NGX_HTTP_UPSTREAM_FT_OFF) {
513 conf->upstream_config.next_upstream = NGX_CONF_BITMASK_SET
514 |NGX_HTTP_UPSTREAM_FT_OFF;
515 }
516
517 ngx_conf_merge_path_value(cf,
518 &conf->upstream_config.temp_path,
519 prev->upstream_config.temp_path,
520 &ngx_http_proxy_temp_path);
521
522#if (NGX_HTTP_CACHE)
523
524 ngx_conf_merge_ptr_value(conf->upstream_config.cache,
525 prev->upstream_config.cache, NULL);
526
527 if (conf->upstream_config.cache && conf->upstream_config.cache->data == NULL) {
528 ngx_shm_zone_t *shm_zone;
529
530 shm_zone = conf->upstream_config.cache;
531
532 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
533 "\"scgi_cache\" zone \"%V\" is unknown",
534 &shm_zone->shm.name);
535
536 return NGX_CONF_ERROR;
537 }
538
539 ngx_conf_merge_uint_value(conf->upstream_config.cache_min_uses,
540 prev->upstream_config.cache_min_uses, 1);
541
542 ngx_conf_merge_bitmask_value(conf->upstream_config.cache_use_stale,
543 prev->upstream_config.cache_use_stale,
544 (NGX_CONF_BITMASK_SET
545 | NGX_HTTP_UPSTREAM_FT_OFF));
546
547 if (conf->upstream_config.cache_use_stale & NGX_HTTP_UPSTREAM_FT_OFF) {
548 conf->upstream_config.cache_use_stale = NGX_CONF_BITMASK_SET
549 | NGX_HTTP_UPSTREAM_FT_OFF;
550 }
551
552 if (conf->upstream_config.cache_use_stale & NGX_HTTP_UPSTREAM_FT_ERROR) {
553 conf->upstream_config.cache_use_stale |= NGX_HTTP_UPSTREAM_FT_NOLIVE;
554 }
555
556 if (conf->upstream_config.cache_methods == 0) {
557 conf->upstream_config.cache_methods = prev->upstream_config.cache_methods;
558 }
559
560 conf->upstream_config.cache_methods |= NGX_HTTP_GET | NGX_HTTP_HEAD;
561
562 ngx_conf_merge_ptr_value(conf->upstream_config.cache_bypass,
563 prev->upstream_config.cache_bypass, NULL);
564
565 ngx_conf_merge_ptr_value(conf->upstream_config.no_cache,
566 prev->upstream_config.no_cache, NULL);
567
568 ngx_conf_merge_ptr_value(conf->upstream_config.cache_valid,
569 prev->upstream_config.cache_valid, NULL);
570
571 if (conf->cache_key.value.data == NULL) {
572 conf->cache_key = prev->cache_key;
573 }
574
575 #if NGINX_VERSION_NUM >= 1002000
576 ngx_conf_merge_value(conf->upstream_config.cache_lock,
577 prev->upstream_config.cache_lock, 0);
578
579 ngx_conf_merge_msec_value(conf->upstream_config.cache_lock_timeout,
580 prev->upstream_config.cache_lock_timeout, 5000);
581 #endif
582
583#endif
584
585 ngx_conf_merge_value(conf->upstream_config.pass_request_headers,
586 prev->upstream_config.pass_request_headers, 1);
587 ngx_conf_merge_value(conf->upstream_config.pass_request_body,
588 prev->upstream_config.pass_request_body, 1);
589
590 ngx_conf_merge_value(conf->upstream_config.intercept_errors,
591 prev->upstream_config.intercept_errors, 0);
592
593
594 hash.max_size = 512;
595 hash.bucket_size = ngx_align(64, ngx_cacheline_size);
596 hash.name = "passenger_hide_headers_hash";
597
598 if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream_config,
599 &prev->upstream_config, headers_to_hide, &hash)
600 != NGX_OK)
601 {
602 return NGX_CONF_ERROR;
603 }
604
605 if (conf->upstream_config.upstream == NULL) {
606 conf->upstream_config.upstream = prev->upstream_config.upstream;
607 }
608
609 if (conf->vars_source == NULL) {
610 conf->flushes = prev->flushes;
611 conf->vars_len = prev->vars_len;
612 conf->vars = prev->vars;
613 conf->vars_source = prev->vars_source;
614
615 if (conf->vars_source == NULL) {
616 return NGX_CONF_OK;
617 }
618 }
619
620 conf->vars_len = ngx_array_create(cf->pool, 64, 1);
621 if (conf->vars_len == NULL) {
622 return NGX_CONF_ERROR;
623 }
624
625 conf->vars = ngx_array_create(cf->pool, 512, 1);
626 if (conf->vars == NULL) {
627 return NGX_CONF_ERROR;
628 }
629
630 src = conf->vars_source->elts;
631 for (i = 0; i < conf->vars_source->nelts; i++) {
632
633 if (ngx_http_script_variables_count(&src[i].value) == 0) {
634 copy = ngx_array_push_n(conf->vars_len,
635 sizeof(ngx_http_script_copy_code_t));
636 if (copy == NULL) {
637 return NGX_CONF_ERROR;
638 }
639
640 copy->code = (ngx_http_script_code_pt)
641 ngx_http_script_copy_len_code;
642 copy->len = src[i].key.len;
643
644
645 copy = ngx_array_push_n(conf->vars_len,
646 sizeof(ngx_http_script_copy_code_t));
647 if (copy == NULL) {
648 return NGX_CONF_ERROR;
649 }
650
651 copy->code = (ngx_http_script_code_pt)
652 ngx_http_script_copy_len_code;
653 copy->len = src[i].value.len;
654
655
656 size = (sizeof(ngx_http_script_copy_code_t)
657 + src[i].key.len + src[i].value.len
658 + sizeof(uintptr_t) - 1)
659 & ~(sizeof(uintptr_t) - 1);
660
661 copy = ngx_array_push_n(conf->vars, size);
662 if (copy == NULL) {
663 return NGX_CONF_ERROR;
664 }
665
666 copy->code = ngx_http_script_copy_code;
667 copy->len = src[i].key.len + src[i].value.len;
668
669 p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t);
670
671 p = ngx_cpymem(p, src[i].key.data, src[i].key.len);
672 ngx_memcpy(p, src[i].value.data, src[i].value.len);
673
674 } else {
675 copy = ngx_array_push_n(conf->vars_len,
676 sizeof(ngx_http_script_copy_code_t));
677 if (copy == NULL) {
678 return NGX_CONF_ERROR;
679 }
680
681 copy->code = (ngx_http_script_code_pt)
682 ngx_http_script_copy_len_code;
683 copy->len = src[i].key.len;
684
685
686 size = (sizeof(ngx_http_script_copy_code_t)
687 + src[i].key.len + sizeof(uintptr_t) - 1)
688 & ~(sizeof(uintptr_t) - 1);
689
690 copy = ngx_array_push_n(conf->vars, size);
691 if (copy == NULL) {
692 return NGX_CONF_ERROR;
693 }
694
695 copy->code = ngx_http_script_copy_code;
696 copy->len = src[i].key.len;
697
698 p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t);
699 ngx_memcpy(p, src[i].key.data, src[i].key.len);
700
701
702 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
703
704 sc.cf = cf;
705 sc.source = &src[i].value;
706 sc.flushes = &conf->flushes;
707 sc.lengths = &conf->vars_len;
708 sc.values = &conf->vars;
709
710 if (ngx_http_script_compile(&sc) != NGX_OK) {
711 return NGX_CONF_ERROR;
712 }
713 }
714
715 code = ngx_array_push_n(conf->vars_len, sizeof(uintptr_t));
716 if (code == NULL) {
717 return NGX_CONF_ERROR;
718 }
719
720 *code = (uintptr_t) NULL;
721
722
723 code = ngx_array_push_n(conf->vars, sizeof(uintptr_t));
724 if (code == NULL) {
725 return NGX_CONF_ERROR;
726 }
727
728 *code = (uintptr_t) NULL;
729 }
730
731 code = ngx_array_push_n(conf->vars_len, sizeof(uintptr_t));
732 if (code == NULL) {
733 return NGX_CONF_ERROR;
734 }
735
736 *code = (uintptr_t) NULL;
737
738 return NGX_CONF_OK;
739}
740
741#ifndef PASSENGER_IS_ENTERPRISE
742static char *
743passenger_enterprise_only(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) {
744 return ": this feature is only available in Phusion Passenger Enterprise. "
745 "You are currently running the open source Phusion Passenger Enterprise. "
746 "Please learn more about and/or buy Phusion Passenger Enterprise at https://www.phusionpassenger.com/enterprise ;";
747}
748#endif
749
750static char *
751passenger_enabled(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
752{
753 passenger_loc_conf_t *passenger_conf = conf;
754 ngx_http_core_loc_conf_t *clcf;
755 ngx_str_t *value;
756 ngx_url_t upstream_url;
757
758 value = cf->args->elts;
759 if (ngx_strcasecmp(value[1].data, (u_char *) "on") == 0) {
760 passenger_conf->enabled = 1;
761
762 /* Register a placeholder value as upstream address. The real upstream
763 * address (the helper agent socket filename) will be set while processing
764 * requests, because we can't start the helper agent until config
765 * loading is done.
766 */
767 ngx_memzero(&upstream_url, sizeof(ngx_url_t));
768 upstream_url.url = pp_placeholder_upstream_address;
769 upstream_url.no_resolve = 1;
770 passenger_conf->upstream_config.upstream = ngx_http_upstream_add(cf, &upstream_url, 0);
771 if (passenger_conf->upstream_config.upstream == NULL) {
772 return NGX_CONF_ERROR;
773 }
774
775 clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
776 clcf->handler = passenger_content_handler;
777
778 if (clcf->name.data != NULL
779 && clcf->name.data[clcf->name.len - 1] == '/') {
780 clcf->auto_redirect = 1;
781 }
782 } else if (ngx_strcasecmp(value[1].data, (u_char *) "off") == 0) {
783 passenger_conf->enabled = 0;
784 } else {
785 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
786 "\"passenger_enabled\" must be either set to \"on\" "
787 "or \"off\"");
788
789 return NGX_CONF_ERROR;
790 }
791
792 return NGX_CONF_OK;
793}
794
795char *
796union_station_filter(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
797{
798 char *p = conf;
799
800 ngx_str_t *value, *s;
801 ngx_array_t **a;
802 ngx_conf_post_t *post;
803 char *message;
804
805 a = (ngx_array_t **) (p + cmd->offset);
806
807 if (*a == NGX_CONF_UNSET_PTR) {
808 *a = ngx_array_create(cf->pool, 4, sizeof(ngx_str_t));
809 if (*a == NULL) {
810 return NGX_CONF_ERROR;
811 }
812 }
813
814 s = ngx_array_push(*a);
815 if (s == NULL) {
816 return NGX_CONF_ERROR;
817 }
818
819 value = cf->args->elts;
820
821 *s = value[1];
822
823 if (cmd->post) {
824 post = cmd->post;
825 return post->post_handler(cf, post, s);
826 }
827
828 message = passenger_filter_validate((const char *) value[1].data, value[1].len);
829 if (message != NULL) {
830 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
831 "Union Station filter syntax error: %s; ",
832 message);
833 free(message);
834 return NGX_CONF_ERROR;
835 }
836
837 return NGX_CONF_OK;
838}
839
840static char *
841rails_framework_spawner_idle_time(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
842{
843 ngx_conf_log_error(NGX_LOG_ALERT, cf, 0, "The 'rails_framework_spawner_idle_time' "
844 "directive is deprecated; please set 'passenger_max_preloader_idle_time' instead");
845 return NGX_CONF_OK;
846}
847
848static char *
849passenger_use_global_queue(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
850{
851 ngx_conf_log_error(NGX_LOG_ALERT, cf, 0, "The 'passenger_use_global_queue' "
852 "directive is obsolete and doesn't do anything anymore. Global queuing "
853 "is now always enabled. Please remove this configuration directive.");
854 return NGX_CONF_OK;
855}
856
857static char *
858set_null_terminated_keyval_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
859{
860 char *p = conf;
861
862 ngx_str_t *value;
863 ngx_array_t **a;
864 ngx_keyval_t *kv;
865 ngx_conf_post_t *post;
866 u_char *last;
867
868 a = (ngx_array_t **) (p + cmd->offset);
869
870 if (*a == NULL) {
871 *a = ngx_array_create(cf->pool, 4, sizeof(ngx_keyval_t));
872 if (*a == NULL) {
873 return NGX_CONF_ERROR;
874 }
875 }
876
877 kv = ngx_array_push(*a);
878 if (kv == NULL) {
879 return NGX_CONF_ERROR;
880 }
881
882 value = cf->args->elts;
883
884 kv->key.data = ngx_palloc(cf->pool, value[1].len + 1);
885 kv->key.len = value[1].len + 1;
886 last = ngx_copy(kv->key.data, value[1].data, value[1].len);
887 *last = '\0';
888
889 kv->value.data = ngx_palloc(cf->pool, value[2].len + 1);
890 kv->value.len = value[2].len + 1;
891 last = ngx_copy(kv->value.data, value[2].data, value[2].len);
892 *last = '\0';
893
894 if (cmd->post) {
895 post = cmd->post;
896 return post->post_handler(cf, post, kv);
897 }
898
899 return NGX_CONF_OK;
900}
901
902
903const ngx_command_t passenger_commands[] = {
904
905 /******** Main config ********/
906
907 { ngx_string("passenger_root"),
908 NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
909 ngx_conf_set_str_slot,
910 NGX_HTTP_MAIN_CONF_OFFSET,
911 offsetof(passenger_main_conf_t, root_dir),
912 NULL },
913
914 { ngx_string("passenger_ctl"),
915 NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE2,
916 set_null_terminated_keyval_slot,
917 NGX_HTTP_MAIN_CONF_OFFSET,
918 offsetof(passenger_main_conf_t, ctl),
919 NULL },
920
921 { ngx_string("passenger_ruby"),
922 NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
923 ngx_conf_set_str_slot,
924 NGX_HTTP_MAIN_CONF_OFFSET,
925 offsetof(passenger_main_conf_t, default_ruby),
926 NULL },
927
928 { ngx_string("passenger_log_level"),
929 NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
930 ngx_conf_set_num_slot,
931 NGX_HTTP_MAIN_CONF_OFFSET,
932 offsetof(passenger_main_conf_t, log_level),
933 NULL },
934
935 { ngx_string("passenger_debug_log_file"),
936 NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
937 ngx_conf_set_str_slot,
938 NGX_HTTP_MAIN_CONF_OFFSET,
939 offsetof(passenger_main_conf_t, debug_log_file),
940 NULL },
941
942 { ngx_string("passenger_temp_dir"),
943 NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
944 ngx_conf_set_str_slot,
945 NGX_HTTP_MAIN_CONF_OFFSET,
946 offsetof(passenger_main_conf_t, temp_dir),
947 NULL },
948
949 { ngx_string("passenger_pre_start"),
950 NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
951 ngx_conf_set_str_array_slot,
952 NGX_HTTP_MAIN_CONF_OFFSET,
953 offsetof(passenger_main_conf_t, prestart_uris),
954 NULL },
955
956 { ngx_string("passenger_abort_on_startup_error"),
957 NGX_HTTP_MAIN_CONF | NGX_CONF_FLAG,
958 ngx_conf_set_flag_slot,
959 NGX_HTTP_MAIN_CONF_OFFSET,
960 offsetof(passenger_main_conf_t, abort_on_startup_error),
961 NULL },
962
963 { ngx_string("passenger_max_pool_size"),
964 NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
965 ngx_conf_set_num_slot,
966 NGX_HTTP_MAIN_CONF_OFFSET,
967 offsetof(passenger_main_conf_t, max_pool_size),
968 NULL },
969
970 { ngx_string("passenger_pool_idle_time"),
971 NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
972 ngx_conf_set_num_slot,
973 NGX_HTTP_MAIN_CONF_OFFSET,
974 offsetof(passenger_main_conf_t, pool_idle_time),
975 NULL },
976
977 { ngx_string("passenger_user_switching"),
978 NGX_HTTP_MAIN_CONF | NGX_CONF_FLAG,
979 ngx_conf_set_flag_slot,
980 NGX_HTTP_MAIN_CONF_OFFSET,
981 offsetof(passenger_main_conf_t, user_switching),
982 NULL },
983
984 { ngx_string("passenger_default_user"),
985 NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
986 ngx_conf_set_str_slot,
987 NGX_HTTP_MAIN_CONF_OFFSET,
988 offsetof(passenger_main_conf_t, default_user),
989 NULL },
990
991 { ngx_string("passenger_default_group"),
992 NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
993 ngx_conf_set_str_slot,
994 NGX_HTTP_MAIN_CONF_OFFSET,
995 offsetof(passenger_main_conf_t, default_group),
996 NULL },
997
998 { ngx_string("passenger_analytics_log_user"),
999 NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
1000 ngx_conf_set_str_slot,
1001 NGX_HTTP_MAIN_CONF_OFFSET,
1002 offsetof(passenger_main_conf_t, analytics_log_user),
1003 NULL },
1004
1005 { ngx_string("passenger_analytics_log_group"),
1006 NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
1007 ngx_conf_set_str_slot,
1008 NGX_HTTP_MAIN_CONF_OFFSET,
1009 offsetof(passenger_main_conf_t, analytics_log_group),
1010 NULL },
1011
1012 { ngx_string("union_station_gateway_address"),
1013 NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
1014 ngx_conf_set_str_slot,
1015 NGX_HTTP_MAIN_CONF_OFFSET,
1016 offsetof(passenger_main_conf_t, union_station_gateway_address),
1017 NULL },
1018
1019 { ngx_string("union_station_gateway_port"),
1020 NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
1021 ngx_conf_set_num_slot,
1022 NGX_HTTP_MAIN_CONF_OFFSET,
1023 offsetof(passenger_main_conf_t, union_station_gateway_port),
1024 NULL },
1025
1026 { ngx_string("union_station_gateway_cert"),
1027 NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
1028 ngx_conf_set_str_slot,
1029 NGX_HTTP_MAIN_CONF_OFFSET,
1030 offsetof(passenger_main_conf_t, union_station_gateway_cert),
1031 NULL },
1032
1033 { ngx_string("union_station_proxy_address"),
1034 NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
1035 ngx_conf_set_str_slot,
1036 NGX_HTTP_MAIN_CONF_OFFSET,
1037 offsetof(passenger_main_conf_t, union_station_proxy_address),
1038 NULL },
1039
1040 /******** Per-location config ********/
1041
1042 #include "ConfigurationCommands.c"
1043
1044 ngx_null_command
1045};