Mercurial > hg > nginx
comparison src/http/ngx_http.c @ 593:425af804d968 release-0.3.18
nginx-0.3.18-RELEASE import
*) Feature: the "server_names" directive supports the ".domain.tld"
names.
*) Feature: the "server_names" directive uses the hash for the
"*.domain.tld" names and more effective hash for usual names.
*) Change: the "server_names_hash_max_size" and
"server_names_hash_bucket_size" directives.
*) Change: the "server_names_hash" and "server_names_hash_threshold"
directives were canceled.
*) Feature: the "valid_referers" directive uses the hash site names.
*) Change: now the "valid_referers" directive checks the site names
only without the URI part.
*) Bugfix: some ".domain.tld" names incorrectly processed by the
ngx_http_map_module.
*) Bugfix: segmentation fault was occurred if configuration file did
not exist; the bug had appeared in 0.3.12.
*) Bugfix: on 64-bit platforms segmentation fault may occurred on
start; the bug had appeared in 0.3.16.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 26 Dec 2005 17:07:48 +0000 |
parents | d4e858a5751a |
children | ebc68d8ca496 |
comparison
equal
deleted
inserted
replaced
592:8b2e7f727cd0 | 593:425af804d968 |
---|---|
12 | 12 |
13 static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); | 13 static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); |
14 static int ngx_libc_cdecl ngx_cmp_server_names(const void *one, | 14 static int ngx_libc_cdecl ngx_cmp_server_names(const void *one, |
15 const void *two); | 15 const void *two); |
16 static ngx_int_t ngx_http_add_address(ngx_conf_t *cf, | 16 static ngx_int_t ngx_http_add_address(ngx_conf_t *cf, |
17 ngx_http_in_port_t *in_port, ngx_http_listen_t *lscf, | 17 ngx_http_conf_in_port_t *in_port, ngx_http_listen_t *lscf, |
18 ngx_http_core_srv_conf_t *cscf); | 18 ngx_http_core_srv_conf_t *cscf); |
19 static ngx_int_t ngx_http_add_names(ngx_conf_t *cf, | 19 static ngx_int_t ngx_http_add_names(ngx_conf_t *cf, |
20 ngx_http_in_addr_t *in_addr, ngx_http_core_srv_conf_t *cscf); | 20 ngx_http_conf_in_addr_t *in_addr, ngx_http_core_srv_conf_t *cscf); |
21 static char *ngx_http_merge_locations(ngx_conf_t *cf, | 21 static char *ngx_http_merge_locations(ngx_conf_t *cf, |
22 ngx_array_t *locations, void **loc_conf, ngx_http_module_t *module, | 22 ngx_array_t *locations, void **loc_conf, ngx_http_module_t *module, |
23 ngx_uint_t ctx_index); | 23 ngx_uint_t ctx_index); |
24 | 24 static int ngx_libc_cdecl ngx_http_cmp_conf_in_addrs(const void *one, |
25 ngx_uint_t ngx_http_max_module; | 25 const void *two); |
26 | 26 static int ngx_libc_cdecl ngx_http_cmp_dns_wildcards(const void *one, |
27 ngx_uint_t ngx_http_total_requests; | 27 const void *two); |
28 uint64_t ngx_http_total_sent; | 28 |
29 ngx_uint_t ngx_http_max_module; | |
30 | |
31 ngx_uint_t ngx_http_total_requests; | |
32 uint64_t ngx_http_total_sent; | |
29 | 33 |
30 | 34 |
31 ngx_int_t (*ngx_http_top_header_filter) (ngx_http_request_t *r); | 35 ngx_int_t (*ngx_http_top_header_filter) (ngx_http_request_t *r); |
32 ngx_int_t (*ngx_http_top_body_filter) (ngx_http_request_t *r, ngx_chain_t *ch); | 36 ngx_int_t (*ngx_http_top_body_filter) (ngx_http_request_t *r, ngx_chain_t *ch); |
33 | 37 |
70 | 74 |
71 static char * | 75 static char * |
72 ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 76 ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
73 { | 77 { |
74 char *rv; | 78 char *rv; |
75 ngx_uint_t mi, m, s, l, p, a, n, key; | 79 u_char ch; |
76 ngx_uint_t port_found, addr_found; | 80 ngx_int_t rc; |
77 ngx_uint_t virtual_names, separate_binding; | 81 ngx_uint_t mi, m, s, l, p, a, n, i; |
82 ngx_uint_t last, bind_all, done; | |
78 ngx_conf_t pcf; | 83 ngx_conf_t pcf; |
79 ngx_array_t in_ports; | 84 ngx_array_t in_ports; |
85 ngx_hash_init_t hash; | |
80 ngx_listening_t *ls; | 86 ngx_listening_t *ls; |
81 ngx_http_listen_t *lscf; | 87 ngx_http_listen_t *lscf; |
82 ngx_http_module_t *module; | 88 ngx_http_module_t *module; |
89 ngx_http_in_port_t *hip; | |
83 ngx_http_handler_pt *h; | 90 ngx_http_handler_pt *h; |
84 ngx_http_conf_ctx_t *ctx; | 91 ngx_http_conf_ctx_t *ctx; |
85 ngx_http_in_port_t *in_port, *inport; | 92 ngx_http_conf_in_port_t *in_port; |
86 ngx_http_in_addr_t *in_addr, *inaddr; | 93 ngx_http_conf_in_addr_t *in_addr; |
87 ngx_http_server_name_t *s_name, *name; | 94 ngx_hash_keys_arrays_t ha; |
95 ngx_http_server_name_t *name; | |
96 ngx_http_virtual_names_t *vn; | |
88 ngx_http_core_srv_conf_t **cscfp, *cscf; | 97 ngx_http_core_srv_conf_t **cscfp, *cscf; |
89 ngx_http_core_loc_conf_t *clcf; | 98 ngx_http_core_loc_conf_t *clcf; |
90 ngx_http_core_main_conf_t *cmcf; | 99 ngx_http_core_main_conf_t *cmcf; |
91 #if (NGX_WIN32) | 100 #if (NGX_WIN32) |
92 ngx_iocp_conf_t *iocpcf; | 101 ngx_iocp_conf_t *iocpcf; |
412 /* | 421 /* |
413 * create the lists of ports, addresses and server names | 422 * create the lists of ports, addresses and server names |
414 * to quickly find the server core module configuration at run-time | 423 * to quickly find the server core module configuration at run-time |
415 */ | 424 */ |
416 | 425 |
417 if (ngx_array_init(&in_ports, cf->pool, 2, sizeof(ngx_http_in_port_t)) | 426 if (ngx_array_init(&in_ports, cf->temp_pool, 2, |
427 sizeof(ngx_http_conf_in_port_t)) | |
418 != NGX_OK) | 428 != NGX_OK) |
419 { | 429 { |
420 return NGX_CONF_ERROR; | 430 return NGX_CONF_ERROR; |
421 } | 431 } |
422 | 432 |
428 /* "listen" directives */ | 438 /* "listen" directives */ |
429 | 439 |
430 lscf = cscfp[s]->listen.elts; | 440 lscf = cscfp[s]->listen.elts; |
431 for (l = 0; l < cscfp[s]->listen.nelts; l++) { | 441 for (l = 0; l < cscfp[s]->listen.nelts; l++) { |
432 | 442 |
433 port_found = 0; | |
434 | |
435 /* AF_INET only */ | 443 /* AF_INET only */ |
436 | 444 |
437 in_port = in_ports.elts; | 445 in_port = in_ports.elts; |
438 for (p = 0; p < in_ports.nelts; p++) { | 446 for (p = 0; p < in_ports.nelts; p++) { |
439 | 447 |
440 if (lscf[l].port == in_port[p].port) { | 448 if (lscf[l].port != in_port[p].port) { |
441 | 449 continue; |
442 /* the port is already in the port list */ | 450 } |
443 | 451 |
444 port_found = 1; | 452 /* the port is already in the port list */ |
445 addr_found = 0; | 453 |
446 | 454 in_addr = in_port[p].addrs.elts; |
447 in_addr = in_port[p].addrs.elts; | 455 for (a = 0; a < in_port[p].addrs.nelts; a++) { |
448 for (a = 0; a < in_port[p].addrs.nelts; a++) { | 456 |
449 | 457 if (lscf[l].addr != in_addr[a].addr) { |
450 if (lscf[l].addr == in_addr[a].addr) { | 458 continue; |
451 | 459 } |
452 /* the address is already in the address list */ | 460 |
453 | 461 /* the address is already in the address list */ |
454 if (ngx_http_add_names(cf, &in_addr[a], cscfp[s]) | 462 |
455 != NGX_OK) | 463 if (ngx_http_add_names(cf, &in_addr[a], cscfp[s]) != NGX_OK) |
456 { | 464 { |
457 return NGX_CONF_ERROR; | 465 return NGX_CONF_ERROR; |
458 } | 466 } |
459 | 467 |
460 /* | 468 /* |
461 * check the duplicate "default" server | 469 * check the duplicate "default" server |
462 * for this address:port | 470 * for this address:port |
463 */ | 471 */ |
464 | 472 |
465 if (lscf[l].conf.default_server) { | 473 if (lscf[l].conf.default_server) { |
466 | 474 |
467 if (in_addr[a].conf.default_server) { | 475 if (in_addr[a].default_server) { |
468 ngx_log_error(NGX_LOG_ERR, cf->log, 0, | 476 ngx_log_error(NGX_LOG_ERR, cf->log, 0, |
469 "the duplicate default server in %V:%d", | 477 "the duplicate default server in %V:%d", |
470 &lscf[l].file_name, lscf[l].line); | 478 &lscf[l].file_name, lscf[l].line); |
471 | 479 |
472 return NGX_CONF_ERROR; | |
473 } | |
474 | |
475 in_addr[a].core_srv_conf = cscfp[s]; | |
476 in_addr[a].conf.default_server = 1; | |
477 } | |
478 | |
479 addr_found = 1; | |
480 | |
481 break; | |
482 | |
483 } else if (in_addr[a].addr == INADDR_ANY) { | |
484 | |
485 /* the INADDR_ANY is always the last address */ | |
486 | |
487 inaddr = ngx_array_push(&in_port[p].addrs); | |
488 if (inaddr == NULL) { | |
489 return NGX_CONF_ERROR; | |
490 } | |
491 in_addr = in_port[p].addrs.elts; | |
492 | |
493 /* | |
494 * the INADDR_ANY must be the last resort | |
495 * so we move it to the end of the address list | |
496 * and put the new address in its place | |
497 */ | |
498 | |
499 ngx_memcpy(inaddr, &in_addr[a], | |
500 sizeof(ngx_http_in_addr_t)); | |
501 | |
502 in_addr[a].addr = lscf[l].addr; | |
503 in_addr[a].names.elts = NULL; | |
504 in_addr[a].hash = NULL; | |
505 in_addr[a].wildcards.elts = NULL; | |
506 in_addr[a].core_srv_conf = cscfp[s]; | |
507 in_addr[a].conf = lscf[l].conf; | |
508 | |
509 if (ngx_http_add_names(cf, &in_addr[a], cscfp[s]) | |
510 != NGX_OK) | |
511 { | |
512 return NGX_CONF_ERROR; | |
513 } | |
514 | |
515 addr_found = 1; | |
516 | |
517 break; | |
518 } | |
519 } | |
520 | |
521 if (!addr_found) { | |
522 | |
523 /* | |
524 * add the address to the addresses list that | |
525 * bound to this port | |
526 */ | |
527 | |
528 if (ngx_http_add_address(cf, &in_port[p], &lscf[l], | |
529 cscfp[s]) != NGX_OK) | |
530 { | |
531 return NGX_CONF_ERROR; | 480 return NGX_CONF_ERROR; |
532 } | 481 } |
482 | |
483 in_addr[a].core_srv_conf = cscfp[s]; | |
484 in_addr[a].default_server = 1; | |
533 } | 485 } |
534 } | 486 |
535 } | 487 goto found; |
536 | 488 } |
537 if (!port_found) { | 489 |
538 | 490 /* |
539 /* add the port to the in_port list */ | 491 * add the address to the addresses list that |
540 | 492 * bound to this port |
541 in_port = ngx_array_push(&in_ports); | 493 */ |
542 if (in_port == NULL) { | 494 |
543 return NGX_CONF_ERROR; | 495 if (ngx_http_add_address(cf, &in_port[p], &lscf[l], cscfp[s]) |
544 } | |
545 | |
546 in_port->port = lscf[l].port; | |
547 in_port->addrs.elts = NULL; | |
548 | |
549 in_port->port_text.data = ngx_palloc(cf->pool, 7); | |
550 if (in_port->port_text.data == NULL) { | |
551 return NGX_CONF_ERROR; | |
552 } | |
553 | |
554 in_port->port_text.len = ngx_sprintf(in_port->port_text.data, | |
555 ":%d", in_port->port) | |
556 - in_port->port_text.data; | |
557 | |
558 if (ngx_http_add_address(cf, in_port, &lscf[l], cscfp[s]) | |
559 != NGX_OK) | 496 != NGX_OK) |
560 { | 497 { |
561 return NGX_CONF_ERROR; | 498 return NGX_CONF_ERROR; |
562 } | 499 } |
563 } | 500 |
501 goto found; | |
502 } | |
503 | |
504 /* add the port to the in_port list */ | |
505 | |
506 in_port = ngx_array_push(&in_ports); | |
507 if (in_port == NULL) { | |
508 return NGX_CONF_ERROR; | |
509 } | |
510 | |
511 in_port->port = lscf[l].port; | |
512 in_port->addrs.elts = NULL; | |
513 | |
514 if (ngx_http_add_address(cf, in_port, &lscf[l], cscfp[s]) != NGX_OK) | |
515 { | |
516 return NGX_CONF_ERROR; | |
517 } | |
518 | |
519 found: | |
520 | |
521 continue; | |
564 } | 522 } |
565 } | 523 } |
566 | 524 |
567 | 525 |
568 /* optimize the lists of ports, addresses and server names */ | 526 /* optimize the lists of ports, addresses and server names */ |
570 /* AF_INET only */ | 528 /* AF_INET only */ |
571 | 529 |
572 in_port = in_ports.elts; | 530 in_port = in_ports.elts; |
573 for (p = 0; p < in_ports.nelts; p++) { | 531 for (p = 0; p < in_ports.nelts; p++) { |
574 | 532 |
575 separate_binding = 0; | 533 ngx_qsort(in_port[p].addrs.elts, (size_t) in_port[p].addrs.nelts, |
534 sizeof(ngx_http_conf_in_addr_t), ngx_http_cmp_conf_in_addrs); | |
576 | 535 |
577 /* | 536 /* |
578 * check whether all name-based servers have the same configuraiton | 537 * check whether all name-based servers have the same configuraiton |
579 * as the default server, or some servers restrict the host names | 538 * as the default server, or some servers restrict the host names |
580 */ | 539 */ |
581 | 540 |
582 in_addr = in_port[p].addrs.elts; | 541 in_addr = in_port[p].addrs.elts; |
583 for (a = 0; a < in_port[p].addrs.nelts; a++) { | 542 for (a = 0; a < in_port[p].addrs.nelts; a++) { |
584 | |
585 if (in_addr[a].conf.bind) { | |
586 separate_binding = 1; | |
587 } | |
588 | |
589 virtual_names = 0; | |
590 | 543 |
591 name = in_addr[a].names.elts; | 544 name = in_addr[a].names.elts; |
592 for (n = 0; n < in_addr[a].names.nelts; n++) { | 545 for (n = 0; n < in_addr[a].names.nelts; n++) { |
593 if (in_addr[a].core_srv_conf != name[n].core_srv_conf | 546 if (in_addr[a].core_srv_conf != name[n].core_srv_conf |
594 || name[n].core_srv_conf->restrict_host_names | 547 || name[n].core_srv_conf->restrict_host_names |
595 != NGX_HTTP_RESTRICT_HOST_OFF) | 548 != NGX_HTTP_RESTRICT_HOST_OFF) |
596 { | 549 { |
597 virtual_names = 1; | 550 goto virtual_names; |
598 break; | |
599 } | |
600 } | |
601 | |
602 if (!virtual_names) { | |
603 name = in_addr[a].wildcards.elts; | |
604 for (n = 0; n < in_addr[a].wildcards.nelts; n++) { | |
605 if (in_addr[a].core_srv_conf != name[n].core_srv_conf | |
606 || name[n].core_srv_conf->restrict_host_names | |
607 != NGX_HTTP_RESTRICT_HOST_OFF) | |
608 { | |
609 virtual_names = 1; | |
610 break; | |
611 } | |
612 } | 551 } |
613 } | 552 } |
614 | 553 |
615 /* | 554 /* |
616 * if all name-based servers have the same configuration | 555 * if all name-based servers have the same configuration |
617 * as the default server, and no servers restrict the host names | 556 * as the default server, and no servers restrict the host names |
618 * then we do not need to check them at run-time at all | 557 * then we do not need to check them at run-time at all |
619 */ | 558 */ |
620 | 559 |
621 if (!virtual_names) { | 560 in_addr[a].names.nelts = 0; |
622 in_addr[a].names.nelts = 0; | 561 |
623 continue; | 562 continue; |
624 } | 563 |
625 | 564 virtual_names: |
626 | 565 |
627 ngx_qsort(in_addr[a].names.elts, in_addr[a].names.nelts, | 566 ha.temp_pool = ngx_create_pool(16384, cf->log); |
628 sizeof(ngx_http_server_name_t), ngx_cmp_server_names); | 567 if (ha.temp_pool == NULL) { |
629 | 568 return NGX_CONF_ERROR; |
630 | 569 } |
631 /* create a hash for many names */ | 570 |
632 | 571 ha.pool = cf->pool; |
633 if (in_addr[a].names.nelts > cmcf->server_names_hash_threshold) { | 572 |
634 in_addr[a].hash = ngx_palloc(cf->pool, | 573 if (ngx_hash_keys_array_init(&ha, NGX_HASH_LARGE) != NGX_OK) { |
635 cmcf->server_names_hash | 574 ngx_destroy_pool(ha.temp_pool); |
636 * sizeof(ngx_array_t)); | 575 return NGX_CONF_ERROR; |
637 if (in_addr[a].hash == NULL) { | 576 } |
577 | |
578 name = in_addr[a].names.elts; | |
579 for (s = 0; s < in_addr[a].names.nelts; s++) { | |
580 | |
581 ch = name[s].name.data[0]; | |
582 | |
583 if (ch == '*' || ch == '.') { | |
584 continue; | |
585 } | |
586 | |
587 rc = ngx_hash_add_key(&ha, &name[s].name, name[s].core_srv_conf, | |
588 0); | |
589 | |
590 if (rc == NGX_ERROR) { | |
638 return NGX_CONF_ERROR; | 591 return NGX_CONF_ERROR; |
639 } | 592 } |
640 | 593 |
641 for (n = 0; n < cmcf->server_names_hash; n++) { | 594 if (rc == NGX_BUSY) { |
642 if (ngx_array_init(&in_addr[a].hash[n], cf->pool, 4, | 595 ngx_log_error(NGX_LOG_WARN, cf->log, 0, |
643 sizeof(ngx_http_server_name_t)) != NGX_OK) | 596 "conflicting server name \"%V\", ignored", |
644 { | 597 &name[s].name); |
645 return NGX_CONF_ERROR; | 598 } |
646 } | 599 } |
647 } | 600 |
648 | 601 for (s = 0; s < in_addr[a].names.nelts; s++) { |
649 name = in_addr[a].names.elts; | 602 |
650 for (s = 0; s < in_addr[a].names.nelts; s++) { | 603 ch = name[s].name.data[0]; |
651 ngx_http_server_names_hash_key(key, name[s].name.data, | 604 |
652 name[s].name.len, | 605 if (ch != '*' && ch != '.') { |
653 cmcf->server_names_hash); | 606 continue; |
654 | 607 } |
655 s_name = ngx_array_push(&in_addr[a].hash[key]); | 608 |
656 if (s_name == NULL) { | 609 rc = ngx_hash_add_key(&ha, &name[s].name, name[s].core_srv_conf, |
657 return NGX_CONF_ERROR; | 610 NGX_HASH_WILDCARD_KEY); |
658 } | 611 |
659 name = in_addr[a].names.elts; | 612 if (rc == NGX_ERROR) { |
660 | 613 return NGX_CONF_ERROR; |
661 *s_name = name[s]; | 614 } |
662 } | 615 |
663 } | 616 if (rc == NGX_BUSY) { |
664 } | 617 ngx_log_error(NGX_LOG_WARN, cf->log, 0, |
618 "conflicting server name \"%V\", ignored", | |
619 &name[s].name); | |
620 } | |
621 } | |
622 | |
623 hash.key = ngx_hash_key_lc; | |
624 hash.max_size = cmcf->server_names_hash_max_size; | |
625 hash.bucket_size = cmcf->server_names_hash_bucket_size; | |
626 hash.name = "server_names_hash"; | |
627 hash.pool = cf->pool; | |
628 | |
629 if (ha.keys.nelts) { | |
630 hash.hash = &in_addr[a].hash; | |
631 hash.temp_pool = NULL; | |
632 | |
633 if (ngx_hash_init(&hash, ha.keys.elts, ha.keys.nelts) != NGX_OK) | |
634 { | |
635 ngx_destroy_pool(ha.temp_pool); | |
636 return NGX_CONF_ERROR; | |
637 } | |
638 } | |
639 | |
640 if (ha.dns_wildcards.nelts) { | |
641 | |
642 ngx_qsort(ha.dns_wildcards.elts, | |
643 (size_t) ha.dns_wildcards.nelts, | |
644 sizeof(ngx_hash_key_t), | |
645 ngx_http_cmp_dns_wildcards); | |
646 | |
647 hash.hash = NULL; | |
648 hash.temp_pool = ha.temp_pool; | |
649 | |
650 if (ngx_hash_wildcard_init(&hash, ha.dns_wildcards.elts, | |
651 ha.dns_wildcards.nelts) | |
652 != NGX_OK) | |
653 { | |
654 ngx_destroy_pool(ha.temp_pool); | |
655 return NGX_CONF_ERROR; | |
656 } | |
657 | |
658 in_addr[a].dns_wildcards = (ngx_hash_wildcard_t *) hash.hash; | |
659 } | |
660 | |
661 ngx_destroy_pool(ha.temp_pool); | |
662 } | |
663 | |
664 in_addr = in_port[p].addrs.elts; | |
665 last = in_port[p].addrs.nelts; | |
665 | 666 |
666 /* | 667 /* |
667 * if there is the binding to the "*:port" then we need to bind() | 668 * if there is the binding to the "*:port" then we need to bind() |
668 * to the "*:port" only and ignore the other bindings | 669 * to the "*:port" only and ignore the other bindings |
669 */ | 670 */ |
670 | 671 |
671 if (in_addr[a - 1].addr == INADDR_ANY && !separate_binding) { | 672 if (in_addr[last - 1].addr == INADDR_ANY) { |
672 a--; | 673 in_addr[last - 1].bind = 1; |
674 bind_all = 0; | |
673 | 675 |
674 } else { | 676 } else { |
675 a = 0; | 677 bind_all = 1; |
676 } | 678 } |
677 | 679 |
678 in_addr = in_port[p].addrs.elts; | 680 for (a = 0; a < last; /* void */ ) { |
679 while (a < in_port[p].addrs.nelts) { | 681 |
682 if (!bind_all && !in_addr[a].bind) { | |
683 a++; | |
684 continue; | |
685 } | |
680 | 686 |
681 ls = ngx_listening_inet_stream_socket(cf, in_addr[a].addr, | 687 ls = ngx_listening_inet_stream_socket(cf, in_addr[a].addr, |
682 in_port[p].port); | 688 in_port[p].port); |
683 if (ls == NULL) { | 689 if (ls == NULL) { |
684 return NGX_CONF_ERROR; | 690 return NGX_CONF_ERROR; |
703 if (iocpcf->acceptex_read) { | 709 if (iocpcf->acceptex_read) { |
704 ls->post_accept_buffer_size = cscf->client_header_buffer_size; | 710 ls->post_accept_buffer_size = cscf->client_header_buffer_size; |
705 } | 711 } |
706 #endif | 712 #endif |
707 | 713 |
708 ls->backlog = in_addr[a].conf.backlog; | 714 ls->backlog = in_addr[a].listen_conf->backlog; |
709 ls->rcvbuf = in_addr[a].conf.rcvbuf; | 715 ls->rcvbuf = in_addr[a].listen_conf->rcvbuf; |
710 ls->sndbuf = in_addr[a].conf.sndbuf; | 716 ls->sndbuf = in_addr[a].listen_conf->sndbuf; |
711 | 717 |
712 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) | 718 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) |
713 ls->accept_filter = in_addr[a].conf.accept_filter; | 719 ls->accept_filter = in_addr[a].listen_conf->accept_filter; |
714 #endif | 720 #endif |
715 | 721 |
716 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT) | 722 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT) |
717 ls->deferred_accept = in_addr[a].conf.deferred_accept; | 723 ls->deferred_accept = in_addr[a].listen_conf->deferred_accept; |
718 #endif | 724 #endif |
719 | 725 |
720 ls->ctx = ctx; | 726 ls->ctx = ctx; |
721 | 727 |
722 if (in_port[p].addrs.nelts > 1) { | 728 hip = ngx_palloc(cf->pool, sizeof(ngx_http_in_port_t)); |
723 | 729 if (hip == NULL) { |
724 in_addr = in_port[p].addrs.elts; | 730 return NGX_CONF_ERROR; |
725 if (in_addr[in_port[p].addrs.nelts - 1].addr != INADDR_ANY) { | 731 } |
726 | 732 |
727 /* | 733 hip->port = in_port[p].port; |
728 * if this port has not the "*:port" binding then create | 734 |
729 * the separate ngx_http_in_port_t for the all bindings | 735 hip->port_text.data = ngx_palloc(cf->pool, 7); |
730 */ | 736 if (hip->port_text.data == NULL) { |
731 | 737 return NGX_CONF_ERROR; |
732 inport = ngx_palloc(cf->pool, sizeof(ngx_http_in_port_t)); | 738 } |
733 if (inport == NULL) { | 739 |
734 return NGX_CONF_ERROR; | 740 ls->servers = hip; |
735 } | 741 |
736 | 742 hip->port_text.len = ngx_sprintf(hip->port_text.data, ":%d", |
737 inport->port = in_port[p].port; | 743 hip->port) |
738 inport->port_text = in_port[p].port_text; | 744 - hip->port_text.data; |
739 | 745 |
740 /* init list of the addresses ... */ | 746 in_addr = in_port[p].addrs.elts; |
741 | 747 |
742 if (ngx_array_init(&inport->addrs, cf->pool, 1, | 748 if (in_addr[a].bind && in_addr[a].addr != INADDR_ANY) { |
743 sizeof(ngx_http_in_addr_t)) != NGX_OK) | 749 hip->naddrs = 1; |
744 { | 750 done = 0; |
745 return NGX_CONF_ERROR; | 751 |
746 } | 752 } else if (in_port[p].addrs.nelts > 1 |
747 | 753 && in_addr[last - 1].addr == INADDR_ANY) |
748 /* ... and set up it with the first address */ | 754 { |
749 | 755 hip->naddrs = last; |
750 inport->addrs.nelts = 1; | 756 done = 1; |
751 inport->addrs.elts = in_port[p].addrs.elts; | 757 |
752 | 758 } else { |
753 ls->servers = inport; | 759 hip->naddrs = 1; |
754 | 760 done = 0; |
755 /* prepare for the next cycle */ | 761 } |
756 | 762 |
757 in_port[p].addrs.elts = (char *) in_port[p].addrs.elts | 763 #if 0 |
758 + in_port[p].addrs.size; | 764 ngx_log_error(NGX_LOG_ALERT, cf->log, 0, |
759 in_port[p].addrs.nelts--; | 765 "%ui: %V %d %ui %ui", |
760 | 766 a, &ls->addr_text, in_addr[a].bind, |
761 in_addr = (ngx_http_in_addr_t *) in_port[p].addrs.elts; | 767 hip->naddrs, last); |
762 a = 0; | 768 #endif |
763 | 769 |
770 hip->addrs = ngx_pcalloc(cf->pool, | |
771 hip->naddrs * sizeof(ngx_http_in_addr_t)); | |
772 if (hip->addrs == NULL) { | |
773 return NGX_CONF_ERROR; | |
774 } | |
775 | |
776 for (i = 0; i < hip->naddrs; i++) { | |
777 hip->addrs[i].addr = in_addr[i].addr; | |
778 hip->addrs[i].core_srv_conf = in_addr[i].core_srv_conf; | |
779 | |
780 if (in_addr[i].hash.buckets == NULL | |
781 && (in_addr[i].dns_wildcards == NULL | |
782 || in_addr[i].dns_wildcards->hash.buckets == NULL)) | |
783 { | |
764 continue; | 784 continue; |
765 } | 785 } |
766 } | 786 |
767 | 787 vn = ngx_palloc(cf->pool, sizeof(ngx_http_virtual_names_t)); |
768 ls->servers = &in_port[p]; | 788 if (vn == NULL) { |
769 a++; | 789 return NGX_CONF_ERROR; |
790 } | |
791 hip->addrs[i].virtual_names = vn; | |
792 | |
793 vn->hash = in_addr[i].hash; | |
794 vn->dns_wildcards = in_addr[i].dns_wildcards; | |
795 } | |
796 | |
797 if (done) { | |
798 break; | |
799 } | |
800 | |
801 in_addr++; | |
802 in_port[p].addrs.elts = in_addr; | |
803 last--; | |
804 | |
805 a = 0; | |
770 } | 806 } |
771 } | 807 } |
772 | 808 |
773 #if 0 | 809 #if 0 |
774 { | 810 { |
783 for (a = 0; a < in_port[p].addrs.nelts; a++) { | 819 for (a = 0; a < in_port[p].addrs.nelts; a++) { |
784 ngx_inet_ntop(AF_INET, &in_addr[a].addr, address, 20); | 820 ngx_inet_ntop(AF_INET, &in_addr[a].addr, address, 20); |
785 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, cf->log, 0, | 821 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, cf->log, 0, |
786 "%s:%d %p", | 822 "%s:%d %p", |
787 address, in_port[p].port, in_addr[a].core_srv_conf); | 823 address, in_port[p].port, in_addr[a].core_srv_conf); |
788 s_name = in_addr[a].names.elts; | 824 name = in_addr[a].names.elts; |
789 for (n = 0; n < in_addr[a].names.nelts; n++) { | 825 for (n = 0; n < in_addr[a].names.nelts; n++) { |
790 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, cf->log, 0, | 826 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, cf->log, 0, |
791 "%s:%d %V %p", | 827 "%s:%d %V %p", |
792 address, in_port[p].port, &s_name[n].name, | 828 address, in_port[p].port, &name[n].name, |
793 s_name[n].core_srv_conf); | 829 name[n].core_srv_conf); |
794 } | 830 } |
795 } | 831 } |
796 } | 832 } |
797 } | 833 } |
798 #endif | 834 #endif |
799 | 835 |
800 return NGX_CONF_OK; | 836 return NGX_CONF_OK; |
801 } | |
802 | |
803 | |
804 static int ngx_libc_cdecl | |
805 ngx_cmp_server_names(const void *one, const void *two) | |
806 { | |
807 ngx_http_server_name_t *first = (ngx_http_server_name_t *) one; | |
808 ngx_http_server_name_t *second = (ngx_http_server_name_t *) two; | |
809 | |
810 return ngx_strcmp(first->name.data, second->name.data); | |
811 } | 837 } |
812 | 838 |
813 | 839 |
814 /* | 840 /* |
815 * add the server address, the server names and the server core module | 841 * add the server address, the server names and the server core module |
816 * configurations to the port (in_port) | 842 * configurations to the port (in_port) |
817 */ | 843 */ |
818 | 844 |
819 static ngx_int_t | 845 static ngx_int_t |
820 ngx_http_add_address(ngx_conf_t *cf, ngx_http_in_port_t *in_port, | 846 ngx_http_add_address(ngx_conf_t *cf, ngx_http_conf_in_port_t *in_port, |
821 ngx_http_listen_t *lscf, ngx_http_core_srv_conf_t *cscf) | 847 ngx_http_listen_t *lscf, ngx_http_core_srv_conf_t *cscf) |
822 { | 848 { |
823 ngx_http_in_addr_t *in_addr; | 849 ngx_http_conf_in_addr_t *in_addr; |
824 | 850 |
825 if (in_port->addrs.elts == NULL) { | 851 if (in_port->addrs.elts == NULL) { |
826 if (ngx_array_init(&in_port->addrs, cf->pool, 4, | 852 if (ngx_array_init(&in_port->addrs, cf->temp_pool, 4, |
827 sizeof(ngx_http_in_addr_t)) != NGX_OK) | 853 sizeof(ngx_http_conf_in_addr_t)) != NGX_OK) |
828 { | 854 { |
829 return NGX_ERROR; | 855 return NGX_ERROR; |
830 } | 856 } |
831 } | 857 } |
832 | 858 |
834 if (in_addr == NULL) { | 860 if (in_addr == NULL) { |
835 return NGX_ERROR; | 861 return NGX_ERROR; |
836 } | 862 } |
837 | 863 |
838 in_addr->addr = lscf->addr; | 864 in_addr->addr = lscf->addr; |
865 in_addr->hash.buckets = NULL; | |
866 in_addr->hash.size = 0; | |
867 in_addr->dns_wildcards = NULL; | |
839 in_addr->names.elts = NULL; | 868 in_addr->names.elts = NULL; |
840 in_addr->hash = NULL; | |
841 in_addr->wildcards.elts = NULL; | |
842 in_addr->core_srv_conf = cscf; | 869 in_addr->core_srv_conf = cscf; |
843 in_addr->conf = lscf->conf; | 870 in_addr->default_server = lscf->conf.default_server; |
871 in_addr->bind = lscf->conf.bind; | |
872 in_addr->listen_conf = &lscf->conf; | |
844 | 873 |
845 #if (NGX_DEBUG) | 874 #if (NGX_DEBUG) |
846 { | 875 { |
847 u_char text[20]; | 876 u_char text[20]; |
848 ngx_inet_ntop(AF_INET, &in_addr->addr, text, 20); | 877 ngx_inet_ntop(AF_INET, &in_addr->addr, text, 20); |
859 * add the server names and the server core module | 888 * add the server names and the server core module |
860 * configurations to the address:port (in_addr) | 889 * configurations to the address:port (in_addr) |
861 */ | 890 */ |
862 | 891 |
863 static ngx_int_t | 892 static ngx_int_t |
864 ngx_http_add_names(ngx_conf_t *cf, ngx_http_in_addr_t *in_addr, | 893 ngx_http_add_names(ngx_conf_t *cf, ngx_http_conf_in_addr_t *in_addr, |
865 ngx_http_core_srv_conf_t *cscf) | 894 ngx_http_core_srv_conf_t *cscf) |
866 { | 895 { |
867 ngx_uint_t i, n; | 896 ngx_uint_t i, n; |
868 ngx_array_t *array; | |
869 ngx_http_server_name_t *server_names, *name; | 897 ngx_http_server_name_t *server_names, *name; |
870 | 898 |
871 if (in_addr->names.elts == NULL) { | 899 if (in_addr->names.elts == NULL) { |
872 if (ngx_array_init(&in_addr->names, cf->pool, 4, | 900 if (ngx_array_init(&in_addr->names, cf->temp_pool, 4, |
873 sizeof(ngx_http_server_name_t)) != NGX_OK) | 901 sizeof(ngx_http_server_name_t)) != NGX_OK) |
874 { | 902 { |
875 return NGX_ERROR; | 903 return NGX_ERROR; |
876 } | 904 } |
877 } | 905 } |
878 | 906 |
879 if (in_addr->wildcards.elts == NULL) { | |
880 if (ngx_array_init(&in_addr->wildcards, cf->pool, 1, | |
881 sizeof(ngx_http_server_name_t)) != NGX_OK) | |
882 { | |
883 return NGX_ERROR; | |
884 } | |
885 } | |
886 | |
887 server_names = cscf->server_names.elts; | 907 server_names = cscf->server_names.elts; |
888 for (i = 0; i < cscf->server_names.nelts; i++) { | 908 for (i = 0; i < cscf->server_names.nelts; i++) { |
889 | 909 |
890 for (n = 0; n < server_names[i].name.len; n++) { | 910 for (n = 0; n < server_names[i].name.len; n++) { |
891 server_names[i].name.data[n] = | 911 server_names[i].name.data[n] = |
893 } | 913 } |
894 | 914 |
895 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0, | 915 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0, |
896 "name: %V", &server_names[i].name); | 916 "name: %V", &server_names[i].name); |
897 | 917 |
898 /* TODO: duplicate names can be checked here */ | 918 |
899 | 919 name = ngx_array_push(&in_addr->names); |
900 | |
901 if (server_names[i].wildcard) { | |
902 array = &in_addr->wildcards; | |
903 | |
904 } else { | |
905 array = &in_addr->names; | |
906 } | |
907 | |
908 name = ngx_array_push(array); | |
909 if (name == NULL) { | 920 if (name == NULL) { |
910 return NGX_ERROR; | 921 return NGX_ERROR; |
911 } | 922 } |
912 server_names = cscf->server_names.elts; | 923 server_names = cscf->server_names.elts; |
913 | 924 |
924 { | 935 { |
925 char *rv; | 936 char *rv; |
926 ngx_uint_t i; | 937 ngx_uint_t i; |
927 ngx_http_core_loc_conf_t **clcfp; | 938 ngx_http_core_loc_conf_t **clcfp; |
928 | 939 |
929 clcfp = /* (ngx_http_core_loc_conf_t **) */ locations->elts; | 940 clcfp = locations->elts; |
930 | 941 |
931 for (i = 0; i < locations->nelts; i++) { | 942 for (i = 0; i < locations->nelts; i++) { |
932 rv = module->merge_loc_conf(cf, loc_conf[ctx_index], | 943 rv = module->merge_loc_conf(cf, loc_conf[ctx_index], |
933 clcfp[i]->loc_conf[ctx_index]); | 944 clcfp[i]->loc_conf[ctx_index]); |
934 if (rv != NGX_CONF_OK) { | 945 if (rv != NGX_CONF_OK) { |
942 } | 953 } |
943 } | 954 } |
944 | 955 |
945 return NGX_CONF_OK; | 956 return NGX_CONF_OK; |
946 } | 957 } |
958 | |
959 | |
960 static int ngx_libc_cdecl | |
961 ngx_http_cmp_conf_in_addrs(const void *one, const void *two) | |
962 { | |
963 ngx_http_conf_in_addr_t *first, *second; | |
964 | |
965 first = (ngx_http_conf_in_addr_t *) one; | |
966 second = (ngx_http_conf_in_addr_t *) two; | |
967 | |
968 if (first->addr == INADDR_ANY) { | |
969 /* the INADDR_ANY must be the last resort, shift it to the end */ | |
970 return 1; | |
971 } | |
972 | |
973 if (first->bind && !second->bind) { | |
974 /* shift explicit bind()ed addresses to the start */ | |
975 return -1; | |
976 } | |
977 | |
978 if (!first->bind && second->bind) { | |
979 /* shift explicit bind()ed addresses to the start */ | |
980 return 1; | |
981 } | |
982 | |
983 /* do not sort by default */ | |
984 | |
985 return 0; | |
986 } | |
987 | |
988 | |
989 static int ngx_libc_cdecl | |
990 ngx_http_cmp_dns_wildcards(const void *one, const void *two) | |
991 { | |
992 ngx_hash_key_t *first, *second; | |
993 | |
994 first = (ngx_hash_key_t *) one; | |
995 second = (ngx_hash_key_t *) two; | |
996 | |
997 return ngx_strcmp(first->key.data, second->key.data); | |
998 } |