# HG changeset patch # User Igor Sysoev # Date 1193148960 0 # Node ID 55c8aede41f58daf4d68280cfdfc57131eaa0e1c # Parent cba2bb1796e4bb150a421e9d629317ec693ea019 refactor index module: remove context diff --git a/src/http/modules/ngx_http_index_module.c b/src/http/modules/ngx_http_index_module.c --- a/src/http/modules/ngx_http_index_module.c +++ b/src/http/modules/ngx_http_index_module.c @@ -22,25 +22,13 @@ typedef struct { } ngx_http_index_loc_conf_t; -typedef struct { - ngx_uint_t current; - - ngx_str_t path; - ngx_str_t index; - - size_t root; - - ngx_uint_t tested; /* unsigned tested:1 */ -} ngx_http_index_ctx_t; - - #define NGX_HTTP_DEFAULT_INDEX "index.html" static ngx_int_t ngx_http_index_test_dir(ngx_http_request_t *r, - ngx_http_core_loc_conf_t *clcf, ngx_http_index_ctx_t *ctx); -static ngx_int_t ngx_http_index_error(ngx_http_request_t *r, - ngx_http_index_ctx_t *ctx, ngx_err_t err); + ngx_http_core_loc_conf_t *clcf, u_char *path, u_char *last); +static ngx_int_t ngx_http_index_error(ngx_http_request_t *r, u_char *file, + ngx_err_t err); static ngx_int_t ngx_http_index_init(ngx_conf_t *cf); static void *ngx_http_index_create_loc_conf(ngx_conf_t *cf); @@ -107,14 +95,13 @@ ngx_module_t ngx_http_index_module = { static ngx_int_t ngx_http_index_handler(ngx_http_request_t *r) { - u_char *last; - size_t len; + u_char *p, *name; + size_t len, nlen, root, allocated; ngx_int_t rc; ngx_str_t path, uri; ngx_log_t *log; - ngx_uint_t i; + ngx_uint_t i, dir_tested; ngx_http_index_t *index; - ngx_http_index_ctx_t *ctx; ngx_open_file_info_t of; ngx_http_script_code_pt code; ngx_http_script_engine_t e; @@ -140,24 +127,14 @@ ngx_http_index_handler(ngx_http_request_ ilcf = ngx_http_get_module_loc_conf(r, ngx_http_index_module); clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - /* - * we use context because the handler supports an async file opening, - * and may be called several times - */ - - ctx = ngx_http_get_module_ctx(r, ngx_http_index_module); - if (ctx == NULL) { - - ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_index_ctx_t)); - if (ctx == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } - - ngx_http_set_ctx(r, ctx, ngx_http_index_module); - } + allocated = 0; + root = 0; + dir_tested = 0; + name = NULL; + path.data = NULL; index = ilcf->indices->elts; - for (i = ctx->current; i < ilcf->indices->nelts; i++) { + for (i = 0; i < ilcf->indices->nelts; i++) { if (index[i].lengths == NULL) { @@ -166,7 +143,7 @@ ngx_http_index_handler(ngx_http_request_ } len = ilcf->max_index_len; - ctx->index.len = index[i].name.len; + nlen = index[i].name.len; } else { ngx_memzero(&e, sizeof(ngx_http_script_engine_t)); @@ -184,45 +161,44 @@ ngx_http_index_handler(ngx_http_request_ len += lcode(&e); } - ctx->index.len = len; + nlen = len; /* 16 bytes are preallocation */ len += 16; } - if (len > (size_t) (ctx->path.data + ctx->path.len - ctx->index.data)) { + if (len > (size_t) (path.data + allocated - name)) { - last = ngx_http_map_uri_to_path(r, &ctx->path, &ctx->root, len); - if (last == NULL) { + name = ngx_http_map_uri_to_path(r, &path, &root, len); + if (name == NULL) { return NGX_ERROR; } - ctx->index.data = last; + allocated = path.len; } - path.data = ctx->path.data; - if (index[i].values == NULL) { /* index[i].name.len includes the terminating '\0' */ - ngx_memcpy(ctx->index.data, index[i].name.data, index[i].name.len); + ngx_memcpy(name, index[i].name.data, index[i].name.len); - path.len = (ctx->index.data + index[i].name.len - 1) - path.data; + path.len = (name + index[i].name.len - 1) - path.data; } else { e.ip = index[i].values->elts; - e.pos = ctx->index.data; + e.pos = name; while (*(uintptr_t *) e.ip) { code = *(ngx_http_script_code_pt *) e.ip; code((ngx_http_script_engine_t *) &e); } - if (*ctx->index.data == '/') { - ctx->index.len--; - return ngx_http_internal_redirect(r, &ctx->index, &r->args); + if (*name == '/') { + uri.len = nlen - 1; + uri.data = name; + return ngx_http_internal_redirect(r, &uri, &r->args); } path.len = e.pos - path.data; @@ -230,8 +206,7 @@ ngx_http_index_handler(ngx_http_request_ *e.pos++ = '\0'; } - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, - "open index \"%V\"", &path); + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, "open index \"%V\"", &path); of.test_dir = 0; of.retest = clcf->open_file_cache_retest; @@ -240,37 +215,27 @@ ngx_http_index_handler(ngx_http_request_ rc = ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool); -#if 0 - if (rc == NGX_AGAIN) { - ctx->current = i; - return NGX_AGAIN; - } -#endif - if (rc == NGX_ERROR) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, of.err, - ngx_open_file_n " \"%s\" failed", ctx->path.data); + ngx_open_file_n " \"%s\" failed", path.data); if (of.err == 0) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } - if (of.err == NGX_ENOTDIR) { - return ngx_http_index_error(r, ctx, of.err); - - } else if (of.err == NGX_EACCES) { - return ngx_http_index_error(r, ctx, of.err); + if (of.err == NGX_ENOTDIR || of.err == NGX_EACCES) { + return ngx_http_index_error(r, path.data, of.err); } - if (!ctx->tested) { - rc = ngx_http_index_test_dir(r, clcf, ctx); + if (!dir_tested) { + rc = ngx_http_index_test_dir(r, clcf, path.data, name - 1); if (rc != NGX_OK) { return rc; } - ctx->tested = 1; + dir_tested = 1; } if (of.err == NGX_ENOENT) { @@ -278,15 +243,15 @@ ngx_http_index_handler(ngx_http_request_ } ngx_log_error(NGX_LOG_ERR, log, of.err, - ngx_open_file_n " \"%s\" failed", ctx->path.data); + ngx_open_file_n " \"%s\" failed", path.data); return NGX_HTTP_INTERNAL_SERVER_ERROR; } - uri.len = r->uri.len + ctx->index.len - 1; + uri.len = r->uri.len + nlen - 1; if (!clcf->alias) { - uri.data = ctx->path.data + ctx->root; + uri.data = path.data + root; } else { uri.data = ngx_palloc(r->pool, uri.len); @@ -294,8 +259,8 @@ ngx_http_index_handler(ngx_http_request_ return NGX_HTTP_INTERNAL_SERVER_ERROR; } - last = ngx_copy(uri.data, r->uri.data, r->uri.len); - ngx_memcpy(last, ctx->index.data, ctx->index.len - 1); + p = ngx_copy(uri.data, r->uri.data, r->uri.len); + ngx_memcpy(p, name, nlen - 1); } return ngx_http_internal_redirect(r, &uri, &r->args); @@ -307,70 +272,71 @@ ngx_http_index_handler(ngx_http_request_ static ngx_int_t ngx_http_index_test_dir(ngx_http_request_t *r, ngx_http_core_loc_conf_t *clcf, - ngx_http_index_ctx_t *ctx) + u_char *path, u_char *last) { u_char c; - ngx_str_t path; - ngx_uint_t i; + ngx_str_t dir; ngx_open_file_info_t of; - c = *(ctx->index.data - 1); - i = (c == '/') ? 1 : 0; - *(ctx->index.data - i) = '\0'; + c = *last; + if (c != '/') { + /* "alias" without trailing slash */ + c = *(++last); + } + *last = '\0'; - path.len = (ctx->index.data - i) - ctx->path.data; - path.data = ctx->path.data; + dir.len = last - path; + dir.data = path; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http index check dir: \"%V\"", &path); + "http index check dir: \"%V\"", &dir); of.test_dir = 1; of.retest = clcf->open_file_cache_retest; of.errors = clcf->open_file_cache_errors; - if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool) + if (ngx_open_cached_file(clcf->open_file_cache, &dir, &of, r->pool) != NGX_OK) { if (of.err) { if (of.err == NGX_ENOENT) { - *(ctx->index.data - i) = c; - return ngx_http_index_error(r, ctx, of.err); + *last = c; + return ngx_http_index_error(r, dir.data, NGX_ENOENT); } ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err, - ngx_open_file_n " \"%s\" failed", path.data); + ngx_open_file_n " \"%s\" failed", dir.data); } return NGX_HTTP_INTERNAL_SERVER_ERROR; } - *(ctx->index.data - i) = c; + *last = c; if (of.is_dir) { return NGX_OK; } ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, - "\"%s\" is not a directory", path.data); + "\"%s\" is not a directory", dir.data); return NGX_HTTP_INTERNAL_SERVER_ERROR; } static ngx_int_t -ngx_http_index_error(ngx_http_request_t *r, ngx_http_index_ctx_t *ctx, - ngx_err_t err) +ngx_http_index_error(ngx_http_request_t *r, u_char *file, ngx_err_t err) { if (err == NGX_EACCES) { ngx_log_error(NGX_LOG_ERR, r->connection->log, err, - "\"%s\" is forbidden", ctx->path.data); + "\"%s\" is forbidden", file); return NGX_HTTP_FORBIDDEN; } ngx_log_error(NGX_LOG_ERR, r->connection->log, err, - "\"%s\" is not found", ctx->path.data); + "\"%s\" is not found", file); return NGX_HTTP_NOT_FOUND; } @@ -472,6 +438,7 @@ ngx_http_index_set_index(ngx_conf_t *cf, value = cf->args->elts; for (i = 1; i < cf->args->nelts; i++) { + if (value[i].data[0] == '/' && i != cf->args->nelts - 1) { ngx_conf_log_error(NGX_LOG_WARN, cf, 0, "only the last index in \"index\" directive "