comparison src/http/ngx_http.c @ 3219:81b8416054b0

fix r3218: Initially building lists of ports, addresses, and server names had been placed at final configuration stage, because complete set of the "listen"s and the "server_names" were required for this operation. r3218 broke it, because the "listen"s go usually first in configuration, and cscf->server_names is empty at this stage, therefore no virtual names were configured. Now server configurations are stored in array for each address:port to configure virtual names. Also regex captures flag is moved from server names to core server configuration.
author Igor Sysoev <igor@sysoev.ru>
date Wed, 21 Oct 2009 16:27:48 +0000
parents 022a7662b4ed
children cdcd9e29c589
comparison
equal deleted inserted replaced
3218:022a7662b4ed 3219:81b8416054b0
21 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,
22 ngx_http_listen_t *listen); 22 ngx_http_listen_t *listen);
23 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,
24 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,
25 ngx_http_listen_t *listen); 25 ngx_http_listen_t *listen);
26 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,
27 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);
28 28
29 static char *ngx_http_merge_locations(ngx_conf_t *cf, 29 static char *ngx_http_merge_locations(ngx_conf_t *cf,
30 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,
31 ngx_uint_t ctx_index); 31 ngx_uint_t ctx_index);
1203 continue; 1203 continue;
1204 } 1204 }
1205 1205
1206 /* the address is already in the address list */ 1206 /* the address is already in the address list */
1207 1207
1208 if (ngx_http_add_names(cf, cscf, &addr[i]) != NGX_OK) { 1208 if (ngx_http_add_server(cf, cscf, &addr[i]) != NGX_OK) {
1209 return NGX_ERROR; 1209 return NGX_ERROR;
1210 } 1210 }
1211 1211
1212 /* check the duplicate "default" server for this address:port */ 1212 /* check the duplicate "default" server for this address:port */
1213 1213
1261 addr->socklen = listen->socklen; 1261 addr->socklen = listen->socklen;
1262 addr->hash.buckets = NULL; 1262 addr->hash.buckets = NULL;
1263 addr->hash.size = 0; 1263 addr->hash.size = 0;
1264 addr->wc_head = NULL; 1264 addr->wc_head = NULL;
1265 addr->wc_tail = NULL; 1265 addr->wc_tail = NULL;
1266 addr->names.elts = NULL;
1267 #if (NGX_PCRE) 1266 #if (NGX_PCRE)
1268 addr->nregex = 0; 1267 addr->nregex = 0;
1269 addr->regex = NULL; 1268 addr->regex = NULL;
1270 #endif 1269 #endif
1271 addr->core_srv_conf = cscf; 1270 addr->core_srv_conf = cscf;
1271 addr->servers.elts = NULL;
1272 addr->opt = listen->opt; 1272 addr->opt = listen->opt;
1273 1273
1274 return ngx_http_add_names(cf, cscf, addr); 1274 return ngx_http_add_server(cf, cscf, addr);
1275 } 1275 }
1276 1276
1277 1277
1278 /* 1278 /* add the server core module configuration to the address:port */
1279 * add the server names and the server core module
1280 * configurations to the address:port
1281 */
1282 1279
1283 static ngx_int_t 1280 static ngx_int_t
1284 ngx_http_add_names(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf, 1281 ngx_http_add_server(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
1285 ngx_http_conf_addr_t *addr) 1282 ngx_http_conf_addr_t *addr)
1286 { 1283 {
1287 ngx_uint_t i; 1284 ngx_http_core_srv_conf_t **server;
1288 ngx_http_server_name_t *server_names, *name; 1285
1289 1286 if (addr->servers.elts == NULL) {
1290 if (addr->names.elts == NULL) { 1287 if (ngx_array_init(&addr->servers, cf->temp_pool, 4,
1291 if (ngx_array_init(&addr->names, cf->temp_pool, 4, 1288 sizeof(ngx_http_core_srv_conf_t *))
1292 sizeof(ngx_http_server_name_t))
1293 != NGX_OK) 1289 != NGX_OK)
1294 { 1290 {
1295 return NGX_ERROR; 1291 return NGX_ERROR;
1296 } 1292 }
1297 } 1293 }
1298 1294
1299 server_names = cscf->server_names.elts; 1295 server = ngx_array_push(&addr->servers);
1300 1296 if (server == NULL) {
1301 for (i = 0; i < cscf->server_names.nelts; i++) { 1297 return NGX_ERROR;
1302 1298 }
1303 ngx_strlow(server_names[i].name.data, server_names[i].name.data, 1299
1304 server_names[i].name.len); 1300 *server = cscf;
1305
1306 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0,
1307 "name: %V", &server_names[i].name);
1308
1309 name = ngx_array_push(&addr->names);
1310 if (name == NULL) {
1311 return NGX_ERROR;
1312 }
1313
1314 *name = server_names[i];
1315 }
1316 1301
1317 return NGX_OK; 1302 return NGX_OK;
1318 } 1303 }
1319 1304
1320 1305
1321 static ngx_int_t 1306 static ngx_int_t
1322 ngx_http_optimize_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf, 1307 ngx_http_optimize_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
1323 ngx_array_t *ports) 1308 ngx_array_t *ports)
1324 { 1309 {
1325 ngx_uint_t s, p, a; 1310 ngx_uint_t p, a;
1326 ngx_http_conf_port_t *port; 1311 ngx_http_conf_port_t *port;
1327 ngx_http_conf_addr_t *addr; 1312 ngx_http_conf_addr_t *addr;
1328 ngx_http_server_name_t *name;
1329 1313
1330 port = ports->elts; 1314 port = ports->elts;
1331 for (p = 0; p < ports->nelts; p++) { 1315 for (p = 0; p < ports->nelts; p++) {
1332 1316
1333 ngx_sort(port[p].addrs.elts, (size_t) port[p].addrs.nelts, 1317 ngx_sort(port[p].addrs.elts, (size_t) port[p].addrs.nelts,
1339 */ 1323 */
1340 1324
1341 addr = port[p].addrs.elts; 1325 addr = port[p].addrs.elts;
1342 for (a = 0; a < port[p].addrs.nelts; a++) { 1326 for (a = 0; a < port[p].addrs.nelts; a++) {
1343 1327
1344 name = addr[a].names.elts; 1328 if (addr[a].servers.nelts > 1
1345 for (s = 0; s < addr[a].names.nelts; s++) {
1346
1347 if (addr[a].core_srv_conf == name[s].core_srv_conf
1348 #if (NGX_PCRE) 1329 #if (NGX_PCRE)
1349 && name[s].captures == 0 1330 || addr[a].core_srv_conf->captures
1350 #endif 1331 #endif
1351 ) 1332 )
1352 { 1333 {
1353 continue;
1354 }
1355
1356 if (ngx_http_server_names(cf, cmcf, &addr[a]) != NGX_OK) { 1334 if (ngx_http_server_names(cf, cmcf, &addr[a]) != NGX_OK) {
1357 return NGX_ERROR; 1335 return NGX_ERROR;
1358 } 1336 }
1359
1360 break;
1361 } 1337 }
1362 } 1338 }
1363 1339
1364 if (ngx_http_init_listening(cf, &port[p]) != NGX_OK) { 1340 if (ngx_http_init_listening(cf, &port[p]) != NGX_OK) {
1365 return NGX_ERROR; 1341 return NGX_ERROR;
1372 1348
1373 static ngx_int_t 1349 static ngx_int_t
1374 ngx_http_server_names(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf, 1350 ngx_http_server_names(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
1375 ngx_http_conf_addr_t *addr) 1351 ngx_http_conf_addr_t *addr)
1376 { 1352 {
1377 ngx_int_t rc; 1353 ngx_int_t rc;
1378 ngx_uint_t s; 1354 ngx_uint_t n, s;
1379 ngx_hash_init_t hash; 1355 ngx_hash_init_t hash;
1380 ngx_hash_keys_arrays_t ha; 1356 ngx_hash_keys_arrays_t ha;
1381 ngx_http_server_name_t *name; 1357 ngx_http_server_name_t *name;
1358 ngx_http_core_srv_conf_t **cscfp;
1382 #if (NGX_PCRE) 1359 #if (NGX_PCRE)
1383 ngx_uint_t regex, i; 1360 ngx_uint_t regex, i;
1384 1361
1385 regex = 0; 1362 regex = 0;
1386 #endif 1363 #endif
1387 1364
1388 ngx_memzero(&ha, sizeof(ngx_hash_keys_arrays_t)); 1365 ngx_memzero(&ha, sizeof(ngx_hash_keys_arrays_t));
1396 1373
1397 if (ngx_hash_keys_array_init(&ha, NGX_HASH_LARGE) != NGX_OK) { 1374 if (ngx_hash_keys_array_init(&ha, NGX_HASH_LARGE) != NGX_OK) {
1398 goto failed; 1375 goto failed;
1399 } 1376 }
1400 1377
1401 name = addr->names.elts; 1378 cscfp = addr->servers.elts;
1402 1379
1403 for (s = 0; s < addr->names.nelts; s++) { 1380 for (s = 0; s < addr->servers.nelts; s++) {
1381
1382 name = cscfp[s]->server_names.elts;
1383
1384 for (n = 0; n < cscfp[s]->server_names.nelts; n++) {
1404 1385
1405 #if (NGX_PCRE) 1386 #if (NGX_PCRE)
1406 if (name[s].regex) { 1387 if (name[n].regex) {
1407 regex++; 1388 regex++;
1408 continue; 1389 continue;
1409 } 1390 }
1410 #endif 1391 #endif
1411 1392
1412 rc = ngx_hash_add_key(&ha, &name[s].name, name[s].core_srv_conf, 1393 rc = ngx_hash_add_key(&ha, &name[n].name, name[n].core_srv_conf,
1413 NGX_HASH_WILDCARD_KEY); 1394 NGX_HASH_WILDCARD_KEY);
1414 1395
1415 if (rc == NGX_ERROR) { 1396 if (rc == NGX_ERROR) {
1416 return NGX_ERROR; 1397 return NGX_ERROR;
1417 } 1398 }
1418 1399
1419 if (rc == NGX_DECLINED) { 1400 if (rc == NGX_DECLINED) {
1420 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, 1401 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
1421 "invalid server name or wildcard \"%V\" on %s", 1402 "invalid server name or wildcard \"%V\" on %s",
1422 &name[s].name, addr->opt.addr); 1403 &name[n].name, addr->opt.addr);
1423 return NGX_ERROR; 1404 return NGX_ERROR;
1424 } 1405 }
1425 1406
1426 if (rc == NGX_BUSY) { 1407 if (rc == NGX_BUSY) {
1427 ngx_log_error(NGX_LOG_WARN, cf->log, 0, 1408 ngx_log_error(NGX_LOG_WARN, cf->log, 0,
1428 "conflicting server name \"%V\" on %s, ignored", 1409 "conflicting server name \"%V\" on %s, ignored",
1429 &name[s].name, addr->opt.addr); 1410 &name[n].name, addr->opt.addr);
1411 }
1430 } 1412 }
1431 } 1413 }
1432 1414
1433 hash.key = ngx_hash_key_lc; 1415 hash.key = ngx_hash_key_lc;
1434 hash.max_size = cmcf->server_names_hash_max_size; 1416 hash.max_size = cmcf->server_names_hash_max_size;
1493 addr->regex = ngx_palloc(cf->pool, regex * sizeof(ngx_http_server_name_t)); 1475 addr->regex = ngx_palloc(cf->pool, regex * sizeof(ngx_http_server_name_t));
1494 if (addr->regex == NULL) { 1476 if (addr->regex == NULL) {
1495 return NGX_ERROR; 1477 return NGX_ERROR;
1496 } 1478 }
1497 1479
1498 for (i = 0, s = 0; s < addr->names.nelts; s++) { 1480 i = 0;
1499 if (name[s].regex) { 1481
1500 addr->regex[i++] = name[s]; 1482 for (s = 0; s < addr->servers.nelts; s++) {
1483
1484 name = cscfp[s]->server_names.elts;
1485
1486 for (n = 0; n < cscfp[s]->server_names.nelts; n++) {
1487 if (name[n].regex) {
1488 addr->regex[i++] = name[n];
1489 }
1501 } 1490 }
1502 } 1491 }
1503 1492
1504 #endif 1493 #endif
1505 1494