Mercurial > hg > nginx-ranges
comparison src/http/ngx_http.c @ 457:76a79816b771 NGINX_0_7_36
nginx 0.7.36
*) Feature: a preliminary IPv6 support; the "listen" directive of the
HTTP module supports IPv6.
*) Bugfix: the $ancient_browser variable did not work for browsers
preset by a "modern_browser" directives.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Sat, 21 Feb 2009 00:00:00 +0300 |
parents | dac47e9ef0d5 |
children | a8424ffa495c |
comparison
equal
deleted
inserted
replaced
456:40964c811e59 | 457:76a79816b771 |
---|---|
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, | 20 static ngx_int_t ngx_http_init_server_lists(ngx_conf_t *cf, |
21 ngx_array_t *servers, ngx_array_t *in_ports); | 21 ngx_array_t *servers, ngx_array_t *in_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, | |
26 ngx_http_core_srv_conf_t *cscf, ngx_http_conf_port_t *port, | |
27 ngx_http_listen_t *listen); | |
22 static ngx_int_t ngx_http_add_address(ngx_conf_t *cf, | 28 static ngx_int_t ngx_http_add_address(ngx_conf_t *cf, |
23 ngx_http_core_srv_conf_t *cscf, ngx_http_conf_in_port_t *in_port, | 29 ngx_http_core_srv_conf_t *cscf, ngx_http_conf_port_t *port, |
24 ngx_http_listen_t *listen); | 30 ngx_http_listen_t *listen); |
25 static ngx_int_t ngx_http_add_names(ngx_conf_t *cf, | 31 static ngx_int_t ngx_http_add_names(ngx_conf_t *cf, |
26 ngx_http_core_srv_conf_t *cscf, ngx_http_conf_in_addr_t *in_addr); | 32 ngx_http_core_srv_conf_t *cscf, ngx_http_conf_addr_t *addr); |
27 | 33 |
28 static char *ngx_http_merge_locations(ngx_conf_t *cf, | 34 static char *ngx_http_merge_locations(ngx_conf_t *cf, |
29 ngx_queue_t *locations, void **loc_conf, ngx_http_module_t *module, | 35 ngx_queue_t *locations, void **loc_conf, ngx_http_module_t *module, |
30 ngx_uint_t ctx_index); | 36 ngx_uint_t ctx_index); |
31 static ngx_int_t ngx_http_init_locations(ngx_conf_t *cf, | 37 static ngx_int_t ngx_http_init_locations(ngx_conf_t *cf, |
41 static ngx_http_location_tree_node_t * | 47 static ngx_http_location_tree_node_t * |
42 ngx_http_create_locations_tree(ngx_conf_t *cf, ngx_queue_t *locations, | 48 ngx_http_create_locations_tree(ngx_conf_t *cf, ngx_queue_t *locations, |
43 size_t prefix); | 49 size_t prefix); |
44 | 50 |
45 static ngx_int_t ngx_http_optimize_servers(ngx_conf_t *cf, | 51 static ngx_int_t ngx_http_optimize_servers(ngx_conf_t *cf, |
46 ngx_http_core_main_conf_t *cmcf, ngx_array_t *in_ports); | 52 ngx_http_core_main_conf_t *cmcf, ngx_array_t *ports); |
47 static ngx_int_t ngx_http_cmp_conf_in_addrs(const void *one, const void *two); | 53 static ngx_int_t ngx_http_server_names(ngx_conf_t *cf, |
54 ngx_http_core_main_conf_t *cmcf, ngx_http_conf_addr_t *addr); | |
55 static ngx_int_t ngx_http_cmp_conf_addrs(const void *one, const void *two); | |
48 static int ngx_libc_cdecl ngx_http_cmp_dns_wildcards(const void *one, | 56 static int ngx_libc_cdecl ngx_http_cmp_dns_wildcards(const void *one, |
49 const void *two); | 57 const void *two); |
50 | 58 |
51 static ngx_int_t ngx_http_init_listening(ngx_conf_t *cf, | 59 static ngx_int_t ngx_http_init_listening(ngx_conf_t *cf, |
52 ngx_http_conf_in_port_t *in_port); | 60 ngx_http_conf_port_t *port); |
61 static ngx_listening_t *ngx_http_add_listening(ngx_conf_t *cf, | |
62 ngx_http_conf_addr_t *addr); | |
63 static ngx_int_t ngx_http_add_addrs(ngx_conf_t *cf, ngx_http_port_t *hport, | |
64 ngx_http_conf_addr_t *addr); | |
65 #if (NGX_HAVE_INET6) | |
66 static ngx_int_t ngx_http_add_addrs6(ngx_conf_t *cf, ngx_http_port_t *hport, | |
67 ngx_http_conf_addr_t *addr); | |
68 #endif | |
53 | 69 |
54 ngx_uint_t ngx_http_max_module; | 70 ngx_uint_t ngx_http_max_module; |
55 | 71 |
56 | 72 |
57 ngx_int_t (*ngx_http_top_header_filter) (ngx_http_request_t *r); | 73 ngx_int_t (*ngx_http_top_header_filter) (ngx_http_request_t *r); |
349 /* | 365 /* |
350 * create the lists of ports, addresses and server names | 366 * create the lists of ports, addresses and server names |
351 * to find quickly the server core module configuration at run-time | 367 * to find quickly the server core module configuration at run-time |
352 */ | 368 */ |
353 | 369 |
354 /* AF_INET only */ | |
355 | |
356 if (ngx_http_init_server_lists(cf, &cmcf->servers, &in_ports) != NGX_OK) { | 370 if (ngx_http_init_server_lists(cf, &cmcf->servers, &in_ports) != NGX_OK) { |
357 return NGX_CONF_ERROR; | 371 return NGX_CONF_ERROR; |
358 } | 372 } |
359 | 373 |
360 | 374 |
361 /* optimize the lists of ports, addresses and server names */ | 375 /* optimize the lists of ports, addresses and server names */ |
362 | |
363 /* AF_INET only */ | |
364 | 376 |
365 if (ngx_http_optimize_servers(cf, cmcf, &in_ports) != NGX_OK) { | 377 if (ngx_http_optimize_servers(cf, cmcf, &in_ports) != NGX_OK) { |
366 return NGX_CONF_ERROR; | 378 return NGX_CONF_ERROR; |
367 } | 379 } |
368 | 380 |
1097 } | 1109 } |
1098 | 1110 |
1099 | 1111 |
1100 static ngx_int_t | 1112 static ngx_int_t |
1101 ngx_http_init_server_lists(ngx_conf_t *cf, ngx_array_t *servers, | 1113 ngx_http_init_server_lists(ngx_conf_t *cf, ngx_array_t *servers, |
1102 ngx_array_t *in_ports) | 1114 ngx_array_t *ports) |
1103 { | 1115 { |
1104 ngx_uint_t s, l, p, a; | 1116 ngx_uint_t s, i; |
1105 ngx_http_listen_t *listen; | 1117 ngx_http_listen_t *listen; |
1106 ngx_http_conf_in_port_t *in_port; | |
1107 ngx_http_conf_in_addr_t *in_addr; | |
1108 ngx_http_core_srv_conf_t **cscfp; | 1118 ngx_http_core_srv_conf_t **cscfp; |
1109 | 1119 |
1110 if (ngx_array_init(in_ports, cf->temp_pool, 2, | 1120 if (ngx_array_init(ports, cf->temp_pool, 2, sizeof(ngx_http_conf_port_t)) |
1111 sizeof(ngx_http_conf_in_port_t)) | |
1112 != NGX_OK) | 1121 != NGX_OK) |
1113 { | 1122 { |
1114 return NGX_ERROR; | 1123 return NGX_ERROR; |
1115 } | 1124 } |
1116 | 1125 |
1120 for (s = 0; s < servers->nelts; s++) { | 1129 for (s = 0; s < servers->nelts; s++) { |
1121 | 1130 |
1122 /* "listen" directives */ | 1131 /* "listen" directives */ |
1123 | 1132 |
1124 listen = cscfp[s]->listen.elts; | 1133 listen = cscfp[s]->listen.elts; |
1125 for (l = 0; l < cscfp[s]->listen.nelts; l++) { | 1134 for (i = 0; i < cscfp[s]->listen.nelts; i++) { |
1126 | 1135 |
1127 /* AF_INET only */ | 1136 if (ngx_http_add_ports(cf, cscfp[s], ports, &listen[i]) != NGX_OK) { |
1128 | 1137 return NGX_ERROR; |
1129 in_port = in_ports->elts; | 1138 } |
1130 for (p = 0; p < in_ports->nelts; p++) { | 1139 } |
1131 | 1140 } |
1132 if (listen[l].port != in_port[p].port) { | 1141 |
1133 continue; | 1142 return NGX_OK; |
1134 } | 1143 } |
1135 | 1144 |
1136 /* the port is already in the port list */ | 1145 |
1137 | 1146 static ngx_int_t |
1138 in_addr = in_port[p].addrs.elts; | 1147 ngx_http_add_ports(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf, |
1139 for (a = 0; a < in_port[p].addrs.nelts; a++) { | 1148 ngx_array_t *ports, ngx_http_listen_t *listen) |
1140 | 1149 { |
1141 if (listen[l].addr != in_addr[a].addr) { | 1150 in_port_t p; |
1142 continue; | 1151 ngx_uint_t i; |
1143 } | 1152 struct sockaddr *sa; |
1144 | 1153 struct sockaddr_in *sin; |
1145 /* the address is already in the address list */ | 1154 ngx_http_conf_port_t *port; |
1146 | 1155 #if (NGX_HAVE_INET6) |
1147 if (ngx_http_add_names(cf, cscfp[s], &in_addr[a]) != NGX_OK) | 1156 struct sockaddr_in6 *sin6; |
1148 { | 1157 #endif |
1149 return NGX_ERROR; | 1158 |
1150 } | 1159 sa = (struct sockaddr *) &listen->sockaddr; |
1151 | 1160 |
1152 /* | 1161 switch (sa->sa_family) { |
1153 * check the duplicate "default" server | 1162 |
1154 * for this address:port | 1163 #if (NGX_HAVE_INET6) |
1155 */ | 1164 case AF_INET6: |
1156 | 1165 sin6 = (struct sockaddr_in6 *) sa; |
1157 if (listen[l].conf.default_server) { | 1166 p = sin6->sin6_port; |
1158 | 1167 break; |
1159 if (in_addr[a].default_server) { | 1168 #endif |
1160 ngx_log_error(NGX_LOG_ERR, cf->log, 0, | 1169 |
1161 "the duplicate default server in %s:%ui", | 1170 default: /* AF_INET */ |
1162 listen[l].file_name, listen[l].line); | 1171 sin = (struct sockaddr_in *) sa; |
1163 | 1172 p = sin->sin_port; |
1164 return NGX_ERROR; | 1173 break; |
1165 } | 1174 } |
1166 | 1175 |
1167 in_addr[a].core_srv_conf = cscfp[s]; | 1176 port = ports->elts; |
1168 in_addr[a].default_server = 1; | 1177 for (i = 0; i < ports->nelts; i++) { |
1178 | |
1179 if (p != port[i].port || sa->sa_family != port[i].family) { | |
1180 continue; | |
1181 } | |
1182 | |
1183 /* a port is already in the in_port list */ | |
1184 | |
1185 return ngx_http_add_addresses(cf, cscf, &port[i], listen); | |
1186 } | |
1187 | |
1188 /* add a port to the in_port list */ | |
1189 | |
1190 port = ngx_array_push(ports); | |
1191 if (port == NULL) { | |
1192 return NGX_ERROR; | |
1193 } | |
1194 | |
1195 port->family = sa->sa_family; | |
1196 port->port = p; | |
1197 port->addrs.elts = NULL; | |
1198 | |
1199 return ngx_http_add_address(cf, cscf, port, listen); | |
1200 } | |
1201 | |
1202 | |
1203 static ngx_int_t | |
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) | |
1206 { | |
1207 u_char *p; | |
1208 size_t len, off; | |
1209 ngx_uint_t i; | |
1210 struct sockaddr *sa; | |
1211 ngx_http_conf_addr_t *addr; | |
1212 | |
1213 /* | |
1214 * we can not compare whole sockaddr struct's as kernel | |
1215 * may fill some fields in inherited sockaddr struct's | |
1216 */ | |
1217 | |
1218 sa = (struct sockaddr *) &listen->sockaddr; | |
1219 | |
1220 switch (sa->sa_family) { | |
1221 | |
1222 #if (NGX_HAVE_INET6) | |
1223 case AF_INET6: | |
1224 off = offsetof(struct sockaddr_in6, sin6_addr); | |
1225 len = 16; | |
1226 break; | |
1227 #endif | |
1228 | |
1229 default: /* AF_INET */ | |
1230 off = offsetof(struct sockaddr_in, sin_addr); | |
1231 len = 4; | |
1232 break; | |
1233 } | |
1234 | |
1235 p = listen->sockaddr + off; | |
1236 | |
1237 addr = port->addrs.elts; | |
1238 | |
1239 for (i = 0; i < port->addrs.nelts; i++) { | |
1240 | |
1241 if (ngx_memcmp(p, (u_char *) addr[i].sockaddr + off, len) != 0) { | |
1242 continue; | |
1243 } | |
1244 | |
1245 /* the address is already in the address list */ | |
1246 | |
1247 if (ngx_http_add_names(cf, cscf, &addr[i]) != NGX_OK) { | |
1248 return NGX_ERROR; | |
1249 } | |
1250 | |
1251 /* check the duplicate "default" server for this address:port */ | |
1252 | |
1253 if (listen->conf.default_server) { | |
1254 | |
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); | |
1259 | |
1260 return NGX_ERROR; | |
1261 } | |
1262 | |
1263 addr[i].core_srv_conf = cscf; | |
1264 addr[i].default_server = 1; | |
1169 #if (NGX_HTTP_SSL) | 1265 #if (NGX_HTTP_SSL) |
1170 in_addr[a].ssl = listen[l].conf.ssl; | 1266 addr[i].ssl = listen->conf.ssl; |
1171 #endif | 1267 #endif |
1172 in_addr[a].listen_conf = &listen[l].conf; | 1268 addr[i].listen_conf = &listen->conf; |
1173 } | 1269 } |
1174 | 1270 |
1175 goto found; | 1271 return NGX_OK; |
1176 } | 1272 } |
1177 | 1273 |
1178 /* | 1274 /* add the address to the addresses list that bound to this port */ |
1179 * add the address to the addresses list that | 1275 |
1180 * bound to this port | 1276 return ngx_http_add_address(cf, cscf, port, listen); |
1181 */ | |
1182 | |
1183 if (ngx_http_add_address(cf, cscfp[s], &in_port[p], &listen[l]) | |
1184 != NGX_OK) | |
1185 { | |
1186 return NGX_ERROR; | |
1187 } | |
1188 | |
1189 goto found; | |
1190 } | |
1191 | |
1192 /* add the port to the in_port list */ | |
1193 | |
1194 in_port = ngx_array_push(in_ports); | |
1195 if (in_port == NULL) { | |
1196 return NGX_ERROR; | |
1197 } | |
1198 | |
1199 in_port->port = listen[l].port; | |
1200 in_port->addrs.elts = NULL; | |
1201 | |
1202 if (ngx_http_add_address(cf, cscfp[s], in_port, &listen[l]) | |
1203 != NGX_OK) | |
1204 { | |
1205 return NGX_ERROR; | |
1206 } | |
1207 | |
1208 found: | |
1209 | |
1210 continue; | |
1211 } | |
1212 } | |
1213 | |
1214 return NGX_OK; | |
1215 } | 1277 } |
1216 | 1278 |
1217 | 1279 |
1218 /* | 1280 /* |
1219 * add the server address, the server names and the server core module | 1281 * add the server address, the server names and the server core module |
1220 * configurations to the port (in_port) | 1282 * configurations to the port (in_port) |
1221 */ | 1283 */ |
1222 | 1284 |
1223 static ngx_int_t | 1285 static ngx_int_t |
1224 ngx_http_add_address(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf, | 1286 ngx_http_add_address(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf, |
1225 ngx_http_conf_in_port_t *in_port, ngx_http_listen_t *listen) | 1287 ngx_http_conf_port_t *port, ngx_http_listen_t *listen) |
1226 { | 1288 { |
1227 ngx_http_conf_in_addr_t *in_addr; | 1289 ngx_http_conf_addr_t *addr; |
1228 | 1290 |
1229 if (in_port->addrs.elts == NULL) { | 1291 if (port->addrs.elts == NULL) { |
1230 if (ngx_array_init(&in_port->addrs, cf->temp_pool, 4, | 1292 if (ngx_array_init(&port->addrs, cf->temp_pool, 4, |
1231 sizeof(ngx_http_conf_in_addr_t)) | 1293 sizeof(ngx_http_conf_addr_t)) |
1232 != NGX_OK) | 1294 != NGX_OK) |
1233 { | 1295 { |
1234 return NGX_ERROR; | 1296 return NGX_ERROR; |
1235 } | 1297 } |
1236 } | 1298 } |
1237 | 1299 |
1238 in_addr = ngx_array_push(&in_port->addrs); | 1300 addr = ngx_array_push(&port->addrs); |
1239 if (in_addr == NULL) { | 1301 if (addr == NULL) { |
1240 return NGX_ERROR; | 1302 return NGX_ERROR; |
1241 } | 1303 } |
1242 | 1304 |
1243 in_addr->addr = listen->addr; | 1305 addr->sockaddr = (struct sockaddr *) &listen->sockaddr; |
1244 in_addr->hash.buckets = NULL; | 1306 addr->socklen = listen->socklen; |
1245 in_addr->hash.size = 0; | 1307 addr->hash.buckets = NULL; |
1246 in_addr->wc_head = NULL; | 1308 addr->hash.size = 0; |
1247 in_addr->wc_tail = NULL; | 1309 addr->wc_head = NULL; |
1248 in_addr->names.elts = NULL; | 1310 addr->wc_tail = NULL; |
1311 addr->names.elts = NULL; | |
1249 #if (NGX_PCRE) | 1312 #if (NGX_PCRE) |
1250 in_addr->nregex = 0; | 1313 addr->nregex = 0; |
1251 in_addr->regex = NULL; | 1314 addr->regex = NULL; |
1252 #endif | 1315 #endif |
1253 in_addr->core_srv_conf = cscf; | 1316 addr->core_srv_conf = cscf; |
1254 in_addr->default_server = listen->conf.default_server; | 1317 addr->default_server = listen->conf.default_server; |
1255 in_addr->bind = listen->conf.bind; | 1318 addr->bind = listen->conf.bind; |
1319 addr->wildcard = listen->conf.wildcard; | |
1256 #if (NGX_HTTP_SSL) | 1320 #if (NGX_HTTP_SSL) |
1257 in_addr->ssl = listen->conf.ssl; | 1321 addr->ssl = listen->conf.ssl; |
1258 #endif | 1322 #endif |
1259 in_addr->listen_conf = &listen->conf; | 1323 addr->listen_conf = &listen->conf; |
1260 | 1324 |
1261 return ngx_http_add_names(cf, cscf, in_addr); | 1325 return ngx_http_add_names(cf, cscf, addr); |
1262 } | 1326 } |
1263 | 1327 |
1264 | 1328 |
1265 /* | 1329 /* |
1266 * add the server names and the server core module | 1330 * add the server names and the server core module |
1267 * configurations to the address:port (in_addr) | 1331 * configurations to the address:port |
1268 */ | 1332 */ |
1269 | 1333 |
1270 static ngx_int_t | 1334 static ngx_int_t |
1271 ngx_http_add_names(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf, | 1335 ngx_http_add_names(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf, |
1272 ngx_http_conf_in_addr_t *in_addr) | 1336 ngx_http_conf_addr_t *addr) |
1273 { | 1337 { |
1274 ngx_uint_t i; | 1338 ngx_uint_t i; |
1275 ngx_http_server_name_t *server_names, *name; | 1339 ngx_http_server_name_t *server_names, *name; |
1276 | 1340 |
1277 if (in_addr->names.elts == NULL) { | 1341 if (addr->names.elts == NULL) { |
1278 if (ngx_array_init(&in_addr->names, cf->temp_pool, 4, | 1342 if (ngx_array_init(&addr->names, cf->temp_pool, 4, |
1279 sizeof(ngx_http_server_name_t)) | 1343 sizeof(ngx_http_server_name_t)) |
1280 != NGX_OK) | 1344 != NGX_OK) |
1281 { | 1345 { |
1282 return NGX_ERROR; | 1346 return NGX_ERROR; |
1283 } | 1347 } |
1291 server_names[i].name.len); | 1355 server_names[i].name.len); |
1292 | 1356 |
1293 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0, | 1357 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0, |
1294 "name: %V", &server_names[i].name); | 1358 "name: %V", &server_names[i].name); |
1295 | 1359 |
1296 name = ngx_array_push(&in_addr->names); | 1360 name = ngx_array_push(&addr->names); |
1297 if (name == NULL) { | 1361 if (name == NULL) { |
1298 return NGX_ERROR; | 1362 return NGX_ERROR; |
1299 } | 1363 } |
1300 | 1364 |
1301 *name = server_names[i]; | 1365 *name = server_names[i]; |
1305 } | 1369 } |
1306 | 1370 |
1307 | 1371 |
1308 static ngx_int_t | 1372 static ngx_int_t |
1309 ngx_http_optimize_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf, | 1373 ngx_http_optimize_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf, |
1310 ngx_array_t *in_ports) | 1374 ngx_array_t *ports) |
1375 { | |
1376 ngx_uint_t s, p, a; | |
1377 ngx_http_conf_port_t *port; | |
1378 ngx_http_conf_addr_t *addr; | |
1379 ngx_http_server_name_t *name; | |
1380 | |
1381 port = ports->elts; | |
1382 for (p = 0; p < ports->nelts; p++) { | |
1383 | |
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); | |
1386 | |
1387 /* | |
1388 * check whether all name-based servers have the same | |
1389 * configuraiton as a default server for given address:port | |
1390 */ | |
1391 | |
1392 addr = port[p].addrs.elts; | |
1393 for (a = 0; a < port[p].addrs.nelts; a++) { | |
1394 | |
1395 name = addr[a].names.elts; | |
1396 for (s = 0; s < addr[a].names.nelts; s++) { | |
1397 | |
1398 if (addr[a].core_srv_conf == name[s].core_srv_conf) { | |
1399 continue; | |
1400 } | |
1401 | |
1402 if (ngx_http_server_names(cf, cmcf, &addr[a]) != NGX_OK) { | |
1403 return NGX_ERROR; | |
1404 } | |
1405 | |
1406 break; | |
1407 } | |
1408 } | |
1409 | |
1410 if (ngx_http_init_listening(cf, &port[p]) != NGX_OK) { | |
1411 return NGX_ERROR; | |
1412 } | |
1413 } | |
1414 | |
1415 return NGX_OK; | |
1416 } | |
1417 | |
1418 | |
1419 static ngx_int_t | |
1420 ngx_http_server_names(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf, | |
1421 ngx_http_conf_addr_t *addr) | |
1311 { | 1422 { |
1312 ngx_int_t rc; | 1423 ngx_int_t rc; |
1313 ngx_uint_t s, p, a; | 1424 ngx_uint_t s; |
1314 ngx_hash_init_t hash; | 1425 ngx_hash_init_t hash; |
1315 ngx_http_server_name_t *name; | 1426 ngx_http_server_name_t *name; |
1316 ngx_hash_keys_arrays_t ha; | 1427 ngx_hash_keys_arrays_t ha; |
1317 ngx_http_conf_in_port_t *in_port; | |
1318 ngx_http_conf_in_addr_t *in_addr; | |
1319 #if (NGX_PCRE) | 1428 #if (NGX_PCRE) |
1320 ngx_uint_t regex, i; | 1429 ngx_uint_t regex, i; |
1321 #endif | 1430 |
1322 | 1431 regex = 0; |
1323 in_port = in_ports->elts; | 1432 #endif |
1324 for (p = 0; p < in_ports->nelts; p++) { | 1433 |
1325 | 1434 ngx_memzero(&ha, sizeof(ngx_hash_keys_arrays_t)); |
1326 ngx_sort(in_port[p].addrs.elts, (size_t) in_port[p].addrs.nelts, | 1435 |
1327 sizeof(ngx_http_conf_in_addr_t), ngx_http_cmp_conf_in_addrs); | 1436 ha.temp_pool = ngx_create_pool(16384, cf->log); |
1328 | 1437 if (ha.temp_pool == NULL) { |
1329 /* | 1438 return NGX_ERROR; |
1330 * check whether all name-based servers have | 1439 } |
1331 * the same configuraiton as the default server | 1440 |
1332 */ | 1441 ha.pool = cf->pool; |
1333 | 1442 |
1334 in_addr = in_port[p].addrs.elts; | 1443 if (ngx_hash_keys_array_init(&ha, NGX_HASH_LARGE) != NGX_OK) { |
1335 for (a = 0; a < in_port[p].addrs.nelts; a++) { | 1444 goto failed; |
1336 | 1445 } |
1337 name = in_addr[a].names.elts; | 1446 |
1338 for (s = 0; s < in_addr[a].names.nelts; s++) { | 1447 name = addr->names.elts; |
1339 | 1448 |
1340 if (in_addr[a].core_srv_conf != name[s].core_srv_conf) { | 1449 for (s = 0; s < addr->names.nelts; s++) { |
1341 goto virtual_names; | 1450 |
1342 } | 1451 #if (NGX_PCRE) |
1343 } | 1452 if (name[s].regex) { |
1344 | 1453 regex++; |
1345 /* | |
1346 * if all name-based servers have the same configuration | |
1347 * as the default server, then we do not need to check | |
1348 * them at run-time at all | |
1349 */ | |
1350 | |
1351 in_addr[a].names.nelts = 0; | |
1352 | |
1353 continue; | 1454 continue; |
1354 | 1455 } |
1355 virtual_names: | 1456 #endif |
1356 | 1457 |
1357 ngx_memzero(&ha, sizeof(ngx_hash_keys_arrays_t)); | 1458 rc = ngx_hash_add_key(&ha, &name[s].name, name[s].core_srv_conf, |
1358 | 1459 NGX_HASH_WILDCARD_KEY); |
1359 ha.temp_pool = ngx_create_pool(16384, cf->log); | 1460 |
1360 if (ha.temp_pool == NULL) { | 1461 if (rc == NGX_ERROR) { |
1361 return NGX_ERROR; | 1462 return NGX_ERROR; |
1362 } | 1463 } |
1363 | 1464 |
1364 ha.pool = cf->pool; | 1465 if (rc == NGX_DECLINED) { |
1365 | 1466 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, |
1366 if (ngx_hash_keys_array_init(&ha, NGX_HASH_LARGE) != NGX_OK) { | 1467 "invalid server name or wildcard \"%V\" on %s", |
1367 goto failed; | 1468 &name[s].name, addr->listen_conf->addr); |
1368 } | 1469 return NGX_ERROR; |
1470 } | |
1471 | |
1472 if (rc == NGX_BUSY) { | |
1473 ngx_log_error(NGX_LOG_WARN, cf->log, 0, | |
1474 "conflicting server name \"%V\" on %s, ignored", | |
1475 &name[s].name, addr->listen_conf->addr); | |
1476 } | |
1477 } | |
1478 | |
1479 hash.key = ngx_hash_key_lc; | |
1480 hash.max_size = cmcf->server_names_hash_max_size; | |
1481 hash.bucket_size = cmcf->server_names_hash_bucket_size; | |
1482 hash.name = "server_names_hash"; | |
1483 hash.pool = cf->pool; | |
1484 | |
1485 if (ha.keys.nelts) { | |
1486 hash.hash = &addr->hash; | |
1487 hash.temp_pool = NULL; | |
1488 | |
1489 if (ngx_hash_init(&hash, ha.keys.elts, ha.keys.nelts) != NGX_OK) { | |
1490 goto failed; | |
1491 } | |
1492 } | |
1493 | |
1494 if (ha.dns_wc_head.nelts) { | |
1495 | |
1496 ngx_qsort(ha.dns_wc_head.elts, (size_t) ha.dns_wc_head.nelts, | |
1497 sizeof(ngx_hash_key_t), ngx_http_cmp_dns_wildcards); | |
1498 | |
1499 hash.hash = NULL; | |
1500 hash.temp_pool = ha.temp_pool; | |
1501 | |
1502 if (ngx_hash_wildcard_init(&hash, ha.dns_wc_head.elts, | |
1503 ha.dns_wc_head.nelts) | |
1504 != NGX_OK) | |
1505 { | |
1506 goto failed; | |
1507 } | |
1508 | |
1509 addr->wc_head = (ngx_hash_wildcard_t *) hash.hash; | |
1510 } | |
1511 | |
1512 if (ha.dns_wc_tail.nelts) { | |
1513 | |
1514 ngx_qsort(ha.dns_wc_tail.elts, (size_t) ha.dns_wc_tail.nelts, | |
1515 sizeof(ngx_hash_key_t), ngx_http_cmp_dns_wildcards); | |
1516 | |
1517 hash.hash = NULL; | |
1518 hash.temp_pool = ha.temp_pool; | |
1519 | |
1520 if (ngx_hash_wildcard_init(&hash, ha.dns_wc_tail.elts, | |
1521 ha.dns_wc_tail.nelts) | |
1522 != NGX_OK) | |
1523 { | |
1524 goto failed; | |
1525 } | |
1526 | |
1527 addr->wc_tail = (ngx_hash_wildcard_t *) hash.hash; | |
1528 } | |
1529 | |
1530 ngx_destroy_pool(ha.temp_pool); | |
1369 | 1531 |
1370 #if (NGX_PCRE) | 1532 #if (NGX_PCRE) |
1371 regex = 0; | 1533 |
1372 #endif | 1534 if (regex == 0) { |
1373 | 1535 return NGX_OK; |
1374 name = in_addr[a].names.elts; | 1536 } |
1375 | 1537 |
1376 for (s = 0; s < in_addr[a].names.nelts; s++) { | 1538 addr->nregex = regex; |
1377 | 1539 addr->regex = ngx_palloc(cf->pool, regex * sizeof(ngx_http_server_name_t)); |
1378 #if (NGX_PCRE) | 1540 if (addr->regex == NULL) { |
1379 if (name[s].regex) { | 1541 return NGX_ERROR; |
1380 regex++; | 1542 } |
1381 continue; | 1543 |
1382 } | 1544 for (i = 0, s = 0; s < addr->names.nelts; s++) { |
1383 #endif | 1545 if (name[s].regex) { |
1384 | 1546 addr->regex[i++] = name[s]; |
1385 rc = ngx_hash_add_key(&ha, &name[s].name, name[s].core_srv_conf, | 1547 } |
1386 NGX_HASH_WILDCARD_KEY); | 1548 } |
1387 | 1549 |
1388 if (rc == NGX_ERROR) { | 1550 #endif |
1389 return NGX_ERROR; | |
1390 } | |
1391 | |
1392 if (rc == NGX_DECLINED) { | |
1393 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
1394 "invalid server name or wildcard \"%V\" on %s", | |
1395 &name[s].name, in_addr[a].listen_conf->addr); | |
1396 return NGX_ERROR; | |
1397 } | |
1398 | |
1399 if (rc == NGX_BUSY) { | |
1400 ngx_log_error(NGX_LOG_WARN, cf->log, 0, | |
1401 "conflicting server name \"%V\" on %s, ignored", | |
1402 &name[s].name, in_addr[a].listen_conf->addr); | |
1403 } | |
1404 } | |
1405 | |
1406 hash.key = ngx_hash_key_lc; | |
1407 hash.max_size = cmcf->server_names_hash_max_size; | |
1408 hash.bucket_size = cmcf->server_names_hash_bucket_size; | |
1409 hash.name = "server_names_hash"; | |
1410 hash.pool = cf->pool; | |
1411 | |
1412 if (ha.keys.nelts) { | |
1413 hash.hash = &in_addr[a].hash; | |
1414 hash.temp_pool = NULL; | |
1415 | |
1416 if (ngx_hash_init(&hash, ha.keys.elts, ha.keys.nelts) != NGX_OK) | |
1417 { | |
1418 goto failed; | |
1419 } | |
1420 } | |
1421 | |
1422 if (ha.dns_wc_head.nelts) { | |
1423 | |
1424 ngx_qsort(ha.dns_wc_head.elts, | |
1425 (size_t) ha.dns_wc_head.nelts, | |
1426 sizeof(ngx_hash_key_t), | |
1427 ngx_http_cmp_dns_wildcards); | |
1428 | |
1429 hash.hash = NULL; | |
1430 hash.temp_pool = ha.temp_pool; | |
1431 | |
1432 if (ngx_hash_wildcard_init(&hash, ha.dns_wc_head.elts, | |
1433 ha.dns_wc_head.nelts) | |
1434 != NGX_OK) | |
1435 { | |
1436 goto failed; | |
1437 } | |
1438 | |
1439 in_addr[a].wc_head = (ngx_hash_wildcard_t *) hash.hash; | |
1440 } | |
1441 | |
1442 if (ha.dns_wc_tail.nelts) { | |
1443 | |
1444 ngx_qsort(ha.dns_wc_tail.elts, | |
1445 (size_t) ha.dns_wc_tail.nelts, | |
1446 sizeof(ngx_hash_key_t), | |
1447 ngx_http_cmp_dns_wildcards); | |
1448 | |
1449 hash.hash = NULL; | |
1450 hash.temp_pool = ha.temp_pool; | |
1451 | |
1452 if (ngx_hash_wildcard_init(&hash, ha.dns_wc_tail.elts, | |
1453 ha.dns_wc_tail.nelts) | |
1454 != NGX_OK) | |
1455 { | |
1456 goto failed; | |
1457 } | |
1458 | |
1459 in_addr[a].wc_tail = (ngx_hash_wildcard_t *) hash.hash; | |
1460 } | |
1461 | |
1462 ngx_destroy_pool(ha.temp_pool); | |
1463 | |
1464 #if (NGX_PCRE) | |
1465 | |
1466 if (regex == 0) { | |
1467 continue; | |
1468 } | |
1469 | |
1470 in_addr[a].nregex = regex; | |
1471 in_addr[a].regex = ngx_palloc(cf->pool, | |
1472 regex * sizeof(ngx_http_server_name_t)); | |
1473 | |
1474 if (in_addr[a].regex == NULL) { | |
1475 return NGX_ERROR; | |
1476 } | |
1477 | |
1478 for (i = 0, s = 0; s < in_addr[a].names.nelts; s++) { | |
1479 if (name[s].regex) { | |
1480 in_addr[a].regex[i++] = name[s]; | |
1481 } | |
1482 } | |
1483 #endif | |
1484 } | |
1485 | |
1486 if (ngx_http_init_listening(cf, &in_port[p]) != NGX_OK) { | |
1487 return NGX_ERROR; | |
1488 } | |
1489 } | |
1490 | 1551 |
1491 return NGX_OK; | 1552 return NGX_OK; |
1492 | 1553 |
1493 failed: | 1554 failed: |
1494 | 1555 |
1497 return NGX_ERROR; | 1558 return NGX_ERROR; |
1498 } | 1559 } |
1499 | 1560 |
1500 | 1561 |
1501 static ngx_int_t | 1562 static ngx_int_t |
1502 ngx_http_cmp_conf_in_addrs(const void *one, const void *two) | 1563 ngx_http_cmp_conf_addrs(const void *one, const void *two) |
1503 { | 1564 { |
1504 ngx_http_conf_in_addr_t *first, *second; | 1565 ngx_http_conf_addr_t *first, *second; |
1505 | 1566 |
1506 first = (ngx_http_conf_in_addr_t *) one; | 1567 first = (ngx_http_conf_addr_t *) one; |
1507 second = (ngx_http_conf_in_addr_t *) two; | 1568 second = (ngx_http_conf_addr_t *) two; |
1508 | 1569 |
1509 if (first->addr == INADDR_ANY) { | 1570 if (first->wildcard) { |
1510 /* the INADDR_ANY must be the last resort, shift it to the end */ | 1571 /* a wildcard address must be the last resort, shift it to the end */ |
1511 return 1; | 1572 return 1; |
1512 } | 1573 } |
1513 | 1574 |
1514 if (first->bind && !second->bind) { | 1575 if (first->bind && !second->bind) { |
1515 /* shift explicit bind()ed addresses to the start */ | 1576 /* shift explicit bind()ed addresses to the start */ |
1538 return ngx_strcmp(first->key.data, second->key.data); | 1599 return ngx_strcmp(first->key.data, second->key.data); |
1539 } | 1600 } |
1540 | 1601 |
1541 | 1602 |
1542 static ngx_int_t | 1603 static ngx_int_t |
1543 ngx_http_init_listening(ngx_conf_t *cf, ngx_http_conf_in_port_t *in_port) | 1604 ngx_http_init_listening(ngx_conf_t *cf, ngx_http_conf_port_t *port) |
1544 { | 1605 { |
1545 ngx_uint_t i, a, last, bind_all, done; | 1606 ngx_uint_t i, a, last, bind_wildcard; |
1546 ngx_listening_t *ls; | 1607 ngx_listening_t *ls; |
1547 ngx_http_in_port_t *hip; | 1608 ngx_http_port_t *hport; |
1548 ngx_http_conf_in_addr_t *in_addr; | 1609 ngx_http_conf_addr_t *addr; |
1549 ngx_http_virtual_names_t *vn; | 1610 |
1611 addr = port->addrs.elts; | |
1612 last = port->addrs.nelts; | |
1613 | |
1614 /* | |
1615 * If there is a binding to an "*:port" then we need to bind() to | |
1616 * the "*:port" only and ignore other implicit bindings. The bindings | |
1617 * have been already sorted: explicit bindings are on the start, then | |
1618 * implicit bindings go, and wildcard binding is in the end. | |
1619 */ | |
1620 | |
1621 if (addr[last - 1].wildcard) { | |
1622 addr[last - 1].bind = 1; | |
1623 bind_wildcard = 1; | |
1624 | |
1625 } else { | |
1626 bind_wildcard = 0; | |
1627 } | |
1628 | |
1629 a = 0; | |
1630 | |
1631 while (a < last) { | |
1632 | |
1633 if (bind_wildcard && !addr[a].bind) { | |
1634 a++; | |
1635 continue; | |
1636 } | |
1637 | |
1638 ls = ngx_http_add_listening(cf, &addr[a]); | |
1639 if (ls == NULL) { | |
1640 return NGX_ERROR; | |
1641 } | |
1642 | |
1643 hport = ngx_pcalloc(cf->pool, sizeof(ngx_http_port_t)); | |
1644 if (hport == NULL) { | |
1645 return NGX_ERROR; | |
1646 } | |
1647 | |
1648 ls->servers = hport; | |
1649 | |
1650 hport->port = ntohs(port->port); | |
1651 | |
1652 for (i = ls->addr_text.len - 1; i; i--) { | |
1653 | |
1654 if (ls->addr_text.data[i] == ':') { | |
1655 hport->port_text.len = ls->addr_text.len - i; | |
1656 hport->port_text.data = &ls->addr_text.data[i]; | |
1657 break; | |
1658 } | |
1659 } | |
1660 | |
1661 if (a == last - 1) { | |
1662 hport->naddrs = last; | |
1663 | |
1664 } else { | |
1665 hport->naddrs = 1; | |
1666 a = 0; | |
1667 } | |
1668 | |
1669 switch (ls->sockaddr->sa_family) { | |
1670 | |
1671 #if (NGX_HAVE_INET6) | |
1672 case AF_INET6: | |
1673 if (ngx_http_add_addrs6(cf, hport, addr) != NGX_OK) { | |
1674 return NGX_ERROR; | |
1675 } | |
1676 break; | |
1677 #endif | |
1678 default: /* AF_INET */ | |
1679 if (ngx_http_add_addrs(cf, hport, addr) != NGX_OK) { | |
1680 return NGX_ERROR; | |
1681 } | |
1682 break; | |
1683 } | |
1684 | |
1685 addr++; | |
1686 last--; | |
1687 } | |
1688 | |
1689 return NGX_OK; | |
1690 } | |
1691 | |
1692 | |
1693 static ngx_listening_t * | |
1694 ngx_http_add_listening(ngx_conf_t *cf, ngx_http_conf_addr_t *addr) | |
1695 { | |
1696 ngx_listening_t *ls; | |
1697 struct sockaddr *sa; | |
1550 ngx_http_core_loc_conf_t *clcf; | 1698 ngx_http_core_loc_conf_t *clcf; |
1551 ngx_http_core_srv_conf_t *cscf; | 1699 ngx_http_core_srv_conf_t *cscf; |
1552 | 1700 u_char text[NGX_SOCKADDR_STRLEN]; |
1553 in_addr = in_port->addrs.elts; | 1701 |
1554 last = in_port->addrs.nelts; | 1702 ls = ngx_array_push(&cf->cycle->listening); |
1555 | 1703 if (ls == NULL) { |
1556 /* | 1704 return NULL; |
1557 * if there is a binding to a "*:port" then we need to bind() | 1705 } |
1558 * to the "*:port" only and ignore other bindings | 1706 |
1559 */ | 1707 ngx_memzero(ls, sizeof(ngx_listening_t)); |
1560 | 1708 |
1561 if (in_addr[last - 1].addr == INADDR_ANY) { | 1709 sa = ngx_palloc(cf->pool, addr->socklen); |
1562 in_addr[last - 1].bind = 1; | 1710 if (sa == NULL) { |
1563 bind_all = 0; | 1711 return NULL; |
1564 | 1712 } |
1565 } else { | 1713 |
1566 bind_all = 1; | 1714 ngx_memcpy(sa, addr->sockaddr, addr->socklen); |
1567 } | 1715 |
1568 | 1716 ls->sockaddr = sa; |
1569 a = 0; | 1717 ls->socklen = addr->socklen; |
1570 | 1718 |
1571 while (a < last) { | 1719 ls->addr_text.len = ngx_sock_ntop(sa, text, NGX_SOCKADDR_STRLEN, 1); |
1572 | 1720 |
1573 if (!bind_all && !in_addr[a].bind) { | 1721 ls->addr_text.data = ngx_pnalloc(cf->pool, ls->addr_text.len); |
1574 a++; | 1722 if (ls->addr_text.data == NULL) { |
1723 return NULL; | |
1724 } | |
1725 | |
1726 ngx_memcpy(ls->addr_text.data, text, ls->addr_text.len); | |
1727 | |
1728 ls->fd = (ngx_socket_t) -1; | |
1729 ls->type = SOCK_STREAM; | |
1730 | |
1731 switch (ls->sockaddr->sa_family) { | |
1732 #if (NGX_HAVE_INET6) | |
1733 case AF_INET6: | |
1734 ls->addr_text_max_len = NGX_INET6_ADDRSTRLEN; | |
1735 break; | |
1736 #endif | |
1737 case AF_INET: | |
1738 ls->addr_text_max_len = NGX_INET_ADDRSTRLEN; | |
1739 break; | |
1740 default: | |
1741 ls->addr_text_max_len = NGX_SOCKADDR_STRLEN; | |
1742 break; | |
1743 } | |
1744 | |
1745 ls->addr_ntop = 1; | |
1746 | |
1747 ls->handler = ngx_http_init_connection; | |
1748 | |
1749 cscf = addr->core_srv_conf; | |
1750 ls->pool_size = cscf->connection_pool_size; | |
1751 ls->post_accept_timeout = cscf->client_header_timeout; | |
1752 | |
1753 clcf = cscf->ctx->loc_conf[ngx_http_core_module.ctx_index]; | |
1754 | |
1755 ls->log = *clcf->err_log; | |
1756 ls->log.data = &ls->addr_text; | |
1757 ls->log.handler = ngx_accept_log_error; | |
1758 | |
1759 #if (NGX_WIN32) | |
1760 { | |
1761 ngx_iocp_conf_t *iocpcf; | |
1762 | |
1763 iocpcf = ngx_event_get_conf(cf->cycle->conf_ctx, ngx_iocp_module); | |
1764 if (iocpcf->acceptex_read) { | |
1765 ls->post_accept_buffer_size = cscf->client_header_buffer_size; | |
1766 } | |
1767 } | |
1768 #endif | |
1769 | |
1770 ls->backlog = addr->listen_conf->backlog; | |
1771 ls->rcvbuf = addr->listen_conf->rcvbuf; | |
1772 ls->sndbuf = addr->listen_conf->sndbuf; | |
1773 | |
1774 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) | |
1775 ls->accept_filter = addr->listen_conf->accept_filter; | |
1776 #endif | |
1777 | |
1778 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT) | |
1779 ls->deferred_accept = addr->listen_conf->deferred_accept; | |
1780 #endif | |
1781 | |
1782 return ls; | |
1783 } | |
1784 | |
1785 | |
1786 static ngx_int_t | |
1787 ngx_http_add_addrs(ngx_conf_t *cf, ngx_http_port_t *hport, | |
1788 ngx_http_conf_addr_t *addr) | |
1789 { | |
1790 ngx_uint_t i; | |
1791 ngx_http_in_addr_t *addrs; | |
1792 struct sockaddr_in *sin; | |
1793 ngx_http_virtual_names_t *vn; | |
1794 | |
1795 hport->addrs = ngx_pcalloc(cf->pool, | |
1796 hport->naddrs * sizeof(ngx_http_in_addr_t)); | |
1797 if (hport->addrs == NULL) { | |
1798 return NGX_ERROR; | |
1799 } | |
1800 | |
1801 addrs = hport->addrs; | |
1802 | |
1803 for (i = 0; i < hport->naddrs; i++) { | |
1804 | |
1805 sin = (struct sockaddr_in *) addr[i].sockaddr; | |
1806 addrs[i].addr = sin->sin_addr.s_addr; | |
1807 addrs[i].conf.core_srv_conf = addr[i].core_srv_conf; | |
1808 #if (NGX_HTTP_SSL) | |
1809 addrs[i].conf.ssl = addr[i].ssl; | |
1810 #endif | |
1811 | |
1812 if (addr[i].hash.buckets == NULL | |
1813 && (addr[i].wc_head == NULL | |
1814 || addr[i].wc_head->hash.buckets == NULL) | |
1815 && (addr[i].wc_head == NULL | |
1816 || addr[i].wc_head->hash.buckets == NULL)) | |
1817 { | |
1575 continue; | 1818 continue; |
1576 } | 1819 } |
1577 | 1820 |
1578 ls = ngx_listening_inet_stream_socket(cf, in_addr[a].addr, | 1821 vn = ngx_palloc(cf->pool, sizeof(ngx_http_virtual_names_t)); |
1579 in_port->port); | 1822 if (vn == NULL) { |
1580 if (ls == NULL) { | |
1581 return NGX_ERROR; | 1823 return NGX_ERROR; |
1582 } | 1824 } |
1583 | 1825 |
1584 ls->addr_ntop = 1; | 1826 addrs[i].conf.virtual_names = vn; |
1585 | 1827 |
1586 ls->handler = ngx_http_init_connection; | 1828 vn->names.hash = addr[i].hash; |
1587 | 1829 vn->names.wc_head = addr[i].wc_head; |
1588 cscf = in_addr[a].core_srv_conf; | 1830 vn->names.wc_tail = addr[i].wc_tail; |
1589 ls->pool_size = cscf->connection_pool_size; | 1831 #if (NGX_PCRE) |
1590 ls->post_accept_timeout = cscf->client_header_timeout; | 1832 vn->nregex = addr[i].nregex; |
1591 | 1833 vn->regex = addr[i].regex; |
1592 clcf = cscf->ctx->loc_conf[ngx_http_core_module.ctx_index]; | 1834 #endif |
1593 | 1835 } |
1594 ls->log = *clcf->err_log; | 1836 |
1595 ls->log.data = &ls->addr_text; | 1837 return NGX_OK; |
1596 ls->log.handler = ngx_accept_log_error; | 1838 } |
1597 | 1839 |
1598 #if (NGX_WIN32) | 1840 |
1841 #if (NGX_HAVE_INET6) | |
1842 | |
1843 static ngx_int_t | |
1844 ngx_http_add_addrs6(ngx_conf_t *cf, ngx_http_port_t *hport, | |
1845 ngx_http_conf_addr_t *addr) | |
1846 { | |
1847 ngx_uint_t i; | |
1848 ngx_http_in6_addr_t *addrs6; | |
1849 struct sockaddr_in6 *sin6; | |
1850 ngx_http_virtual_names_t *vn; | |
1851 | |
1852 hport->addrs = ngx_pcalloc(cf->pool, | |
1853 hport->naddrs * sizeof(ngx_http_in6_addr_t)); | |
1854 if (hport->addrs == NULL) { | |
1855 return NGX_ERROR; | |
1856 } | |
1857 | |
1858 addrs6 = hport->addrs; | |
1859 | |
1860 for (i = 0; i < hport->naddrs; i++) { | |
1861 | |
1862 sin6 = (struct sockaddr_in6 *) addr[i].sockaddr; | |
1863 addrs6[i].addr6 = sin6->sin6_addr; | |
1864 addrs6[i].conf.core_srv_conf = addr[i].core_srv_conf; | |
1865 #if (NGX_HTTP_SSL) | |
1866 addrs6[i].conf.ssl = addr[i].ssl; | |
1867 #endif | |
1868 | |
1869 if (addr[i].hash.buckets == NULL | |
1870 && (addr[i].wc_head == NULL | |
1871 || addr[i].wc_head->hash.buckets == NULL) | |
1872 && (addr[i].wc_head == NULL | |
1873 || addr[i].wc_head->hash.buckets == NULL)) | |
1599 { | 1874 { |
1600 ngx_iocp_conf_t *iocpcf; | 1875 continue; |
1601 | 1876 } |
1602 iocpcf = ngx_event_get_conf(cf->cycle->conf_ctx, ngx_iocp_module); | 1877 |
1603 if (iocpcf->acceptex_read) { | 1878 vn = ngx_palloc(cf->pool, sizeof(ngx_http_virtual_names_t)); |
1604 ls->post_accept_buffer_size = cscf->client_header_buffer_size; | 1879 if (vn == NULL) { |
1605 } | |
1606 } | |
1607 #endif | |
1608 | |
1609 ls->backlog = in_addr[a].listen_conf->backlog; | |
1610 ls->rcvbuf = in_addr[a].listen_conf->rcvbuf; | |
1611 ls->sndbuf = in_addr[a].listen_conf->sndbuf; | |
1612 | |
1613 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) | |
1614 ls->accept_filter = in_addr[a].listen_conf->accept_filter; | |
1615 #endif | |
1616 | |
1617 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT) | |
1618 ls->deferred_accept = in_addr[a].listen_conf->deferred_accept; | |
1619 #endif | |
1620 | |
1621 hip = ngx_palloc(cf->pool, sizeof(ngx_http_in_port_t)); | |
1622 if (hip == NULL) { | |
1623 return NGX_ERROR; | 1880 return NGX_ERROR; |
1624 } | 1881 } |
1625 | 1882 |
1626 hip->port = in_port->port; | 1883 addrs6[i].conf.virtual_names = vn; |
1627 | 1884 |
1628 hip->port_text.data = ngx_pnalloc(cf->pool, 7); | 1885 vn->names.hash = addr[i].hash; |
1629 if (hip->port_text.data == NULL) { | 1886 vn->names.wc_head = addr[i].wc_head; |
1630 return NGX_ERROR; | 1887 vn->names.wc_tail = addr[i].wc_tail; |
1631 } | |
1632 | |
1633 ls->servers = hip; | |
1634 | |
1635 hip->port_text.len = ngx_sprintf(hip->port_text.data, ":%d", hip->port) | |
1636 - hip->port_text.data; | |
1637 | |
1638 in_addr = in_port->addrs.elts; | |
1639 | |
1640 if (in_addr[a].bind && in_addr[a].addr != INADDR_ANY) { | |
1641 hip->naddrs = 1; | |
1642 done = 0; | |
1643 | |
1644 } else if (in_port->addrs.nelts > 1 | |
1645 && in_addr[last - 1].addr == INADDR_ANY) | |
1646 { | |
1647 hip->naddrs = last; | |
1648 done = 1; | |
1649 | |
1650 } else { | |
1651 hip->naddrs = 1; | |
1652 done = 0; | |
1653 } | |
1654 | |
1655 hip->addrs = ngx_pcalloc(cf->pool, | |
1656 hip->naddrs * sizeof(ngx_http_in_addr_t)); | |
1657 if (hip->addrs == NULL) { | |
1658 return NGX_ERROR; | |
1659 } | |
1660 | |
1661 for (i = 0; i < hip->naddrs; i++) { | |
1662 hip->addrs[i].addr = in_addr[i].addr; | |
1663 hip->addrs[i].core_srv_conf = in_addr[i].core_srv_conf; | |
1664 | |
1665 #if (NGX_HTTP_SSL) | |
1666 hip->addrs[i].ssl = in_addr[i].ssl; | |
1667 #endif | |
1668 | |
1669 if (in_addr[i].hash.buckets == NULL | |
1670 && (in_addr[i].wc_head == NULL | |
1671 || in_addr[i].wc_head->hash.buckets == NULL) | |
1672 && (in_addr[i].wc_head == NULL | |
1673 || in_addr[i].wc_head->hash.buckets == NULL)) | |
1674 { | |
1675 continue; | |
1676 } | |
1677 | |
1678 vn = ngx_palloc(cf->pool, sizeof(ngx_http_virtual_names_t)); | |
1679 if (vn == NULL) { | |
1680 return NGX_ERROR; | |
1681 } | |
1682 hip->addrs[i].virtual_names = vn; | |
1683 | |
1684 vn->names.hash = in_addr[i].hash; | |
1685 vn->names.wc_head = in_addr[i].wc_head; | |
1686 vn->names.wc_tail = in_addr[i].wc_tail; | |
1687 #if (NGX_PCRE) | 1888 #if (NGX_PCRE) |
1688 vn->nregex = in_addr[i].nregex; | 1889 vn->nregex = addr[i].nregex; |
1689 vn->regex = in_addr[i].regex; | 1890 vn->regex = addr[i].regex; |
1690 #endif | 1891 #endif |
1691 } | |
1692 | |
1693 if (done) { | |
1694 return NGX_OK; | |
1695 } | |
1696 | |
1697 in_addr++; | |
1698 in_port->addrs.elts = in_addr; | |
1699 last--; | |
1700 | |
1701 a = 0; | |
1702 } | 1892 } |
1703 | 1893 |
1704 return NGX_OK; | 1894 return NGX_OK; |
1705 } | 1895 } |
1896 | |
1897 #endif | |
1706 | 1898 |
1707 | 1899 |
1708 char * | 1900 char * |
1709 ngx_http_types_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 1901 ngx_http_types_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
1710 { | 1902 { |