comparison src/http/ngx_http.c @ 578:f3a9e57d2e17

Merge with current.
author Maxim Dounin <mdounin@mdounin.ru>
date Thu, 11 Mar 2010 21:27:17 +0300
parents 2da4537168f8
children 4d3e880ce86c
comparison
equal deleted inserted replaced
539:5f4de8cf0d9d 578:f3a9e57d2e17
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 = &lsopt->u.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 = &lsopt->u.sockaddr_in6;
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 = &lsopt->u.sockaddr_in;
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 = &lsopt->u.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->u.sockaddr_data + 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, addr[i].opt.u.sockaddr_data + 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; 1354
1355 if (ports == NULL) {
1356 return NGX_OK;
1357 }
1380 1358
1381 port = ports->elts; 1359 port = ports->elts;
1382 for (p = 0; p < ports->nelts; p++) { 1360 for (p = 0; p < ports->nelts; p++) {
1383 1361
1384 ngx_sort(port[p].addrs.elts, (size_t) port[p].addrs.nelts, 1362 ngx_sort(port[p].addrs.elts, (size_t) port[p].addrs.nelts,
1390 */ 1368 */
1391 1369
1392 addr = port[p].addrs.elts; 1370 addr = port[p].addrs.elts;
1393 for (a = 0; a < port[p].addrs.nelts; a++) { 1371 for (a = 0; a < port[p].addrs.nelts; a++) {
1394 1372
1395 name = addr[a].names.elts; 1373 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) 1374 #if (NGX_PCRE)
1400 && name[s].captures == 0 1375 || addr[a].default_server->captures
1401 #endif 1376 #endif
1402 ) 1377 )
1403 { 1378 {
1404 continue;
1405 }
1406
1407 if (ngx_http_server_names(cf, cmcf, &addr[a]) != NGX_OK) { 1379 if (ngx_http_server_names(cf, cmcf, &addr[a]) != NGX_OK) {
1408 return NGX_ERROR; 1380 return NGX_ERROR;
1409 } 1381 }
1410
1411 break;
1412 } 1382 }
1413 } 1383 }
1414 1384
1415 if (ngx_http_init_listening(cf, &port[p]) != NGX_OK) { 1385 if (ngx_http_init_listening(cf, &port[p]) != NGX_OK) {
1416 return NGX_ERROR; 1386 return NGX_ERROR;
1423 1393
1424 static ngx_int_t 1394 static ngx_int_t
1425 ngx_http_server_names(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf, 1395 ngx_http_server_names(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
1426 ngx_http_conf_addr_t *addr) 1396 ngx_http_conf_addr_t *addr)
1427 { 1397 {
1428 ngx_int_t rc; 1398 ngx_int_t rc;
1429 ngx_uint_t s; 1399 ngx_uint_t n, s;
1430 ngx_hash_init_t hash; 1400 ngx_hash_init_t hash;
1431 ngx_hash_keys_arrays_t ha; 1401 ngx_hash_keys_arrays_t ha;
1432 ngx_http_server_name_t *name; 1402 ngx_http_server_name_t *name;
1403 ngx_http_core_srv_conf_t **cscfp;
1433 #if (NGX_PCRE) 1404 #if (NGX_PCRE)
1434 ngx_uint_t regex, i; 1405 ngx_uint_t regex, i;
1435 1406
1436 regex = 0; 1407 regex = 0;
1437 #endif 1408 #endif
1438 1409
1439 ngx_memzero(&ha, sizeof(ngx_hash_keys_arrays_t)); 1410 ngx_memzero(&ha, sizeof(ngx_hash_keys_arrays_t));
1447 1418
1448 if (ngx_hash_keys_array_init(&ha, NGX_HASH_LARGE) != NGX_OK) { 1419 if (ngx_hash_keys_array_init(&ha, NGX_HASH_LARGE) != NGX_OK) {
1449 goto failed; 1420 goto failed;
1450 } 1421 }
1451 1422
1452 name = addr->names.elts; 1423 cscfp = addr->servers.elts;
1453 1424
1454 for (s = 0; s < addr->names.nelts; s++) { 1425 for (s = 0; s < addr->servers.nelts; s++) {
1426
1427 name = cscfp[s]->server_names.elts;
1428
1429 for (n = 0; n < cscfp[s]->server_names.nelts; n++) {
1455 1430
1456 #if (NGX_PCRE) 1431 #if (NGX_PCRE)
1457 if (name[s].regex) { 1432 if (name[n].regex) {
1458 regex++; 1433 regex++;
1459 continue; 1434 continue;
1460 } 1435 }
1461 #endif 1436 #endif
1462 1437
1463 rc = ngx_hash_add_key(&ha, &name[s].name, name[s].core_srv_conf, 1438 rc = ngx_hash_add_key(&ha, &name[n].name, name[n].server,
1464 NGX_HASH_WILDCARD_KEY); 1439 NGX_HASH_WILDCARD_KEY);
1465 1440
1466 if (rc == NGX_ERROR) { 1441 if (rc == NGX_ERROR) {
1467 return NGX_ERROR; 1442 return NGX_ERROR;
1468 } 1443 }
1469 1444
1470 if (rc == NGX_DECLINED) { 1445 if (rc == NGX_DECLINED) {
1471 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, 1446 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
1472 "invalid server name or wildcard \"%V\" on %s", 1447 "invalid server name or wildcard \"%V\" on %s",
1473 &name[s].name, addr->listen_conf->addr); 1448 &name[n].name, addr->opt.addr);
1474 return NGX_ERROR; 1449 return NGX_ERROR;
1475 } 1450 }
1476 1451
1477 if (rc == NGX_BUSY) { 1452 if (rc == NGX_BUSY) {
1478 ngx_log_error(NGX_LOG_WARN, cf->log, 0, 1453 ngx_log_error(NGX_LOG_WARN, cf->log, 0,
1479 "conflicting server name \"%V\" on %s, ignored", 1454 "conflicting server name \"%V\" on %s, ignored",
1480 &name[s].name, addr->listen_conf->addr); 1455 &name[n].name, addr->opt.addr);
1456 }
1481 } 1457 }
1482 } 1458 }
1483 1459
1484 hash.key = ngx_hash_key_lc; 1460 hash.key = ngx_hash_key_lc;
1485 hash.max_size = cmcf->server_names_hash_max_size; 1461 hash.max_size = cmcf->server_names_hash_max_size;
1544 addr->regex = ngx_palloc(cf->pool, regex * sizeof(ngx_http_server_name_t)); 1520 addr->regex = ngx_palloc(cf->pool, regex * sizeof(ngx_http_server_name_t));
1545 if (addr->regex == NULL) { 1521 if (addr->regex == NULL) {
1546 return NGX_ERROR; 1522 return NGX_ERROR;
1547 } 1523 }
1548 1524
1549 for (i = 0, s = 0; s < addr->names.nelts; s++) { 1525 i = 0;
1550 if (name[s].regex) { 1526
1551 addr->regex[i++] = name[s]; 1527 for (s = 0; s < addr->servers.nelts; s++) {
1528
1529 name = cscfp[s]->server_names.elts;
1530
1531 for (n = 0; n < cscfp[s]->server_names.nelts; n++) {
1532 if (name[n].regex) {
1533 addr->regex[i++] = name[n];
1534 }
1552 } 1535 }
1553 } 1536 }
1554 1537
1555 #endif 1538 #endif
1556 1539
1570 ngx_http_conf_addr_t *first, *second; 1553 ngx_http_conf_addr_t *first, *second;
1571 1554
1572 first = (ngx_http_conf_addr_t *) one; 1555 first = (ngx_http_conf_addr_t *) one;
1573 second = (ngx_http_conf_addr_t *) two; 1556 second = (ngx_http_conf_addr_t *) two;
1574 1557
1575 if (first->wildcard) { 1558 if (first->opt.wildcard) {
1576 /* a wildcard address must be the last resort, shift it to the end */ 1559 /* a wildcard address must be the last resort, shift it to the end */
1577 return 1; 1560 return 1;
1578 } 1561 }
1579 1562
1580 if (first->bind && !second->bind) { 1563 if (first->opt.bind && !second->opt.bind) {
1581 /* shift explicit bind()ed addresses to the start */ 1564 /* shift explicit bind()ed addresses to the start */
1582 return -1; 1565 return -1;
1583 } 1566 }
1584 1567
1585 if (!first->bind && second->bind) { 1568 if (!first->opt.bind && second->opt.bind) {
1586 /* shift explicit bind()ed addresses to the start */ 1569 /* shift explicit bind()ed addresses to the start */
1587 return 1; 1570 return 1;
1588 } 1571 }
1589 1572
1590 /* do not sort by default */ 1573 /* do not sort by default */
1621 * the "*:port" only and ignore other implicit bindings. The bindings 1604 * the "*:port" only and ignore other implicit bindings. The bindings
1622 * have been already sorted: explicit bindings are on the start, then 1605 * have been already sorted: explicit bindings are on the start, then
1623 * implicit bindings go, and wildcard binding is in the end. 1606 * implicit bindings go, and wildcard binding is in the end.
1624 */ 1607 */
1625 1608
1626 if (addr[last - 1].wildcard) { 1609 if (addr[last - 1].opt.wildcard) {
1627 addr[last - 1].bind = 1; 1610 addr[last - 1].opt.bind = 1;
1628 bind_wildcard = 1; 1611 bind_wildcard = 1;
1629 1612
1630 } else { 1613 } else {
1631 bind_wildcard = 0; 1614 bind_wildcard = 0;
1632 } 1615 }
1633 1616
1634 i = 0; 1617 i = 0;
1635 1618
1636 while (i < last) { 1619 while (i < last) {
1637 1620
1638 if (bind_wildcard && !addr[i].bind) { 1621 if (bind_wildcard && !addr[i].opt.bind) {
1639 i++; 1622 i++;
1640 continue; 1623 continue;
1641 } 1624 }
1642 1625
1643 ls = ngx_http_add_listening(cf, &addr[i]); 1626 ls = ngx_http_add_listening(cf, &addr[i]);
1689 { 1672 {
1690 ngx_listening_t *ls; 1673 ngx_listening_t *ls;
1691 ngx_http_core_loc_conf_t *clcf; 1674 ngx_http_core_loc_conf_t *clcf;
1692 ngx_http_core_srv_conf_t *cscf; 1675 ngx_http_core_srv_conf_t *cscf;
1693 1676
1694 ls = ngx_create_listening(cf, addr->sockaddr, addr->socklen); 1677 ls = ngx_create_listening(cf, &addr->opt.u.sockaddr, addr->opt.socklen);
1695 if (ls == NULL) { 1678 if (ls == NULL) {
1696 return NULL; 1679 return NULL;
1697 } 1680 }
1698 1681
1699 ls->addr_ntop = 1; 1682 ls->addr_ntop = 1;
1700 1683
1701 ls->handler = ngx_http_init_connection; 1684 ls->handler = ngx_http_init_connection;
1702 1685
1703 cscf = addr->core_srv_conf; 1686 cscf = addr->default_server;
1704 ls->pool_size = cscf->connection_pool_size; 1687 ls->pool_size = cscf->connection_pool_size;
1705 ls->post_accept_timeout = cscf->client_header_timeout; 1688 ls->post_accept_timeout = cscf->client_header_timeout;
1706 1689
1707 clcf = cscf->ctx->loc_conf[ngx_http_core_module.ctx_index]; 1690 clcf = cscf->ctx->loc_conf[ngx_http_core_module.ctx_index];
1708 1691
1719 ls->post_accept_buffer_size = cscf->client_header_buffer_size; 1702 ls->post_accept_buffer_size = cscf->client_header_buffer_size;
1720 } 1703 }
1721 } 1704 }
1722 #endif 1705 #endif
1723 1706
1724 ls->backlog = addr->listen_conf->backlog; 1707 ls->backlog = addr->opt.backlog;
1725 ls->rcvbuf = addr->listen_conf->rcvbuf; 1708 ls->rcvbuf = addr->opt.rcvbuf;
1726 ls->sndbuf = addr->listen_conf->sndbuf; 1709 ls->sndbuf = addr->opt.sndbuf;
1727 1710
1728 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) 1711 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
1729 ls->accept_filter = addr->listen_conf->accept_filter; 1712 ls->accept_filter = addr->opt.accept_filter;
1730 #endif 1713 #endif
1731 1714
1732 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT) 1715 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
1733 ls->deferred_accept = addr->listen_conf->deferred_accept; 1716 ls->deferred_accept = addr->opt.deferred_accept;
1734 #endif 1717 #endif
1735 1718
1736 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) 1719 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
1737 ls->ipv6only = addr->listen_conf->ipv6only; 1720 ls->ipv6only = addr->opt.ipv6only;
1738 #endif 1721 #endif
1739 1722
1740 return ls; 1723 return ls;
1741 } 1724 }
1742 1725
1758 1741
1759 addrs = hport->addrs; 1742 addrs = hport->addrs;
1760 1743
1761 for (i = 0; i < hport->naddrs; i++) { 1744 for (i = 0; i < hport->naddrs; i++) {
1762 1745
1763 sin = (struct sockaddr_in *) addr[i].sockaddr; 1746 sin = &addr[i].opt.u.sockaddr_in;
1764 addrs[i].addr = sin->sin_addr.s_addr; 1747 addrs[i].addr = sin->sin_addr.s_addr;
1765 addrs[i].conf.core_srv_conf = addr[i].core_srv_conf; 1748 addrs[i].conf.default_server = addr[i].default_server;
1766 #if (NGX_HTTP_SSL) 1749 #if (NGX_HTTP_SSL)
1767 addrs[i].conf.ssl = addr[i].ssl; 1750 addrs[i].conf.ssl = addr[i].opt.ssl;
1768 #endif 1751 #endif
1769 1752
1770 if (addr[i].hash.buckets == NULL 1753 if (addr[i].hash.buckets == NULL
1771 && (addr[i].wc_head == NULL 1754 && (addr[i].wc_head == NULL
1772 || addr[i].wc_head->hash.buckets == NULL) 1755 || addr[i].wc_head->hash.buckets == NULL)
1819 1802
1820 addrs6 = hport->addrs; 1803 addrs6 = hport->addrs;
1821 1804
1822 for (i = 0; i < hport->naddrs; i++) { 1805 for (i = 0; i < hport->naddrs; i++) {
1823 1806
1824 sin6 = (struct sockaddr_in6 *) addr[i].sockaddr; 1807 sin6 = &addr[i].opt.u.sockaddr_in6;
1825 addrs6[i].addr6 = sin6->sin6_addr; 1808 addrs6[i].addr6 = sin6->sin6_addr;
1826 addrs6[i].conf.core_srv_conf = addr[i].core_srv_conf; 1809 addrs6[i].conf.default_server = addr[i].default_server;
1827 #if (NGX_HTTP_SSL) 1810 #if (NGX_HTTP_SSL)
1828 addrs6[i].conf.ssl = addr[i].ssl; 1811 addrs6[i].conf.ssl = addr[i].opt.ssl;
1829 #endif 1812 #endif
1830 1813
1831 if (addr[i].hash.buckets == NULL 1814 if (addr[i].hash.buckets == NULL
1832 && (addr[i].wc_head == NULL 1815 && (addr[i].wc_head == NULL
1833 || addr[i].wc_head->hash.buckets == NULL) 1816 || addr[i].wc_head->hash.buckets == NULL)
1869 ngx_uint_t i, n, hash; 1852 ngx_uint_t i, n, hash;
1870 ngx_hash_key_t *type; 1853 ngx_hash_key_t *type;
1871 1854
1872 types = (ngx_array_t **) (p + cmd->offset); 1855 types = (ngx_array_t **) (p + cmd->offset);
1873 1856
1857 if (*types == (void *) -1) {
1858 return NGX_CONF_OK;
1859 }
1860
1874 default_type = cmd->post; 1861 default_type = cmd->post;
1875 1862
1876 if (*types == NULL) { 1863 if (*types == NULL) {
1877 *types = ngx_array_create(cf->temp_pool, 1, sizeof(ngx_hash_key_t)); 1864 *types = ngx_array_create(cf->temp_pool, 1, sizeof(ngx_hash_key_t));
1878 if (*types == NULL) { 1865 if (*types == NULL) {
1894 1881
1895 value = cf->args->elts; 1882 value = cf->args->elts;
1896 1883
1897 for (i = 1; i < cf->args->nelts; i++) { 1884 for (i = 1; i < cf->args->nelts; i++) {
1898 1885
1886 if (value[i].len == 1 && value[i].data[0] == '*') {
1887 *types = (void *) -1;
1888 return NGX_CONF_OK;
1889 }
1890
1899 hash = ngx_hash_strlow(value[i].data, value[i].data, value[i].len); 1891 hash = ngx_hash_strlow(value[i].data, value[i].data, value[i].len);
1900 value[i].data[value[i].len] = '\0'; 1892 value[i].data[value[i].len] = '\0';
1901 1893
1902 type = (*types)->elts; 1894 type = (*types)->elts;
1903 for (n = 0; n < (*types)->nelts; n++) { 1895 for (n = 0; n < (*types)->nelts; n++) {
1922 return NGX_CONF_OK; 1914 return NGX_CONF_OK;
1923 } 1915 }
1924 1916
1925 1917
1926 char * 1918 char *
1927 ngx_http_merge_types(ngx_conf_t *cf, ngx_array_t *keys, ngx_hash_t *types_hash, 1919 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, 1920 ngx_array_t **prev_keys, ngx_hash_t *prev_types_hash,
1929 ngx_str_t *default_types) 1921 ngx_str_t *default_types)
1930 { 1922 {
1931 ngx_hash_init_t hash; 1923 ngx_hash_init_t hash;
1932 1924
1933 if (keys) { 1925 if (*keys) {
1926
1927 if (*keys == (void *) -1) {
1928 return NGX_CONF_OK;
1929 }
1934 1930
1935 hash.hash = types_hash; 1931 hash.hash = types_hash;
1936 hash.key = NULL; 1932 hash.key = NULL;
1937 hash.max_size = 2048; 1933 hash.max_size = 2048;
1938 hash.bucket_size = 64; 1934 hash.bucket_size = 64;
1939 hash.name = "test_types_hash"; 1935 hash.name = "test_types_hash";
1940 hash.pool = cf->pool; 1936 hash.pool = cf->pool;
1941 hash.temp_pool = NULL; 1937 hash.temp_pool = NULL;
1942 1938
1943 if (ngx_hash_init(&hash, keys->elts, keys->nelts) != NGX_OK) { 1939 if (ngx_hash_init(&hash, (*keys)->elts, (*keys)->nelts) != NGX_OK) {
1944 return NGX_CONF_ERROR; 1940 return NGX_CONF_ERROR;
1945 } 1941 }
1946 1942
1947 return NGX_CONF_OK; 1943 return NGX_CONF_OK;
1948 } 1944 }
1949 1945
1950 if (prev_types_hash->buckets == NULL) { 1946 if (prev_types_hash->buckets == NULL) {
1951 1947
1952 if (prev_keys == NULL) { 1948 if (*prev_keys == NULL) {
1953 1949
1954 if (ngx_http_set_default_types(cf, &prev_keys, default_types) 1950 if (ngx_http_set_default_types(cf, prev_keys, default_types)
1955 != NGX_OK) 1951 != NGX_OK)
1956 { 1952 {
1957 return NGX_CONF_ERROR; 1953 return NGX_CONF_ERROR;
1958 } 1954 }
1955
1956 } else if (*prev_keys == (void *) -1) {
1957 *keys = *prev_keys;
1958 return NGX_CONF_OK;
1959 } 1959 }
1960 1960
1961 hash.hash = prev_types_hash; 1961 hash.hash = prev_types_hash;
1962 hash.key = NULL; 1962 hash.key = NULL;
1963 hash.max_size = 2048; 1963 hash.max_size = 2048;
1964 hash.bucket_size = 64; 1964 hash.bucket_size = 64;
1965 hash.name = "test_types_hash"; 1965 hash.name = "test_types_hash";
1966 hash.pool = cf->pool; 1966 hash.pool = cf->pool;
1967 hash.temp_pool = NULL; 1967 hash.temp_pool = NULL;
1968 1968
1969 if (ngx_hash_init(&hash, prev_keys->elts, prev_keys->nelts) != NGX_OK) { 1969 if (ngx_hash_init(&hash, (*prev_keys)->elts, (*prev_keys)->nelts)
1970 != NGX_OK)
1971 {
1970 return NGX_CONF_ERROR; 1972 return NGX_CONF_ERROR;
1971 } 1973 }
1972 } 1974 }
1973 1975
1974 *types_hash = *prev_types_hash; 1976 *types_hash = *prev_types_hash;