open_file_cache in HTTP

This commit is contained in:
Igor Sysoev 2007-09-01 12:12:48 +00:00
parent d92bee51ea
commit 140c7556a2
7 changed files with 302 additions and 295 deletions

View File

@ -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);
fd = ngx_open_file(path.data, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);
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 (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;
}
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;

View File

@ -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;
}
} else if (err == NGX_EACCES) {
return ngx_http_index_error(r, ctx, err);
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 (!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, of.err,
ngx_open_file_n " \"%s\" failed", path.data);
}
ngx_log_error(NGX_LOG_CRIT, r->connection->log, err,
ngx_file_info_n " \"%s\" failed", ctx->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;
}

View File

@ -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);
fd = ngx_open_file(path.data, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);
of.test_dir = 0;
of.retest = clcf->open_file_cache_retest;
of.errors = clcf->open_file_cache_errors;
if (fd == NGX_INVALID_FILE) {
err = ngx_errno;
rc = ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool);
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;
}
fd = of.fd;
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);
}
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
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)
{

View File

@ -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);

View File

@ -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;
}
@ -3161,6 +3181,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)
{

View File

@ -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;

View File

@ -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;
if (ngx_file_info(value->data, &fi) == -1) {
err = ngx_errno;
r = e->request;
if (err != NGX_ENOENT && err != NGX_ENOTDIR) {
ngx_log_error(NGX_LOG_CRIT, e->request->connection->log, err,
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);
of.test_dir = 0;
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)
== 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;