mirror of
https://github.com/nginx/nginx.git
synced 2024-12-04 22:09:01 +08:00
named location
This commit is contained in:
parent
a1df416d65
commit
8889b65711
@ -2276,13 +2276,17 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
|
||||
plcf->upstream.location = clcf->name;
|
||||
|
||||
if (clcf->named
|
||||
#if (NGX_PCRE)
|
||||
|
||||
if (clcf->regex || clcf->noname) {
|
||||
|| clcf->regex
|
||||
#endif
|
||||
|| clcf->noname)
|
||||
{
|
||||
if (plcf->upstream.uri.len) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"\"proxy_pass\" may not have URI part in "
|
||||
"location given by regular expression, "
|
||||
"or inside named location, "
|
||||
"or inside the \"if\" statement, "
|
||||
"or inside the \"limit_except\" block");
|
||||
return NGX_CONF_ERROR;
|
||||
@ -2291,8 +2295,6 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
plcf->upstream.location.len = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
plcf->upstream.url = *url;
|
||||
|
||||
if (clcf->name.data[clcf->name.len - 1] == '/') {
|
||||
|
@ -401,6 +401,7 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
|
||||
|
||||
cmcf->phase_engine.server_rewrite_index = (ngx_uint_t) -1;
|
||||
cmcf->phase_engine.location_rewrite_index = (ngx_uint_t) -1;
|
||||
find_config_index = 0;
|
||||
use_rewrite = cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers.nelts ? 1 : 0;
|
||||
use_access = cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers.nelts ? 1 : 0;
|
||||
@ -442,6 +443,14 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
|
||||
continue;
|
||||
|
||||
case NGX_HTTP_REWRITE_PHASE:
|
||||
if (cmcf->phase_engine.location_rewrite_index == (ngx_uint_t) -1) {
|
||||
cmcf->phase_engine.location_rewrite_index = n;
|
||||
}
|
||||
checker = ngx_http_core_generic_phase;
|
||||
|
||||
break;
|
||||
|
||||
case NGX_HTTP_POST_REWRITE_PHASE:
|
||||
if (use_rewrite) {
|
||||
ph->checker = ngx_http_core_post_rewrite_phase;
|
||||
|
@ -945,13 +945,12 @@ ngx_http_core_find_location(ngx_http_request_t *r,
|
||||
clcfp = locations->elts;
|
||||
for (i = 0; i < locations->nelts; i++) {
|
||||
|
||||
if (clcfp[i]->noname
|
||||
#if (NGX_PCRE)
|
||||
if (clcfp[i]->regex) {
|
||||
break;
|
||||
}
|
||||
|| clcfp[i]->regex
|
||||
#endif
|
||||
|
||||
if (clcfp[i]->noname) {
|
||||
|| clcfp[i]->named)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1028,7 +1027,7 @@ ngx_http_core_find_location(ngx_http_request_t *r,
|
||||
|
||||
for (i = regex_start; i < locations->nelts; i++) {
|
||||
|
||||
if (clcfp[i]->noname) {
|
||||
if (!clcfp[i]->regex) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1514,6 +1513,51 @@ ngx_http_internal_redirect(ngx_http_request_t *r,
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_named_location(ngx_http_request_t *r, ngx_str_t *name)
|
||||
{
|
||||
ngx_uint_t i;
|
||||
ngx_http_core_srv_conf_t *cscf;
|
||||
ngx_http_core_loc_conf_t **clcfp;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
|
||||
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
|
||||
|
||||
clcfp = cscf->locations.elts;
|
||||
|
||||
for (i = cscf->named_start; i < cscf->locations.nelts; i++) {
|
||||
|
||||
if (name->len != clcfp[i]->name.len
|
||||
|| ngx_strncmp(name->data, clcfp[i]->name.data, name->len) != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"named location: %V \"%V?%V\"", name, &r->uri, &r->args);
|
||||
|
||||
r->internal = 1;
|
||||
|
||||
r->loc_conf = clcfp[i]->loc_conf;
|
||||
|
||||
ngx_http_update_location_config(r);
|
||||
|
||||
cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
|
||||
|
||||
r->phase_handler = cmcf->phase_engine.location_rewrite_index;
|
||||
ngx_http_core_run_phases(r);
|
||||
|
||||
return NGX_DONE;
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"could not find name location \"%V\"", name);
|
||||
|
||||
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return NGX_DONE;
|
||||
}
|
||||
|
||||
|
||||
ngx_http_cleanup_t *
|
||||
ngx_http_cleanup_add(ngx_http_request_t *r, size_t size)
|
||||
{
|
||||
@ -1558,10 +1602,8 @@ ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
|
||||
ngx_http_module_t *module;
|
||||
ngx_http_conf_ctx_t *ctx, *http_ctx;
|
||||
ngx_http_core_srv_conf_t *cscf, **cscfp;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
#if (NGX_PCRE)
|
||||
ngx_http_core_loc_conf_t **clcfp;
|
||||
#endif
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
|
||||
ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
|
||||
if (ctx == NULL) {
|
||||
@ -1645,10 +1687,11 @@ ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
|
||||
ngx_sort(cscf->locations.elts, (size_t) cscf->locations.nelts,
|
||||
sizeof(ngx_http_core_loc_conf_t *), ngx_http_core_cmp_locations);
|
||||
|
||||
clcfp = cscf->locations.elts;
|
||||
|
||||
#if (NGX_PCRE)
|
||||
|
||||
cscf->regex_start = cscf->locations.nelts;
|
||||
clcfp = cscf->locations.elts;
|
||||
|
||||
for (i = 0; i < cscf->locations.nelts; i++) {
|
||||
if (clcfp[i]->regex) {
|
||||
@ -1659,6 +1702,15 @@ ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
|
||||
|
||||
#endif
|
||||
|
||||
cscf->named_start = cscf->locations.nelts;
|
||||
|
||||
for (i = 0; i < cscf->locations.nelts; i++) {
|
||||
if (clcfp[i]->named) {
|
||||
cscf->named_start = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -1759,7 +1811,12 @@ ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
clcf->name = value[1];
|
||||
|
||||
if (value[1].data[0] == '@') {
|
||||
clcf->named = 1;
|
||||
}
|
||||
}
|
||||
|
||||
pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index];
|
||||
@ -1785,6 +1842,14 @@ ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (pclcf->named) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"location \"%V\" could not be inside "
|
||||
"the named location \"%V\"",
|
||||
&clcf->name, &pclcf->name);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
#if (NGX_PCRE)
|
||||
if (clcf->regex == NULL
|
||||
&& ngx_strncmp(clcf->name.data, pclcf->name.data, pclcf->name.len)
|
||||
@ -1862,6 +1927,20 @@ ngx_http_core_cmp_locations(const void *one, const void *two)
|
||||
first = *(ngx_http_core_loc_conf_t **) one;
|
||||
second = *(ngx_http_core_loc_conf_t **) two;
|
||||
|
||||
if (first->named && !second->named) {
|
||||
/* shift named locations to the end */
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!first->named && second->named) {
|
||||
/* shift named locations to the end */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (first->named && second->named) {
|
||||
return ngx_strcmp(first->name.data, second->name.data);
|
||||
}
|
||||
|
||||
if (first->noname && !second->noname) {
|
||||
/* shift no named locations to the end */
|
||||
return 1;
|
||||
@ -2707,6 +2786,14 @@ ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (lcf->named && alias) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"the \"alias\" directive may not be used "
|
||||
"inside named location");
|
||||
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
#if (NGX_PCRE)
|
||||
|
||||
if (lcf->regex && alias) {
|
||||
|
@ -79,6 +79,7 @@ struct ngx_http_phase_handler_s {
|
||||
typedef struct {
|
||||
ngx_http_phase_handler_t *handlers;
|
||||
ngx_uint_t server_rewrite_index;
|
||||
ngx_uint_t location_rewrite_index;
|
||||
} ngx_http_phase_engine_t;
|
||||
|
||||
|
||||
@ -117,7 +118,8 @@ typedef struct {
|
||||
*/
|
||||
ngx_array_t locations;
|
||||
|
||||
unsigned regex_start:16;
|
||||
unsigned regex_start:15;
|
||||
unsigned named_start:15;
|
||||
unsigned wildcard:1;
|
||||
|
||||
/* array of the ngx_http_listen_t, "listen" directive */
|
||||
@ -212,9 +214,10 @@ struct ngx_http_core_loc_conf_s {
|
||||
ngx_regex_t *regex;
|
||||
#endif
|
||||
|
||||
unsigned regex_start:16;
|
||||
unsigned regex_start:15;
|
||||
|
||||
unsigned noname:1; /* "if () {}" block */
|
||||
unsigned noname:1; /* "if () {}" block or limit_except */
|
||||
unsigned named:1;
|
||||
|
||||
unsigned exact_match:1;
|
||||
unsigned noregex:1;
|
||||
@ -314,6 +317,8 @@ ngx_int_t ngx_http_subrequest(ngx_http_request_t *r,
|
||||
ngx_http_post_subrequest_t *psr, ngx_uint_t flags);
|
||||
ngx_int_t ngx_http_internal_redirect(ngx_http_request_t *r,
|
||||
ngx_str_t *uri, ngx_str_t *args);
|
||||
ngx_int_t ngx_http_named_location(ngx_http_request_t *r, ngx_str_t *name);
|
||||
|
||||
|
||||
ngx_http_cleanup_t *ngx_http_cleanup_add(ngx_http_request_t *r, size_t size);
|
||||
|
||||
|
@ -409,6 +409,10 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
|
||||
return ngx_http_internal_redirect(r, uri, NULL);
|
||||
}
|
||||
|
||||
if (uri->data[0] == '@') {
|
||||
return ngx_http_named_location(r, uri);
|
||||
}
|
||||
|
||||
r->headers_out.location =
|
||||
ngx_list_push(&r->headers_out.headers);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user