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.
This commit is contained in:
Igor Sysoev 2009-10-21 16:27:48 +00:00
parent d2d0931ed5
commit 2a634f5342
4 changed files with 73 additions and 83 deletions

View File

@ -23,7 +23,7 @@ static ngx_int_t ngx_http_add_addresses(ngx_conf_t *cf,
static ngx_int_t ngx_http_add_address(ngx_conf_t *cf, static ngx_int_t ngx_http_add_address(ngx_conf_t *cf,
ngx_http_core_srv_conf_t *cscf, ngx_http_conf_port_t *port, ngx_http_core_srv_conf_t *cscf, ngx_http_conf_port_t *port,
ngx_http_listen_t *listen); ngx_http_listen_t *listen);
static ngx_int_t ngx_http_add_names(ngx_conf_t *cf, static ngx_int_t ngx_http_add_server(ngx_conf_t *cf,
ngx_http_core_srv_conf_t *cscf, ngx_http_conf_addr_t *addr); ngx_http_core_srv_conf_t *cscf, ngx_http_conf_addr_t *addr);
static char *ngx_http_merge_locations(ngx_conf_t *cf, static char *ngx_http_merge_locations(ngx_conf_t *cf,
@ -1205,7 +1205,7 @@ ngx_http_add_addresses(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
/* the address is already in the address list */ /* the address is already in the address list */
if (ngx_http_add_names(cf, cscf, &addr[i]) != NGX_OK) { if (ngx_http_add_server(cf, cscf, &addr[i]) != NGX_OK) {
return NGX_ERROR; return NGX_ERROR;
} }
@ -1263,57 +1263,42 @@ ngx_http_add_address(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
addr->hash.size = 0; addr->hash.size = 0;
addr->wc_head = NULL; addr->wc_head = NULL;
addr->wc_tail = NULL; addr->wc_tail = NULL;
addr->names.elts = NULL;
#if (NGX_PCRE) #if (NGX_PCRE)
addr->nregex = 0; addr->nregex = 0;
addr->regex = NULL; addr->regex = NULL;
#endif #endif
addr->core_srv_conf = cscf; addr->core_srv_conf = cscf;
addr->servers.elts = NULL;
addr->opt = listen->opt; addr->opt = listen->opt;
return ngx_http_add_names(cf, cscf, addr); return ngx_http_add_server(cf, cscf, addr);
} }
/* /* add the server core module configuration to the address:port */
* add the server names and the server core module
* configurations to the address:port
*/
static ngx_int_t static ngx_int_t
ngx_http_add_names(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf, ngx_http_add_server(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
ngx_http_conf_addr_t *addr) ngx_http_conf_addr_t *addr)
{ {
ngx_uint_t i; ngx_http_core_srv_conf_t **server;
ngx_http_server_name_t *server_names, *name;
if (addr->names.elts == NULL) { if (addr->servers.elts == NULL) {
if (ngx_array_init(&addr->names, cf->temp_pool, 4, if (ngx_array_init(&addr->servers, cf->temp_pool, 4,
sizeof(ngx_http_server_name_t)) sizeof(ngx_http_core_srv_conf_t *))
!= NGX_OK) != NGX_OK)
{ {
return NGX_ERROR; return NGX_ERROR;
} }
} }
server_names = cscf->server_names.elts; server = ngx_array_push(&addr->servers);
if (server == NULL) {
for (i = 0; i < cscf->server_names.nelts; i++) { return NGX_ERROR;
ngx_strlow(server_names[i].name.data, server_names[i].name.data,
server_names[i].name.len);
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0,
"name: %V", &server_names[i].name);
name = ngx_array_push(&addr->names);
if (name == NULL) {
return NGX_ERROR;
}
*name = server_names[i];
} }
*server = cscf;
return NGX_OK; return NGX_OK;
} }
@ -1322,10 +1307,9 @@ static ngx_int_t
ngx_http_optimize_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf, ngx_http_optimize_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
ngx_array_t *ports) ngx_array_t *ports)
{ {
ngx_uint_t s, p, a; ngx_uint_t p, a;
ngx_http_conf_port_t *port; ngx_http_conf_port_t *port;
ngx_http_conf_addr_t *addr; ngx_http_conf_addr_t *addr;
ngx_http_server_name_t *name;
port = ports->elts; port = ports->elts;
for (p = 0; p < ports->nelts; p++) { for (p = 0; p < ports->nelts; p++) {
@ -1341,23 +1325,15 @@ ngx_http_optimize_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
addr = port[p].addrs.elts; addr = port[p].addrs.elts;
for (a = 0; a < port[p].addrs.nelts; a++) { for (a = 0; a < port[p].addrs.nelts; a++) {
name = addr[a].names.elts; if (addr[a].servers.nelts > 1
for (s = 0; s < addr[a].names.nelts; s++) {
if (addr[a].core_srv_conf == name[s].core_srv_conf
#if (NGX_PCRE) #if (NGX_PCRE)
&& name[s].captures == 0 || addr[a].core_srv_conf->captures
#endif #endif
) )
{ {
continue;
}
if (ngx_http_server_names(cf, cmcf, &addr[a]) != NGX_OK) { if (ngx_http_server_names(cf, cmcf, &addr[a]) != NGX_OK) {
return NGX_ERROR; return NGX_ERROR;
} }
break;
} }
} }
@ -1374,13 +1350,14 @@ static ngx_int_t
ngx_http_server_names(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf, ngx_http_server_names(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
ngx_http_conf_addr_t *addr) ngx_http_conf_addr_t *addr)
{ {
ngx_int_t rc; ngx_int_t rc;
ngx_uint_t s; ngx_uint_t n, s;
ngx_hash_init_t hash; ngx_hash_init_t hash;
ngx_hash_keys_arrays_t ha; ngx_hash_keys_arrays_t ha;
ngx_http_server_name_t *name; ngx_http_server_name_t *name;
ngx_http_core_srv_conf_t **cscfp;
#if (NGX_PCRE) #if (NGX_PCRE)
ngx_uint_t regex, i; ngx_uint_t regex, i;
regex = 0; regex = 0;
#endif #endif
@ -1398,35 +1375,40 @@ ngx_http_server_names(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
goto failed; goto failed;
} }
name = addr->names.elts; cscfp = addr->servers.elts;
for (s = 0; s < addr->names.nelts; s++) { for (s = 0; s < addr->servers.nelts; s++) {
name = cscfp[s]->server_names.elts;
for (n = 0; n < cscfp[s]->server_names.nelts; n++) {
#if (NGX_PCRE) #if (NGX_PCRE)
if (name[s].regex) { if (name[n].regex) {
regex++; regex++;
continue; continue;
} }
#endif #endif
rc = ngx_hash_add_key(&ha, &name[s].name, name[s].core_srv_conf, rc = ngx_hash_add_key(&ha, &name[n].name, name[n].core_srv_conf,
NGX_HASH_WILDCARD_KEY); NGX_HASH_WILDCARD_KEY);
if (rc == NGX_ERROR) { if (rc == NGX_ERROR) {
return NGX_ERROR; return NGX_ERROR;
} }
if (rc == NGX_DECLINED) { if (rc == NGX_DECLINED) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0, ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
"invalid server name or wildcard \"%V\" on %s", "invalid server name or wildcard \"%V\" on %s",
&name[s].name, addr->opt.addr); &name[n].name, addr->opt.addr);
return NGX_ERROR; return NGX_ERROR;
} }
if (rc == NGX_BUSY) { if (rc == NGX_BUSY) {
ngx_log_error(NGX_LOG_WARN, cf->log, 0, ngx_log_error(NGX_LOG_WARN, cf->log, 0,
"conflicting server name \"%V\" on %s, ignored", "conflicting server name \"%V\" on %s, ignored",
&name[s].name, addr->opt.addr); &name[n].name, addr->opt.addr);
}
} }
} }
@ -1495,9 +1477,16 @@ ngx_http_server_names(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
return NGX_ERROR; return NGX_ERROR;
} }
for (i = 0, s = 0; s < addr->names.nelts; s++) { i = 0;
if (name[s].regex) {
addr->regex[i++] = name[s]; for (s = 0; s < addr->servers.nelts; s++) {
name = cscfp[s]->server_names.elts;
for (n = 0; n < cscfp[s]->server_names.nelts; n++) {
if (name[n].regex) {
addr->regex[i++] = name[n];
}
} }
} }

View File

@ -2876,7 +2876,6 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
#if (NGX_PCRE) #if (NGX_PCRE)
sn->regex = NULL; sn->regex = NULL;
sn->captures = 0;
#endif #endif
sn->core_srv_conf = conf; sn->core_srv_conf = conf;
sn->name.len = conf->server_name.len; sn->name.len = conf->server_name.len;
@ -3529,11 +3528,12 @@ ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
#if (NGX_PCRE) #if (NGX_PCRE)
sn->regex = NULL; sn->regex = NULL;
sn->captures = 0;
#endif #endif
sn->core_srv_conf = cscf; sn->core_srv_conf = cscf;
sn->name = value[i]; sn->name = value[i];
ngx_strlow(sn->name.data, sn->name.data, sn->name.len);
if (value[i].data[0] != '~') { if (value[i].data[0] != '~') {
continue; continue;
} }
@ -3562,8 +3562,8 @@ ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR; return NGX_CONF_ERROR;
} }
sn->captures = (ngx_regex_capture_count(sn->regex) > 0);
sn->name = value[i]; sn->name = value[i];
cscf->captures = (ngx_regex_capture_count(sn->regex) > 0);
} }
#else #else
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,

View File

@ -168,7 +168,10 @@ typedef struct {
ngx_flag_t merge_slashes; ngx_flag_t merge_slashes;
ngx_flag_t underscores_in_headers; ngx_flag_t underscores_in_headers;
ngx_uint_t listen; /* unsigned listen:1; */ unsigned listen:1;
#if (NGX_PCRE)
unsigned captures:1;
#endif
ngx_http_core_loc_conf_t **named_locations; ngx_http_core_loc_conf_t **named_locations;
} ngx_http_core_srv_conf_t; } ngx_http_core_srv_conf_t;
@ -227,8 +230,6 @@ typedef struct {
ngx_hash_wildcard_t *wc_head; ngx_hash_wildcard_t *wc_head;
ngx_hash_wildcard_t *wc_tail; ngx_hash_wildcard_t *wc_tail;
ngx_array_t names; /* array of ngx_http_server_name_t */
#if (NGX_PCRE) #if (NGX_PCRE)
ngx_uint_t nregex; ngx_uint_t nregex;
ngx_http_server_name_t *regex; ngx_http_server_name_t *regex;
@ -236,6 +237,7 @@ typedef struct {
/* the default server configuration for this address:port */ /* the default server configuration for this address:port */
ngx_http_core_srv_conf_t *core_srv_conf; ngx_http_core_srv_conf_t *core_srv_conf;
ngx_array_t servers; /* array of ngx_http_core_srv_conf_t */
ngx_http_listen_opt_t opt; ngx_http_listen_opt_t opt;
} ngx_http_conf_addr_t; } ngx_http_conf_addr_t;
@ -244,7 +246,6 @@ typedef struct {
struct ngx_http_server_name_s { struct ngx_http_server_name_s {
#if (NGX_PCRE) #if (NGX_PCRE)
ngx_regex_t *regex; ngx_regex_t *regex;
ngx_uint_t captures; /* unsigned captures:1; */
#endif #endif
ngx_http_core_srv_conf_t *core_srv_conf; /* virtual name server conf */ ngx_http_core_srv_conf_t *core_srv_conf; /* virtual name server conf */
ngx_str_t name; ngx_str_t name;

View File

@ -1704,7 +1704,7 @@ ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len)
for (i = 0; i < r->virtual_names->nregex; i++) { for (i = 0; i < r->virtual_names->nregex; i++) {
if (sn[i].captures && r->captures == NULL) { if (sn[i].core_srv_conf->captures && r->captures == NULL) {
ncaptures = (NGX_HTTP_MAX_CAPTURES + 1) * 3; ncaptures = (NGX_HTTP_MAX_CAPTURES + 1) * 3;