X-Git-Url: http://git.rot13.org/?p=nginx.git;a=blobdiff_plain;f=nginx%2Fsrc%2Fhttp%2Fngx_http_core_module.c;h=43d464418e1cb9d12a1c0ea8381c0e5605d5b435;hp=88672f0881a134f0cb1cbab2b75f0b3f08deb26e;hb=ab3a81dcb25e009023af8ddd716ebe154b85a714;hpb=edef48fd7f4269957bc636301b0ffc73a16f9a4a diff --git a/nginx/src/http/ngx_http_core_module.c b/nginx/src/http/ngx_http_core_module.c index 88672f0..43d4644 100644 --- a/nginx/src/http/ngx_http_core_module.c +++ b/nginx/src/http/ngx_http_core_module.c @@ -1122,7 +1122,7 @@ ngx_http_core_try_files_phase(ngx_http_request_t *r, path.len = e.pos - path.data; - *e.pos++ = '\0'; + *e.pos = '\0'; if (alias && ngx_strncmp(name, clcf->name.data, alias) == 0) { ngx_memcpy(name, name + alias, len - alias); @@ -1337,7 +1337,7 @@ ngx_http_core_find_location(ngx_http_request_t *r) ngx_int_t rc; ngx_http_core_loc_conf_t *pclcf; #if (NGX_PCRE) - ngx_int_t n; + ngx_int_t n, len; ngx_uint_t noregex; ngx_http_core_loc_conf_t *clcf, **clcfp; @@ -1371,12 +1371,26 @@ ngx_http_core_find_location(ngx_http_request_t *r) if (noregex == 0 && pclcf->regex_locations) { + len = 0; + for (clcfp = pclcf->regex_locations; *clcfp; clcfp++) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "test location: ~ \"%V\"", &(*clcfp)->name); - n = ngx_regex_exec((*clcfp)->regex, &r->uri, NULL, 0); + if ((*clcfp)->captures) { + + len = (NGX_HTTP_MAX_CAPTURES + 1) * 3; + + if (r->captures == NULL) { + r->captures = ngx_palloc(r->pool, len * sizeof(int)); + if (r->captures == NULL) { + return NGX_ERROR; + } + } + } + + n = ngx_regex_exec((*clcfp)->regex, &r->uri, r->captures, len); if (n == NGX_REGEX_NO_MATCHED) { continue; @@ -1394,6 +1408,9 @@ ngx_http_core_find_location(ngx_http_request_t *r) r->loc_conf = (*clcfp)->loc_conf; + r->ncaptures = len; + r->captures_data = r->uri.data; + /* look up nested locations */ rc = ngx_http_core_find_location(r); @@ -1657,13 +1674,11 @@ ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *path, return NULL; } - reserved += r->uri.len - alias + 1; - if (clcf->root_lengths == NULL) { *root_length = clcf->root.len; - path->len = clcf->root.len + reserved; + path->len = clcf->root.len + reserved + r->uri.len - alias + 1; path->data = ngx_pnalloc(r->pool, path->len); if (path->data == NULL) { @@ -1673,6 +1688,8 @@ ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *path, last = ngx_copy(path->data, clcf->root.data, clcf->root.len); } else { + reserved += alias ? 1 : r->uri.len + 1; + if (ngx_http_script_run(r, path, clcf->root_lengths->elts, reserved, clcf->root_values->elts) == NULL) @@ -1686,6 +1703,11 @@ ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *path, *root_length = path->len - reserved; last = path->data + *root_length; + + if (alias) { + *last = '\0'; + return last; + } } last = ngx_cpystrn(last, r->uri.data + alias, r->uri.len - alias + 1); @@ -1769,13 +1791,38 @@ ngx_http_auth_basic_user(ngx_http_request_t *r) ngx_int_t ngx_http_server_addr(ngx_http_request_t *r, ngx_str_t *s) { - socklen_t len; - ngx_connection_t *c; - u_char sa[NGX_SOCKADDRLEN]; + socklen_t len; + ngx_uint_t addr; + ngx_connection_t *c; + u_char sa[NGX_SOCKADDRLEN]; + struct sockaddr_in *sin; +#if (NGX_HAVE_INET6) + ngx_uint_t i; + struct sockaddr_in6 *sin6; +#endif c = r->connection; - if (c->local_sockaddr == NULL) { + switch (c->local_sockaddr->sa_family) { + +#if (NGX_HAVE_INET6) + case AF_INET6: + sin6 = (struct sockaddr_in6 *) c->local_sockaddr; + + for (addr = 0, i = 0; addr == 0 && i < 16; i++) { + addr |= sin6->sin6_addr.s6_addr[i]; + } + + break; +#endif + + default: /* AF_INET */ + sin = (struct sockaddr_in *) c->local_sockaddr; + addr = sin->sin_addr.s_addr; + break; + } + + if (addr == 0) { len = NGX_SOCKADDRLEN; @@ -2534,6 +2581,7 @@ ngx_http_core_regex_location(ngx_conf_t *cf, ngx_http_core_loc_conf_t *clcf, } clcf->name = *regex; + clcf->captures = (ngx_regex_capture_count(clcf->regex) > 0); return NGX_OK; @@ -2798,6 +2846,7 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) #if (NGX_PCRE) sn->regex = NULL; + sn->captures = 0; #endif sn->core_srv_conf = conf; sn->name.len = conf->server_name.len; @@ -3310,6 +3359,45 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) continue; } + if (ngx_strncmp(value[n].data, "ipv6only=o", 10) == 0) { +#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) + struct sockaddr *sa; + + sa = (struct sockaddr *) ls->sockaddr; + + if (sa->sa_family == AF_INET6) { + + if (ngx_strcmp(&value[n].data[10], "n") == 0) { + ls->conf.ipv6only = 1; + + } else if (ngx_strcmp(&value[n].data[10], "ff") == 0) { + ls->conf.ipv6only = 2; + + } else { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid ipv6only flags \"%s\"", + &value[n].data[9]); + return NGX_CONF_ERROR; + } + + ls->conf.bind = 1; + + } else { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "ipv6only is not supported " + "on addr \"%s\", ignored", + ls->conf.addr); + } + + continue; +#else + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "bind ipv6only is not supported " + "on this platform"); + return NGX_CONF_ERROR; +#endif + } + if (ngx_strcmp(value[n].data, "ssl") == 0) { #if (NGX_HTTP_SSL) ls->conf.ssl = 1; @@ -3399,6 +3487,7 @@ ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) #if (NGX_PCRE) sn->regex = NULL; + sn->captures = 0; #endif sn->core_srv_conf = cscf; sn->name = value[i]; @@ -3425,6 +3514,7 @@ ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) return NGX_CONF_ERROR; } + sn->captures = (ngx_regex_capture_count(sn->regex) > 0); sn->name = value[i]; } #else @@ -3477,18 +3567,6 @@ ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) return NGX_CONF_ERROR; } -#if (NGX_PCRE) - - if (lcf->regex && alias) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "the \"alias\" directive may not be used " - "inside location given by regular expression"); - - return NGX_CONF_ERROR; - } - -#endif - value = cf->args->elts; if (ngx_strstr(value[1].data, "$document_root") @@ -3528,24 +3606,36 @@ ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) n = ngx_http_script_variables_count(&lcf->root); - if (n == 0) { - return NGX_CONF_OK; + ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); + + if (n) { + sc.cf = cf; + sc.source = &lcf->root; + sc.lengths = &lcf->root_lengths; + sc.values = &lcf->root_values; + sc.variables = n; + sc.complete_lengths = 1; + sc.complete_values = 1; + + if (ngx_http_script_compile(&sc) != NGX_OK) { + return NGX_CONF_ERROR; + } } - ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); +#if (NGX_PCRE) - sc.cf = cf; - sc.source = &lcf->root; - sc.lengths = &lcf->root_lengths; - sc.values = &lcf->root_values; - sc.variables = n; - sc.complete_lengths = 1; - sc.complete_values = 1; + if (alias && lcf->regex + && (ngx_regex_capture_count(lcf->regex) <= 0 || sc.ncaptures == 0)) + { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "the \"alias\" directive must use captures " + "inside location given by regular expression"); - if (ngx_http_script_compile(&sc) != NGX_OK) { return NGX_CONF_ERROR; } +#endif + return NGX_CONF_OK; }