~ubuntu-branches/debian/squeeze/nginx/squeeze

« back to all changes in this revision

Viewing changes to src/http/ngx_http.c

  • Committer: Bazaar Package Importer
  • Author(s): Fabio Tranchitella
  • Date: 2009-05-31 18:38:56 UTC
  • mfrom: (1.1.10 upstream) (4.1.12 experimental)
  • Revision ID: james.westby@ubuntu.com-20090531183856-3xhvf6wd0bw5556i
Tags: 0.7.59-1
* New upstream release, first in Debian for the 0.7 branch. Among other
  issues, it also fixes the problem with wildcard dns names used with SSL.
  (Closes: #515904)
* debian/watch: updated.
* debian/postinst: fixed a bashism. (Closes: #507913)
* debian/conf/nginx.conf: removed default_type. (Closes: #509390)
* debian/control: updated Standards-Version to 3.8.1, no changes needed.
* debian/NEWS.Debian: documented the issues with
  server_names_hash_bucket_size. (Closes: #524785)

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
 
7
7
#include <ngx_config.h>
8
8
#include <ngx_core.h>
9
 
#include <ngx_event.h>
10
9
#include <ngx_http.h>
11
10
 
12
11
 
13
12
static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
 
13
static ngx_int_t ngx_http_init_phases(ngx_conf_t *cf,
 
14
    ngx_http_core_main_conf_t *cmcf);
 
15
static ngx_int_t ngx_http_init_headers_in_hash(ngx_conf_t *cf,
 
16
    ngx_http_core_main_conf_t *cmcf);
 
17
static ngx_int_t ngx_http_init_phase_handlers(ngx_conf_t *cf,
 
18
    ngx_http_core_main_conf_t *cmcf);
 
19
 
 
20
static ngx_int_t ngx_http_init_server_lists(ngx_conf_t *cf,
 
21
    ngx_array_t *servers, ngx_array_t *ports);
 
22
static ngx_int_t ngx_http_add_ports(ngx_conf_t *cf,
 
23
    ngx_http_core_srv_conf_t *cscf, ngx_array_t *ports,
 
24
    ngx_http_listen_t *listen);
 
25
static ngx_int_t ngx_http_add_addresses(ngx_conf_t *cf,
 
26
    ngx_http_core_srv_conf_t *cscf, ngx_http_conf_port_t *port,
 
27
    ngx_http_listen_t *listen);
14
28
static ngx_int_t ngx_http_add_address(ngx_conf_t *cf,
15
 
    ngx_http_conf_in_port_t *in_port, ngx_http_listen_t *lscf,
16
 
    ngx_http_core_srv_conf_t *cscf);
 
29
    ngx_http_core_srv_conf_t *cscf, ngx_http_conf_port_t *port,
 
30
    ngx_http_listen_t *listen);
17
31
static ngx_int_t ngx_http_add_names(ngx_conf_t *cf,
18
 
    ngx_http_conf_in_addr_t *in_addr, ngx_http_core_srv_conf_t *cscf);
 
32
    ngx_http_core_srv_conf_t *cscf, ngx_http_conf_addr_t *addr);
 
33
 
19
34
static char *ngx_http_merge_locations(ngx_conf_t *cf,
20
 
    ngx_array_t *locations, void **loc_conf, ngx_http_module_t *module,
 
35
    ngx_queue_t *locations, void **loc_conf, ngx_http_module_t *module,
21
36
    ngx_uint_t ctx_index);
22
 
static ngx_int_t ngx_http_cmp_conf_in_addrs(const void *one, const void *two);
 
37
static ngx_int_t ngx_http_init_locations(ngx_conf_t *cf,
 
38
    ngx_http_core_srv_conf_t *cscf, ngx_http_core_loc_conf_t *pclcf);
 
39
static ngx_int_t ngx_http_init_static_location_trees(ngx_conf_t *cf,
 
40
    ngx_http_core_loc_conf_t *pclcf);
 
41
static ngx_int_t ngx_http_cmp_locations(const ngx_queue_t *one,
 
42
    const ngx_queue_t *two);
 
43
static ngx_int_t ngx_http_join_exact_locations(ngx_conf_t *cf,
 
44
    ngx_queue_t *locations);
 
45
static void ngx_http_create_locations_list(ngx_queue_t *locations,
 
46
    ngx_queue_t *q);
 
47
static ngx_http_location_tree_node_t *
 
48
    ngx_http_create_locations_tree(ngx_conf_t *cf, ngx_queue_t *locations,
 
49
    size_t prefix);
 
50
 
 
51
static ngx_int_t ngx_http_optimize_servers(ngx_conf_t *cf,
 
52
    ngx_http_core_main_conf_t *cmcf, ngx_array_t *ports);
 
53
static ngx_int_t ngx_http_server_names(ngx_conf_t *cf,
 
54
    ngx_http_core_main_conf_t *cmcf, ngx_http_conf_addr_t *addr);
 
55
static ngx_int_t ngx_http_cmp_conf_addrs(const void *one, const void *two);
23
56
static int ngx_libc_cdecl ngx_http_cmp_dns_wildcards(const void *one,
24
57
    const void *two);
25
58
 
 
59
static ngx_int_t ngx_http_init_listening(ngx_conf_t *cf,
 
60
    ngx_http_conf_port_t *port);
 
61
static ngx_listening_t *ngx_http_add_listening(ngx_conf_t *cf,
 
62
    ngx_http_conf_addr_t *addr);
 
63
static ngx_int_t ngx_http_add_addrs(ngx_conf_t *cf, ngx_http_port_t *hport,
 
64
    ngx_http_conf_addr_t *addr);
 
65
#if (NGX_HAVE_INET6)
 
66
static ngx_int_t ngx_http_add_addrs6(ngx_conf_t *cf, ngx_http_port_t *hport,
 
67
    ngx_http_conf_addr_t *addr);
 
68
#endif
 
69
 
26
70
ngx_uint_t   ngx_http_max_module;
27
71
 
28
 
ngx_uint_t   ngx_http_total_requests;
29
 
uint64_t     ngx_http_total_sent;
30
 
 
31
72
 
32
73
ngx_int_t  (*ngx_http_top_header_filter) (ngx_http_request_t *r);
33
74
ngx_int_t  (*ngx_http_top_body_filter) (ngx_http_request_t *r, ngx_chain_t *ch);
34
75
 
35
76
 
 
77
ngx_str_t  ngx_http_html_default_types[] = {
 
78
    ngx_string("text/html"),
 
79
    ngx_null_string
 
80
};
 
81
 
 
82
 
36
83
static ngx_command_t  ngx_http_commands[] = {
37
84
 
38
85
    { ngx_string("http"),
73
120
ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
74
121
{
75
122
    char                        *rv;
76
 
    ngx_int_t                    rc, j;
77
 
    ngx_uint_t                   mi, m, s, l, p, a, i, n;
78
 
    ngx_uint_t                   find_config_index, use_rewrite, use_access;
79
 
    ngx_uint_t                   last, bind_all, done;
 
123
    ngx_uint_t                   mi, m, s;
80
124
    ngx_conf_t                   pcf;
81
 
    ngx_array_t                  headers_in, in_ports;
82
 
    ngx_hash_key_t              *hk;
83
 
    ngx_hash_init_t              hash;
84
 
    ngx_listening_t             *ls;
85
 
    ngx_http_listen_t           *lscf;
 
125
    ngx_array_t                  ports;
86
126
    ngx_http_module_t           *module;
87
 
    ngx_http_header_t           *header;
88
 
    ngx_http_in_port_t          *hip;
89
 
    ngx_http_handler_pt         *h;
90
127
    ngx_http_conf_ctx_t         *ctx;
91
 
    ngx_http_conf_in_port_t     *in_port;
92
 
    ngx_http_conf_in_addr_t     *in_addr;
93
 
    ngx_hash_keys_arrays_t       ha;
94
 
    ngx_http_server_name_t      *name;
95
 
    ngx_http_phase_handler_t    *ph;
96
 
    ngx_http_virtual_names_t    *vn;
97
 
    ngx_http_core_srv_conf_t   **cscfp, *cscf;
98
128
    ngx_http_core_loc_conf_t    *clcf;
99
 
    ngx_http_phase_handler_pt    checker;
 
129
    ngx_http_core_srv_conf_t   **cscfp;
100
130
    ngx_http_core_main_conf_t   *cmcf;
101
 
#if (NGX_PCRE)
102
 
    ngx_uint_t                   regex;
103
 
#endif
104
131
 
105
132
    /* the main http context */
106
133
 
199
226
        }
200
227
 
201
228
        module = ngx_modules[m]->ctx;
202
 
        mi = ngx_modules[m]->ctx_index;
203
229
 
204
230
        if (module->preconfiguration) {
205
231
            if (module->preconfiguration(cf) != NGX_OK) {
215
241
    rv = ngx_conf_parse(cf, NULL);
216
242
 
217
243
    if (rv != NGX_CONF_OK) {
218
 
        *cf = pcf;
219
 
        return rv;
 
244
        goto failed;
220
245
    }
221
246
 
222
247
    /*
240
265
        if (module->init_main_conf) {
241
266
            rv = module->init_main_conf(cf, ctx->main_conf[mi]);
242
267
            if (rv != NGX_CONF_OK) {
243
 
                *cf = pcf;
244
 
                return rv;
 
268
                goto failed;
245
269
            }
246
270
        }
247
271
 
250
274
            /* merge the server{}s' srv_conf's */
251
275
 
252
276
            if (module->merge_srv_conf) {
253
 
                rv = module->merge_srv_conf(cf,
254
 
                                            ctx->srv_conf[mi],
 
277
                rv = module->merge_srv_conf(cf, ctx->srv_conf[mi],
255
278
                                            cscfp[s]->ctx->srv_conf[mi]);
256
279
                if (rv != NGX_CONF_OK) {
257
 
                    *cf = pcf;
258
 
                    return rv;
 
280
                    goto failed;
259
281
                }
260
282
            }
261
283
 
263
285
 
264
286
                /* merge the server{}'s loc_conf */
265
287
 
266
 
                rv = module->merge_loc_conf(cf,
267
 
                                            ctx->loc_conf[mi],
 
288
                rv = module->merge_loc_conf(cf, ctx->loc_conf[mi],
268
289
                                            cscfp[s]->ctx->loc_conf[mi]);
269
290
                if (rv != NGX_CONF_OK) {
270
 
                    *cf = pcf;
271
 
                    return rv;
 
291
                    goto failed;
272
292
                }
273
293
 
274
294
                /* merge the locations{}' loc_conf's */
275
295
 
276
 
                rv = ngx_http_merge_locations(cf, &cscfp[s]->locations,
 
296
                clcf = cscfp[s]->ctx->loc_conf[ngx_http_core_module.ctx_index];
 
297
 
 
298
                rv = ngx_http_merge_locations(cf, clcf->locations,
277
299
                                              cscfp[s]->ctx->loc_conf,
278
300
                                              module, mi);
279
301
                if (rv != NGX_CONF_OK) {
280
 
                    *cf = pcf;
281
 
                    return rv;
 
302
                    goto failed;
282
303
                }
283
304
            }
284
305
        }
285
306
    }
286
307
 
287
308
 
288
 
    /* init lists of the handlers */
289
 
 
 
309
    /* create location trees */
 
310
 
 
311
    for (s = 0; s < cmcf->servers.nelts; s++) {
 
312
 
 
313
        clcf = cscfp[s]->ctx->loc_conf[ngx_http_core_module.ctx_index];
 
314
 
 
315
        if (ngx_http_init_locations(cf, cscfp[s], clcf) != NGX_OK) {
 
316
            return NGX_CONF_ERROR;
 
317
        }
 
318
 
 
319
        if (ngx_http_init_static_location_trees(cf, clcf) != NGX_OK) {
 
320
            return NGX_CONF_ERROR;
 
321
        }
 
322
    }
 
323
 
 
324
 
 
325
    if (ngx_http_init_phases(cf, cmcf) != NGX_OK) {
 
326
        return NGX_CONF_ERROR;
 
327
    }
 
328
 
 
329
    if (ngx_http_init_headers_in_hash(cf, cmcf) != NGX_OK) {
 
330
        return NGX_CONF_ERROR;
 
331
    }
 
332
 
 
333
 
 
334
    for (m = 0; ngx_modules[m]; m++) {
 
335
        if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
 
336
            continue;
 
337
        }
 
338
 
 
339
        module = ngx_modules[m]->ctx;
 
340
 
 
341
        if (module->postconfiguration) {
 
342
            if (module->postconfiguration(cf) != NGX_OK) {
 
343
                return NGX_CONF_ERROR;
 
344
            }
 
345
        }
 
346
    }
 
347
 
 
348
    if (ngx_http_variables_init_vars(cf) != NGX_OK) {
 
349
        return NGX_CONF_ERROR;
 
350
    }
 
351
 
 
352
    /*
 
353
     * http{}'s cf->ctx was needed while the configuration merging
 
354
     * and in postconfiguration process
 
355
     */
 
356
 
 
357
    *cf = pcf;
 
358
 
 
359
 
 
360
    if (ngx_http_init_phase_handlers(cf, cmcf) != NGX_OK) {
 
361
        return NGX_CONF_ERROR;
 
362
    }
 
363
 
 
364
 
 
365
    /*
 
366
     * create the lists of ports, addresses and server names
 
367
     * to find quickly the server core module configuration at run-time
 
368
     */
 
369
 
 
370
    if (ngx_http_init_server_lists(cf, &cmcf->servers, &ports) != NGX_OK) {
 
371
        return NGX_CONF_ERROR;
 
372
    }
 
373
 
 
374
 
 
375
    /* optimize the lists of ports, addresses and server names */
 
376
 
 
377
    if (ngx_http_optimize_servers(cf, cmcf, &ports) != NGX_OK) {
 
378
        return NGX_CONF_ERROR;
 
379
    }
 
380
 
 
381
    return NGX_CONF_OK;
 
382
 
 
383
failed:
 
384
 
 
385
    *cf = pcf;
 
386
 
 
387
    return rv;
 
388
}
 
389
 
 
390
 
 
391
static ngx_int_t
 
392
ngx_http_init_phases(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf)
 
393
{
290
394
    if (ngx_array_init(&cmcf->phases[NGX_HTTP_POST_READ_PHASE].handlers,
291
395
                       cf->pool, 1, sizeof(ngx_http_handler_pt))
292
396
        != NGX_OK)
293
397
    {
294
 
        return NGX_CONF_ERROR;
 
398
        return NGX_ERROR;
295
399
    }
296
400
 
297
 
 
298
401
    if (ngx_array_init(&cmcf->phases[NGX_HTTP_SERVER_REWRITE_PHASE].handlers,
299
402
                       cf->pool, 1, sizeof(ngx_http_handler_pt))
300
403
        != NGX_OK)
301
404
    {
302
 
        return NGX_CONF_ERROR;
 
405
        return NGX_ERROR;
303
406
    }
304
407
 
305
 
 
306
408
    if (ngx_array_init(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers,
307
409
                       cf->pool, 1, sizeof(ngx_http_handler_pt))
308
410
        != NGX_OK)
309
411
    {
310
 
        return NGX_CONF_ERROR;
 
412
        return NGX_ERROR;
311
413
    }
312
414
 
313
 
 
314
415
    if (ngx_array_init(&cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers,
315
416
                       cf->pool, 1, sizeof(ngx_http_handler_pt))
316
417
        != NGX_OK)
317
418
    {
318
 
        return NGX_CONF_ERROR;
 
419
        return NGX_ERROR;
319
420
    }
320
421
 
321
 
 
322
422
    if (ngx_array_init(&cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers,
323
423
                       cf->pool, 2, sizeof(ngx_http_handler_pt))
324
424
        != NGX_OK)
325
425
    {
326
 
        return NGX_CONF_ERROR;
 
426
        return NGX_ERROR;
327
427
    }
328
428
 
329
 
 
330
429
    if (ngx_array_init(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers,
331
430
                       cf->pool, 4, sizeof(ngx_http_handler_pt))
332
431
        != NGX_OK)
333
432
    {
334
 
        return NGX_CONF_ERROR;
 
433
        return NGX_ERROR;
335
434
    }
336
435
 
337
 
 
338
436
    if (ngx_array_init(&cmcf->phases[NGX_HTTP_LOG_PHASE].handlers,
339
437
                       cf->pool, 1, sizeof(ngx_http_handler_pt))
340
438
        != NGX_OK)
341
439
    {
342
 
        return NGX_CONF_ERROR;
 
440
        return NGX_ERROR;
343
441
    }
344
442
 
 
443
    return NGX_OK;
 
444
}
 
445
 
 
446
 
 
447
static ngx_int_t
 
448
ngx_http_init_headers_in_hash(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf)
 
449
{
 
450
    ngx_array_t         headers_in;
 
451
    ngx_hash_key_t     *hk;
 
452
    ngx_hash_init_t     hash;
 
453
    ngx_http_header_t  *header;
345
454
 
346
455
    if (ngx_array_init(&headers_in, cf->temp_pool, 32, sizeof(ngx_hash_key_t))
347
456
        != NGX_OK)
348
457
    {
349
 
        return NGX_CONF_ERROR;
 
458
        return NGX_ERROR;
350
459
    }
351
460
 
352
461
    for (header = ngx_http_headers_in; header->name.len; header++) {
353
462
        hk = ngx_array_push(&headers_in);
354
463
        if (hk == NULL) {
355
 
            return NGX_CONF_ERROR;
 
464
            return NGX_ERROR;
356
465
        }
357
466
 
358
467
        hk->key = header->name;
369
478
    hash.temp_pool = NULL;
370
479
 
371
480
    if (ngx_hash_init(&hash, headers_in.elts, headers_in.nelts) != NGX_OK) {
372
 
        return NGX_CONF_ERROR;
373
 
    }
374
 
 
375
 
 
376
 
    for (m = 0; ngx_modules[m]; m++) {
377
 
        if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
378
 
            continue;
379
 
        }
380
 
 
381
 
        module = ngx_modules[m]->ctx;
382
 
        mi = ngx_modules[m]->ctx_index;
383
 
 
384
 
        if (module->postconfiguration) {
385
 
            if (module->postconfiguration(cf) != NGX_OK) {
386
 
                return NGX_CONF_ERROR;
387
 
            }
388
 
        }
389
 
    }
390
 
 
391
 
    if (ngx_http_variables_init_vars(cf) != NGX_OK) {
392
 
        return NGX_CONF_ERROR;
393
 
    }
394
 
 
395
 
    /*
396
 
     * http{}'s cf->ctx was needed while the configuration merging
397
 
     * and in postconfiguration process
398
 
     */
399
 
 
400
 
    *cf = pcf;
401
 
 
 
481
        return NGX_ERROR;
 
482
    }
 
483
 
 
484
    return NGX_OK;
 
485
}
 
486
 
 
487
 
 
488
static ngx_int_t
 
489
ngx_http_init_phase_handlers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf)
 
490
{
 
491
    ngx_int_t                   j;
 
492
    ngx_uint_t                  i, n;
 
493
    ngx_uint_t                  find_config_index, use_rewrite, use_access;
 
494
    ngx_http_handler_pt        *h;
 
495
    ngx_http_phase_handler_t   *ph;
 
496
    ngx_http_phase_handler_pt   checker;
402
497
 
403
498
    cmcf->phase_engine.server_rewrite_index = (ngx_uint_t) -1;
404
499
    cmcf->phase_engine.location_rewrite_index = (ngx_uint_t) -1;
406
501
    use_rewrite = cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers.nelts ? 1 : 0;
407
502
    use_access = cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers.nelts ? 1 : 0;
408
503
 
409
 
    n = use_rewrite + use_access + 1; /* find config phase */
 
504
    n = use_rewrite + use_access + cmcf->try_files + 1 /* find config phase */;
410
505
 
411
506
    for (i = 0; i < NGX_HTTP_LOG_PHASE; i++) {
412
507
        n += cmcf->phases[i].handlers.nelts;
415
510
    ph = ngx_pcalloc(cf->pool,
416
511
                     n * sizeof(ngx_http_phase_handler_t) + sizeof(void *));
417
512
    if (ph == NULL) {
418
 
        return NGX_CONF_ERROR;
 
513
        return NGX_ERROR;
419
514
    }
420
515
 
421
516
    cmcf->phase_engine.handlers = ph;
475
570
 
476
571
            continue;
477
572
 
 
573
        case NGX_HTTP_TRY_FILES_PHASE:
 
574
            if (cmcf->try_files) {
 
575
                ph->checker = ngx_http_core_try_files_phase;
 
576
                n++;
 
577
                ph++;
 
578
            }
 
579
 
 
580
            continue;
 
581
 
478
582
        case NGX_HTTP_CONTENT_PHASE:
479
583
            checker = ngx_http_core_content_phase;
480
584
            break;
493
597
        }
494
598
    }
495
599
 
496
 
 
497
 
    /*
498
 
     * create the lists of ports, addresses and server names
499
 
     * to quickly find the server core module configuration at run-time
500
 
     */
501
 
 
502
 
    if (ngx_array_init(&in_ports, cf->temp_pool, 2,
503
 
                       sizeof(ngx_http_conf_in_port_t))
 
600
    return NGX_OK;
 
601
}
 
602
 
 
603
 
 
604
static char *
 
605
ngx_http_merge_locations(ngx_conf_t *cf, ngx_queue_t *locations,
 
606
    void **loc_conf, ngx_http_module_t *module, ngx_uint_t ctx_index)
 
607
{
 
608
    char                       *rv;
 
609
    ngx_queue_t                *q;
 
610
    ngx_http_core_loc_conf_t   *clcf;
 
611
    ngx_http_location_queue_t  *lq;
 
612
 
 
613
    if (locations == NULL) {
 
614
        return NGX_CONF_OK;
 
615
    }
 
616
 
 
617
    for (q = ngx_queue_head(locations);
 
618
         q != ngx_queue_sentinel(locations);
 
619
         q = ngx_queue_next(q))
 
620
    {
 
621
        lq = (ngx_http_location_queue_t *) q;
 
622
 
 
623
        clcf = lq->exact ? lq->exact : lq->inclusive;
 
624
 
 
625
        rv = module->merge_loc_conf(cf, loc_conf[ctx_index],
 
626
                                    clcf->loc_conf[ctx_index]);
 
627
        if (rv != NGX_CONF_OK) {
 
628
            return rv;
 
629
        }
 
630
 
 
631
        rv = ngx_http_merge_locations(cf, clcf->locations, clcf->loc_conf,
 
632
                                      module, ctx_index);
 
633
        if (rv != NGX_CONF_OK) {
 
634
            return rv;
 
635
        }
 
636
    }
 
637
 
 
638
    return NGX_CONF_OK;
 
639
}
 
640
 
 
641
 
 
642
static ngx_int_t
 
643
ngx_http_init_locations(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
 
644
    ngx_http_core_loc_conf_t *pclcf)
 
645
{
 
646
    ngx_uint_t                   n;
 
647
    ngx_queue_t                 *q, *locations, *named, tail;
 
648
    ngx_http_core_loc_conf_t    *clcf;
 
649
    ngx_http_location_queue_t   *lq;
 
650
    ngx_http_core_loc_conf_t   **clcfp;
 
651
#if (NGX_PCRE)
 
652
    ngx_uint_t                   r;
 
653
    ngx_queue_t                 *regex;
 
654
#endif
 
655
 
 
656
    locations = pclcf->locations;
 
657
 
 
658
    if (locations == NULL) {
 
659
        return NGX_OK;
 
660
    }
 
661
 
 
662
    ngx_queue_sort(locations, ngx_http_cmp_locations);
 
663
 
 
664
    named = NULL;
 
665
    n = 0;
 
666
#if (NGX_PCRE)
 
667
    regex = NULL;
 
668
    r = 0;
 
669
#endif
 
670
 
 
671
    for (q = ngx_queue_head(locations);
 
672
         q != ngx_queue_sentinel(locations);
 
673
         q = ngx_queue_next(q))
 
674
    {
 
675
        lq = (ngx_http_location_queue_t *) q;
 
676
 
 
677
        clcf = lq->exact ? lq->exact : lq->inclusive;
 
678
 
 
679
        if (ngx_http_init_locations(cf, NULL, clcf) != NGX_OK) {
 
680
            return NGX_ERROR;
 
681
        }
 
682
 
 
683
#if (NGX_PCRE)
 
684
 
 
685
        if (clcf->regex) {
 
686
            r++;
 
687
 
 
688
            if (regex == NULL) {
 
689
                regex = q;
 
690
            }
 
691
 
 
692
            continue;
 
693
        }
 
694
 
 
695
#endif
 
696
 
 
697
        if (clcf->named) {
 
698
            n++;
 
699
 
 
700
            if (named == NULL) {
 
701
                named = q;
 
702
            }
 
703
 
 
704
            continue;
 
705
        }
 
706
 
 
707
        if (clcf->noname) {
 
708
            break;
 
709
        }
 
710
    }
 
711
 
 
712
    if (q != ngx_queue_sentinel(locations)) {
 
713
        ngx_queue_split(locations, q, &tail);
 
714
    }
 
715
 
 
716
    if (named) {
 
717
        clcfp = ngx_palloc(cf->pool,
 
718
                           (n + 1) * sizeof(ngx_http_core_loc_conf_t **));
 
719
        if (clcfp == NULL) {
 
720
            return NGX_ERROR;
 
721
        }
 
722
 
 
723
        cscf->named_locations = clcfp;
 
724
 
 
725
        for (q = named;
 
726
             q != ngx_queue_sentinel(locations);
 
727
             q = ngx_queue_next(q))
 
728
        {
 
729
            lq = (ngx_http_location_queue_t *) q;
 
730
 
 
731
            *(clcfp++) = lq->exact;
 
732
        }
 
733
 
 
734
        *clcfp = NULL;
 
735
 
 
736
        ngx_queue_split(locations, named, &tail);
 
737
    }
 
738
 
 
739
#if (NGX_PCRE)
 
740
 
 
741
    if (regex) {
 
742
 
 
743
        clcfp = ngx_palloc(cf->pool,
 
744
                           (r + 1) * sizeof(ngx_http_core_loc_conf_t **));
 
745
        if (clcfp == NULL) {
 
746
            return NGX_ERROR;
 
747
        }
 
748
 
 
749
        pclcf->regex_locations = clcfp;
 
750
 
 
751
        for (q = regex;
 
752
             q != ngx_queue_sentinel(locations);
 
753
             q = ngx_queue_next(q))
 
754
        {
 
755
            lq = (ngx_http_location_queue_t *) q;
 
756
 
 
757
            *(clcfp++) = lq->exact;
 
758
        }
 
759
 
 
760
        *clcfp = NULL;
 
761
 
 
762
        ngx_queue_split(locations, regex, &tail);
 
763
    }
 
764
 
 
765
#endif
 
766
 
 
767
    return NGX_OK;
 
768
}
 
769
 
 
770
 
 
771
static ngx_int_t
 
772
ngx_http_init_static_location_trees(ngx_conf_t *cf,
 
773
    ngx_http_core_loc_conf_t *pclcf)
 
774
{
 
775
    ngx_queue_t                *q, *locations;
 
776
    ngx_http_core_loc_conf_t   *clcf;
 
777
    ngx_http_location_queue_t  *lq;
 
778
 
 
779
    locations = pclcf->locations;
 
780
 
 
781
    if (locations == NULL) {
 
782
        return NGX_OK;
 
783
    }
 
784
 
 
785
    if (ngx_queue_empty(locations)) {
 
786
        return NGX_OK;
 
787
    }
 
788
 
 
789
    for (q = ngx_queue_head(locations);
 
790
         q != ngx_queue_sentinel(locations);
 
791
         q = ngx_queue_next(q))
 
792
    {
 
793
        lq = (ngx_http_location_queue_t *) q;
 
794
 
 
795
        clcf = lq->exact ? lq->exact : lq->inclusive;
 
796
 
 
797
        if (ngx_http_init_static_location_trees(cf, clcf) != NGX_OK) {
 
798
            return NGX_ERROR;
 
799
        }
 
800
    }
 
801
 
 
802
    if (ngx_http_join_exact_locations(cf, locations) != NGX_OK) {
 
803
        return NGX_ERROR;
 
804
    }
 
805
 
 
806
    ngx_http_create_locations_list(locations, ngx_queue_head(locations));
 
807
 
 
808
    pclcf->static_locations = ngx_http_create_locations_tree(cf, locations, 0);
 
809
    if (pclcf->static_locations == NULL) {
 
810
        return NGX_ERROR;
 
811
    }
 
812
 
 
813
    return NGX_OK;
 
814
}
 
815
 
 
816
 
 
817
ngx_int_t
 
818
ngx_http_add_location(ngx_conf_t *cf, ngx_queue_t **locations,
 
819
    ngx_http_core_loc_conf_t *clcf)
 
820
{
 
821
    ngx_http_location_queue_t  *lq;
 
822
 
 
823
    if (*locations == NULL) {
 
824
        *locations = ngx_palloc(cf->temp_pool,
 
825
                                sizeof(ngx_http_location_queue_t));
 
826
        if (*locations == NULL) {
 
827
            return NGX_ERROR;
 
828
        }
 
829
 
 
830
        ngx_queue_init(*locations);
 
831
    }
 
832
 
 
833
    lq = ngx_palloc(cf->temp_pool, sizeof(ngx_http_location_queue_t));
 
834
    if (lq == NULL) {
 
835
        return NGX_ERROR;
 
836
    }
 
837
 
 
838
    if (clcf->exact_match
 
839
#if (NGX_PCRE)
 
840
        || clcf->regex
 
841
#endif
 
842
        || clcf->named || clcf->noname)
 
843
    {
 
844
        lq->exact = clcf;
 
845
        lq->inclusive = NULL;
 
846
 
 
847
    } else {
 
848
        lq->exact = NULL;
 
849
        lq->inclusive = clcf;
 
850
    }
 
851
 
 
852
    lq->name = &clcf->name;
 
853
    lq->file_name = cf->conf_file->file.name.data;
 
854
    lq->line = cf->conf_file->line;
 
855
 
 
856
    ngx_queue_init(&lq->list);
 
857
 
 
858
    ngx_queue_insert_tail(*locations, &lq->queue);
 
859
 
 
860
    return NGX_OK;
 
861
}
 
862
 
 
863
 
 
864
static ngx_int_t
 
865
ngx_http_cmp_locations(const ngx_queue_t *one, const ngx_queue_t *two)
 
866
{
 
867
    ngx_int_t                   rc;
 
868
    ngx_http_core_loc_conf_t   *first, *second;
 
869
    ngx_http_location_queue_t  *lq1, *lq2;
 
870
 
 
871
    lq1 = (ngx_http_location_queue_t *) one;
 
872
    lq2 = (ngx_http_location_queue_t *) two;
 
873
 
 
874
    first = lq1->exact ? lq1->exact : lq1->inclusive;
 
875
    second = lq2->exact ? lq2->exact : lq2->inclusive;
 
876
 
 
877
    if (first->noname && !second->noname) {
 
878
        /* shift no named locations to the end */
 
879
        return 1;
 
880
    }
 
881
 
 
882
    if (!first->noname && second->noname) {
 
883
        /* shift no named locations to the end */
 
884
        return -1;
 
885
    }
 
886
 
 
887
    if (first->noname || second->noname) {
 
888
        /* do not sort no named locations */
 
889
        return 0;
 
890
    }
 
891
 
 
892
    if (first->named && !second->named) {
 
893
        /* shift named locations to the end */
 
894
        return 1;
 
895
    }
 
896
 
 
897
    if (!first->named && second->named) {
 
898
        /* shift named locations to the end */
 
899
        return -1;
 
900
    }
 
901
 
 
902
    if (first->named && second->named) {
 
903
        return ngx_strcmp(first->name.data, second->name.data);
 
904
    }
 
905
 
 
906
#if (NGX_PCRE)
 
907
 
 
908
    if (first->regex && !second->regex) {
 
909
        /* shift the regex matches to the end */
 
910
        return 1;
 
911
    }
 
912
 
 
913
    if (!first->regex && second->regex) {
 
914
        /* shift the regex matches to the end */
 
915
        return -1;
 
916
    }
 
917
 
 
918
    if (first->regex || second->regex) {
 
919
        /* do not sort the regex matches */
 
920
        return 0;
 
921
    }
 
922
 
 
923
#endif
 
924
 
 
925
    rc = ngx_strcmp(first->name.data, second->name.data);
 
926
 
 
927
    if (rc == 0 && !first->exact_match && second->exact_match) {
 
928
        /* an exact match must be before the same inclusive one */
 
929
        return 1;
 
930
    }
 
931
 
 
932
    return rc;
 
933
}
 
934
 
 
935
 
 
936
static ngx_int_t
 
937
ngx_http_join_exact_locations(ngx_conf_t *cf, ngx_queue_t *locations)
 
938
{
 
939
    ngx_queue_t                *q, *x;
 
940
    ngx_http_location_queue_t  *lq, *lx;
 
941
 
 
942
    q = ngx_queue_head(locations);
 
943
 
 
944
    while (q != ngx_queue_last(locations)) {
 
945
 
 
946
        x = ngx_queue_next(q);
 
947
 
 
948
        lq = (ngx_http_location_queue_t *) q;
 
949
        lx = (ngx_http_location_queue_t *) x;
 
950
 
 
951
        if (ngx_strcmp(lq->name->data, lx->name->data) == 0) {
 
952
 
 
953
            if ((lq->exact && lx->exact) || (lq->inclusive && lx->inclusive)) {
 
954
                ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
 
955
                              "duplicate location \"%V\" in %s:%ui",
 
956
                              lx->name, lx->file_name, lx->line);
 
957
 
 
958
                return NGX_ERROR;
 
959
            }
 
960
 
 
961
            lq->inclusive = lx->inclusive;
 
962
 
 
963
            ngx_queue_remove(x);
 
964
 
 
965
            continue;
 
966
        }
 
967
 
 
968
        q = ngx_queue_next(q);
 
969
    }
 
970
 
 
971
    return NGX_OK;
 
972
}
 
973
 
 
974
 
 
975
static void
 
976
ngx_http_create_locations_list(ngx_queue_t *locations, ngx_queue_t *q)
 
977
{
 
978
    u_char                     *name;
 
979
    size_t                      len;
 
980
    ngx_queue_t                *x, tail;
 
981
    ngx_http_location_queue_t  *lq, *lx;
 
982
 
 
983
    if (q == ngx_queue_last(locations)) {
 
984
        return;
 
985
    }
 
986
 
 
987
    lq = (ngx_http_location_queue_t *) q;
 
988
 
 
989
    if (lq->inclusive == NULL) {
 
990
        ngx_http_create_locations_list(locations, ngx_queue_next(q));
 
991
        return;
 
992
    }
 
993
 
 
994
    len = lq->name->len;
 
995
    name = lq->name->data;
 
996
 
 
997
    for (x = ngx_queue_next(q);
 
998
         x != ngx_queue_sentinel(locations);
 
999
         x = ngx_queue_next(x))
 
1000
    {
 
1001
        lx = (ngx_http_location_queue_t *) x;
 
1002
 
 
1003
        if (len > lx->name->len
 
1004
            || (ngx_strncmp(name, lx->name->data, len) != 0))
 
1005
        {
 
1006
            break;
 
1007
        }
 
1008
    }
 
1009
 
 
1010
    q = ngx_queue_next(q);
 
1011
 
 
1012
    if (q == x) {
 
1013
        ngx_http_create_locations_list(locations, x);
 
1014
        return;
 
1015
    }
 
1016
 
 
1017
    ngx_queue_split(locations, q, &tail);
 
1018
    ngx_queue_add(&lq->list, &tail);
 
1019
 
 
1020
    if (x == ngx_queue_sentinel(locations)) {
 
1021
        ngx_http_create_locations_list(&lq->list, ngx_queue_head(&lq->list));
 
1022
        return;
 
1023
    }
 
1024
 
 
1025
    ngx_queue_split(&lq->list, x, &tail);
 
1026
    ngx_queue_add(locations, &tail);
 
1027
 
 
1028
    ngx_http_create_locations_list(&lq->list, ngx_queue_head(&lq->list));
 
1029
 
 
1030
    ngx_http_create_locations_list(locations, x);
 
1031
}
 
1032
 
 
1033
 
 
1034
/*
 
1035
 * to keep cache locality for left leaf nodes, allocate nodes in following
 
1036
 * order: node, left subtree, right subtree, inclusive subtree
 
1037
 */
 
1038
 
 
1039
static ngx_http_location_tree_node_t *
 
1040
ngx_http_create_locations_tree(ngx_conf_t *cf, ngx_queue_t *locations,
 
1041
    size_t prefix)
 
1042
{
 
1043
    size_t                          len;
 
1044
    ngx_queue_t                    *q, tail;
 
1045
    ngx_http_location_queue_t      *lq;
 
1046
    ngx_http_location_tree_node_t  *node;
 
1047
 
 
1048
    q = ngx_queue_middle(locations);
 
1049
 
 
1050
    lq = (ngx_http_location_queue_t *) q;
 
1051
    len = lq->name->len - prefix;
 
1052
 
 
1053
    node = ngx_palloc(cf->pool,
 
1054
                      offsetof(ngx_http_location_tree_node_t, name) + len);
 
1055
    if (node == NULL) {
 
1056
        return NULL;
 
1057
    }
 
1058
 
 
1059
    node->left = NULL;
 
1060
    node->right = NULL;
 
1061
    node->tree = NULL;
 
1062
    node->exact = lq->exact;
 
1063
    node->inclusive = lq->inclusive;
 
1064
 
 
1065
    node->auto_redirect = (u_char) ((lq->exact && lq->exact->auto_redirect)
 
1066
                           || (lq->inclusive && lq->inclusive->auto_redirect));
 
1067
 
 
1068
    node->len = (u_char) len;
 
1069
    ngx_memcpy(node->name, &lq->name->data[prefix], len);
 
1070
 
 
1071
    ngx_queue_split(locations, q, &tail);
 
1072
 
 
1073
    if (ngx_queue_empty(locations)) {
 
1074
        /*
 
1075
         * ngx_queue_split() insures that if left part is empty,
 
1076
         * then right one is empty too
 
1077
         */
 
1078
        goto inclusive;
 
1079
    }
 
1080
 
 
1081
    node->left = ngx_http_create_locations_tree(cf, locations, prefix);
 
1082
    if (node->left == NULL) {
 
1083
        return NULL;
 
1084
    }
 
1085
 
 
1086
    ngx_queue_remove(q);
 
1087
 
 
1088
    if (ngx_queue_empty(&tail)) {
 
1089
        goto inclusive;
 
1090
    }
 
1091
 
 
1092
    node->right = ngx_http_create_locations_tree(cf, &tail, prefix);
 
1093
    if (node->right == NULL) {
 
1094
        return NULL;
 
1095
    }
 
1096
 
 
1097
inclusive:
 
1098
 
 
1099
    if (ngx_queue_empty(&lq->list)) {
 
1100
        return node;
 
1101
    }
 
1102
 
 
1103
    node->tree = ngx_http_create_locations_tree(cf, &lq->list, prefix + len);
 
1104
    if (node->tree == NULL) {
 
1105
        return NULL;
 
1106
    }
 
1107
 
 
1108
    return node;
 
1109
}
 
1110
 
 
1111
 
 
1112
static ngx_int_t
 
1113
ngx_http_init_server_lists(ngx_conf_t *cf, ngx_array_t *servers,
 
1114
    ngx_array_t *ports)
 
1115
{
 
1116
    ngx_uint_t                  s, i;
 
1117
    ngx_http_listen_t          *listen;
 
1118
    ngx_http_core_srv_conf_t  **cscfp;
 
1119
 
 
1120
    if (ngx_array_init(ports, cf->temp_pool, 2, sizeof(ngx_http_conf_port_t))
504
1121
        != NGX_OK)
505
1122
    {
506
 
        return NGX_CONF_ERROR;
 
1123
        return NGX_ERROR;
507
1124
    }
508
1125
 
509
1126
    /* "server" directives */
510
1127
 
511
 
    cscfp = cmcf->servers.elts;
512
 
    for (s = 0; s < cmcf->servers.nelts; s++) {
 
1128
    cscfp = servers->elts;
 
1129
    for (s = 0; s < servers->nelts; s++) {
513
1130
 
514
1131
        /* "listen" directives */
515
1132
 
516
 
        lscf = cscfp[s]->listen.elts;
517
 
        for (l = 0; l < cscfp[s]->listen.nelts; l++) {
518
 
 
519
 
            /* AF_INET only */
520
 
 
521
 
            in_port = in_ports.elts;
522
 
            for (p = 0; p < in_ports.nelts; p++) {
523
 
 
524
 
                if (lscf[l].port != in_port[p].port) {
525
 
                    continue;
526
 
                }
527
 
 
528
 
                /* the port is already in the port list */
529
 
 
530
 
                in_addr = in_port[p].addrs.elts;
531
 
                for (a = 0; a < in_port[p].addrs.nelts; a++) {
532
 
 
533
 
                    if (lscf[l].addr != in_addr[a].addr) {
534
 
                        continue;
535
 
                    }
536
 
 
537
 
                    /* the address is already in the address list */
538
 
 
539
 
                    if (ngx_http_add_names(cf, &in_addr[a], cscfp[s]) != NGX_OK)
540
 
                    {
541
 
                        return NGX_CONF_ERROR;
542
 
                    }
543
 
 
544
 
                    /*
545
 
                     * check the duplicate "default" server
546
 
                     * for this address:port
547
 
                     */
548
 
 
549
 
                    if (lscf[l].conf.default_server) {
550
 
 
551
 
                        if (in_addr[a].default_server) {
552
 
                            ngx_log_error(NGX_LOG_ERR, cf->log, 0,
553
 
                                      "the duplicate default server in %s:%ui",
554
 
                                       lscf[l].file_name, lscf[l].line);
555
 
 
556
 
                            return NGX_CONF_ERROR;
557
 
                        }
558
 
 
559
 
                        in_addr[a].core_srv_conf = cscfp[s];
560
 
                        in_addr[a].default_server = 1;
561
 
                        in_addr[a].listen_conf = &lscf[l].conf;
562
 
                    }
563
 
 
564
 
                    goto found;
565
 
                }
566
 
 
567
 
                /*
568
 
                 * add the address to the addresses list that
569
 
                 * bound to this port
570
 
                 */
571
 
 
572
 
                if (ngx_http_add_address(cf, &in_port[p], &lscf[l], cscfp[s])
573
 
                    != NGX_OK)
574
 
                {
575
 
                    return NGX_CONF_ERROR;
576
 
                }
577
 
 
578
 
                goto found;
579
 
            }
580
 
 
581
 
            /* add the port to the in_port list */
582
 
 
583
 
            in_port = ngx_array_push(&in_ports);
584
 
            if (in_port == NULL) {
585
 
                return NGX_CONF_ERROR;
586
 
            }
587
 
 
588
 
            in_port->port = lscf[l].port;
589
 
            in_port->addrs.elts = NULL;
590
 
 
591
 
            if (ngx_http_add_address(cf, in_port, &lscf[l], cscfp[s]) != NGX_OK)
592
 
            {
593
 
                return NGX_CONF_ERROR;
594
 
            }
595
 
 
596
 
        found:
597
 
 
598
 
            continue;
599
 
        }
600
 
    }
601
 
 
602
 
 
603
 
    /* optimize the lists of ports, addresses and server names */
604
 
 
605
 
    /* AF_INET only */
606
 
 
607
 
    in_port = in_ports.elts;
608
 
    for (p = 0; p < in_ports.nelts; p++) {
609
 
 
610
 
        ngx_sort(in_port[p].addrs.elts, (size_t) in_port[p].addrs.nelts,
611
 
                 sizeof(ngx_http_conf_in_addr_t), ngx_http_cmp_conf_in_addrs);
612
 
 
613
 
        /*
614
 
         * check whether all name-based servers have the same configuraiton
615
 
         *     as the default server,
616
 
         * or some servers disable optimizing the server names
617
 
         */
618
 
 
619
 
        in_addr = in_port[p].addrs.elts;
620
 
        for (a = 0; a < in_port[p].addrs.nelts; a++) {
621
 
 
622
 
            name = in_addr[a].names.elts;
623
 
            for (s = 0; s < in_addr[a].names.nelts; s++) {
624
 
 
625
 
                if (in_addr[a].core_srv_conf != name[s].core_srv_conf
626
 
                    || name[s].core_srv_conf->optimize_server_names == 0)
627
 
                {
628
 
                    goto virtual_names;
629
 
                }
630
 
            }
631
 
 
632
 
            /*
633
 
             * if all name-based servers have the same configuration
634
 
             *         as the default server,
635
 
             *     and no servers disable optimizing the server names
636
 
             * then we do not need to check them at run-time at all
637
 
             */
638
 
 
639
 
            in_addr[a].names.nelts = 0;
640
 
 
641
 
            continue;
642
 
 
643
 
        virtual_names:
644
 
 
645
 
            ngx_memzero(&ha, sizeof(ngx_hash_keys_arrays_t));
646
 
 
647
 
            ha.temp_pool = ngx_create_pool(16384, cf->log);
648
 
            if (ha.temp_pool == NULL) {
649
 
                return NGX_CONF_ERROR;
650
 
            }
651
 
 
652
 
            ha.pool = cf->pool;
653
 
 
654
 
            if (ngx_hash_keys_array_init(&ha, NGX_HASH_LARGE) != NGX_OK) {
655
 
                ngx_destroy_pool(ha.temp_pool);
656
 
                return NGX_CONF_ERROR;
657
 
            }
658
 
 
659
 
#if (NGX_PCRE)
660
 
            regex = 0;
661
 
#endif
662
 
 
663
 
            name = in_addr[a].names.elts;
664
 
 
665
 
            for (s = 0; s < in_addr[a].names.nelts; s++) {
666
 
 
667
 
#if (NGX_PCRE)
668
 
                if (name[s].regex) {
669
 
                    regex++;
670
 
                    continue;
671
 
                }
672
 
#endif
673
 
 
674
 
                rc = ngx_hash_add_key(&ha, &name[s].name, name[s].core_srv_conf,
675
 
                                      NGX_HASH_WILDCARD_KEY);
676
 
 
677
 
                if (rc == NGX_ERROR) {
678
 
                    return NGX_CONF_ERROR;
679
 
                }
680
 
 
681
 
                if (rc == NGX_DECLINED) {
682
 
                    ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
683
 
                                "invalid server name or wildcard \"%V\" on %s",
684
 
                                &name[s].name, in_addr[a].listen_conf->addr);
685
 
                    return NGX_CONF_ERROR;
686
 
                }
687
 
 
688
 
                if (rc == NGX_BUSY) {
689
 
                    ngx_log_error(NGX_LOG_WARN, cf->log, 0,
690
 
                                "conflicting server name \"%V\" on %s, ignored",
691
 
                                &name[s].name, in_addr[a].listen_conf->addr);
692
 
                }
693
 
            }
694
 
 
695
 
            hash.key = ngx_hash_key_lc;
696
 
            hash.max_size = cmcf->server_names_hash_max_size;
697
 
            hash.bucket_size = cmcf->server_names_hash_bucket_size;
698
 
            hash.name = "server_names_hash";
699
 
            hash.pool = cf->pool;
700
 
 
701
 
            if (ha.keys.nelts) {
702
 
                hash.hash = &in_addr[a].hash;
703
 
                hash.temp_pool = NULL;
704
 
 
705
 
                if (ngx_hash_init(&hash, ha.keys.elts, ha.keys.nelts) != NGX_OK)
706
 
                {
707
 
                    ngx_destroy_pool(ha.temp_pool);
708
 
                    return NGX_CONF_ERROR;
709
 
                }
710
 
            }
711
 
 
712
 
            if (ha.dns_wc_head.nelts) {
713
 
 
714
 
                ngx_qsort(ha.dns_wc_head.elts,
715
 
                          (size_t) ha.dns_wc_head.nelts,
716
 
                          sizeof(ngx_hash_key_t),
717
 
                          ngx_http_cmp_dns_wildcards);
718
 
 
719
 
                hash.hash = NULL;
720
 
                hash.temp_pool = ha.temp_pool;
721
 
 
722
 
                if (ngx_hash_wildcard_init(&hash, ha.dns_wc_head.elts,
723
 
                                           ha.dns_wc_head.nelts)
724
 
                    != NGX_OK)
725
 
                {
726
 
                    ngx_destroy_pool(ha.temp_pool);
727
 
                    return NGX_CONF_ERROR;
728
 
                }
729
 
 
730
 
                in_addr[a].wc_head = (ngx_hash_wildcard_t *) hash.hash;
731
 
            }
732
 
 
733
 
            if (ha.dns_wc_tail.nelts) {
734
 
 
735
 
                ngx_qsort(ha.dns_wc_tail.elts,
736
 
                          (size_t) ha.dns_wc_tail.nelts,
737
 
                          sizeof(ngx_hash_key_t),
738
 
                          ngx_http_cmp_dns_wildcards);
739
 
 
740
 
                hash.hash = NULL;
741
 
                hash.temp_pool = ha.temp_pool;
742
 
 
743
 
                if (ngx_hash_wildcard_init(&hash, ha.dns_wc_tail.elts,
744
 
                                           ha.dns_wc_tail.nelts)
745
 
                    != NGX_OK)
746
 
                {
747
 
                    ngx_destroy_pool(ha.temp_pool);
748
 
                    return NGX_CONF_ERROR;
749
 
                }
750
 
 
751
 
                in_addr[a].wc_tail = (ngx_hash_wildcard_t *) hash.hash;
752
 
            }
753
 
 
754
 
            ngx_destroy_pool(ha.temp_pool);
755
 
 
756
 
#if (NGX_PCRE)
757
 
 
758
 
            if (regex == 0) {
759
 
                continue;
760
 
            }
761
 
 
762
 
            in_addr[a].nregex = regex;
763
 
            in_addr[a].regex = ngx_palloc(cf->pool,
764
 
                                       regex * sizeof(ngx_http_server_name_t));
765
 
 
766
 
            if (in_addr[a].regex == NULL) {
767
 
                return NGX_CONF_ERROR;
768
 
            }
769
 
 
770
 
            for (i = 0, s = 0; s < in_addr[a].names.nelts; s++) {
771
 
                if (name[s].regex) {
772
 
                    in_addr[a].regex[i++] = name[s];
773
 
                }
774
 
            }
775
 
#endif
776
 
        }
777
 
 
778
 
        in_addr = in_port[p].addrs.elts;
779
 
        last = in_port[p].addrs.nelts;
780
 
 
781
 
        /*
782
 
         * if there is the binding to the "*:port" then we need to bind()
783
 
         * to the "*:port" only and ignore the other bindings
784
 
         */
785
 
 
786
 
        if (in_addr[last - 1].addr == INADDR_ANY) {
787
 
            in_addr[last - 1].bind = 1;
788
 
            bind_all = 0;
789
 
 
790
 
        } else {
791
 
            bind_all = 1;
792
 
        }
793
 
 
794
 
        for (a = 0; a < last; /* void */ ) {
795
 
 
796
 
            if (!bind_all && !in_addr[a].bind) {
797
 
                a++;
798
 
                continue;
799
 
            }
800
 
 
801
 
            ls = ngx_listening_inet_stream_socket(cf, in_addr[a].addr,
802
 
                                                  in_port[p].port);
803
 
            if (ls == NULL) {
804
 
                return NGX_CONF_ERROR;
805
 
            }
806
 
 
807
 
            ls->addr_ntop = 1;
808
 
 
809
 
            ls->handler = ngx_http_init_connection;
810
 
 
811
 
            cscf = in_addr[a].core_srv_conf;
812
 
            ls->pool_size = cscf->connection_pool_size;
813
 
            ls->post_accept_timeout = cscf->client_header_timeout;
814
 
 
815
 
            clcf = cscf->ctx->loc_conf[ngx_http_core_module.ctx_index];
816
 
 
817
 
            ls->log = *clcf->err_log;
818
 
            ls->log.data = &ls->addr_text;
819
 
            ls->log.handler = ngx_accept_log_error;
820
 
 
821
 
#if (NGX_WIN32)
822
 
            {
823
 
            ngx_iocp_conf_t  *iocpcf;
824
 
 
825
 
            iocpcf = ngx_event_get_conf(cf->cycle->conf_ctx, ngx_iocp_module);
826
 
            if (iocpcf->acceptex_read) {
827
 
                ls->post_accept_buffer_size = cscf->client_header_buffer_size;
828
 
            }
829
 
            }
830
 
#endif
831
 
 
832
 
            ls->backlog = in_addr[a].listen_conf->backlog;
833
 
            ls->rcvbuf = in_addr[a].listen_conf->rcvbuf;
834
 
            ls->sndbuf = in_addr[a].listen_conf->sndbuf;
835
 
 
836
 
#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
837
 
            ls->accept_filter = in_addr[a].listen_conf->accept_filter;
838
 
#endif
839
 
 
840
 
#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
841
 
            ls->deferred_accept = in_addr[a].listen_conf->deferred_accept;
842
 
#endif
843
 
 
844
 
            hip = ngx_palloc(cf->pool, sizeof(ngx_http_in_port_t));
845
 
            if (hip == NULL) {
846
 
                return NGX_CONF_ERROR;
847
 
            }
848
 
 
849
 
            hip->port = in_port[p].port;
850
 
 
851
 
            hip->port_text.data = ngx_palloc(cf->pool, 7);
852
 
            if (hip->port_text.data == NULL) {
853
 
                return NGX_CONF_ERROR;
854
 
            }
855
 
 
856
 
            ls->servers = hip;
857
 
 
858
 
            hip->port_text.len = ngx_sprintf(hip->port_text.data, ":%d",
859
 
                                             hip->port)
860
 
                                 - hip->port_text.data;
861
 
 
862
 
            in_addr = in_port[p].addrs.elts;
863
 
 
864
 
            if (in_addr[a].bind && in_addr[a].addr != INADDR_ANY) {
865
 
                hip->naddrs = 1;
866
 
                done = 0;
867
 
 
868
 
            } else if (in_port[p].addrs.nelts > 1
869
 
                       && in_addr[last - 1].addr == INADDR_ANY)
870
 
            {
871
 
                hip->naddrs = last;
872
 
                done = 1;
873
 
 
874
 
            } else {
875
 
                hip->naddrs = 1;
876
 
                done = 0;
877
 
            }
878
 
 
879
 
#if 0
880
 
            ngx_log_error(NGX_LOG_ALERT, cf->log, 0,
881
 
                          "%ui: %V %d %ui %ui",
882
 
                          a, &ls->addr_text, in_addr[a].bind,
883
 
                          hip->naddrs, last);
884
 
#endif
885
 
 
886
 
            hip->addrs = ngx_pcalloc(cf->pool,
887
 
                                     hip->naddrs * sizeof(ngx_http_in_addr_t));
888
 
            if (hip->addrs == NULL) {
889
 
                return NGX_CONF_ERROR;
890
 
            }
891
 
 
892
 
            for (i = 0; i < hip->naddrs; i++) {
893
 
                hip->addrs[i].addr = in_addr[i].addr;
894
 
                hip->addrs[i].core_srv_conf = in_addr[i].core_srv_conf;
895
 
 
896
 
                if (in_addr[i].hash.buckets == NULL
897
 
                    && (in_addr[i].wc_head == NULL
898
 
                        || in_addr[i].wc_head->hash.buckets == NULL)
899
 
                    && (in_addr[i].wc_head == NULL
900
 
                        || in_addr[i].wc_head->hash.buckets == NULL))
901
 
                {
902
 
                    continue;
903
 
                }
904
 
 
905
 
                vn = ngx_palloc(cf->pool, sizeof(ngx_http_virtual_names_t));
906
 
                if (vn == NULL) {
907
 
                    return NGX_CONF_ERROR;
908
 
                }
909
 
                hip->addrs[i].virtual_names = vn;
910
 
 
911
 
                vn->names.hash = in_addr[i].hash;
912
 
                vn->names.wc_head = in_addr[i].wc_head;
913
 
                vn->names.wc_tail = in_addr[i].wc_tail;
914
 
#if (NGX_PCRE)
915
 
                vn->nregex = in_addr[i].nregex;
916
 
                vn->regex = in_addr[i].regex;
917
 
#endif
918
 
            }
919
 
 
920
 
            if (done) {
921
 
                break;
922
 
            }
923
 
 
924
 
            in_addr++;
925
 
            in_port[p].addrs.elts = in_addr;
926
 
            last--;
927
 
 
928
 
            a = 0;
929
 
        }
930
 
    }
931
 
 
932
 
#if 0
933
 
    {
934
 
    u_char      address[20];
935
 
    ngx_uint_t  p, a;
936
 
 
937
 
    in_port = in_ports.elts;
938
 
    for (p = 0; p < in_ports.nelts; p++) {
939
 
        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0,
940
 
                      "port: %d %p", in_port[p].port, &in_port[p]);
941
 
        in_addr = in_port[p].addrs.elts;
942
 
        for (a = 0; a < in_port[p].addrs.nelts; a++) {
943
 
            ngx_inet_ntop(AF_INET, &in_addr[a].addr, address, 20);
944
 
            ngx_log_debug3(NGX_LOG_DEBUG_HTTP, cf->log, 0,
945
 
                           "%s:%d %p",
946
 
                           address, in_port[p].port, in_addr[a].core_srv_conf);
947
 
            name = in_addr[a].names.elts;
948
 
            for (n = 0; n < in_addr[a].names.nelts; n++) {
949
 
                 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, cf->log, 0,
950
 
                                "%s:%d %V %p",
951
 
                                address, in_port[p].port, &name[n].name,
952
 
                                name[n].core_srv_conf);
953
 
            }
954
 
        }
955
 
    }
956
 
    }
957
 
#endif
958
 
 
959
 
    return NGX_CONF_OK;
 
1133
        listen = cscfp[s]->listen.elts;
 
1134
        for (i = 0; i < cscfp[s]->listen.nelts; i++) {
 
1135
 
 
1136
            if (ngx_http_add_ports(cf, cscfp[s], ports, &listen[i]) != NGX_OK) {
 
1137
                return NGX_ERROR;
 
1138
            }
 
1139
        }
 
1140
    }
 
1141
 
 
1142
    return NGX_OK;
 
1143
}
 
1144
 
 
1145
 
 
1146
static ngx_int_t
 
1147
ngx_http_add_ports(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
 
1148
    ngx_array_t *ports, ngx_http_listen_t *listen)
 
1149
{
 
1150
    in_port_t                 p;
 
1151
    ngx_uint_t                i;
 
1152
    struct sockaddr          *sa;
 
1153
    struct sockaddr_in       *sin;
 
1154
    ngx_http_conf_port_t     *port;
 
1155
#if (NGX_HAVE_INET6)
 
1156
    struct sockaddr_in6      *sin6;
 
1157
#endif
 
1158
 
 
1159
    sa = (struct sockaddr *) &listen->sockaddr;
 
1160
 
 
1161
    switch (sa->sa_family) {
 
1162
 
 
1163
#if (NGX_HAVE_INET6)
 
1164
    case AF_INET6:
 
1165
        sin6 = (struct sockaddr_in6 *) sa;
 
1166
        p = sin6->sin6_port;
 
1167
        break;
 
1168
#endif
 
1169
 
 
1170
    default: /* AF_INET */
 
1171
        sin = (struct sockaddr_in *) sa;
 
1172
        p = sin->sin_port;
 
1173
        break;
 
1174
    }
 
1175
 
 
1176
    port = ports->elts;
 
1177
    for (i = 0; i < ports->nelts; i++) {
 
1178
 
 
1179
        if (p != port[i].port || sa->sa_family != port[i].family) {
 
1180
            continue;
 
1181
        }
 
1182
 
 
1183
        /* a port is already in the port list */
 
1184
 
 
1185
        return ngx_http_add_addresses(cf, cscf, &port[i], listen);
 
1186
    }
 
1187
 
 
1188
    /* add a port to the port list */
 
1189
 
 
1190
    port = ngx_array_push(ports);
 
1191
    if (port == NULL) {
 
1192
        return NGX_ERROR;
 
1193
    }
 
1194
 
 
1195
    port->family = sa->sa_family;
 
1196
    port->port = p;
 
1197
    port->addrs.elts = NULL;
 
1198
 
 
1199
    return ngx_http_add_address(cf, cscf, port, listen);
 
1200
}
 
1201
 
 
1202
 
 
1203
static ngx_int_t
 
1204
ngx_http_add_addresses(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
 
1205
    ngx_http_conf_port_t *port, ngx_http_listen_t *listen)
 
1206
{
 
1207
    u_char                *p;
 
1208
    size_t                 len, off;
 
1209
    ngx_uint_t             i;
 
1210
    struct sockaddr       *sa;
 
1211
    ngx_http_conf_addr_t  *addr;
 
1212
 
 
1213
    /*
 
1214
     * we can not compare whole sockaddr struct's as kernel
 
1215
     * may fill some fields in inherited sockaddr struct's
 
1216
     */
 
1217
 
 
1218
    sa = (struct sockaddr *) &listen->sockaddr;
 
1219
 
 
1220
    switch (sa->sa_family) {
 
1221
 
 
1222
#if (NGX_HAVE_INET6)
 
1223
    case AF_INET6:
 
1224
        off = offsetof(struct sockaddr_in6, sin6_addr);
 
1225
        len = 16;
 
1226
        break;
 
1227
#endif
 
1228
 
 
1229
    default: /* AF_INET */
 
1230
        off = offsetof(struct sockaddr_in, sin_addr);
 
1231
        len = 4;
 
1232
        break;
 
1233
    }
 
1234
 
 
1235
    p = listen->sockaddr + off;
 
1236
 
 
1237
    addr = port->addrs.elts;
 
1238
 
 
1239
    for (i = 0; i < port->addrs.nelts; i++) {
 
1240
 
 
1241
        if (ngx_memcmp(p, (u_char *) addr[i].sockaddr + off, len) != 0) {
 
1242
            continue;
 
1243
        }
 
1244
 
 
1245
        /* the address is already in the address list */
 
1246
 
 
1247
        if (ngx_http_add_names(cf, cscf, &addr[i]) != NGX_OK) {
 
1248
            return NGX_ERROR;
 
1249
        }
 
1250
 
 
1251
        /* check the duplicate "default" server for this address:port */
 
1252
 
 
1253
        if (listen->conf.default_server) {
 
1254
 
 
1255
            if (addr[i].default_server) {
 
1256
                ngx_log_error(NGX_LOG_ERR, cf->log, 0,
 
1257
                              "the duplicate default server in %s:%ui",
 
1258
                               listen->file_name, listen->line);
 
1259
 
 
1260
                return NGX_ERROR;
 
1261
            }
 
1262
 
 
1263
            addr[i].core_srv_conf = cscf;
 
1264
            addr[i].default_server = 1;
 
1265
#if (NGX_HTTP_SSL)
 
1266
            addr[i].ssl = listen->conf.ssl;
 
1267
#endif
 
1268
            addr[i].listen_conf = &listen->conf;
 
1269
        }
 
1270
 
 
1271
        return NGX_OK;
 
1272
    }
 
1273
 
 
1274
    /* add the address to the addresses list that bound to this port */
 
1275
 
 
1276
    return ngx_http_add_address(cf, cscf, port, listen);
960
1277
}
961
1278
 
962
1279
 
963
1280
/*
964
1281
 * add the server address, the server names and the server core module
965
 
 * configurations to the port (in_port)
 
1282
 * configurations to the port list
966
1283
 */
967
1284
 
968
1285
static ngx_int_t
969
 
ngx_http_add_address(ngx_conf_t *cf, ngx_http_conf_in_port_t *in_port,
970
 
    ngx_http_listen_t *lscf, ngx_http_core_srv_conf_t *cscf)
 
1286
ngx_http_add_address(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
 
1287
    ngx_http_conf_port_t *port, ngx_http_listen_t *listen)
971
1288
{
972
 
    ngx_http_conf_in_addr_t  *in_addr;
 
1289
    ngx_http_conf_addr_t  *addr;
973
1290
 
974
 
    if (in_port->addrs.elts == NULL) {
975
 
        if (ngx_array_init(&in_port->addrs, cf->temp_pool, 4,
976
 
                           sizeof(ngx_http_conf_in_addr_t))
 
1291
    if (port->addrs.elts == NULL) {
 
1292
        if (ngx_array_init(&port->addrs, cf->temp_pool, 4,
 
1293
                           sizeof(ngx_http_conf_addr_t))
977
1294
            != NGX_OK)
978
1295
        {
979
1296
            return NGX_ERROR;
980
1297
        }
981
1298
    }
982
1299
 
983
 
    in_addr = ngx_array_push(&in_port->addrs);
984
 
    if (in_addr == NULL) {
 
1300
    addr = ngx_array_push(&port->addrs);
 
1301
    if (addr == NULL) {
985
1302
        return NGX_ERROR;
986
1303
    }
987
1304
 
988
 
    in_addr->addr = lscf->addr;
989
 
    in_addr->hash.buckets = NULL;
990
 
    in_addr->hash.size = 0;
991
 
    in_addr->wc_head = NULL;
992
 
    in_addr->wc_tail = NULL;
993
 
    in_addr->names.elts = NULL;
 
1305
    addr->sockaddr = (struct sockaddr *) &listen->sockaddr;
 
1306
    addr->socklen = listen->socklen;
 
1307
    addr->hash.buckets = NULL;
 
1308
    addr->hash.size = 0;
 
1309
    addr->wc_head = NULL;
 
1310
    addr->wc_tail = NULL;
 
1311
    addr->names.elts = NULL;
994
1312
#if (NGX_PCRE)
995
 
    in_addr->nregex = 0;
996
 
    in_addr->regex = NULL;
997
 
#endif
998
 
    in_addr->core_srv_conf = cscf;
999
 
    in_addr->default_server = lscf->conf.default_server;
1000
 
    in_addr->bind = lscf->conf.bind;
1001
 
    in_addr->listen_conf = &lscf->conf;
1002
 
 
1003
 
#if (NGX_DEBUG)
1004
 
    {
1005
 
    u_char text[20];
1006
 
    ngx_inet_ntop(AF_INET, &in_addr->addr, text, 20);
1007
 
    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0, "address: %s:%d",
1008
 
                   text, in_port->port);
1009
 
    }
1010
 
#endif
1011
 
 
1012
 
    return ngx_http_add_names(cf, in_addr, cscf);
 
1313
    addr->nregex = 0;
 
1314
    addr->regex = NULL;
 
1315
#endif
 
1316
    addr->core_srv_conf = cscf;
 
1317
    addr->default_server = listen->conf.default_server;
 
1318
    addr->bind = listen->conf.bind;
 
1319
    addr->wildcard = listen->conf.wildcard;
 
1320
#if (NGX_HTTP_SSL)
 
1321
    addr->ssl = listen->conf.ssl;
 
1322
#endif
 
1323
    addr->listen_conf = &listen->conf;
 
1324
 
 
1325
    return ngx_http_add_names(cf, cscf, addr);
1013
1326
}
1014
1327
 
1015
1328
 
1016
1329
/*
1017
1330
 * add the server names and the server core module
1018
 
 * configurations to the address:port (in_addr)
 
1331
 * configurations to the address:port
1019
1332
 */
1020
1333
 
1021
1334
static ngx_int_t
1022
 
ngx_http_add_names(ngx_conf_t *cf, ngx_http_conf_in_addr_t *in_addr,
1023
 
    ngx_http_core_srv_conf_t *cscf)
 
1335
ngx_http_add_names(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
 
1336
    ngx_http_conf_addr_t *addr)
1024
1337
{
1025
 
    ngx_uint_t               i, n;
 
1338
    ngx_uint_t               i;
1026
1339
    ngx_http_server_name_t  *server_names, *name;
1027
1340
 
1028
 
    if (in_addr->names.elts == NULL) {
1029
 
        if (ngx_array_init(&in_addr->names, cf->temp_pool, 4,
 
1341
    if (addr->names.elts == NULL) {
 
1342
        if (ngx_array_init(&addr->names, cf->temp_pool, 4,
1030
1343
                           sizeof(ngx_http_server_name_t))
1031
1344
            != NGX_OK)
1032
1345
        {
1038
1351
 
1039
1352
    for (i = 0; i < cscf->server_names.nelts; i++) {
1040
1353
 
1041
 
        for (n = 0; n < server_names[i].name.len; n++) {
1042
 
            server_names[i].name.data[n] =
1043
 
                                     ngx_tolower(server_names[i].name.data[n]);
1044
 
        }
 
1354
        ngx_strlow(server_names[i].name.data, server_names[i].name.data,
 
1355
                   server_names[i].name.len);
1045
1356
 
1046
1357
        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0,
1047
1358
                       "name: %V", &server_names[i].name);
1048
1359
 
1049
 
        name = ngx_array_push(&in_addr->names);
 
1360
        name = ngx_array_push(&addr->names);
1050
1361
        if (name == NULL) {
1051
1362
            return NGX_ERROR;
1052
1363
        }
1058
1369
}
1059
1370
 
1060
1371
 
1061
 
static char *
1062
 
ngx_http_merge_locations(ngx_conf_t *cf, ngx_array_t *locations,
1063
 
    void **loc_conf, ngx_http_module_t *module, ngx_uint_t ctx_index)
1064
 
{
1065
 
    char                       *rv;
1066
 
    ngx_uint_t                  i;
1067
 
    ngx_http_core_loc_conf_t  **clcfp;
1068
 
 
1069
 
    clcfp = locations->elts;
1070
 
 
1071
 
    for (i = 0; i < locations->nelts; i++) {
1072
 
        rv = module->merge_loc_conf(cf, loc_conf[ctx_index],
1073
 
                                    clcfp[i]->loc_conf[ctx_index]);
1074
 
        if (rv != NGX_CONF_OK) {
1075
 
            return rv;
1076
 
        }
1077
 
 
1078
 
        if (clcfp[i]->locations == NULL) {
 
1372
static ngx_int_t
 
1373
ngx_http_optimize_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
 
1374
    ngx_array_t *ports)
 
1375
{
 
1376
    ngx_uint_t               s, p, a;
 
1377
    ngx_http_conf_port_t    *port;
 
1378
    ngx_http_conf_addr_t    *addr;
 
1379
    ngx_http_server_name_t  *name;
 
1380
 
 
1381
    port = ports->elts;
 
1382
    for (p = 0; p < ports->nelts; p++) {
 
1383
 
 
1384
        ngx_sort(port[p].addrs.elts, (size_t) port[p].addrs.nelts,
 
1385
                 sizeof(ngx_http_conf_addr_t), ngx_http_cmp_conf_addrs);
 
1386
 
 
1387
        /*
 
1388
         * check whether all name-based servers have the same
 
1389
         * configuraiton as a default server for given address:port
 
1390
         */
 
1391
 
 
1392
        addr = port[p].addrs.elts;
 
1393
        for (a = 0; a < port[p].addrs.nelts; a++) {
 
1394
 
 
1395
            name = addr[a].names.elts;
 
1396
            for (s = 0; s < addr[a].names.nelts; s++) {
 
1397
 
 
1398
                if (addr[a].core_srv_conf == name[s].core_srv_conf
 
1399
#if (NGX_PCRE)
 
1400
                    && name[s].captures == 0
 
1401
#endif
 
1402
                    )
 
1403
                {
 
1404
                    continue;
 
1405
                }
 
1406
 
 
1407
                if (ngx_http_server_names(cf, cmcf, &addr[a]) != NGX_OK) {
 
1408
                    return NGX_ERROR;
 
1409
                }
 
1410
 
 
1411
                break;
 
1412
            }
 
1413
        }
 
1414
 
 
1415
        if (ngx_http_init_listening(cf, &port[p]) != NGX_OK) {
 
1416
            return NGX_ERROR;
 
1417
        }
 
1418
    }
 
1419
 
 
1420
    return NGX_OK;
 
1421
}
 
1422
 
 
1423
 
 
1424
static ngx_int_t
 
1425
ngx_http_server_names(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
 
1426
    ngx_http_conf_addr_t *addr)
 
1427
{
 
1428
    ngx_int_t                rc;
 
1429
    ngx_uint_t               s;
 
1430
    ngx_hash_init_t          hash;
 
1431
    ngx_hash_keys_arrays_t   ha;
 
1432
    ngx_http_server_name_t  *name;
 
1433
#if (NGX_PCRE)
 
1434
    ngx_uint_t               regex, i;
 
1435
 
 
1436
    regex = 0;
 
1437
#endif
 
1438
 
 
1439
    ngx_memzero(&ha, sizeof(ngx_hash_keys_arrays_t));
 
1440
 
 
1441
    ha.temp_pool = ngx_create_pool(16384, cf->log);
 
1442
    if (ha.temp_pool == NULL) {
 
1443
        return NGX_ERROR;
 
1444
    }
 
1445
 
 
1446
    ha.pool = cf->pool;
 
1447
 
 
1448
    if (ngx_hash_keys_array_init(&ha, NGX_HASH_LARGE) != NGX_OK) {
 
1449
        goto failed;
 
1450
    }
 
1451
 
 
1452
    name = addr->names.elts;
 
1453
 
 
1454
    for (s = 0; s < addr->names.nelts; s++) {
 
1455
 
 
1456
#if (NGX_PCRE)
 
1457
        if (name[s].regex) {
 
1458
            regex++;
1079
1459
            continue;
1080
1460
        }
1081
 
 
1082
 
        rv = ngx_http_merge_locations(cf, clcfp[i]->locations,
1083
 
                                      clcfp[i]->loc_conf, module, ctx_index);
1084
 
        if (rv != NGX_CONF_OK) {
1085
 
            return rv;
1086
 
        }
1087
 
    }
1088
 
 
1089
 
    return NGX_CONF_OK;
 
1461
#endif
 
1462
 
 
1463
        rc = ngx_hash_add_key(&ha, &name[s].name, name[s].core_srv_conf,
 
1464
                              NGX_HASH_WILDCARD_KEY);
 
1465
 
 
1466
        if (rc == NGX_ERROR) {
 
1467
            return NGX_ERROR;
 
1468
        }
 
1469
 
 
1470
        if (rc == NGX_DECLINED) {
 
1471
            ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
 
1472
                          "invalid server name or wildcard \"%V\" on %s",
 
1473
                          &name[s].name, addr->listen_conf->addr);
 
1474
            return NGX_ERROR;
 
1475
        }
 
1476
 
 
1477
        if (rc == NGX_BUSY) {
 
1478
            ngx_log_error(NGX_LOG_WARN, cf->log, 0,
 
1479
                          "conflicting server name \"%V\" on %s, ignored",
 
1480
                          &name[s].name, addr->listen_conf->addr);
 
1481
        }
 
1482
    }
 
1483
 
 
1484
    hash.key = ngx_hash_key_lc;
 
1485
    hash.max_size = cmcf->server_names_hash_max_size;
 
1486
    hash.bucket_size = cmcf->server_names_hash_bucket_size;
 
1487
    hash.name = "server_names_hash";
 
1488
    hash.pool = cf->pool;
 
1489
 
 
1490
    if (ha.keys.nelts) {
 
1491
        hash.hash = &addr->hash;
 
1492
        hash.temp_pool = NULL;
 
1493
 
 
1494
        if (ngx_hash_init(&hash, ha.keys.elts, ha.keys.nelts) != NGX_OK) {
 
1495
            goto failed;
 
1496
        }
 
1497
    }
 
1498
 
 
1499
    if (ha.dns_wc_head.nelts) {
 
1500
 
 
1501
        ngx_qsort(ha.dns_wc_head.elts, (size_t) ha.dns_wc_head.nelts,
 
1502
                  sizeof(ngx_hash_key_t), ngx_http_cmp_dns_wildcards);
 
1503
 
 
1504
        hash.hash = NULL;
 
1505
        hash.temp_pool = ha.temp_pool;
 
1506
 
 
1507
        if (ngx_hash_wildcard_init(&hash, ha.dns_wc_head.elts,
 
1508
                                   ha.dns_wc_head.nelts)
 
1509
            != NGX_OK)
 
1510
        {
 
1511
            goto failed;
 
1512
        }
 
1513
 
 
1514
        addr->wc_head = (ngx_hash_wildcard_t *) hash.hash;
 
1515
    }
 
1516
 
 
1517
    if (ha.dns_wc_tail.nelts) {
 
1518
 
 
1519
        ngx_qsort(ha.dns_wc_tail.elts, (size_t) ha.dns_wc_tail.nelts,
 
1520
                  sizeof(ngx_hash_key_t), ngx_http_cmp_dns_wildcards);
 
1521
 
 
1522
        hash.hash = NULL;
 
1523
        hash.temp_pool = ha.temp_pool;
 
1524
 
 
1525
        if (ngx_hash_wildcard_init(&hash, ha.dns_wc_tail.elts,
 
1526
                                   ha.dns_wc_tail.nelts)
 
1527
            != NGX_OK)
 
1528
        {
 
1529
            goto failed;
 
1530
        }
 
1531
 
 
1532
        addr->wc_tail = (ngx_hash_wildcard_t *) hash.hash;
 
1533
    }
 
1534
 
 
1535
    ngx_destroy_pool(ha.temp_pool);
 
1536
 
 
1537
#if (NGX_PCRE)
 
1538
 
 
1539
    if (regex == 0) {
 
1540
        return NGX_OK;
 
1541
    }
 
1542
 
 
1543
    addr->nregex = regex;
 
1544
    addr->regex = ngx_palloc(cf->pool, regex * sizeof(ngx_http_server_name_t));
 
1545
    if (addr->regex == NULL) {
 
1546
        return NGX_ERROR;
 
1547
    }
 
1548
 
 
1549
    for (i = 0, s = 0; s < addr->names.nelts; s++) {
 
1550
        if (name[s].regex) {
 
1551
            addr->regex[i++] = name[s];
 
1552
        }
 
1553
    }
 
1554
 
 
1555
#endif
 
1556
 
 
1557
    return NGX_OK;
 
1558
 
 
1559
failed:
 
1560
 
 
1561
    ngx_destroy_pool(ha.temp_pool);
 
1562
 
 
1563
    return NGX_ERROR;
1090
1564
}
1091
1565
 
1092
1566
 
1093
1567
static ngx_int_t
1094
 
ngx_http_cmp_conf_in_addrs(const void *one, const void *two)
 
1568
ngx_http_cmp_conf_addrs(const void *one, const void *two)
1095
1569
{
1096
 
    ngx_http_conf_in_addr_t  *first, *second;
1097
 
 
1098
 
    first = (ngx_http_conf_in_addr_t *) one;
1099
 
    second = (ngx_http_conf_in_addr_t *) two;
1100
 
 
1101
 
    if (first->addr == INADDR_ANY) {
1102
 
        /* the INADDR_ANY must be the last resort, shift it to the end */
 
1570
    ngx_http_conf_addr_t  *first, *second;
 
1571
 
 
1572
    first = (ngx_http_conf_addr_t *) one;
 
1573
    second = (ngx_http_conf_addr_t *) two;
 
1574
 
 
1575
    if (first->wildcard) {
 
1576
        /* a wildcard address must be the last resort, shift it to the end */
1103
1577
        return 1;
1104
1578
    }
1105
1579
 
1129
1603
 
1130
1604
    return ngx_strcmp(first->key.data, second->key.data);
1131
1605
}
 
1606
 
 
1607
 
 
1608
static ngx_int_t
 
1609
ngx_http_init_listening(ngx_conf_t *cf, ngx_http_conf_port_t *port)
 
1610
{
 
1611
    ngx_uint_t                 i, last, bind_wildcard;
 
1612
    ngx_listening_t           *ls;
 
1613
    ngx_http_port_t           *hport;
 
1614
    ngx_http_conf_addr_t      *addr;
 
1615
 
 
1616
    addr = port->addrs.elts;
 
1617
    last = port->addrs.nelts;
 
1618
 
 
1619
    /*
 
1620
     * If there is a binding to an "*:port" then we need to bind() to
 
1621
     * the "*:port" only and ignore other implicit bindings.  The bindings
 
1622
     * have been already sorted: explicit bindings are on the start, then
 
1623
     * implicit bindings go, and wildcard binding is in the end.
 
1624
     */
 
1625
 
 
1626
    if (addr[last - 1].wildcard) {
 
1627
        addr[last - 1].bind = 1;
 
1628
        bind_wildcard = 1;
 
1629
 
 
1630
    } else {
 
1631
        bind_wildcard = 0;
 
1632
    }
 
1633
 
 
1634
    i = 0;
 
1635
 
 
1636
    while (i < last) {
 
1637
 
 
1638
        if (bind_wildcard && !addr[i].bind) {
 
1639
            i++;
 
1640
            continue;
 
1641
        }
 
1642
 
 
1643
        ls = ngx_http_add_listening(cf, &addr[i]);
 
1644
        if (ls == NULL) {
 
1645
            return NGX_ERROR;
 
1646
        }
 
1647
 
 
1648
        hport = ngx_pcalloc(cf->pool, sizeof(ngx_http_port_t));
 
1649
        if (hport == NULL) {
 
1650
            return NGX_ERROR;
 
1651
        }
 
1652
 
 
1653
        ls->servers = hport;
 
1654
 
 
1655
        if (i == last - 1) {
 
1656
            hport->naddrs = last;
 
1657
 
 
1658
        } else {
 
1659
            hport->naddrs = 1;
 
1660
            i = 0;
 
1661
        }
 
1662
 
 
1663
        switch (ls->sockaddr->sa_family) {
 
1664
 
 
1665
#if (NGX_HAVE_INET6)
 
1666
        case AF_INET6:
 
1667
            if (ngx_http_add_addrs6(cf, hport, addr) != NGX_OK) {
 
1668
                return NGX_ERROR;
 
1669
            }
 
1670
            break;
 
1671
#endif
 
1672
        default: /* AF_INET */
 
1673
            if (ngx_http_add_addrs(cf, hport, addr) != NGX_OK) {
 
1674
                return NGX_ERROR;
 
1675
            }
 
1676
            break;
 
1677
        }
 
1678
 
 
1679
        addr++;
 
1680
        last--;
 
1681
    }
 
1682
 
 
1683
    return NGX_OK;
 
1684
}
 
1685
 
 
1686
 
 
1687
static ngx_listening_t *
 
1688
ngx_http_add_listening(ngx_conf_t *cf, ngx_http_conf_addr_t *addr)
 
1689
{
 
1690
    ngx_listening_t           *ls;
 
1691
    ngx_http_core_loc_conf_t  *clcf;
 
1692
    ngx_http_core_srv_conf_t  *cscf;
 
1693
 
 
1694
    ls = ngx_create_listening(cf, addr->sockaddr, addr->socklen);
 
1695
    if (ls == NULL) {
 
1696
        return NULL;
 
1697
    }
 
1698
 
 
1699
    ls->addr_ntop = 1;
 
1700
 
 
1701
    ls->handler = ngx_http_init_connection;
 
1702
 
 
1703
    cscf = addr->core_srv_conf;
 
1704
    ls->pool_size = cscf->connection_pool_size;
 
1705
    ls->post_accept_timeout = cscf->client_header_timeout;
 
1706
 
 
1707
    clcf = cscf->ctx->loc_conf[ngx_http_core_module.ctx_index];
 
1708
 
 
1709
    ls->logp = clcf->error_log;
 
1710
    ls->log.data = &ls->addr_text;
 
1711
    ls->log.handler = ngx_accept_log_error;
 
1712
 
 
1713
#if (NGX_WIN32)
 
1714
    {
 
1715
    ngx_iocp_conf_t  *iocpcf;
 
1716
 
 
1717
    iocpcf = ngx_event_get_conf(cf->cycle->conf_ctx, ngx_iocp_module);
 
1718
    if (iocpcf->acceptex_read) {
 
1719
        ls->post_accept_buffer_size = cscf->client_header_buffer_size;
 
1720
    }
 
1721
    }
 
1722
#endif
 
1723
 
 
1724
    ls->backlog = addr->listen_conf->backlog;
 
1725
    ls->rcvbuf = addr->listen_conf->rcvbuf;
 
1726
    ls->sndbuf = addr->listen_conf->sndbuf;
 
1727
 
 
1728
#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
 
1729
    ls->accept_filter = addr->listen_conf->accept_filter;
 
1730
#endif
 
1731
 
 
1732
#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
 
1733
    ls->deferred_accept = addr->listen_conf->deferred_accept;
 
1734
#endif
 
1735
 
 
1736
#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
 
1737
    ls->ipv6only = addr->listen_conf->ipv6only;
 
1738
#endif
 
1739
 
 
1740
    return ls;
 
1741
}
 
1742
 
 
1743
 
 
1744
static ngx_int_t
 
1745
ngx_http_add_addrs(ngx_conf_t *cf, ngx_http_port_t *hport,
 
1746
    ngx_http_conf_addr_t *addr)
 
1747
{
 
1748
    ngx_uint_t                 i;
 
1749
    ngx_http_in_addr_t        *addrs;
 
1750
    struct sockaddr_in        *sin;
 
1751
    ngx_http_virtual_names_t  *vn;
 
1752
 
 
1753
    hport->addrs = ngx_pcalloc(cf->pool,
 
1754
                               hport->naddrs * sizeof(ngx_http_in_addr_t));
 
1755
    if (hport->addrs == NULL) {
 
1756
        return NGX_ERROR;
 
1757
    }
 
1758
 
 
1759
    addrs = hport->addrs;
 
1760
 
 
1761
    for (i = 0; i < hport->naddrs; i++) {
 
1762
 
 
1763
        sin = (struct sockaddr_in *) addr[i].sockaddr;
 
1764
        addrs[i].addr = sin->sin_addr.s_addr;
 
1765
        addrs[i].conf.core_srv_conf = addr[i].core_srv_conf;
 
1766
#if (NGX_HTTP_SSL)
 
1767
        addrs[i].conf.ssl = addr[i].ssl;
 
1768
#endif
 
1769
 
 
1770
        if (addr[i].hash.buckets == NULL
 
1771
            && (addr[i].wc_head == NULL
 
1772
                || addr[i].wc_head->hash.buckets == NULL)
 
1773
            && (addr[i].wc_tail == NULL
 
1774
                || addr[i].wc_tail->hash.buckets == NULL)
 
1775
#if (NGX_PCRE)
 
1776
            && addr[i].nregex == 0
 
1777
#endif
 
1778
            )
 
1779
        {
 
1780
            continue;
 
1781
        }
 
1782
 
 
1783
        vn = ngx_palloc(cf->pool, sizeof(ngx_http_virtual_names_t));
 
1784
        if (vn == NULL) {
 
1785
            return NGX_ERROR;
 
1786
        }
 
1787
 
 
1788
        addrs[i].conf.virtual_names = vn;
 
1789
 
 
1790
        vn->names.hash = addr[i].hash;
 
1791
        vn->names.wc_head = addr[i].wc_head;
 
1792
        vn->names.wc_tail = addr[i].wc_tail;
 
1793
#if (NGX_PCRE)
 
1794
        vn->nregex = addr[i].nregex;
 
1795
        vn->regex = addr[i].regex;
 
1796
#endif
 
1797
    }
 
1798
 
 
1799
    return NGX_OK;
 
1800
}
 
1801
 
 
1802
 
 
1803
#if (NGX_HAVE_INET6)
 
1804
 
 
1805
static ngx_int_t
 
1806
ngx_http_add_addrs6(ngx_conf_t *cf, ngx_http_port_t *hport,
 
1807
    ngx_http_conf_addr_t *addr)
 
1808
{
 
1809
    ngx_uint_t                 i;
 
1810
    ngx_http_in6_addr_t       *addrs6;
 
1811
    struct sockaddr_in6       *sin6;
 
1812
    ngx_http_virtual_names_t  *vn;
 
1813
 
 
1814
    hport->addrs = ngx_pcalloc(cf->pool,
 
1815
                               hport->naddrs * sizeof(ngx_http_in6_addr_t));
 
1816
    if (hport->addrs == NULL) {
 
1817
        return NGX_ERROR;
 
1818
    }
 
1819
 
 
1820
    addrs6 = hport->addrs;
 
1821
 
 
1822
    for (i = 0; i < hport->naddrs; i++) {
 
1823
 
 
1824
        sin6 = (struct sockaddr_in6 *) addr[i].sockaddr;
 
1825
        addrs6[i].addr6 = sin6->sin6_addr;
 
1826
        addrs6[i].conf.core_srv_conf = addr[i].core_srv_conf;
 
1827
#if (NGX_HTTP_SSL)
 
1828
        addrs6[i].conf.ssl = addr[i].ssl;
 
1829
#endif
 
1830
 
 
1831
        if (addr[i].hash.buckets == NULL
 
1832
            && (addr[i].wc_head == NULL
 
1833
                || addr[i].wc_head->hash.buckets == NULL)
 
1834
            && (addr[i].wc_head == NULL
 
1835
                || addr[i].wc_head->hash.buckets == NULL))
 
1836
        {
 
1837
            continue;
 
1838
        }
 
1839
 
 
1840
        vn = ngx_palloc(cf->pool, sizeof(ngx_http_virtual_names_t));
 
1841
        if (vn == NULL) {
 
1842
            return NGX_ERROR;
 
1843
        }
 
1844
 
 
1845
        addrs6[i].conf.virtual_names = vn;
 
1846
 
 
1847
        vn->names.hash = addr[i].hash;
 
1848
        vn->names.wc_head = addr[i].wc_head;
 
1849
        vn->names.wc_tail = addr[i].wc_tail;
 
1850
#if (NGX_PCRE)
 
1851
        vn->nregex = addr[i].nregex;
 
1852
        vn->regex = addr[i].regex;
 
1853
#endif
 
1854
    }
 
1855
 
 
1856
    return NGX_OK;
 
1857
}
 
1858
 
 
1859
#endif
 
1860
 
 
1861
 
 
1862
char *
 
1863
ngx_http_types_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
1864
{
 
1865
    char  *p = conf;
 
1866
 
 
1867
    ngx_array_t     **types;
 
1868
    ngx_str_t        *value, *default_type;
 
1869
    ngx_uint_t        i, n, hash;
 
1870
    ngx_hash_key_t   *type;
 
1871
 
 
1872
    types = (ngx_array_t **) (p + cmd->offset);
 
1873
 
 
1874
    default_type = cmd->post;
 
1875
 
 
1876
    if (*types == NULL) {
 
1877
        *types = ngx_array_create(cf->temp_pool, 1, sizeof(ngx_hash_key_t));
 
1878
        if (*types == NULL) {
 
1879
            return NGX_CONF_ERROR;
 
1880
        }
 
1881
 
 
1882
        if (default_type) {
 
1883
            type = ngx_array_push(*types);
 
1884
            if (type == NULL) {
 
1885
                return NGX_CONF_ERROR;
 
1886
            }
 
1887
 
 
1888
            type->key = *default_type;
 
1889
            type->key_hash = ngx_hash_key(default_type->data,
 
1890
                                          default_type->len);
 
1891
            type->value = (void *) 4;
 
1892
        }
 
1893
    }
 
1894
 
 
1895
    value = cf->args->elts;
 
1896
 
 
1897
    for (i = 1; i < cf->args->nelts; i++) {
 
1898
 
 
1899
        hash = ngx_hash_strlow(value[i].data, value[i].data, value[i].len);
 
1900
        value[i].data[value[i].len] = '\0';
 
1901
 
 
1902
        type = (*types)->elts;
 
1903
        for (n = 0; n < (*types)->nelts; n++) {
 
1904
 
 
1905
            if (ngx_strcmp(value[i].data, type[n].key.data) == 0) {
 
1906
                ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
 
1907
                                   "duplicate MIME type \"%V\"", &value[i]);
 
1908
                continue;
 
1909
            }
 
1910
        }
 
1911
 
 
1912
        type = ngx_array_push(*types);
 
1913
        if (type == NULL) {
 
1914
            return NGX_CONF_ERROR;
 
1915
        }
 
1916
 
 
1917
        type->key = value[i];
 
1918
        type->key_hash = hash;
 
1919
        type->value = (void *) 4;
 
1920
    }
 
1921
 
 
1922
    return NGX_CONF_OK;
 
1923
}
 
1924
 
 
1925
 
 
1926
char *
 
1927
ngx_http_merge_types(ngx_conf_t *cf, ngx_array_t *keys, ngx_hash_t *types_hash,
 
1928
    ngx_array_t *prev_keys, ngx_hash_t *prev_types_hash,
 
1929
    ngx_str_t *default_types)
 
1930
{
 
1931
    ngx_hash_init_t  hash;
 
1932
 
 
1933
    if (keys) {
 
1934
 
 
1935
        hash.hash = types_hash;
 
1936
        hash.key = NULL;
 
1937
        hash.max_size = 2048;
 
1938
        hash.bucket_size = 64;
 
1939
        hash.name = "test_types_hash";
 
1940
        hash.pool = cf->pool;
 
1941
        hash.temp_pool = NULL;
 
1942
 
 
1943
        if (ngx_hash_init(&hash, keys->elts, keys->nelts) != NGX_OK) {
 
1944
            return NGX_CONF_ERROR;
 
1945
        }
 
1946
 
 
1947
        return NGX_CONF_OK;
 
1948
    }
 
1949
 
 
1950
    if (prev_types_hash->buckets == NULL) {
 
1951
 
 
1952
        if (prev_keys == NULL) {
 
1953
 
 
1954
            if (ngx_http_set_default_types(cf, &prev_keys, default_types)
 
1955
                != NGX_OK)
 
1956
            {
 
1957
                return NGX_CONF_ERROR;
 
1958
            }
 
1959
        }
 
1960
 
 
1961
        hash.hash = prev_types_hash;
 
1962
        hash.key = NULL;
 
1963
        hash.max_size = 2048;
 
1964
        hash.bucket_size = 64;
 
1965
        hash.name = "test_types_hash";
 
1966
        hash.pool = cf->pool;
 
1967
        hash.temp_pool = NULL;
 
1968
 
 
1969
        if (ngx_hash_init(&hash, prev_keys->elts, prev_keys->nelts) != NGX_OK) {
 
1970
            return NGX_CONF_ERROR;
 
1971
        }
 
1972
    }
 
1973
 
 
1974
    *types_hash = *prev_types_hash;
 
1975
 
 
1976
    return NGX_CONF_OK;
 
1977
 
 
1978
}
 
1979
 
 
1980
 
 
1981
ngx_int_t
 
1982
ngx_http_set_default_types(ngx_conf_t *cf, ngx_array_t **types,
 
1983
    ngx_str_t *default_type)
 
1984
{
 
1985
    ngx_hash_key_t  *type;
 
1986
 
 
1987
    *types = ngx_array_create(cf->temp_pool, 1, sizeof(ngx_hash_key_t));
 
1988
    if (*types == NULL) {
 
1989
        return NGX_ERROR;
 
1990
    }
 
1991
 
 
1992
    while (default_type->len) {
 
1993
 
 
1994
        type = ngx_array_push(*types);
 
1995
        if (type == NULL) {
 
1996
            return NGX_ERROR;
 
1997
        }
 
1998
 
 
1999
        type->key = *default_type;
 
2000
        type->key_hash = ngx_hash_key(default_type->data,
 
2001
                                      default_type->len);
 
2002
        type->value = (void *) 4;
 
2003
 
 
2004
        default_type++;
 
2005
    }
 
2006
 
 
2007
    return NGX_OK;
 
2008
}