498
* create the lists of ports, addresses and server names
499
* to quickly find the server core module configuration at run-time
502
if (ngx_array_init(&in_ports, cf->temp_pool, 2,
503
sizeof(ngx_http_conf_in_port_t))
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)
610
ngx_http_core_loc_conf_t *clcf;
611
ngx_http_location_queue_t *lq;
613
if (locations == NULL) {
617
for (q = ngx_queue_head(locations);
618
q != ngx_queue_sentinel(locations);
619
q = ngx_queue_next(q))
621
lq = (ngx_http_location_queue_t *) q;
623
clcf = lq->exact ? lq->exact : lq->inclusive;
625
rv = module->merge_loc_conf(cf, loc_conf[ctx_index],
626
clcf->loc_conf[ctx_index]);
627
if (rv != NGX_CONF_OK) {
631
rv = ngx_http_merge_locations(cf, clcf->locations, clcf->loc_conf,
633
if (rv != NGX_CONF_OK) {
643
ngx_http_init_locations(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
644
ngx_http_core_loc_conf_t *pclcf)
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;
656
locations = pclcf->locations;
658
if (locations == NULL) {
662
ngx_queue_sort(locations, ngx_http_cmp_locations);
671
for (q = ngx_queue_head(locations);
672
q != ngx_queue_sentinel(locations);
673
q = ngx_queue_next(q))
675
lq = (ngx_http_location_queue_t *) q;
677
clcf = lq->exact ? lq->exact : lq->inclusive;
679
if (ngx_http_init_locations(cf, NULL, clcf) != NGX_OK) {
712
if (q != ngx_queue_sentinel(locations)) {
713
ngx_queue_split(locations, q, &tail);
717
clcfp = ngx_palloc(cf->pool,
718
(n + 1) * sizeof(ngx_http_core_loc_conf_t **));
723
cscf->named_locations = clcfp;
726
q != ngx_queue_sentinel(locations);
727
q = ngx_queue_next(q))
729
lq = (ngx_http_location_queue_t *) q;
731
*(clcfp++) = lq->exact;
736
ngx_queue_split(locations, named, &tail);
743
clcfp = ngx_palloc(cf->pool,
744
(r + 1) * sizeof(ngx_http_core_loc_conf_t **));
749
pclcf->regex_locations = clcfp;
752
q != ngx_queue_sentinel(locations);
753
q = ngx_queue_next(q))
755
lq = (ngx_http_location_queue_t *) q;
757
*(clcfp++) = lq->exact;
762
ngx_queue_split(locations, regex, &tail);
772
ngx_http_init_static_location_trees(ngx_conf_t *cf,
773
ngx_http_core_loc_conf_t *pclcf)
775
ngx_queue_t *q, *locations;
776
ngx_http_core_loc_conf_t *clcf;
777
ngx_http_location_queue_t *lq;
779
locations = pclcf->locations;
781
if (locations == NULL) {
785
if (ngx_queue_empty(locations)) {
789
for (q = ngx_queue_head(locations);
790
q != ngx_queue_sentinel(locations);
791
q = ngx_queue_next(q))
793
lq = (ngx_http_location_queue_t *) q;
795
clcf = lq->exact ? lq->exact : lq->inclusive;
797
if (ngx_http_init_static_location_trees(cf, clcf) != NGX_OK) {
802
if (ngx_http_join_exact_locations(cf, locations) != NGX_OK) {
806
ngx_http_create_locations_list(locations, ngx_queue_head(locations));
808
pclcf->static_locations = ngx_http_create_locations_tree(cf, locations, 0);
809
if (pclcf->static_locations == NULL) {
818
ngx_http_add_location(ngx_conf_t *cf, ngx_queue_t **locations,
819
ngx_http_core_loc_conf_t *clcf)
821
ngx_http_location_queue_t *lq;
823
if (*locations == NULL) {
824
*locations = ngx_palloc(cf->temp_pool,
825
sizeof(ngx_http_location_queue_t));
826
if (*locations == NULL) {
830
ngx_queue_init(*locations);
833
lq = ngx_palloc(cf->temp_pool, sizeof(ngx_http_location_queue_t));
838
if (clcf->exact_match
842
|| clcf->named || clcf->noname)
845
lq->inclusive = NULL;
849
lq->inclusive = clcf;
852
lq->name = &clcf->name;
853
lq->file_name = cf->conf_file->file.name.data;
854
lq->line = cf->conf_file->line;
856
ngx_queue_init(&lq->list);
858
ngx_queue_insert_tail(*locations, &lq->queue);
865
ngx_http_cmp_locations(const ngx_queue_t *one, const ngx_queue_t *two)
868
ngx_http_core_loc_conf_t *first, *second;
869
ngx_http_location_queue_t *lq1, *lq2;
871
lq1 = (ngx_http_location_queue_t *) one;
872
lq2 = (ngx_http_location_queue_t *) two;
874
first = lq1->exact ? lq1->exact : lq1->inclusive;
875
second = lq2->exact ? lq2->exact : lq2->inclusive;
877
if (first->noname && !second->noname) {
878
/* shift no named locations to the end */
882
if (!first->noname && second->noname) {
883
/* shift no named locations to the end */
887
if (first->noname || second->noname) {
888
/* do not sort no named locations */
892
if (first->named && !second->named) {
893
/* shift named locations to the end */
897
if (!first->named && second->named) {
898
/* shift named locations to the end */
902
if (first->named && second->named) {
903
return ngx_strcmp(first->name.data, second->name.data);
908
if (first->regex && !second->regex) {
909
/* shift the regex matches to the end */
913
if (!first->regex && second->regex) {
914
/* shift the regex matches to the end */
918
if (first->regex || second->regex) {
919
/* do not sort the regex matches */
925
rc = ngx_strcmp(first->name.data, second->name.data);
927
if (rc == 0 && !first->exact_match && second->exact_match) {
928
/* an exact match must be before the same inclusive one */
937
ngx_http_join_exact_locations(ngx_conf_t *cf, ngx_queue_t *locations)
940
ngx_http_location_queue_t *lq, *lx;
942
q = ngx_queue_head(locations);
944
while (q != ngx_queue_last(locations)) {
946
x = ngx_queue_next(q);
948
lq = (ngx_http_location_queue_t *) q;
949
lx = (ngx_http_location_queue_t *) x;
951
if (ngx_strcmp(lq->name->data, lx->name->data) == 0) {
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);
961
lq->inclusive = lx->inclusive;
968
q = ngx_queue_next(q);
976
ngx_http_create_locations_list(ngx_queue_t *locations, ngx_queue_t *q)
980
ngx_queue_t *x, tail;
981
ngx_http_location_queue_t *lq, *lx;
983
if (q == ngx_queue_last(locations)) {
987
lq = (ngx_http_location_queue_t *) q;
989
if (lq->inclusive == NULL) {
990
ngx_http_create_locations_list(locations, ngx_queue_next(q));
995
name = lq->name->data;
997
for (x = ngx_queue_next(q);
998
x != ngx_queue_sentinel(locations);
999
x = ngx_queue_next(x))
1001
lx = (ngx_http_location_queue_t *) x;
1003
if (len > lx->name->len
1004
|| (ngx_strncmp(name, lx->name->data, len) != 0))
1010
q = ngx_queue_next(q);
1013
ngx_http_create_locations_list(locations, x);
1017
ngx_queue_split(locations, q, &tail);
1018
ngx_queue_add(&lq->list, &tail);
1020
if (x == ngx_queue_sentinel(locations)) {
1021
ngx_http_create_locations_list(&lq->list, ngx_queue_head(&lq->list));
1025
ngx_queue_split(&lq->list, x, &tail);
1026
ngx_queue_add(locations, &tail);
1028
ngx_http_create_locations_list(&lq->list, ngx_queue_head(&lq->list));
1030
ngx_http_create_locations_list(locations, x);
1035
* to keep cache locality for left leaf nodes, allocate nodes in following
1036
* order: node, left subtree, right subtree, inclusive subtree
1039
static ngx_http_location_tree_node_t *
1040
ngx_http_create_locations_tree(ngx_conf_t *cf, ngx_queue_t *locations,
1044
ngx_queue_t *q, tail;
1045
ngx_http_location_queue_t *lq;
1046
ngx_http_location_tree_node_t *node;
1048
q = ngx_queue_middle(locations);
1050
lq = (ngx_http_location_queue_t *) q;
1051
len = lq->name->len - prefix;
1053
node = ngx_palloc(cf->pool,
1054
offsetof(ngx_http_location_tree_node_t, name) + len);
1062
node->exact = lq->exact;
1063
node->inclusive = lq->inclusive;
1065
node->auto_redirect = (u_char) ((lq->exact && lq->exact->auto_redirect)
1066
|| (lq->inclusive && lq->inclusive->auto_redirect));
1068
node->len = (u_char) len;
1069
ngx_memcpy(node->name, &lq->name->data[prefix], len);
1071
ngx_queue_split(locations, q, &tail);
1073
if (ngx_queue_empty(locations)) {
1075
* ngx_queue_split() insures that if left part is empty,
1076
* then right one is empty too
1081
node->left = ngx_http_create_locations_tree(cf, locations, prefix);
1082
if (node->left == NULL) {
1086
ngx_queue_remove(q);
1088
if (ngx_queue_empty(&tail)) {
1092
node->right = ngx_http_create_locations_tree(cf, &tail, prefix);
1093
if (node->right == NULL) {
1099
if (ngx_queue_empty(&lq->list)) {
1103
node->tree = ngx_http_create_locations_tree(cf, &lq->list, prefix + len);
1104
if (node->tree == NULL) {
1113
ngx_http_init_server_lists(ngx_conf_t *cf, ngx_array_t *servers,
1117
ngx_http_listen_t *listen;
1118
ngx_http_core_srv_conf_t **cscfp;
1120
if (ngx_array_init(ports, cf->temp_pool, 2, sizeof(ngx_http_conf_port_t))
506
return NGX_CONF_ERROR;
509
1126
/* "server" directives */
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++) {
514
1131
/* "listen" directives */
516
lscf = cscfp[s]->listen.elts;
517
for (l = 0; l < cscfp[s]->listen.nelts; l++) {
521
in_port = in_ports.elts;
522
for (p = 0; p < in_ports.nelts; p++) {
524
if (lscf[l].port != in_port[p].port) {
528
/* the port is already in the port list */
530
in_addr = in_port[p].addrs.elts;
531
for (a = 0; a < in_port[p].addrs.nelts; a++) {
533
if (lscf[l].addr != in_addr[a].addr) {
537
/* the address is already in the address list */
539
if (ngx_http_add_names(cf, &in_addr[a], cscfp[s]) != NGX_OK)
541
return NGX_CONF_ERROR;
545
* check the duplicate "default" server
546
* for this address:port
549
if (lscf[l].conf.default_server) {
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);
556
return NGX_CONF_ERROR;
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;
568
* add the address to the addresses list that
572
if (ngx_http_add_address(cf, &in_port[p], &lscf[l], cscfp[s])
575
return NGX_CONF_ERROR;
581
/* add the port to the in_port list */
583
in_port = ngx_array_push(&in_ports);
584
if (in_port == NULL) {
585
return NGX_CONF_ERROR;
588
in_port->port = lscf[l].port;
589
in_port->addrs.elts = NULL;
591
if (ngx_http_add_address(cf, in_port, &lscf[l], cscfp[s]) != NGX_OK)
593
return NGX_CONF_ERROR;
603
/* optimize the lists of ports, addresses and server names */
607
in_port = in_ports.elts;
608
for (p = 0; p < in_ports.nelts; p++) {
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);
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
619
in_addr = in_port[p].addrs.elts;
620
for (a = 0; a < in_port[p].addrs.nelts; a++) {
622
name = in_addr[a].names.elts;
623
for (s = 0; s < in_addr[a].names.nelts; s++) {
625
if (in_addr[a].core_srv_conf != name[s].core_srv_conf
626
|| name[s].core_srv_conf->optimize_server_names == 0)
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
639
in_addr[a].names.nelts = 0;
645
ngx_memzero(&ha, sizeof(ngx_hash_keys_arrays_t));
647
ha.temp_pool = ngx_create_pool(16384, cf->log);
648
if (ha.temp_pool == NULL) {
649
return NGX_CONF_ERROR;
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;
663
name = in_addr[a].names.elts;
665
for (s = 0; s < in_addr[a].names.nelts; s++) {
674
rc = ngx_hash_add_key(&ha, &name[s].name, name[s].core_srv_conf,
675
NGX_HASH_WILDCARD_KEY);
677
if (rc == NGX_ERROR) {
678
return NGX_CONF_ERROR;
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;
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);
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;
702
hash.hash = &in_addr[a].hash;
703
hash.temp_pool = NULL;
705
if (ngx_hash_init(&hash, ha.keys.elts, ha.keys.nelts) != NGX_OK)
707
ngx_destroy_pool(ha.temp_pool);
708
return NGX_CONF_ERROR;
712
if (ha.dns_wc_head.nelts) {
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);
720
hash.temp_pool = ha.temp_pool;
722
if (ngx_hash_wildcard_init(&hash, ha.dns_wc_head.elts,
723
ha.dns_wc_head.nelts)
726
ngx_destroy_pool(ha.temp_pool);
727
return NGX_CONF_ERROR;
730
in_addr[a].wc_head = (ngx_hash_wildcard_t *) hash.hash;
733
if (ha.dns_wc_tail.nelts) {
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);
741
hash.temp_pool = ha.temp_pool;
743
if (ngx_hash_wildcard_init(&hash, ha.dns_wc_tail.elts,
744
ha.dns_wc_tail.nelts)
747
ngx_destroy_pool(ha.temp_pool);
748
return NGX_CONF_ERROR;
751
in_addr[a].wc_tail = (ngx_hash_wildcard_t *) hash.hash;
754
ngx_destroy_pool(ha.temp_pool);
762
in_addr[a].nregex = regex;
763
in_addr[a].regex = ngx_palloc(cf->pool,
764
regex * sizeof(ngx_http_server_name_t));
766
if (in_addr[a].regex == NULL) {
767
return NGX_CONF_ERROR;
770
for (i = 0, s = 0; s < in_addr[a].names.nelts; s++) {
772
in_addr[a].regex[i++] = name[s];
778
in_addr = in_port[p].addrs.elts;
779
last = in_port[p].addrs.nelts;
782
* if there is the binding to the "*:port" then we need to bind()
783
* to the "*:port" only and ignore the other bindings
786
if (in_addr[last - 1].addr == INADDR_ANY) {
787
in_addr[last - 1].bind = 1;
794
for (a = 0; a < last; /* void */ ) {
796
if (!bind_all && !in_addr[a].bind) {
801
ls = ngx_listening_inet_stream_socket(cf, in_addr[a].addr,
804
return NGX_CONF_ERROR;
809
ls->handler = ngx_http_init_connection;
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;
815
clcf = cscf->ctx->loc_conf[ngx_http_core_module.ctx_index];
817
ls->log = *clcf->err_log;
818
ls->log.data = &ls->addr_text;
819
ls->log.handler = ngx_accept_log_error;
823
ngx_iocp_conf_t *iocpcf;
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;
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;
836
#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
837
ls->accept_filter = in_addr[a].listen_conf->accept_filter;
840
#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
841
ls->deferred_accept = in_addr[a].listen_conf->deferred_accept;
844
hip = ngx_palloc(cf->pool, sizeof(ngx_http_in_port_t));
846
return NGX_CONF_ERROR;
849
hip->port = in_port[p].port;
851
hip->port_text.data = ngx_palloc(cf->pool, 7);
852
if (hip->port_text.data == NULL) {
853
return NGX_CONF_ERROR;
858
hip->port_text.len = ngx_sprintf(hip->port_text.data, ":%d",
860
- hip->port_text.data;
862
in_addr = in_port[p].addrs.elts;
864
if (in_addr[a].bind && in_addr[a].addr != INADDR_ANY) {
868
} else if (in_port[p].addrs.nelts > 1
869
&& in_addr[last - 1].addr == INADDR_ANY)
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,
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;
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;
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))
905
vn = ngx_palloc(cf->pool, sizeof(ngx_http_virtual_names_t));
907
return NGX_CONF_ERROR;
909
hip->addrs[i].virtual_names = vn;
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;
915
vn->nregex = in_addr[i].nregex;
916
vn->regex = in_addr[i].regex;
925
in_port[p].addrs.elts = in_addr;
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,
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,
951
address, in_port[p].port, &name[n].name,
952
name[n].core_srv_conf);
1133
listen = cscfp[s]->listen.elts;
1134
for (i = 0; i < cscfp[s]->listen.nelts; i++) {
1136
if (ngx_http_add_ports(cf, cscfp[s], ports, &listen[i]) != NGX_OK) {
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)
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;
1159
sa = (struct sockaddr *) &listen->sockaddr;
1161
switch (sa->sa_family) {
1163
#if (NGX_HAVE_INET6)
1165
sin6 = (struct sockaddr_in6 *) sa;
1166
p = sin6->sin6_port;
1170
default: /* AF_INET */
1171
sin = (struct sockaddr_in *) sa;
1177
for (i = 0; i < ports->nelts; i++) {
1179
if (p != port[i].port || sa->sa_family != port[i].family) {
1183
/* a port is already in the port list */
1185
return ngx_http_add_addresses(cf, cscf, &port[i], listen);
1188
/* add a port to the port list */
1190
port = ngx_array_push(ports);
1195
port->family = sa->sa_family;
1197
port->addrs.elts = NULL;
1199
return ngx_http_add_address(cf, cscf, port, listen);
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)
1210
struct sockaddr *sa;
1211
ngx_http_conf_addr_t *addr;
1214
* we can not compare whole sockaddr struct's as kernel
1215
* may fill some fields in inherited sockaddr struct's
1218
sa = (struct sockaddr *) &listen->sockaddr;
1220
switch (sa->sa_family) {
1222
#if (NGX_HAVE_INET6)
1224
off = offsetof(struct sockaddr_in6, sin6_addr);
1229
default: /* AF_INET */
1230
off = offsetof(struct sockaddr_in, sin_addr);
1235
p = listen->sockaddr + off;
1237
addr = port->addrs.elts;
1239
for (i = 0; i < port->addrs.nelts; i++) {
1241
if (ngx_memcmp(p, (u_char *) addr[i].sockaddr + off, len) != 0) {
1245
/* the address is already in the address list */
1247
if (ngx_http_add_names(cf, cscf, &addr[i]) != NGX_OK) {
1251
/* check the duplicate "default" server for this address:port */
1253
if (listen->conf.default_server) {
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);
1263
addr[i].core_srv_conf = cscf;
1264
addr[i].default_server = 1;
1266
addr[i].ssl = listen->conf.ssl;
1268
addr[i].listen_conf = &listen->conf;
1274
/* add the address to the addresses list that bound to this port */
1276
return ngx_http_add_address(cf, cscf, port, listen);
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
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)
972
ngx_http_conf_in_addr_t *in_addr;
1289
ngx_http_conf_addr_t *addr;
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))
979
1296
return NGX_ERROR;
983
in_addr = ngx_array_push(&in_port->addrs);
984
if (in_addr == NULL) {
1300
addr = ngx_array_push(&port->addrs);
985
1302
return NGX_ERROR;
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;
996
in_addr->regex = NULL;
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;
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);
1012
return ngx_http_add_names(cf, in_addr, cscf);
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;
1321
addr->ssl = listen->conf.ssl;
1323
addr->listen_conf = &listen->conf;
1325
return ngx_http_add_names(cf, cscf, addr);
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
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)
1026
1339
ngx_http_server_name_t *server_names, *name;
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))
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)
1067
ngx_http_core_loc_conf_t **clcfp;
1069
clcfp = locations->elts;
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) {
1078
if (clcfp[i]->locations == NULL) {
1373
ngx_http_optimize_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
1377
ngx_http_conf_port_t *port;
1378
ngx_http_conf_addr_t *addr;
1379
ngx_http_server_name_t *name;
1382
for (p = 0; p < ports->nelts; p++) {
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);
1388
* check whether all name-based servers have the same
1389
* configuraiton as a default server for given address:port
1392
addr = port[p].addrs.elts;
1393
for (a = 0; a < port[p].addrs.nelts; a++) {
1395
name = addr[a].names.elts;
1396
for (s = 0; s < addr[a].names.nelts; s++) {
1398
if (addr[a].core_srv_conf == name[s].core_srv_conf
1400
&& name[s].captures == 0
1407
if (ngx_http_server_names(cf, cmcf, &addr[a]) != NGX_OK) {
1415
if (ngx_http_init_listening(cf, &port[p]) != NGX_OK) {
1425
ngx_http_server_names(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
1426
ngx_http_conf_addr_t *addr)
1430
ngx_hash_init_t hash;
1431
ngx_hash_keys_arrays_t ha;
1432
ngx_http_server_name_t *name;
1434
ngx_uint_t regex, i;
1439
ngx_memzero(&ha, sizeof(ngx_hash_keys_arrays_t));
1441
ha.temp_pool = ngx_create_pool(16384, cf->log);
1442
if (ha.temp_pool == NULL) {
1448
if (ngx_hash_keys_array_init(&ha, NGX_HASH_LARGE) != NGX_OK) {
1452
name = addr->names.elts;
1454
for (s = 0; s < addr->names.nelts; s++) {
1457
if (name[s].regex) {
1082
rv = ngx_http_merge_locations(cf, clcfp[i]->locations,
1083
clcfp[i]->loc_conf, module, ctx_index);
1084
if (rv != NGX_CONF_OK) {
1463
rc = ngx_hash_add_key(&ha, &name[s].name, name[s].core_srv_conf,
1464
NGX_HASH_WILDCARD_KEY);
1466
if (rc == NGX_ERROR) {
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);
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);
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;
1490
if (ha.keys.nelts) {
1491
hash.hash = &addr->hash;
1492
hash.temp_pool = NULL;
1494
if (ngx_hash_init(&hash, ha.keys.elts, ha.keys.nelts) != NGX_OK) {
1499
if (ha.dns_wc_head.nelts) {
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);
1505
hash.temp_pool = ha.temp_pool;
1507
if (ngx_hash_wildcard_init(&hash, ha.dns_wc_head.elts,
1508
ha.dns_wc_head.nelts)
1514
addr->wc_head = (ngx_hash_wildcard_t *) hash.hash;
1517
if (ha.dns_wc_tail.nelts) {
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);
1523
hash.temp_pool = ha.temp_pool;
1525
if (ngx_hash_wildcard_init(&hash, ha.dns_wc_tail.elts,
1526
ha.dns_wc_tail.nelts)
1532
addr->wc_tail = (ngx_hash_wildcard_t *) hash.hash;
1535
ngx_destroy_pool(ha.temp_pool);
1543
addr->nregex = regex;
1544
addr->regex = ngx_palloc(cf->pool, regex * sizeof(ngx_http_server_name_t));
1545
if (addr->regex == NULL) {
1549
for (i = 0, s = 0; s < addr->names.nelts; s++) {
1550
if (name[s].regex) {
1551
addr->regex[i++] = name[s];
1561
ngx_destroy_pool(ha.temp_pool);
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)
1096
ngx_http_conf_in_addr_t *first, *second;
1098
first = (ngx_http_conf_in_addr_t *) one;
1099
second = (ngx_http_conf_in_addr_t *) two;
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;
1572
first = (ngx_http_conf_addr_t *) one;
1573
second = (ngx_http_conf_addr_t *) two;
1575
if (first->wildcard) {
1576
/* a wildcard address must be the last resort, shift it to the end */
1130
1604
return ngx_strcmp(first->key.data, second->key.data);
1609
ngx_http_init_listening(ngx_conf_t *cf, ngx_http_conf_port_t *port)
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;
1616
addr = port->addrs.elts;
1617
last = port->addrs.nelts;
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.
1626
if (addr[last - 1].wildcard) {
1627
addr[last - 1].bind = 1;
1638
if (bind_wildcard && !addr[i].bind) {
1643
ls = ngx_http_add_listening(cf, &addr[i]);
1648
hport = ngx_pcalloc(cf->pool, sizeof(ngx_http_port_t));
1649
if (hport == NULL) {
1653
ls->servers = hport;
1655
if (i == last - 1) {
1656
hport->naddrs = last;
1663
switch (ls->sockaddr->sa_family) {
1665
#if (NGX_HAVE_INET6)
1667
if (ngx_http_add_addrs6(cf, hport, addr) != NGX_OK) {
1672
default: /* AF_INET */
1673
if (ngx_http_add_addrs(cf, hport, addr) != NGX_OK) {
1687
static ngx_listening_t *
1688
ngx_http_add_listening(ngx_conf_t *cf, ngx_http_conf_addr_t *addr)
1690
ngx_listening_t *ls;
1691
ngx_http_core_loc_conf_t *clcf;
1692
ngx_http_core_srv_conf_t *cscf;
1694
ls = ngx_create_listening(cf, addr->sockaddr, addr->socklen);
1701
ls->handler = ngx_http_init_connection;
1703
cscf = addr->core_srv_conf;
1704
ls->pool_size = cscf->connection_pool_size;
1705
ls->post_accept_timeout = cscf->client_header_timeout;
1707
clcf = cscf->ctx->loc_conf[ngx_http_core_module.ctx_index];
1709
ls->logp = clcf->error_log;
1710
ls->log.data = &ls->addr_text;
1711
ls->log.handler = ngx_accept_log_error;
1715
ngx_iocp_conf_t *iocpcf;
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;
1724
ls->backlog = addr->listen_conf->backlog;
1725
ls->rcvbuf = addr->listen_conf->rcvbuf;
1726
ls->sndbuf = addr->listen_conf->sndbuf;
1728
#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
1729
ls->accept_filter = addr->listen_conf->accept_filter;
1732
#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
1733
ls->deferred_accept = addr->listen_conf->deferred_accept;
1736
#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
1737
ls->ipv6only = addr->listen_conf->ipv6only;
1745
ngx_http_add_addrs(ngx_conf_t *cf, ngx_http_port_t *hport,
1746
ngx_http_conf_addr_t *addr)
1749
ngx_http_in_addr_t *addrs;
1750
struct sockaddr_in *sin;
1751
ngx_http_virtual_names_t *vn;
1753
hport->addrs = ngx_pcalloc(cf->pool,
1754
hport->naddrs * sizeof(ngx_http_in_addr_t));
1755
if (hport->addrs == NULL) {
1759
addrs = hport->addrs;
1761
for (i = 0; i < hport->naddrs; i++) {
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;
1767
addrs[i].conf.ssl = addr[i].ssl;
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)
1776
&& addr[i].nregex == 0
1783
vn = ngx_palloc(cf->pool, sizeof(ngx_http_virtual_names_t));
1788
addrs[i].conf.virtual_names = vn;
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;
1794
vn->nregex = addr[i].nregex;
1795
vn->regex = addr[i].regex;
1803
#if (NGX_HAVE_INET6)
1806
ngx_http_add_addrs6(ngx_conf_t *cf, ngx_http_port_t *hport,
1807
ngx_http_conf_addr_t *addr)
1810
ngx_http_in6_addr_t *addrs6;
1811
struct sockaddr_in6 *sin6;
1812
ngx_http_virtual_names_t *vn;
1814
hport->addrs = ngx_pcalloc(cf->pool,
1815
hport->naddrs * sizeof(ngx_http_in6_addr_t));
1816
if (hport->addrs == NULL) {
1820
addrs6 = hport->addrs;
1822
for (i = 0; i < hport->naddrs; i++) {
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;
1828
addrs6[i].conf.ssl = addr[i].ssl;
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))
1840
vn = ngx_palloc(cf->pool, sizeof(ngx_http_virtual_names_t));
1845
addrs6[i].conf.virtual_names = vn;
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;
1851
vn->nregex = addr[i].nregex;
1852
vn->regex = addr[i].regex;
1863
ngx_http_types_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
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;
1872
types = (ngx_array_t **) (p + cmd->offset);
1874
default_type = cmd->post;
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;
1883
type = ngx_array_push(*types);
1885
return NGX_CONF_ERROR;
1888
type->key = *default_type;
1889
type->key_hash = ngx_hash_key(default_type->data,
1891
type->value = (void *) 4;
1895
value = cf->args->elts;
1897
for (i = 1; i < cf->args->nelts; i++) {
1899
hash = ngx_hash_strlow(value[i].data, value[i].data, value[i].len);
1900
value[i].data[value[i].len] = '\0';
1902
type = (*types)->elts;
1903
for (n = 0; n < (*types)->nelts; n++) {
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]);
1912
type = ngx_array_push(*types);
1914
return NGX_CONF_ERROR;
1917
type->key = value[i];
1918
type->key_hash = hash;
1919
type->value = (void *) 4;
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)
1931
ngx_hash_init_t hash;
1935
hash.hash = types_hash;
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;
1943
if (ngx_hash_init(&hash, keys->elts, keys->nelts) != NGX_OK) {
1944
return NGX_CONF_ERROR;
1950
if (prev_types_hash->buckets == NULL) {
1952
if (prev_keys == NULL) {
1954
if (ngx_http_set_default_types(cf, &prev_keys, default_types)
1957
return NGX_CONF_ERROR;
1961
hash.hash = prev_types_hash;
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;
1969
if (ngx_hash_init(&hash, prev_keys->elts, prev_keys->nelts) != NGX_OK) {
1970
return NGX_CONF_ERROR;
1974
*types_hash = *prev_types_hash;
1982
ngx_http_set_default_types(ngx_conf_t *cf, ngx_array_t **types,
1983
ngx_str_t *default_type)
1985
ngx_hash_key_t *type;
1987
*types = ngx_array_create(cf->temp_pool, 1, sizeof(ngx_hash_key_t));
1988
if (*types == NULL) {
1992
while (default_type->len) {
1994
type = ngx_array_push(*types);
1999
type->key = *default_type;
2000
type->key_hash = ngx_hash_key(default_type->data,
2002
type->value = (void *) 4;