Mercurial > hg > nginx-mail
comparison src/http/ngx_http.c @ 581:1dcf6adad484 NGINX_0_8_21
nginx 0.8.21
*) Feature: now the "-V" switch shows TLS SNI support.
*) Feature: the "listen" directive of the HTTP module supports unix
domain sockets.
Thanks to Hongli Lai.
*) Feature: the "default_server" parameter of the "listen" directive.
*) Feature: now a "default" parameter is not required to set listen
socket options.
*) Bugfix: nginx did not support dates in 2038 year on 32-bit platforms;
*) Bugfix: socket leak; the bug had appeared in 0.8.11.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 26 Oct 2009 00:00:00 +0300 |
parents | 0161f3197817 |
children | c04fa65fe604 |
comparison
equal
deleted
inserted
replaced
580:3ca2e495d9de | 581:1dcf6adad484 |
---|---|
15 static ngx_int_t ngx_http_init_headers_in_hash(ngx_conf_t *cf, | 15 static ngx_int_t ngx_http_init_headers_in_hash(ngx_conf_t *cf, |
16 ngx_http_core_main_conf_t *cmcf); | 16 ngx_http_core_main_conf_t *cmcf); |
17 static ngx_int_t ngx_http_init_phase_handlers(ngx_conf_t *cf, | 17 static ngx_int_t ngx_http_init_phase_handlers(ngx_conf_t *cf, |
18 ngx_http_core_main_conf_t *cmcf); | 18 ngx_http_core_main_conf_t *cmcf); |
19 | 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, | 20 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, | 21 ngx_http_core_srv_conf_t *cscf, ngx_http_conf_port_t *port, |
27 ngx_http_listen_t *listen); | 22 ngx_http_listen_opt_t *lsopt); |
28 static ngx_int_t ngx_http_add_address(ngx_conf_t *cf, | 23 static ngx_int_t ngx_http_add_address(ngx_conf_t *cf, |
29 ngx_http_core_srv_conf_t *cscf, ngx_http_conf_port_t *port, | 24 ngx_http_core_srv_conf_t *cscf, ngx_http_conf_port_t *port, |
30 ngx_http_listen_t *listen); | 25 ngx_http_listen_opt_t *lsopt); |
31 static ngx_int_t ngx_http_add_names(ngx_conf_t *cf, | 26 static ngx_int_t ngx_http_add_server(ngx_conf_t *cf, |
32 ngx_http_core_srv_conf_t *cscf, ngx_http_conf_addr_t *addr); | 27 ngx_http_core_srv_conf_t *cscf, ngx_http_conf_addr_t *addr); |
33 | 28 |
34 static char *ngx_http_merge_locations(ngx_conf_t *cf, | 29 static char *ngx_http_merge_locations(ngx_conf_t *cf, |
35 ngx_queue_t *locations, void **loc_conf, ngx_http_module_t *module, | 30 ngx_queue_t *locations, void **loc_conf, ngx_http_module_t *module, |
36 ngx_uint_t ctx_index); | 31 ngx_uint_t ctx_index); |
120 ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 115 ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
121 { | 116 { |
122 char *rv; | 117 char *rv; |
123 ngx_uint_t mi, m, s; | 118 ngx_uint_t mi, m, s; |
124 ngx_conf_t pcf; | 119 ngx_conf_t pcf; |
125 ngx_array_t ports; | |
126 ngx_http_module_t *module; | 120 ngx_http_module_t *module; |
127 ngx_http_conf_ctx_t *ctx; | 121 ngx_http_conf_ctx_t *ctx; |
128 ngx_http_core_loc_conf_t *clcf; | 122 ngx_http_core_loc_conf_t *clcf; |
129 ngx_http_core_srv_conf_t **cscfp; | 123 ngx_http_core_srv_conf_t **cscfp; |
130 ngx_http_core_main_conf_t *cmcf; | 124 ngx_http_core_main_conf_t *cmcf; |
360 if (ngx_http_init_phase_handlers(cf, cmcf) != NGX_OK) { | 354 if (ngx_http_init_phase_handlers(cf, cmcf) != NGX_OK) { |
361 return NGX_CONF_ERROR; | 355 return NGX_CONF_ERROR; |
362 } | 356 } |
363 | 357 |
364 | 358 |
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 */ | 359 /* optimize the lists of ports, addresses and server names */ |
376 | 360 |
377 if (ngx_http_optimize_servers(cf, cmcf, &ports) != NGX_OK) { | 361 if (ngx_http_optimize_servers(cf, cmcf, cmcf->ports) != NGX_OK) { |
378 return NGX_CONF_ERROR; | 362 return NGX_CONF_ERROR; |
379 } | 363 } |
380 | 364 |
381 return NGX_CONF_OK; | 365 return NGX_CONF_OK; |
382 | 366 |
1107 | 1091 |
1108 return node; | 1092 return node; |
1109 } | 1093 } |
1110 | 1094 |
1111 | 1095 |
1112 static ngx_int_t | 1096 ngx_int_t |
1113 ngx_http_init_server_lists(ngx_conf_t *cf, ngx_array_t *servers, | 1097 ngx_http_add_listen(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf, |
1114 ngx_array_t *ports) | 1098 ngx_http_listen_opt_t *lsopt) |
1115 { | 1099 { |
1116 ngx_uint_t s, i; | 1100 in_port_t p; |
1117 ngx_http_listen_t *listen; | 1101 ngx_uint_t i; |
1118 ngx_http_core_srv_conf_t **cscfp; | 1102 struct sockaddr *sa; |
1119 | 1103 struct sockaddr_in *sin; |
1120 if (ngx_array_init(ports, cf->temp_pool, 2, sizeof(ngx_http_conf_port_t)) | 1104 ngx_http_conf_port_t *port; |
1121 != NGX_OK) | 1105 ngx_http_core_main_conf_t *cmcf; |
1122 { | |
1123 return NGX_ERROR; | |
1124 } | |
1125 | |
1126 /* "server" directives */ | |
1127 | |
1128 cscfp = servers->elts; | |
1129 for (s = 0; s < servers->nelts; s++) { | |
1130 | |
1131 /* "listen" directives */ | |
1132 | |
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) | 1106 #if (NGX_HAVE_INET6) |
1156 struct sockaddr_in6 *sin6; | 1107 struct sockaddr_in6 *sin6; |
1157 #endif | 1108 #endif |
1158 | 1109 |
1159 sa = (struct sockaddr *) &listen->sockaddr; | 1110 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); |
1111 | |
1112 if (cmcf->ports == NULL) { | |
1113 cmcf->ports = ngx_array_create(cf->temp_pool, 2, | |
1114 sizeof(ngx_http_conf_port_t)); | |
1115 if (cmcf->ports == NULL) { | |
1116 return NGX_ERROR; | |
1117 } | |
1118 } | |
1119 | |
1120 sa = (struct sockaddr *) &lsopt->sockaddr; | |
1160 | 1121 |
1161 switch (sa->sa_family) { | 1122 switch (sa->sa_family) { |
1162 | 1123 |
1163 #if (NGX_HAVE_INET6) | 1124 #if (NGX_HAVE_INET6) |
1164 case AF_INET6: | 1125 case AF_INET6: |
1165 sin6 = (struct sockaddr_in6 *) sa; | 1126 sin6 = (struct sockaddr_in6 *) sa; |
1166 p = sin6->sin6_port; | 1127 p = sin6->sin6_port; |
1167 break; | 1128 break; |
1168 #endif | 1129 #endif |
1169 | 1130 |
1131 #if (NGX_HAVE_UNIX_DOMAIN) | |
1132 case AF_UNIX: | |
1133 p = 0; | |
1134 break; | |
1135 #endif | |
1136 | |
1170 default: /* AF_INET */ | 1137 default: /* AF_INET */ |
1171 sin = (struct sockaddr_in *) sa; | 1138 sin = (struct sockaddr_in *) sa; |
1172 p = sin->sin_port; | 1139 p = sin->sin_port; |
1173 break; | 1140 break; |
1174 } | 1141 } |
1175 | 1142 |
1176 port = ports->elts; | 1143 port = cmcf->ports->elts; |
1177 for (i = 0; i < ports->nelts; i++) { | 1144 for (i = 0; i < cmcf->ports->nelts; i++) { |
1178 | 1145 |
1179 if (p != port[i].port || sa->sa_family != port[i].family) { | 1146 if (p != port[i].port || sa->sa_family != port[i].family) { |
1180 continue; | 1147 continue; |
1181 } | 1148 } |
1182 | 1149 |
1183 /* a port is already in the port list */ | 1150 /* a port is already in the port list */ |
1184 | 1151 |
1185 return ngx_http_add_addresses(cf, cscf, &port[i], listen); | 1152 return ngx_http_add_addresses(cf, cscf, &port[i], lsopt); |
1186 } | 1153 } |
1187 | 1154 |
1188 /* add a port to the port list */ | 1155 /* add a port to the port list */ |
1189 | 1156 |
1190 port = ngx_array_push(ports); | 1157 port = ngx_array_push(cmcf->ports); |
1191 if (port == NULL) { | 1158 if (port == NULL) { |
1192 return NGX_ERROR; | 1159 return NGX_ERROR; |
1193 } | 1160 } |
1194 | 1161 |
1195 port->family = sa->sa_family; | 1162 port->family = sa->sa_family; |
1196 port->port = p; | 1163 port->port = p; |
1197 port->addrs.elts = NULL; | 1164 port->addrs.elts = NULL; |
1198 | 1165 |
1199 return ngx_http_add_address(cf, cscf, port, listen); | 1166 return ngx_http_add_address(cf, cscf, port, lsopt); |
1200 } | 1167 } |
1201 | 1168 |
1202 | 1169 |
1203 static ngx_int_t | 1170 static ngx_int_t |
1204 ngx_http_add_addresses(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf, | 1171 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) | 1172 ngx_http_conf_port_t *port, ngx_http_listen_opt_t *lsopt) |
1206 { | 1173 { |
1207 u_char *p; | 1174 u_char *p; |
1208 size_t len, off; | 1175 size_t len, off; |
1209 ngx_uint_t i; | 1176 ngx_uint_t i, default_server; |
1210 struct sockaddr *sa; | 1177 struct sockaddr *sa; |
1211 ngx_http_conf_addr_t *addr; | 1178 ngx_http_conf_addr_t *addr; |
1179 #if (NGX_HAVE_UNIX_DOMAIN) | |
1180 struct sockaddr_un *saun; | |
1181 #endif | |
1212 | 1182 |
1213 /* | 1183 /* |
1214 * we can not compare whole sockaddr struct's as kernel | 1184 * we can not compare whole sockaddr struct's as kernel |
1215 * may fill some fields in inherited sockaddr struct's | 1185 * may fill some fields in inherited sockaddr struct's |
1216 */ | 1186 */ |
1217 | 1187 |
1218 sa = (struct sockaddr *) &listen->sockaddr; | 1188 sa = (struct sockaddr *) &lsopt->sockaddr; |
1219 | 1189 |
1220 switch (sa->sa_family) { | 1190 switch (sa->sa_family) { |
1221 | 1191 |
1222 #if (NGX_HAVE_INET6) | 1192 #if (NGX_HAVE_INET6) |
1223 case AF_INET6: | 1193 case AF_INET6: |
1224 off = offsetof(struct sockaddr_in6, sin6_addr); | 1194 off = offsetof(struct sockaddr_in6, sin6_addr); |
1225 len = 16; | 1195 len = 16; |
1226 break; | 1196 break; |
1227 #endif | 1197 #endif |
1228 | 1198 |
1199 #if (NGX_HAVE_UNIX_DOMAIN) | |
1200 case AF_UNIX: | |
1201 off = offsetof(struct sockaddr_un, sun_path); | |
1202 len = sizeof(saun->sun_path); | |
1203 break; | |
1204 #endif | |
1205 | |
1229 default: /* AF_INET */ | 1206 default: /* AF_INET */ |
1230 off = offsetof(struct sockaddr_in, sin_addr); | 1207 off = offsetof(struct sockaddr_in, sin_addr); |
1231 len = 4; | 1208 len = 4; |
1232 break; | 1209 break; |
1233 } | 1210 } |
1234 | 1211 |
1235 p = listen->sockaddr + off; | 1212 p = lsopt->sockaddr + off; |
1236 | 1213 |
1237 addr = port->addrs.elts; | 1214 addr = port->addrs.elts; |
1238 | 1215 |
1239 for (i = 0; i < port->addrs.nelts; i++) { | 1216 for (i = 0; i < port->addrs.nelts; i++) { |
1240 | 1217 |
1241 if (ngx_memcmp(p, (u_char *) addr[i].sockaddr + off, len) != 0) { | 1218 if (ngx_memcmp(p, (u_char *) addr[i].opt.sockaddr + off, len) != 0) { |
1242 continue; | 1219 continue; |
1243 } | 1220 } |
1244 | 1221 |
1245 /* the address is already in the address list */ | 1222 /* the address is already in the address list */ |
1246 | 1223 |
1247 if (ngx_http_add_names(cf, cscf, &addr[i]) != NGX_OK) { | 1224 if (ngx_http_add_server(cf, cscf, &addr[i]) != NGX_OK) { |
1248 return NGX_ERROR; | 1225 return NGX_ERROR; |
1249 } | 1226 } |
1250 | 1227 |
1228 /* preserve default_server bit during listen options overwriting */ | |
1229 default_server = addr[i].opt.default_server; | |
1230 | |
1231 if (lsopt->set) { | |
1232 | |
1233 if (addr[i].opt.set) { | |
1234 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1235 "a duplicate listen options for %s", addr[i].opt.addr); | |
1236 return NGX_ERROR; | |
1237 } | |
1238 | |
1239 addr[i].opt = *lsopt; | |
1240 } | |
1241 | |
1251 /* check the duplicate "default" server for this address:port */ | 1242 /* check the duplicate "default" server for this address:port */ |
1252 | 1243 |
1253 if (listen->conf.default_server) { | 1244 if (lsopt->default_server) { |
1254 | 1245 |
1255 if (addr[i].default_server) { | 1246 if (default_server) { |
1256 ngx_log_error(NGX_LOG_ERR, cf->log, 0, | 1247 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
1257 "the duplicate default server in %s:%ui", | 1248 "a duplicate default server for %s", addr[i].opt.addr); |
1258 listen->file_name, listen->line); | |
1259 | |
1260 return NGX_ERROR; | 1249 return NGX_ERROR; |
1261 } | 1250 } |
1262 | 1251 |
1263 addr[i].core_srv_conf = cscf; | 1252 default_server = 1; |
1264 addr[i].default_server = 1; | 1253 addr[i].default_server = cscf; |
1265 #if (NGX_HTTP_SSL) | 1254 } |
1266 addr[i].ssl = listen->conf.ssl; | 1255 |
1267 #endif | 1256 addr[i].opt.default_server = default_server; |
1268 addr[i].listen_conf = &listen->conf; | |
1269 } | |
1270 | 1257 |
1271 return NGX_OK; | 1258 return NGX_OK; |
1272 } | 1259 } |
1273 | 1260 |
1274 /* add the address to the addresses list that bound to this port */ | 1261 /* add the address to the addresses list that bound to this port */ |
1275 | 1262 |
1276 return ngx_http_add_address(cf, cscf, port, listen); | 1263 return ngx_http_add_address(cf, cscf, port, lsopt); |
1277 } | 1264 } |
1278 | 1265 |
1279 | 1266 |
1280 /* | 1267 /* |
1281 * add the server address, the server names and the server core module | 1268 * add the server address, the server names and the server core module |
1282 * configurations to the port list | 1269 * configurations to the port list |
1283 */ | 1270 */ |
1284 | 1271 |
1285 static ngx_int_t | 1272 static ngx_int_t |
1286 ngx_http_add_address(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf, | 1273 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) | 1274 ngx_http_conf_port_t *port, ngx_http_listen_opt_t *lsopt) |
1288 { | 1275 { |
1289 ngx_http_conf_addr_t *addr; | 1276 ngx_http_conf_addr_t *addr; |
1290 | 1277 |
1291 if (port->addrs.elts == NULL) { | 1278 if (port->addrs.elts == NULL) { |
1292 if (ngx_array_init(&port->addrs, cf->temp_pool, 4, | 1279 if (ngx_array_init(&port->addrs, cf->temp_pool, 4, |
1300 addr = ngx_array_push(&port->addrs); | 1287 addr = ngx_array_push(&port->addrs); |
1301 if (addr == NULL) { | 1288 if (addr == NULL) { |
1302 return NGX_ERROR; | 1289 return NGX_ERROR; |
1303 } | 1290 } |
1304 | 1291 |
1305 addr->sockaddr = (struct sockaddr *) &listen->sockaddr; | 1292 addr->opt = *lsopt; |
1306 addr->socklen = listen->socklen; | |
1307 addr->hash.buckets = NULL; | 1293 addr->hash.buckets = NULL; |
1308 addr->hash.size = 0; | 1294 addr->hash.size = 0; |
1309 addr->wc_head = NULL; | 1295 addr->wc_head = NULL; |
1310 addr->wc_tail = NULL; | 1296 addr->wc_tail = NULL; |
1311 addr->names.elts = NULL; | |
1312 #if (NGX_PCRE) | 1297 #if (NGX_PCRE) |
1313 addr->nregex = 0; | 1298 addr->nregex = 0; |
1314 addr->regex = NULL; | 1299 addr->regex = NULL; |
1315 #endif | 1300 #endif |
1316 addr->core_srv_conf = cscf; | 1301 addr->default_server = cscf; |
1317 addr->default_server = listen->conf.default_server; | 1302 addr->servers.elts = NULL; |
1318 addr->bind = listen->conf.bind; | 1303 |
1319 addr->wildcard = listen->conf.wildcard; | 1304 return ngx_http_add_server(cf, cscf, addr); |
1320 #if (NGX_HTTP_SSL) | 1305 } |
1321 addr->ssl = listen->conf.ssl; | 1306 |
1322 #endif | 1307 |
1323 addr->listen_conf = &listen->conf; | 1308 /* add the server core module configuration to the address:port */ |
1324 | |
1325 return ngx_http_add_names(cf, cscf, addr); | |
1326 } | |
1327 | |
1328 | |
1329 /* | |
1330 * add the server names and the server core module | |
1331 * configurations to the address:port | |
1332 */ | |
1333 | 1309 |
1334 static ngx_int_t | 1310 static ngx_int_t |
1335 ngx_http_add_names(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf, | 1311 ngx_http_add_server(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf, |
1336 ngx_http_conf_addr_t *addr) | 1312 ngx_http_conf_addr_t *addr) |
1337 { | 1313 { |
1338 ngx_uint_t i; | 1314 ngx_uint_t i; |
1339 ngx_http_server_name_t *server_names, *name; | 1315 ngx_http_core_srv_conf_t **server; |
1340 | 1316 |
1341 if (addr->names.elts == NULL) { | 1317 if (addr->servers.elts == NULL) { |
1342 if (ngx_array_init(&addr->names, cf->temp_pool, 4, | 1318 if (ngx_array_init(&addr->servers, cf->temp_pool, 4, |
1343 sizeof(ngx_http_server_name_t)) | 1319 sizeof(ngx_http_core_srv_conf_t *)) |
1344 != NGX_OK) | 1320 != NGX_OK) |
1345 { | 1321 { |
1346 return NGX_ERROR; | 1322 return NGX_ERROR; |
1347 } | 1323 } |
1348 } | 1324 |
1349 | 1325 } else { |
1350 server_names = cscf->server_names.elts; | 1326 server = addr->servers.elts; |
1351 | 1327 for (i = 0; i < addr->servers.nelts; i++) { |
1352 for (i = 0; i < cscf->server_names.nelts; i++) { | 1328 if (server[i] == cscf) { |
1353 | 1329 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
1354 ngx_strlow(server_names[i].name.data, server_names[i].name.data, | 1330 "a duplicate listen %s", addr->opt.addr); |
1355 server_names[i].name.len); | 1331 return NGX_ERROR; |
1356 | 1332 } |
1357 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0, | 1333 } |
1358 "name: %V", &server_names[i].name); | 1334 } |
1359 | 1335 |
1360 name = ngx_array_push(&addr->names); | 1336 server = ngx_array_push(&addr->servers); |
1361 if (name == NULL) { | 1337 if (server == NULL) { |
1362 return NGX_ERROR; | 1338 return NGX_ERROR; |
1363 } | 1339 } |
1364 | 1340 |
1365 *name = server_names[i]; | 1341 *server = cscf; |
1366 } | |
1367 | 1342 |
1368 return NGX_OK; | 1343 return NGX_OK; |
1369 } | 1344 } |
1370 | 1345 |
1371 | 1346 |
1372 static ngx_int_t | 1347 static ngx_int_t |
1373 ngx_http_optimize_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf, | 1348 ngx_http_optimize_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf, |
1374 ngx_array_t *ports) | 1349 ngx_array_t *ports) |
1375 { | 1350 { |
1376 ngx_uint_t s, p, a; | 1351 ngx_uint_t p, a; |
1377 ngx_http_conf_port_t *port; | 1352 ngx_http_conf_port_t *port; |
1378 ngx_http_conf_addr_t *addr; | 1353 ngx_http_conf_addr_t *addr; |
1379 ngx_http_server_name_t *name; | |
1380 | 1354 |
1381 port = ports->elts; | 1355 port = ports->elts; |
1382 for (p = 0; p < ports->nelts; p++) { | 1356 for (p = 0; p < ports->nelts; p++) { |
1383 | 1357 |
1384 ngx_sort(port[p].addrs.elts, (size_t) port[p].addrs.nelts, | 1358 ngx_sort(port[p].addrs.elts, (size_t) port[p].addrs.nelts, |
1390 */ | 1364 */ |
1391 | 1365 |
1392 addr = port[p].addrs.elts; | 1366 addr = port[p].addrs.elts; |
1393 for (a = 0; a < port[p].addrs.nelts; a++) { | 1367 for (a = 0; a < port[p].addrs.nelts; a++) { |
1394 | 1368 |
1395 name = addr[a].names.elts; | 1369 if (addr[a].servers.nelts > 1 |
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) | 1370 #if (NGX_PCRE) |
1400 && name[s].captures == 0 | 1371 || addr[a].default_server->captures |
1401 #endif | 1372 #endif |
1402 ) | 1373 ) |
1403 { | 1374 { |
1404 continue; | |
1405 } | |
1406 | |
1407 if (ngx_http_server_names(cf, cmcf, &addr[a]) != NGX_OK) { | 1375 if (ngx_http_server_names(cf, cmcf, &addr[a]) != NGX_OK) { |
1408 return NGX_ERROR; | 1376 return NGX_ERROR; |
1409 } | 1377 } |
1410 | |
1411 break; | |
1412 } | 1378 } |
1413 } | 1379 } |
1414 | 1380 |
1415 if (ngx_http_init_listening(cf, &port[p]) != NGX_OK) { | 1381 if (ngx_http_init_listening(cf, &port[p]) != NGX_OK) { |
1416 return NGX_ERROR; | 1382 return NGX_ERROR; |
1423 | 1389 |
1424 static ngx_int_t | 1390 static ngx_int_t |
1425 ngx_http_server_names(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf, | 1391 ngx_http_server_names(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf, |
1426 ngx_http_conf_addr_t *addr) | 1392 ngx_http_conf_addr_t *addr) |
1427 { | 1393 { |
1428 ngx_int_t rc; | 1394 ngx_int_t rc; |
1429 ngx_uint_t s; | 1395 ngx_uint_t n, s; |
1430 ngx_hash_init_t hash; | 1396 ngx_hash_init_t hash; |
1431 ngx_hash_keys_arrays_t ha; | 1397 ngx_hash_keys_arrays_t ha; |
1432 ngx_http_server_name_t *name; | 1398 ngx_http_server_name_t *name; |
1399 ngx_http_core_srv_conf_t **cscfp; | |
1433 #if (NGX_PCRE) | 1400 #if (NGX_PCRE) |
1434 ngx_uint_t regex, i; | 1401 ngx_uint_t regex, i; |
1435 | 1402 |
1436 regex = 0; | 1403 regex = 0; |
1437 #endif | 1404 #endif |
1438 | 1405 |
1439 ngx_memzero(&ha, sizeof(ngx_hash_keys_arrays_t)); | 1406 ngx_memzero(&ha, sizeof(ngx_hash_keys_arrays_t)); |
1447 | 1414 |
1448 if (ngx_hash_keys_array_init(&ha, NGX_HASH_LARGE) != NGX_OK) { | 1415 if (ngx_hash_keys_array_init(&ha, NGX_HASH_LARGE) != NGX_OK) { |
1449 goto failed; | 1416 goto failed; |
1450 } | 1417 } |
1451 | 1418 |
1452 name = addr->names.elts; | 1419 cscfp = addr->servers.elts; |
1453 | 1420 |
1454 for (s = 0; s < addr->names.nelts; s++) { | 1421 for (s = 0; s < addr->servers.nelts; s++) { |
1422 | |
1423 name = cscfp[s]->server_names.elts; | |
1424 | |
1425 for (n = 0; n < cscfp[s]->server_names.nelts; n++) { | |
1455 | 1426 |
1456 #if (NGX_PCRE) | 1427 #if (NGX_PCRE) |
1457 if (name[s].regex) { | 1428 if (name[n].regex) { |
1458 regex++; | 1429 regex++; |
1459 continue; | 1430 continue; |
1460 } | 1431 } |
1461 #endif | 1432 #endif |
1462 | 1433 |
1463 rc = ngx_hash_add_key(&ha, &name[s].name, name[s].core_srv_conf, | 1434 rc = ngx_hash_add_key(&ha, &name[n].name, name[n].server, |
1464 NGX_HASH_WILDCARD_KEY); | 1435 NGX_HASH_WILDCARD_KEY); |
1465 | 1436 |
1466 if (rc == NGX_ERROR) { | 1437 if (rc == NGX_ERROR) { |
1467 return NGX_ERROR; | 1438 return NGX_ERROR; |
1468 } | 1439 } |
1469 | 1440 |
1470 if (rc == NGX_DECLINED) { | 1441 if (rc == NGX_DECLINED) { |
1471 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | 1442 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, |
1472 "invalid server name or wildcard \"%V\" on %s", | 1443 "invalid server name or wildcard \"%V\" on %s", |
1473 &name[s].name, addr->listen_conf->addr); | 1444 &name[n].name, addr->opt.addr); |
1474 return NGX_ERROR; | 1445 return NGX_ERROR; |
1475 } | 1446 } |
1476 | 1447 |
1477 if (rc == NGX_BUSY) { | 1448 if (rc == NGX_BUSY) { |
1478 ngx_log_error(NGX_LOG_WARN, cf->log, 0, | 1449 ngx_log_error(NGX_LOG_WARN, cf->log, 0, |
1479 "conflicting server name \"%V\" on %s, ignored", | 1450 "conflicting server name \"%V\" on %s, ignored", |
1480 &name[s].name, addr->listen_conf->addr); | 1451 &name[n].name, addr->opt.addr); |
1452 } | |
1481 } | 1453 } |
1482 } | 1454 } |
1483 | 1455 |
1484 hash.key = ngx_hash_key_lc; | 1456 hash.key = ngx_hash_key_lc; |
1485 hash.max_size = cmcf->server_names_hash_max_size; | 1457 hash.max_size = cmcf->server_names_hash_max_size; |
1544 addr->regex = ngx_palloc(cf->pool, regex * sizeof(ngx_http_server_name_t)); | 1516 addr->regex = ngx_palloc(cf->pool, regex * sizeof(ngx_http_server_name_t)); |
1545 if (addr->regex == NULL) { | 1517 if (addr->regex == NULL) { |
1546 return NGX_ERROR; | 1518 return NGX_ERROR; |
1547 } | 1519 } |
1548 | 1520 |
1549 for (i = 0, s = 0; s < addr->names.nelts; s++) { | 1521 i = 0; |
1550 if (name[s].regex) { | 1522 |
1551 addr->regex[i++] = name[s]; | 1523 for (s = 0; s < addr->servers.nelts; s++) { |
1524 | |
1525 name = cscfp[s]->server_names.elts; | |
1526 | |
1527 for (n = 0; n < cscfp[s]->server_names.nelts; n++) { | |
1528 if (name[n].regex) { | |
1529 addr->regex[i++] = name[n]; | |
1530 } | |
1552 } | 1531 } |
1553 } | 1532 } |
1554 | 1533 |
1555 #endif | 1534 #endif |
1556 | 1535 |
1570 ngx_http_conf_addr_t *first, *second; | 1549 ngx_http_conf_addr_t *first, *second; |
1571 | 1550 |
1572 first = (ngx_http_conf_addr_t *) one; | 1551 first = (ngx_http_conf_addr_t *) one; |
1573 second = (ngx_http_conf_addr_t *) two; | 1552 second = (ngx_http_conf_addr_t *) two; |
1574 | 1553 |
1575 if (first->wildcard) { | 1554 if (first->opt.wildcard) { |
1576 /* a wildcard address must be the last resort, shift it to the end */ | 1555 /* a wildcard address must be the last resort, shift it to the end */ |
1577 return 1; | 1556 return 1; |
1578 } | 1557 } |
1579 | 1558 |
1580 if (first->bind && !second->bind) { | 1559 if (first->opt.bind && !second->opt.bind) { |
1581 /* shift explicit bind()ed addresses to the start */ | 1560 /* shift explicit bind()ed addresses to the start */ |
1582 return -1; | 1561 return -1; |
1583 } | 1562 } |
1584 | 1563 |
1585 if (!first->bind && second->bind) { | 1564 if (!first->opt.bind && second->opt.bind) { |
1586 /* shift explicit bind()ed addresses to the start */ | 1565 /* shift explicit bind()ed addresses to the start */ |
1587 return 1; | 1566 return 1; |
1588 } | 1567 } |
1589 | 1568 |
1590 /* do not sort by default */ | 1569 /* do not sort by default */ |
1621 * the "*:port" only and ignore other implicit bindings. The bindings | 1600 * the "*:port" only and ignore other implicit bindings. The bindings |
1622 * have been already sorted: explicit bindings are on the start, then | 1601 * have been already sorted: explicit bindings are on the start, then |
1623 * implicit bindings go, and wildcard binding is in the end. | 1602 * implicit bindings go, and wildcard binding is in the end. |
1624 */ | 1603 */ |
1625 | 1604 |
1626 if (addr[last - 1].wildcard) { | 1605 if (addr[last - 1].opt.wildcard) { |
1627 addr[last - 1].bind = 1; | 1606 addr[last - 1].opt.bind = 1; |
1628 bind_wildcard = 1; | 1607 bind_wildcard = 1; |
1629 | 1608 |
1630 } else { | 1609 } else { |
1631 bind_wildcard = 0; | 1610 bind_wildcard = 0; |
1632 } | 1611 } |
1633 | 1612 |
1634 i = 0; | 1613 i = 0; |
1635 | 1614 |
1636 while (i < last) { | 1615 while (i < last) { |
1637 | 1616 |
1638 if (bind_wildcard && !addr[i].bind) { | 1617 if (bind_wildcard && !addr[i].opt.bind) { |
1639 i++; | 1618 i++; |
1640 continue; | 1619 continue; |
1641 } | 1620 } |
1642 | 1621 |
1643 ls = ngx_http_add_listening(cf, &addr[i]); | 1622 ls = ngx_http_add_listening(cf, &addr[i]); |
1689 { | 1668 { |
1690 ngx_listening_t *ls; | 1669 ngx_listening_t *ls; |
1691 ngx_http_core_loc_conf_t *clcf; | 1670 ngx_http_core_loc_conf_t *clcf; |
1692 ngx_http_core_srv_conf_t *cscf; | 1671 ngx_http_core_srv_conf_t *cscf; |
1693 | 1672 |
1694 ls = ngx_create_listening(cf, addr->sockaddr, addr->socklen); | 1673 ls = ngx_create_listening(cf, addr->opt.sockaddr, addr->opt.socklen); |
1695 if (ls == NULL) { | 1674 if (ls == NULL) { |
1696 return NULL; | 1675 return NULL; |
1697 } | 1676 } |
1698 | 1677 |
1699 ls->addr_ntop = 1; | 1678 ls->addr_ntop = 1; |
1700 | 1679 |
1701 ls->handler = ngx_http_init_connection; | 1680 ls->handler = ngx_http_init_connection; |
1702 | 1681 |
1703 cscf = addr->core_srv_conf; | 1682 cscf = addr->default_server; |
1704 ls->pool_size = cscf->connection_pool_size; | 1683 ls->pool_size = cscf->connection_pool_size; |
1705 ls->post_accept_timeout = cscf->client_header_timeout; | 1684 ls->post_accept_timeout = cscf->client_header_timeout; |
1706 | 1685 |
1707 clcf = cscf->ctx->loc_conf[ngx_http_core_module.ctx_index]; | 1686 clcf = cscf->ctx->loc_conf[ngx_http_core_module.ctx_index]; |
1708 | 1687 |
1719 ls->post_accept_buffer_size = cscf->client_header_buffer_size; | 1698 ls->post_accept_buffer_size = cscf->client_header_buffer_size; |
1720 } | 1699 } |
1721 } | 1700 } |
1722 #endif | 1701 #endif |
1723 | 1702 |
1724 ls->backlog = addr->listen_conf->backlog; | 1703 ls->backlog = addr->opt.backlog; |
1725 ls->rcvbuf = addr->listen_conf->rcvbuf; | 1704 ls->rcvbuf = addr->opt.rcvbuf; |
1726 ls->sndbuf = addr->listen_conf->sndbuf; | 1705 ls->sndbuf = addr->opt.sndbuf; |
1727 | 1706 |
1728 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) | 1707 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) |
1729 ls->accept_filter = addr->listen_conf->accept_filter; | 1708 ls->accept_filter = addr->opt.accept_filter; |
1730 #endif | 1709 #endif |
1731 | 1710 |
1732 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT) | 1711 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT) |
1733 ls->deferred_accept = addr->listen_conf->deferred_accept; | 1712 ls->deferred_accept = addr->opt.deferred_accept; |
1734 #endif | 1713 #endif |
1735 | 1714 |
1736 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) | 1715 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) |
1737 ls->ipv6only = addr->listen_conf->ipv6only; | 1716 ls->ipv6only = addr->opt.ipv6only; |
1738 #endif | 1717 #endif |
1739 | 1718 |
1740 return ls; | 1719 return ls; |
1741 } | 1720 } |
1742 | 1721 |
1758 | 1737 |
1759 addrs = hport->addrs; | 1738 addrs = hport->addrs; |
1760 | 1739 |
1761 for (i = 0; i < hport->naddrs; i++) { | 1740 for (i = 0; i < hport->naddrs; i++) { |
1762 | 1741 |
1763 sin = (struct sockaddr_in *) addr[i].sockaddr; | 1742 sin = (struct sockaddr_in *) addr[i].opt.sockaddr; |
1764 addrs[i].addr = sin->sin_addr.s_addr; | 1743 addrs[i].addr = sin->sin_addr.s_addr; |
1765 addrs[i].conf.core_srv_conf = addr[i].core_srv_conf; | 1744 addrs[i].conf.default_server = addr[i].default_server; |
1766 #if (NGX_HTTP_SSL) | 1745 #if (NGX_HTTP_SSL) |
1767 addrs[i].conf.ssl = addr[i].ssl; | 1746 addrs[i].conf.ssl = addr[i].opt.ssl; |
1768 #endif | 1747 #endif |
1769 | 1748 |
1770 if (addr[i].hash.buckets == NULL | 1749 if (addr[i].hash.buckets == NULL |
1771 && (addr[i].wc_head == NULL | 1750 && (addr[i].wc_head == NULL |
1772 || addr[i].wc_head->hash.buckets == NULL) | 1751 || addr[i].wc_head->hash.buckets == NULL) |
1819 | 1798 |
1820 addrs6 = hport->addrs; | 1799 addrs6 = hport->addrs; |
1821 | 1800 |
1822 for (i = 0; i < hport->naddrs; i++) { | 1801 for (i = 0; i < hport->naddrs; i++) { |
1823 | 1802 |
1824 sin6 = (struct sockaddr_in6 *) addr[i].sockaddr; | 1803 sin6 = (struct sockaddr_in6 *) addr[i].opt.sockaddr; |
1825 addrs6[i].addr6 = sin6->sin6_addr; | 1804 addrs6[i].addr6 = sin6->sin6_addr; |
1826 addrs6[i].conf.core_srv_conf = addr[i].core_srv_conf; | 1805 addrs6[i].conf.default_server = addr[i].default_server; |
1827 #if (NGX_HTTP_SSL) | 1806 #if (NGX_HTTP_SSL) |
1828 addrs6[i].conf.ssl = addr[i].ssl; | 1807 addrs6[i].conf.ssl = addr[i].opt.ssl; |
1829 #endif | 1808 #endif |
1830 | 1809 |
1831 if (addr[i].hash.buckets == NULL | 1810 if (addr[i].hash.buckets == NULL |
1832 && (addr[i].wc_head == NULL | 1811 && (addr[i].wc_head == NULL |
1833 || addr[i].wc_head->hash.buckets == NULL) | 1812 || addr[i].wc_head->hash.buckets == NULL) |