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=c22e71776c9a9cbbe18f4afd77dc6d868f983867;hb=ab3a81dcb25e009023af8ddd716ebe154b85a714;hpb=11a1dc0e6739e733330819d1b7b42f386f13017d diff --git a/nginx/src/http/ngx_http_core_module.c b/nginx/src/http/ngx_http_core_module.c index c22e717..43d4644 100644 --- a/nginx/src/http/ngx_http_core_module.c +++ b/nginx/src/http/ngx_http_core_module.c @@ -112,8 +112,9 @@ static ngx_conf_enum_t ngx_http_core_satisfy[] = { static ngx_conf_enum_t ngx_http_core_if_modified_since[] = { - { ngx_string("exact"), 0 }, - { ngx_string("before"), 1 }, + { ngx_string("off"), NGX_HTTP_IMS_OFF }, + { ngx_string("exact"), NGX_HTTP_IMS_EXACT }, + { ngx_string("before"), NGX_HTTP_IMS_BEFORE }, { ngx_null_string, 0 } }; @@ -1034,8 +1035,7 @@ ngx_int_t ngx_http_core_try_files_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph) { - size_t len, root, alias; - ssize_t reserve, allocated; + size_t len, root, alias, reserve, allocated; u_char *p, *name; ngx_str_t path; ngx_uint_t test_dir; @@ -1059,7 +1059,7 @@ ngx_http_core_try_files_phase(ngx_http_request_t *r, allocated = 0; root = 0; name = NULL; - path.len = 0; + /* suppress MSVC warning */ path.data = NULL; tf = clcf->try_files; @@ -1086,12 +1086,8 @@ ngx_http_core_try_files_phase(ngx_http_request_t *r, len = tf->name.len; } - reserve = len - r->uri.len; - /* 16 bytes are preallocation */ - reserve = reserve < 16 ? 16 : reserve + 16; - - reserve += alias; + reserve = ngx_abs((ssize_t) (len - r->uri.len)) + alias + 16; if (reserve > allocated) { @@ -1126,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); @@ -1197,6 +1193,11 @@ ngx_http_core_try_files_phase(ngx_http_request_t *r, ngx_memcpy(p, name, path.len); } + if (ngx_http_set_exten(r) != NGX_OK) { + ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + return NGX_OK; + } + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "try file uri: \"%V\"", &r->uri); @@ -1336,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; @@ -1370,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; @@ -1393,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); @@ -1550,7 +1568,7 @@ ngx_http_set_content_type(ngx_http_request_t *r) exten = ngx_pnalloc(r->pool, r->exten.len); if (exten == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + return NGX_ERROR; } hash = ngx_hash_strlow(exten, r->exten.data, r->exten.len); @@ -1656,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) { @@ -1672,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) @@ -1679,13 +1697,17 @@ ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *path, return NULL; } - if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, path, 0)== NGX_ERROR) - { + if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, path, 0) != NGX_OK) { return NULL; } *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,34 +1791,60 @@ 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; - struct sockaddr_in sin; - - /* AF_INET only */ + 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 (r->in_addr == 0) { - len = sizeof(struct sockaddr_in); - if (getsockname(c->fd, (struct sockaddr *) &sin, &len) == -1) { + 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; + + if (getsockname(c->fd, (struct sockaddr *) &sa, &len) == -1) { ngx_connection_error(c, ngx_socket_errno, "getsockname() failed"); return NGX_ERROR; } - r->in_addr = sin.sin_addr.s_addr; + c->local_sockaddr = ngx_palloc(r->connection->pool, len); + if (c->local_sockaddr == NULL) { + return NGX_ERROR; + } - } else { - sin.sin_family = c->sockaddr->sa_family; - sin.sin_addr.s_addr = r->in_addr; + c->local_socklen = len; + ngx_memcpy(c->local_sockaddr, &sa, len); } if (s == NULL) { return NGX_OK; } - s->len = ngx_sock_ntop((struct sockaddr *) &sin, s->data, - NGX_INET_ADDRSTRLEN); + s->len = ngx_sock_ntop(c->local_sockaddr, s->data, s->len, 0); return NGX_OK; } @@ -2000,7 +2048,7 @@ ngx_http_subrequest(ngx_http_request_t *r, if (ngx_list_init(&sr->headers_out.headers, r->pool, 20, sizeof(ngx_table_elt_t)) - == NGX_ERROR) + != NGX_OK) { return NGX_ERROR; } @@ -2055,10 +2103,6 @@ ngx_http_subrequest(ngx_http_request_t *r, c->data = sr; } - sr->in_addr = r->in_addr; - sr->port = r->port; - sr->port_text = r->port_text; - sr->variables = r->variables; sr->log_handler = r->log_handler; @@ -2537,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; @@ -2592,7 +2637,7 @@ ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) if (ngx_strcmp(value[0].data, "include") == 0) { file = value[1]; - if (ngx_conf_full_name(cf->cycle, &file, 1) == NGX_ERROR){ + if (ngx_conf_full_name(cf->cycle, &file, 1) != NGX_OK) { return NGX_CONF_ERROR; } @@ -2724,15 +2769,16 @@ ngx_http_core_create_srv_conf(ngx_conf_t *cf) * conf->client_large_buffers.num = 0; */ - if (ngx_array_init(&cscf->listen, cf->pool, 4, sizeof(ngx_http_listen_t)) - == NGX_ERROR) + if (ngx_array_init(&cscf->listen, cf->temp_pool, 4, + sizeof(ngx_http_listen_t)) + != NGX_OK) { return NGX_CONF_ERROR; } if (ngx_array_init(&cscf->server_names, cf->temp_pool, 4, sizeof(ngx_http_server_name_t)) - == NGX_ERROR) + != NGX_OK) { return NGX_CONF_ERROR; } @@ -2756,6 +2802,7 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) ngx_http_core_srv_conf_t *conf = child; ngx_http_listen_t *ls; + struct sockaddr_in *sin; ngx_http_server_name_t *sn; /* TODO: it does not merge, it inits only */ @@ -2768,18 +2815,25 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) ngx_memzero(ls, sizeof(ngx_http_listen_t)); - ls->addr = INADDR_ANY; + sin = (struct sockaddr_in *) &ls->sockaddr; + + sin->sin_family = AF_INET; #if (NGX_WIN32) - ls->port = 80; + sin->sin_port = htons(80); #else - /* STUB: getuid() should be cached */ - ls->port = (getuid() == 0) ? 80 : 8000; + sin->sin_port = htons((getuid() == 0) ? 80 : 8000); #endif - ls->family = AF_INET; + sin->sin_addr.s_addr = INADDR_ANY; + + ls->socklen = sizeof(struct sockaddr_in); ls->conf.backlog = NGX_LISTEN_BACKLOG; ls->conf.rcvbuf = -1; ls->conf.sndbuf = -1; + ls->conf.wildcard = 1; + + (void) ngx_sock_ntop((struct sockaddr *) &ls->sockaddr, ls->conf.addr, + NGX_SOCKADDR_STRLEN, 1); } if (conf->server_name.data == NULL) { @@ -2792,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; @@ -2943,7 +2998,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) conf->root.len = sizeof("html") - 1; conf->root.data = (u_char *) "html"; - if (ngx_conf_full_name(cf->cycle, &conf->root, 0) == NGX_ERROR) { + if (ngx_conf_full_name(cf->cycle, &conf->root, 0) != NGX_OK) { return NGX_CONF_ERROR; } } @@ -3053,7 +3108,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) ngx_conf_merge_uint_value(conf->satisfy, prev->satisfy, NGX_HTTP_SATISFY_ALL); ngx_conf_merge_uint_value(conf->if_modified_since, prev->if_modified_since, - 0); + NGX_HTTP_IMS_EXACT); ngx_conf_merge_value(conf->internal, prev->internal, 0); ngx_conf_merge_value(conf->client_body_in_file_only, prev->client_body_in_file_only, 0); @@ -3154,8 +3209,6 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) } -/* AF_INET only */ - static char * ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { @@ -3196,17 +3249,18 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ngx_memzero(ls, sizeof(ngx_http_listen_t)); - ls->family = u.family; - ls->addr = u.addr.in_addr; - ls->port = u.port; + ngx_memcpy(ls->sockaddr, u.sockaddr, u.socklen); + + ls->socklen = u.socklen; ls->file_name = cf->conf_file->file.name.data; ls->line = cf->conf_file->line; ls->conf.backlog = NGX_LISTEN_BACKLOG; ls->conf.rcvbuf = -1; ls->conf.sndbuf = -1; + ls->conf.wildcard = u.wildcard; - n = ngx_inet_ntop(AF_INET, &ls->addr, ls->conf.addr, NGX_INET_ADDRSTRLEN); - ngx_sprintf(&ls->conf.addr[n], ":%ui", ls->port); + (void) ngx_sock_ntop((struct sockaddr *) &ls->sockaddr, ls->conf.addr, + NGX_SOCKADDR_STRLEN, 1); if (cf->args->nelts == 2) { return NGX_CONF_OK; @@ -3305,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; @@ -3394,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]; @@ -3420,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 @@ -3472,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") @@ -3516,31 +3599,43 @@ ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) } if (lcf->root.data[0] != '$') { - if (ngx_conf_full_name(cf->cycle, &lcf->root, 0) == NGX_ERROR) { + if (ngx_conf_full_name(cf->cycle, &lcf->root, 0) != NGX_OK) { return NGX_CONF_ERROR; } } 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; }