mirror of
https://github.com/nginx/nginx.git
synced 2025-01-19 01:42:58 +08:00
refactor index module: remove context
This commit is contained in:
parent
747bb06d62
commit
31fd642c5c
@ -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_t *r)
|
||||
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_t *r)
|
||||
}
|
||||
|
||||
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_t *r)
|
||||
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_t *r)
|
||||
*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_t *r)
|
||||
|
||||
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_t *r)
|
||||
}
|
||||
|
||||
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_t *r)
|
||||
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_t *r)
|
||||
|
||||
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, ngx_command_t *cmd, void *conf)
|
||||
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 "
|
||||
|
Loading…
Reference in New Issue
Block a user