aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2007-09-01 12:12:48 +0000
committerIgor Sysoev <igor@sysoev.ru>2007-09-01 12:12:48 +0000
commit140c7556a27050f5059e2edd9b038835ff6cd338 (patch)
treed176eeb05f2e7ea2222979e828e568d6de0cdcb2
parentd92bee51ea4db438a79c075a45937d5789210ab2 (diff)
downloadnginx-140c7556a27050f5059e2edd9b038835ff6cd338.tar.gz
nginx-140c7556a27050f5059e2edd9b038835ff6cd338.zip
open_file_cache in HTTP
-rw-r--r--src/http/modules/ngx_http_flv_module.c81
-rw-r--r--src/http/modules/ngx_http_index_module.c120
-rw-r--r--src/http/modules/ngx_http_static_module.c155
-rw-r--r--src/http/modules/perl/nginx.xs64
-rw-r--r--src/http/ngx_http_core_module.c114
-rw-r--r--src/http/ngx_http_core_module.h4
-rw-r--r--src/http/ngx_http_script.c59
7 files changed, 302 insertions, 295 deletions
diff --git a/src/http/modules/ngx_http_flv_module.c b/src/http/modules/ngx_http_flv_module.c
index cc258ea23..ad0d5bd97 100644
--- a/src/http/modules/ngx_http_flv_module.c
+++ b/src/http/modules/ngx_http_flv_module.c
@@ -60,20 +60,17 @@ ngx_module_t ngx_http_flv_module = {
static ngx_int_t
ngx_http_flv_handler(ngx_http_request_t *r)
{
- u_char *p;
+ u_char *p, *last;
off_t start, len;
size_t root;
ngx_fd_t fd;
ngx_int_t rc;
ngx_uint_t level, i;
ngx_str_t path;
- ngx_err_t err;
ngx_log_t *log;
ngx_buf_t *b;
ngx_chain_t out[2];
- ngx_file_info_t fi;
- ngx_pool_cleanup_t *cln;
- ngx_pool_cleanup_file_t *clnf;
+ ngx_open_file_info_t of;
ngx_http_core_loc_conf_t *clcf;
if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
@@ -95,64 +92,65 @@ ngx_http_flv_handler(ngx_http_request_t *r)
return rc;
}
- if (ngx_http_map_uri_to_path(r, &path, &root, 0) == NULL) {
+ last = ngx_http_map_uri_to_path(r, &path, &root, 0);
+ if (last == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
log = r->connection->log;
+ path.len = last - path.data;
+
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
- "http flv filename: \"%s\"", path.data);
+ "http flv filename: \"%V\"", &path);
- cln = ngx_pool_cleanup_add(r->pool, sizeof(ngx_pool_cleanup_file_t));
- if (cln == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+ of.test_dir = 0;
+ of.retest = clcf->open_file_cache_retest;
+ of.errors = clcf->open_file_cache_errors;
+
+ rc = ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool);
+
+ if (rc == NGX_ERROR) {
- fd = ngx_open_file(path.data, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);
+ switch (of.err) {
- if (fd == NGX_INVALID_FILE) {
- err = ngx_errno;
+ case 0:
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+
+ case NGX_ENOENT:
+ case NGX_ENOTDIR:
+ case NGX_ENAMETOOLONG:
- if (err == NGX_ENOENT
- || err == NGX_ENOTDIR
- || err == NGX_ENAMETOOLONG)
- {
level = NGX_LOG_ERR;
rc = NGX_HTTP_NOT_FOUND;
+ break;
+
+ case NGX_EACCES:
- } else if (err == NGX_EACCES) {
level = NGX_LOG_ERR;
rc = NGX_HTTP_FORBIDDEN;
+ break;
+
+ default:
- } else {
level = NGX_LOG_CRIT;
rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
+ break;
}
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
if (rc != NGX_HTTP_NOT_FOUND || clcf->log_not_found) {
- ngx_log_error(level, log, err,
+ ngx_log_error(level, log, of.err,
ngx_open_file_n " \"%s\" failed", path.data);
}
return rc;
}
- if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_CRIT, log, ngx_errno,
- ngx_fd_info_n " \"%s\" failed", path.data);
+ fd = of.fd;
- if (ngx_close_file(fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- ngx_close_file_n " \"%s\" failed", path.data);
- }
-
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- if (!ngx_is_file(&fi)) {
+ if (!of.is_file) {
if (ngx_close_file(fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
@@ -163,7 +161,7 @@ ngx_http_flv_handler(ngx_http_request_t *r)
}
start = 0;
- len = ngx_file_size(&fi);
+ len = of.size;
i = 1;
if (r->args.len) {
@@ -187,16 +185,9 @@ ngx_http_flv_handler(ngx_http_request_t *r)
log->action = "sending flv to client";
- cln->handler = ngx_pool_cleanup_file;
- clnf = cln->data;
-
- clnf->fd = fd;
- clnf->name = path.data;
- clnf->log = r->pool->log;
-
r->headers_out.status = NGX_HTTP_OK;
r->headers_out.content_length_n = len;
- r->headers_out.last_modified_time = ngx_file_mtime(&fi);
+ r->headers_out.last_modified_time = of.mtime;
if (ngx_http_set_content_type(r) != NGX_OK) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
@@ -237,7 +228,7 @@ ngx_http_flv_handler(ngx_http_request_t *r)
}
b->file_pos = start;
- b->file_last = ngx_file_size(&fi);
+ b->file_last = of.size;
b->in_file = b->file_last ? 1: 0;
b->last_buf = 1;
diff --git a/src/http/modules/ngx_http_index_module.c b/src/http/modules/ngx_http_index_module.c
index d0f415fce..f3f2b61ce 100644
--- a/src/http/modules/ngx_http_index_module.c
+++ b/src/http/modules/ngx_http_index_module.c
@@ -38,7 +38,7 @@ typedef struct {
static ngx_int_t ngx_http_index_test_dir(ngx_http_request_t *r,
- ngx_http_index_ctx_t *ctx);
+ 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);
@@ -59,17 +59,6 @@ static ngx_command_t ngx_http_index_commands[] = {
0,
NULL },
-#if (NGX_HTTP_CACHE)
-
- { ngx_string("index_cache"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE3,
- ngx_http_set_cache_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_index_loc_conf_t, index_cache),
- NULL },
-
-#endif
-
ngx_null_command
};
@@ -120,16 +109,13 @@ ngx_http_index_handler(ngx_http_request_t *r)
{
u_char *last;
size_t len;
- ngx_fd_t fd;
ngx_int_t rc;
- ngx_err_t err;
- ngx_str_t uri;
+ ngx_str_t path, uri;
ngx_log_t *log;
ngx_uint_t i;
ngx_http_index_t *index;
ngx_http_index_ctx_t *ctx;
- ngx_pool_cleanup_t *cln;
- ngx_pool_cleanup_file_t *clnf;
+ ngx_open_file_info_t of;
ngx_http_script_code_pt code;
ngx_http_script_engine_t e;
ngx_http_core_loc_conf_t *clcf;
@@ -151,13 +137,14 @@ ngx_http_index_handler(ngx_http_request_t *r)
log = r->connection->log;
+ 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
*/
- ilcf = ngx_http_get_module_loc_conf(r, ngx_http_index_module);
-
ctx = ngx_http_get_module_ctx(r, ngx_http_index_module);
if (ctx == NULL) {
@@ -214,12 +201,16 @@ ngx_http_index_handler(ngx_http_request_t *r)
ctx->index.data = last;
}
+ 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);
+ path.len = (ctx->index.data + index[i].name.len - 1) - path.data;
+
} else {
e.ip = index[i].values->elts;
e.pos = ctx->index.data;
@@ -234,39 +225,45 @@ ngx_http_index_handler(ngx_http_request_t *r)
return ngx_http_internal_redirect(r, &ctx->index, &r->args);
}
+ path.len = e.pos - path.data;
+
*e.pos++ = '\0';
}
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
- "open index \"%s\"", ctx->path.data);
+ "open index \"%V\"", &path);
- cln = ngx_pool_cleanup_add(r->pool, sizeof(ngx_pool_cleanup_file_t));
- if (cln == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
+ of.test_dir = 0;
+ of.retest = clcf->open_file_cache_retest;
+ of.errors = clcf->open_file_cache_errors;
- fd = ngx_open_file(ctx->path.data, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);
+ rc = ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool);
- if (fd == (ngx_fd_t) NGX_AGAIN) {
+#if 0
+ if (rc == NGX_AGAIN) {
ctx->current = i;
return NGX_AGAIN;
}
+#endif
- if (fd == NGX_INVALID_FILE) {
- err = ngx_errno;
+ if (rc == NGX_ERROR) {
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, err,
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, of.err,
ngx_open_file_n " \"%s\" failed", ctx->path.data);
- if (err == NGX_ENOTDIR) {
- return ngx_http_index_error(r, ctx, err);
+ 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 (err == NGX_EACCES) {
- return ngx_http_index_error(r, ctx, err);
+ } else if (of.err == NGX_EACCES) {
+ return ngx_http_index_error(r, ctx, of.err);
}
if (!ctx->tested) {
- rc = ngx_http_index_test_dir(r, ctx);
+ rc = ngx_http_index_test_dir(r, clcf, ctx);
if (rc != NGX_OK) {
return rc;
@@ -275,25 +272,16 @@ ngx_http_index_handler(ngx_http_request_t *r)
ctx->tested = 1;
}
- if (err == NGX_ENOENT) {
+ if (of.err == NGX_ENOENT) {
continue;
}
- ngx_log_error(NGX_LOG_ERR, log, err,
+ ngx_log_error(NGX_LOG_ERR, log, of.err,
ngx_open_file_n " \"%s\" failed", ctx->path.data);
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- cln->handler = ngx_pool_cleanup_file;
- clnf = cln->data;
-
- clnf->fd = fd;
- clnf->name = ctx->path.data;
- clnf->log = r->pool->log;
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
uri.len = r->uri.len + ctx->index.len - 1;
if (!clcf->alias) {
@@ -317,43 +305,53 @@ 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_index_ctx_t *ctx)
+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 c;
- ngx_uint_t i;
- ngx_err_t err;
- ngx_file_info_t fi;
+ u_char c;
+ ngx_str_t path;
+ ngx_uint_t i;
+ ngx_open_file_info_t of;
c = *(ctx->index.data - 1);
i = (c == '/') ? 1 : 0;
*(ctx->index.data - i) = '\0';
+ path.len = (ctx->index.data - i) - ctx->path.data;
+ path.data = ctx->path.data;
+
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http index check dir: \"%s\"", ctx->path.data);
+ "http index check dir: \"%V\"", &path);
- if (ngx_file_info(ctx->path.data, &fi) == -1) {
+ of.test_dir = 1;
+ of.retest = clcf->open_file_cache_retest;
+ of.errors = clcf->open_file_cache_errors;
- err = ngx_errno;
+ if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
+ != NGX_OK)
+ {
+ if (of.err) {
- if (err == NGX_ENOENT) {
- *(ctx->index.data - i) = c;
- return ngx_http_index_error(r, ctx, err);
- }
+ if (of.err == NGX_ENOENT) {
+ *(ctx->index.data - i) = c;
+ return ngx_http_index_error(r, ctx, of.err);
+ }
- ngx_log_error(NGX_LOG_CRIT, r->connection->log, err,
- ngx_file_info_n " \"%s\" failed", ctx->path.data);
+ ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err,
+ ngx_open_file_n " \"%s\" failed", path.data);
+ }
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
*(ctx->index.data - i) = c;
- if (ngx_is_dir(&fi)) {
+ if (of.is_dir) {
return NGX_OK;
}
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- "\"%s\" is not a directory", ctx->path.data);
+ "\"%s\" is not a directory", path.data);
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
diff --git a/src/http/modules/ngx_http_static_module.c b/src/http/modules/ngx_http_static_module.c
index b94ebf230..aa5e72eb9 100644
--- a/src/http/modules/ngx_http_static_module.c
+++ b/src/http/modules/ngx_http_static_module.c
@@ -9,35 +9,10 @@
#include <ngx_http.h>
-typedef struct {
- ngx_http_cache_hash_t *redirect_cache;
-} ngx_http_static_loc_conf_t;
-
-
static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r);
-static void *ngx_http_static_create_loc_conf(ngx_conf_t *cf);
-static char *ngx_http_static_merge_loc_conf(ngx_conf_t *cf,
- void *parent, void *child);
static ngx_int_t ngx_http_static_init(ngx_conf_t *cf);
-static ngx_command_t ngx_http_static_commands[] = {
-
-#if (NGX_HTTP_CACHE)
-
- { ngx_string("redirect_cache"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE3,
- ngx_http_set_cache_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_static_loc_conf_t, redirect_cache),
- NULL },
-
-#endif
-
- ngx_null_command
-};
-
-
ngx_http_module_t ngx_http_static_module_ctx = {
NULL, /* preconfiguration */
ngx_http_static_init, /* postconfiguration */
@@ -48,15 +23,15 @@ ngx_http_module_t ngx_http_static_module_ctx = {
NULL, /* create server configuration */
NULL, /* merge server configuration */
- ngx_http_static_create_loc_conf, /* create location configuration */
- ngx_http_static_merge_loc_conf /* merge location configuration */
+ NULL, /* create location configuration */
+ NULL /* merge location configuration */
};
ngx_module_t ngx_http_static_module = {
NGX_MODULE_V1,
&ngx_http_static_module_ctx, /* module context */
- ngx_http_static_commands, /* module directives */
+ NULL, /* module directives */
NGX_HTTP_MODULE, /* module type */
NULL, /* init master */
NULL, /* init module */
@@ -75,16 +50,13 @@ ngx_http_static_handler(ngx_http_request_t *r)
u_char *last, *location;
size_t root;
ngx_fd_t fd;
+ ngx_str_t path;
ngx_int_t rc;
ngx_uint_t level;
- ngx_str_t path;
- ngx_err_t err;
ngx_log_t *log;
ngx_buf_t *b;
ngx_chain_t out;
- ngx_file_info_t fi;
- ngx_pool_cleanup_t *cln;
- ngx_pool_cleanup_file_t *clnf;
+ ngx_open_file_info_t of;
ngx_http_core_loc_conf_t *clcf;
if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
@@ -118,75 +90,68 @@ ngx_http_static_handler(ngx_http_request_t *r)
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
+ path.len = last - path.data;
+
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
"http filename: \"%s\"", path.data);
- cln = ngx_pool_cleanup_add(r->pool, sizeof(ngx_pool_cleanup_file_t));
- if (cln == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+ of.test_dir = 0;
+ of.retest = clcf->open_file_cache_retest;
+ of.errors = clcf->open_file_cache_errors;
- fd = ngx_open_file(path.data, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);
+ rc = ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool);
- if (fd == NGX_INVALID_FILE) {
- err = ngx_errno;
+ if (rc == NGX_ERROR) {
+
+ switch (of.err) {
+
+ case 0:
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+
+ case NGX_ENOENT:
+ case NGX_ENOTDIR:
+ case NGX_ENAMETOOLONG:
- if (err == NGX_ENOENT
- || err == NGX_ENOTDIR
- || err == NGX_ENAMETOOLONG)
- {
level = NGX_LOG_ERR;
rc = NGX_HTTP_NOT_FOUND;
+ break;
+
+ case NGX_EACCES:
- } else if (err == NGX_EACCES) {
level = NGX_LOG_ERR;
rc = NGX_HTTP_FORBIDDEN;
+ break;
+
+ default:
- } else {
level = NGX_LOG_CRIT;
rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
+ break;
}
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
if (rc != NGX_HTTP_NOT_FOUND || clcf->log_not_found) {
- ngx_log_error(level, log, err,
+ ngx_log_error(level, log, of.err,
ngx_open_file_n " \"%s\" failed", path.data);
}
return rc;
}
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, "http static fd: %d", fd);
-
- if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_CRIT, log, ngx_errno,
- ngx_fd_info_n " \"%s\" failed", path.data);
-
- if (ngx_close_file(fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- ngx_close_file_n " \"%s\" failed", path.data);
- }
+ fd = of.fd;
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, "http static fd: %d", fd);
- if (ngx_is_dir(&fi)) {
+ if (of.is_dir) {
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, 0, "http dir");
- if (ngx_close_file(fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- ngx_close_file_n " \"%s\" failed", path.data);
- }
-
r->headers_out.location = ngx_palloc(r->pool, sizeof(ngx_table_elt_t));
if (r->headers_out.location == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
if (!clcf->alias && clcf->root_lengths == NULL) {
location = path.data + clcf->root.len;
@@ -214,15 +179,10 @@ ngx_http_static_handler(ngx_http_request_t *r)
#if !(NGX_WIN32) /* the not regular files are probably Unix specific */
- if (!ngx_is_file(&fi)) {
+ if (!of.is_file) {
ngx_log_error(NGX_LOG_CRIT, log, ngx_errno,
"\"%s\" is not a regular file", path.data);
- if (ngx_close_file(fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- ngx_close_file_n " \"%s\" failed", path.data);
- }
-
return NGX_HTTP_NOT_FOUND;
}
@@ -230,22 +190,15 @@ ngx_http_static_handler(ngx_http_request_t *r)
log->action = "sending response to client";
- cln->handler = ngx_pool_cleanup_file;
- clnf = cln->data;
-
- clnf->fd = fd;
- clnf->name = path.data;
- clnf->log = r->pool->log;
-
r->headers_out.status = NGX_HTTP_OK;
- r->headers_out.content_length_n = ngx_file_size(&fi);
- r->headers_out.last_modified_time = ngx_file_mtime(&fi);
+ r->headers_out.content_length_n = of.size;
+ r->headers_out.last_modified_time = of.mtime;
if (ngx_http_set_content_type(r) != NGX_OK) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- if (r != r->main && ngx_file_size(&fi) == 0) {
+ if (r != r->main && of.size == 0) {
return ngx_http_send_header(r);
}
@@ -270,7 +223,7 @@ ngx_http_static_handler(ngx_http_request_t *r)
}
b->file_pos = 0;
- b->file_last = ngx_file_size(&fi);
+ b->file_last = of.size;
b->in_file = b->file_last ? 1: 0;
b->last_buf = (r == r->main) ? 1: 0;
@@ -287,36 +240,6 @@ ngx_http_static_handler(ngx_http_request_t *r)
}
-static void *
-ngx_http_static_create_loc_conf(ngx_conf_t *cf)
-{
- ngx_http_static_loc_conf_t *conf;
-
- conf = ngx_palloc(cf->pool, sizeof(ngx_http_static_loc_conf_t));
- if (conf == NULL) {
- return NGX_CONF_ERROR;
- }
-
- conf->redirect_cache = NULL;
-
- return conf;
-}
-
-
-static char *
-ngx_http_static_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_static_loc_conf_t *prev = parent;
- ngx_http_static_loc_conf_t *conf = child;
-
- if (conf->redirect_cache == NULL) {
- conf->redirect_cache = prev->redirect_cache;
- }
-
- return NGX_CONF_OK;
-}
-
-
static ngx_int_t
ngx_http_static_init(ngx_conf_t *cf)
{
diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs
index fdaedd750..8b7ef2250 100644
--- a/src/http/modules/perl/nginx.xs
+++ b/src/http/modules/perl/nginx.xs
@@ -605,15 +605,15 @@ void
sendfile(r, filename, offset = -1, bytes = 0)
CODE:
- ngx_http_request_t *r;
- char *filename;
- int offset;
- size_t bytes;
- ngx_fd_t fd;
- ngx_buf_t *b;
- ngx_file_info_t fi;
- ngx_pool_cleanup_t *cln;
- ngx_pool_cleanup_file_t *clnf;
+ ngx_http_request_t *r;
+ char *filename;
+ int offset;
+ size_t bytes;
+ ngx_int_t rc;
+ ngx_str_t path;
+ ngx_buf_t *b;
+ ngx_open_file_info_t of;
+ ngx_http_core_loc_conf_t *clcf;
ngx_http_perl_set_request(r);
@@ -636,14 +636,29 @@ sendfile(r, filename, offset = -1, bytes = 0)
XSRETURN_EMPTY;
}
- cln = ngx_pool_cleanup_add(r->pool, sizeof(ngx_pool_cleanup_file_t));
- if (cln == NULL) {
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+ of.test_dir = 0;
+ of.retest = clcf->open_file_cache_retest;
+ of.errors = clcf->open_file_cache_errors;
+
+ path.len = ngx_strlen(filename);
+
+ path.data = ngx_pcalloc(r->pool, path.len + 1);
+ if (path.data == NULL) {
XSRETURN_EMPTY;
}
- fd = ngx_open_file((u_char *) filename, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);
+ (void) ngx_cpystrn(path.data, filename, path.len + 1);
+
+ rc = ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool);
+
+ if (rc == NGX_ERROR) {
+
+ if (of.err == 0) {
+ XSRETURN_EMPTY;
+ }
- if (fd == NGX_INVALID_FILE) {
ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
ngx_open_file_n " \"%s\" failed", filename);
XSRETURN_EMPTY;
@@ -654,34 +669,15 @@ sendfile(r, filename, offset = -1, bytes = 0)
}
if (bytes == 0) {
- if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
- ngx_fd_info_n " \"%s\" failed", filename);
-
- if (ngx_close_file(fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno,
- ngx_close_file_n " \"%s\" failed", filename);
- }
-
- XSRETURN_EMPTY;
- }
-
- bytes = ngx_file_size(&fi) - offset;
+ bytes = of.size - offset;
}
- cln->handler = ngx_pool_cleanup_file;
- clnf = cln->data;
-
- clnf->fd = fd;
- clnf->name = (u_char *) "";
- clnf->log = r->pool->log;
-
b->in_file = 1;
b->file_pos = offset;
b->file_last = offset + bytes;
- b->file->fd = fd;
+ b->file->fd = of.fd;
b->file->log = r->connection->log;
(void) ngx_http_perl_output(r, b);
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 13273f678..9a52678bd 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -61,6 +61,8 @@ static char *ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char *ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
+static char *ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
static char *ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char *ngx_http_core_keepalive(ngx_conf_t *cf, ngx_command_t *cmd,
@@ -448,16 +450,26 @@ static ngx_command_t ngx_http_core_commands[] = {
0,
NULL },
-#if (NGX_HTTP_CACHE)
-
{ ngx_string("open_file_cache"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE4,
- ngx_http_set_cache_slot,
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
+ ngx_http_core_open_file_cache,
NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, open_files),
+ offsetof(ngx_http_core_loc_conf_t, open_file_cache),
NULL },
-#endif
+ { ngx_string("open_file_cache_retest"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_sec_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_core_loc_conf_t, open_file_cache_retest),
+ NULL },
+
+ { ngx_string("open_file_cache_errors"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+ ngx_conf_set_flag_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_core_loc_conf_t, open_file_cache_errors),
+ NULL },
ngx_null_command
};
@@ -2360,6 +2372,9 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf)
lcf->recursive_error_pages = NGX_CONF_UNSET;
lcf->types_hash_max_size = NGX_CONF_UNSET_UINT;
lcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT;
+ lcf->open_file_cache = NGX_CONF_UNSET_PTR;
+ lcf->open_file_cache_retest = NGX_CONF_UNSET;
+ lcf->open_file_cache_errors = NGX_CONF_UNSET;
return lcf;
}
@@ -2543,9 +2558,14 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_value(conf->recursive_error_pages,
prev->recursive_error_pages, 0);
- if (conf->open_files == NULL) {
- conf->open_files = prev->open_files;
- }
+ ngx_conf_merge_ptr_value(conf->open_file_cache,
+ prev->open_file_cache, NULL);
+
+ ngx_conf_merge_sec_value(conf->open_file_cache_retest,
+ prev->open_file_cache_retest, 60);
+
+ ngx_conf_merge_sec_value(conf->open_file_cache_errors,
+ prev->open_file_cache_errors, 0);
return NGX_CONF_OK;
}
@@ -3162,6 +3182,82 @@ ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
static char *
+ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_http_core_loc_conf_t *lcf = conf;
+
+ time_t inactive;
+ ngx_str_t *value, s;
+ ngx_int_t max;
+ ngx_uint_t i;
+
+ if (lcf->open_file_cache != NGX_CONF_UNSET_PTR) {
+ return "is duplicate";
+ }
+
+ value = cf->args->elts;
+
+ max = 0;
+ inactive = 60;
+
+ for (i = 1; i < cf->args->nelts; i++) {
+
+ if (ngx_strncmp(value[i].data, "max=", 4) == 0) {
+
+ max = ngx_atoi(value[i].data + 4, value[i].len - 4);
+ if (max == NGX_ERROR) {
+ return NGX_CONF_ERROR;
+ }
+
+ continue;
+ }
+
+ if (ngx_strncmp(value[i].data, "inactive=", 9) == 0) {
+
+ s.len = value[i].len - 9;
+ s.data = value[i].data + 9;
+
+ inactive = ngx_parse_time(&s, 1);
+ if (inactive < 0) {
+ return NGX_CONF_ERROR;
+ }
+
+ continue;
+ }
+
+ if (ngx_strcmp(value[i].data, "off") == 0) {
+
+ lcf->open_file_cache = NULL;
+
+ continue;
+ }
+
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid \"open_file_cache\" parameter \"%V\"",
+ &value[i]);
+ return NGX_CONF_ERROR;
+ }
+
+ if (lcf->open_file_cache == NULL) {
+ return NGX_CONF_OK;
+ }
+
+ if (max == 0) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "\"open_file_cache\" must have \"max\" parameter");
+ return NGX_CONF_ERROR;
+ }
+
+ lcf->open_file_cache = ngx_open_file_cache_init(cf->pool, max, inactive);
+ if (lcf->open_file_cache) {
+ return NGX_CONF_OK;
+ }
+
+ return NGX_CONF_ERROR;
+}
+
+
+static char *
ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_core_loc_conf_t *lcf = conf;
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index ec96c3ee1..5455c5c12 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -290,7 +290,9 @@ struct ngx_http_core_loc_conf_s {
ngx_path_t *client_body_temp_path; /* client_body_temp_path */
- ngx_http_cache_hash_t *open_files;
+ ngx_open_file_cache_t *open_file_cache;
+ time_t open_file_cache_retest;
+ ngx_flag_t open_file_cache_errors;
ngx_log_t *err_log;
diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c
index 945602178..78c42722e 100644
--- a/src/http/ngx_http_script.c
+++ b/src/http/ngx_http_script.c
@@ -952,8 +952,10 @@ ngx_http_script_not_equal_code(ngx_http_script_engine_t *e)
void
ngx_http_script_file_code(ngx_http_script_engine_t *e)
{
- ngx_err_t err;
- ngx_file_info_t fi;
+ ngx_str_t path;
+ ngx_http_request_t *r;
+ ngx_open_file_info_t of;
+ ngx_http_core_loc_conf_t *clcf;
ngx_http_variable_value_t *value;
ngx_http_script_file_code_t *code;
@@ -962,14 +964,25 @@ ngx_http_script_file_code(ngx_http_script_engine_t *e)
code = (ngx_http_script_file_code_t *) e->ip;
e->ip += sizeof(ngx_http_script_file_code_t);
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script file op %p", code->op);
+ path.len = value->len - 1;
+ path.data = value->data;
+
+ r = e->request;
+
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "http script file op %p \"%V\"", code->op, &path);
+
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
- if (ngx_file_info(value->data, &fi) == -1) {
- err = ngx_errno;
+ of.test_dir = 0;
+ of.retest = clcf->open_file_cache_retest;
+ of.errors = clcf->open_file_cache_errors;
- if (err != NGX_ENOENT && err != NGX_ENOTDIR) {
- ngx_log_error(NGX_LOG_CRIT, e->request->connection->log, err,
+ if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
+ == NGX_ERROR)
+ {
+ if (of.err != NGX_ENOENT && of.err != NGX_ENOTDIR) {
+ ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err,
ngx_file_info_n " \"%s\" failed", value->data);
}
@@ -993,69 +1006,57 @@ ngx_http_script_file_code(ngx_http_script_engine_t *e)
switch (code->op) {
case ngx_http_script_file_plain:
- if (ngx_is_file(&fi)) {
+ if (of.is_file) {
goto true;
}
goto false;
case ngx_http_script_file_not_plain:
- if (ngx_is_file(&fi)) {
+ if (of.is_file) {
goto false;
}
goto true;
case ngx_http_script_file_dir:
- if (ngx_is_dir(&fi)) {
+ if (of.is_dir) {
goto true;
}
goto false;
case ngx_http_script_file_not_dir:
- if (ngx_is_dir(&fi)) {
+ if (of.is_dir) {
goto false;
}
goto true;
case ngx_http_script_file_exists:
- if (ngx_is_file(&fi) || ngx_is_dir(&fi) || ngx_is_link(&fi)) {
+ if (of.is_file || of.is_dir || of.is_link) {
goto true;
}
goto false;
case ngx_http_script_file_not_exists:
- if (ngx_is_file(&fi) || ngx_is_dir(&fi) || ngx_is_link(&fi)) {
+ if (of.is_file || of.is_dir || of.is_link) {
goto false;
}
goto true;
-#if (NGX_WIN32)
-
- case ngx_http_script_file_exec:
- goto false;
-
- case ngx_http_script_file_not_exec:
- goto true;
-
-#else
-
case ngx_http_script_file_exec:
- if (ngx_is_exec(&fi)) {
+ if (of.is_exec) {
goto true;
}
goto false;
case ngx_http_script_file_not_exec:
- if (ngx_is_exec(&fi)) {
+ if (of.is_exec) {
goto false;
}
goto true;
-
-#endif
}
false:
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http script file op false");
*value = ngx_http_variable_null_value;