open_file_cache in HTTP
This commit is contained in:
parent
5d30aa5e86
commit
fa7f65761c
7 changed files with 302 additions and 295 deletions
|
@ -60,20 +60,17 @@ ngx_module_t ngx_http_flv_module = {
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_http_flv_handler(ngx_http_request_t *r)
|
ngx_http_flv_handler(ngx_http_request_t *r)
|
||||||
{
|
{
|
||||||
u_char *p;
|
u_char *p, *last;
|
||||||
off_t start, len;
|
off_t start, len;
|
||||||
size_t root;
|
size_t root;
|
||||||
ngx_fd_t fd;
|
ngx_fd_t fd;
|
||||||
ngx_int_t rc;
|
ngx_int_t rc;
|
||||||
ngx_uint_t level, i;
|
ngx_uint_t level, i;
|
||||||
ngx_str_t path;
|
ngx_str_t path;
|
||||||
ngx_err_t err;
|
|
||||||
ngx_log_t *log;
|
ngx_log_t *log;
|
||||||
ngx_buf_t *b;
|
ngx_buf_t *b;
|
||||||
ngx_chain_t out[2];
|
ngx_chain_t out[2];
|
||||||
ngx_file_info_t fi;
|
ngx_open_file_info_t of;
|
||||||
ngx_pool_cleanup_t *cln;
|
|
||||||
ngx_pool_cleanup_file_t *clnf;
|
|
||||||
ngx_http_core_loc_conf_t *clcf;
|
ngx_http_core_loc_conf_t *clcf;
|
||||||
|
|
||||||
if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
|
if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
|
||||||
|
@ -95,64 +92,65 @@ ngx_http_flv_handler(ngx_http_request_t *r)
|
||||||
return rc;
|
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;
|
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
log = r->connection->log;
|
log = r->connection->log;
|
||||||
|
|
||||||
|
path.len = last - path.data;
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
|
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));
|
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||||
if (cln == NULL) {
|
|
||||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
if (rc == NGX_ERROR) {
|
||||||
err = ngx_errno;
|
|
||||||
|
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;
|
level = NGX_LOG_ERR;
|
||||||
rc = NGX_HTTP_NOT_FOUND;
|
rc = NGX_HTTP_NOT_FOUND;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NGX_EACCES:
|
||||||
|
|
||||||
} else if (err == NGX_EACCES) {
|
|
||||||
level = NGX_LOG_ERR;
|
level = NGX_LOG_ERR;
|
||||||
rc = NGX_HTTP_FORBIDDEN;
|
rc = NGX_HTTP_FORBIDDEN;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
} else {
|
|
||||||
level = NGX_LOG_CRIT;
|
level = NGX_LOG_CRIT;
|
||||||
rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
|
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) {
|
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);
|
ngx_open_file_n " \"%s\" failed", path.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) {
|
fd = of.fd;
|
||||||
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) {
|
if (!of.is_file) {
|
||||||
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 (ngx_close_file(fd) == NGX_FILE_ERROR) {
|
if (ngx_close_file(fd) == NGX_FILE_ERROR) {
|
||||||
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
|
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
|
||||||
|
@ -163,7 +161,7 @@ ngx_http_flv_handler(ngx_http_request_t *r)
|
||||||
}
|
}
|
||||||
|
|
||||||
start = 0;
|
start = 0;
|
||||||
len = ngx_file_size(&fi);
|
len = of.size;
|
||||||
i = 1;
|
i = 1;
|
||||||
|
|
||||||
if (r->args.len) {
|
if (r->args.len) {
|
||||||
|
@ -187,16 +185,9 @@ ngx_http_flv_handler(ngx_http_request_t *r)
|
||||||
|
|
||||||
log->action = "sending flv to client";
|
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.status = NGX_HTTP_OK;
|
||||||
r->headers_out.content_length_n = len;
|
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) {
|
if (ngx_http_set_content_type(r) != NGX_OK) {
|
||||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
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_pos = start;
|
||||||
b->file_last = ngx_file_size(&fi);
|
b->file_last = of.size;
|
||||||
|
|
||||||
b->in_file = b->file_last ? 1: 0;
|
b->in_file = b->file_last ? 1: 0;
|
||||||
b->last_buf = 1;
|
b->last_buf = 1;
|
||||||
|
|
|
@ -38,7 +38,7 @@ typedef struct {
|
||||||
|
|
||||||
|
|
||||||
static ngx_int_t ngx_http_index_test_dir(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_core_loc_conf_t *clcf, ngx_http_index_ctx_t *ctx);
|
||||||
static ngx_int_t ngx_http_index_error(ngx_http_request_t *r,
|
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_ctx_t *ctx, ngx_err_t err);
|
||||||
|
|
||||||
|
@ -59,17 +59,6 @@ static ngx_command_t ngx_http_index_commands[] = {
|
||||||
0,
|
0,
|
||||||
NULL },
|
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
|
ngx_null_command
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -120,16 +109,13 @@ ngx_http_index_handler(ngx_http_request_t *r)
|
||||||
{
|
{
|
||||||
u_char *last;
|
u_char *last;
|
||||||
size_t len;
|
size_t len;
|
||||||
ngx_fd_t fd;
|
|
||||||
ngx_int_t rc;
|
ngx_int_t rc;
|
||||||
ngx_err_t err;
|
ngx_str_t path, uri;
|
||||||
ngx_str_t uri;
|
|
||||||
ngx_log_t *log;
|
ngx_log_t *log;
|
||||||
ngx_uint_t i;
|
ngx_uint_t i;
|
||||||
ngx_http_index_t *index;
|
ngx_http_index_t *index;
|
||||||
ngx_http_index_ctx_t *ctx;
|
ngx_http_index_ctx_t *ctx;
|
||||||
ngx_pool_cleanup_t *cln;
|
ngx_open_file_info_t of;
|
||||||
ngx_pool_cleanup_file_t *clnf;
|
|
||||||
ngx_http_script_code_pt code;
|
ngx_http_script_code_pt code;
|
||||||
ngx_http_script_engine_t e;
|
ngx_http_script_engine_t e;
|
||||||
ngx_http_core_loc_conf_t *clcf;
|
ngx_http_core_loc_conf_t *clcf;
|
||||||
|
@ -151,13 +137,14 @@ ngx_http_index_handler(ngx_http_request_t *r)
|
||||||
|
|
||||||
log = r->connection->log;
|
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,
|
* we use context because the handler supports an async file opening,
|
||||||
* and may be called several times
|
* 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);
|
ctx = ngx_http_get_module_ctx(r, ngx_http_index_module);
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
|
|
||||||
|
@ -214,12 +201,16 @@ ngx_http_index_handler(ngx_http_request_t *r)
|
||||||
ctx->index.data = last;
|
ctx->index.data = last;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
path.data = ctx->path.data;
|
||||||
|
|
||||||
if (index[i].values == NULL) {
|
if (index[i].values == NULL) {
|
||||||
|
|
||||||
/* index[i].name.len includes the terminating '\0' */
|
/* index[i].name.len includes the terminating '\0' */
|
||||||
|
|
||||||
ngx_memcpy(ctx->index.data, index[i].name.data, index[i].name.len);
|
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 {
|
} else {
|
||||||
e.ip = index[i].values->elts;
|
e.ip = index[i].values->elts;
|
||||||
e.pos = ctx->index.data;
|
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);
|
return ngx_http_internal_redirect(r, &ctx->index, &r->args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
path.len = e.pos - path.data;
|
||||||
|
|
||||||
*e.pos++ = '\0';
|
*e.pos++ = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 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));
|
of.test_dir = 0;
|
||||||
if (cln == NULL) {
|
of.retest = clcf->open_file_cache_retest;
|
||||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
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;
|
ctx->current = i;
|
||||||
return NGX_AGAIN;
|
return NGX_AGAIN;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (fd == NGX_INVALID_FILE) {
|
if (rc == NGX_ERROR) {
|
||||||
err = ngx_errno;
|
|
||||||
|
|
||||||
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);
|
ngx_open_file_n " \"%s\" failed", ctx->path.data);
|
||||||
|
|
||||||
if (err == NGX_ENOTDIR) {
|
if (of.err == 0) {
|
||||||
return ngx_http_index_error(r, ctx, err);
|
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
} else if (err == NGX_EACCES) {
|
if (of.err == NGX_ENOTDIR) {
|
||||||
return ngx_http_index_error(r, ctx, err);
|
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) {
|
if (!ctx->tested) {
|
||||||
rc = ngx_http_index_test_dir(r, ctx);
|
rc = ngx_http_index_test_dir(r, clcf, ctx);
|
||||||
|
|
||||||
if (rc != NGX_OK) {
|
if (rc != NGX_OK) {
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -275,25 +272,16 @@ ngx_http_index_handler(ngx_http_request_t *r)
|
||||||
ctx->tested = 1;
|
ctx->tested = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err == NGX_ENOENT) {
|
if (of.err == NGX_ENOENT) {
|
||||||
continue;
|
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);
|
ngx_open_file_n " \"%s\" failed", ctx->path.data);
|
||||||
|
|
||||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
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;
|
uri.len = r->uri.len + ctx->index.len - 1;
|
||||||
|
|
||||||
if (!clcf->alias) {
|
if (!clcf->alias) {
|
||||||
|
@ -317,43 +305,53 @@ ngx_http_index_handler(ngx_http_request_t *r)
|
||||||
|
|
||||||
|
|
||||||
static ngx_int_t
|
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;
|
u_char c;
|
||||||
ngx_uint_t i;
|
ngx_str_t path;
|
||||||
ngx_err_t err;
|
ngx_uint_t i;
|
||||||
ngx_file_info_t fi;
|
ngx_open_file_info_t of;
|
||||||
|
|
||||||
c = *(ctx->index.data - 1);
|
c = *(ctx->index.data - 1);
|
||||||
i = (c == '/') ? 1 : 0;
|
i = (c == '/') ? 1 : 0;
|
||||||
*(ctx->index.data - i) = '\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,
|
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) {
|
if (of.err == NGX_ENOENT) {
|
||||||
*(ctx->index.data - i) = c;
|
*(ctx->index.data - i) = c;
|
||||||
return ngx_http_index_error(r, ctx, err);
|
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;
|
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
*(ctx->index.data - i) = c;
|
*(ctx->index.data - i) = c;
|
||||||
|
|
||||||
if (ngx_is_dir(&fi)) {
|
if (of.is_dir) {
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
|
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;
|
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,35 +9,10 @@
|
||||||
#include <ngx_http.h>
|
#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 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_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 = {
|
ngx_http_module_t ngx_http_static_module_ctx = {
|
||||||
NULL, /* preconfiguration */
|
NULL, /* preconfiguration */
|
||||||
ngx_http_static_init, /* postconfiguration */
|
ngx_http_static_init, /* postconfiguration */
|
||||||
|
@ -48,15 +23,15 @@ ngx_http_module_t ngx_http_static_module_ctx = {
|
||||||
NULL, /* create server configuration */
|
NULL, /* create server configuration */
|
||||||
NULL, /* merge server configuration */
|
NULL, /* merge server configuration */
|
||||||
|
|
||||||
ngx_http_static_create_loc_conf, /* create location configuration */
|
NULL, /* create location configuration */
|
||||||
ngx_http_static_merge_loc_conf /* merge location configuration */
|
NULL /* merge location configuration */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
ngx_module_t ngx_http_static_module = {
|
ngx_module_t ngx_http_static_module = {
|
||||||
NGX_MODULE_V1,
|
NGX_MODULE_V1,
|
||||||
&ngx_http_static_module_ctx, /* module context */
|
&ngx_http_static_module_ctx, /* module context */
|
||||||
ngx_http_static_commands, /* module directives */
|
NULL, /* module directives */
|
||||||
NGX_HTTP_MODULE, /* module type */
|
NGX_HTTP_MODULE, /* module type */
|
||||||
NULL, /* init master */
|
NULL, /* init master */
|
||||||
NULL, /* init module */
|
NULL, /* init module */
|
||||||
|
@ -75,16 +50,13 @@ ngx_http_static_handler(ngx_http_request_t *r)
|
||||||
u_char *last, *location;
|
u_char *last, *location;
|
||||||
size_t root;
|
size_t root;
|
||||||
ngx_fd_t fd;
|
ngx_fd_t fd;
|
||||||
|
ngx_str_t path;
|
||||||
ngx_int_t rc;
|
ngx_int_t rc;
|
||||||
ngx_uint_t level;
|
ngx_uint_t level;
|
||||||
ngx_str_t path;
|
|
||||||
ngx_err_t err;
|
|
||||||
ngx_log_t *log;
|
ngx_log_t *log;
|
||||||
ngx_buf_t *b;
|
ngx_buf_t *b;
|
||||||
ngx_chain_t out;
|
ngx_chain_t out;
|
||||||
ngx_file_info_t fi;
|
ngx_open_file_info_t of;
|
||||||
ngx_pool_cleanup_t *cln;
|
|
||||||
ngx_pool_cleanup_file_t *clnf;
|
|
||||||
ngx_http_core_loc_conf_t *clcf;
|
ngx_http_core_loc_conf_t *clcf;
|
||||||
|
|
||||||
if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
|
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;
|
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
path.len = last - path.data;
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
|
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
|
||||||
"http filename: \"%s\"", path.data);
|
"http filename: \"%s\"", path.data);
|
||||||
|
|
||||||
cln = ngx_pool_cleanup_add(r->pool, sizeof(ngx_pool_cleanup_file_t));
|
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||||
if (cln == NULL) {
|
|
||||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
rc = ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool);
|
||||||
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;
|
level = NGX_LOG_ERR;
|
||||||
rc = NGX_HTTP_NOT_FOUND;
|
rc = NGX_HTTP_NOT_FOUND;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NGX_EACCES:
|
||||||
|
|
||||||
} else if (err == NGX_EACCES) {
|
|
||||||
level = NGX_LOG_ERR;
|
level = NGX_LOG_ERR;
|
||||||
rc = NGX_HTTP_FORBIDDEN;
|
rc = NGX_HTTP_FORBIDDEN;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
} else {
|
|
||||||
level = NGX_LOG_CRIT;
|
level = NGX_LOG_CRIT;
|
||||||
rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
|
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) {
|
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);
|
ngx_open_file_n " \"%s\" failed", path.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fd = of.fd;
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, "http static fd: %d", fd);
|
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, "http static fd: %d", fd);
|
||||||
|
|
||||||
if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) {
|
if (of.is_dir) {
|
||||||
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)) {
|
|
||||||
|
|
||||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, 0, "http 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));
|
r->headers_out.location = ngx_palloc(r->pool, sizeof(ngx_table_elt_t));
|
||||||
if (r->headers_out.location == NULL) {
|
if (r->headers_out.location == NULL) {
|
||||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
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) {
|
if (!clcf->alias && clcf->root_lengths == NULL) {
|
||||||
location = path.data + clcf->root.len;
|
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_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,
|
ngx_log_error(NGX_LOG_CRIT, log, ngx_errno,
|
||||||
"\"%s\" is not a regular file", path.data);
|
"\"%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;
|
return NGX_HTTP_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,22 +190,15 @@ ngx_http_static_handler(ngx_http_request_t *r)
|
||||||
|
|
||||||
log->action = "sending response to client";
|
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.status = NGX_HTTP_OK;
|
||||||
r->headers_out.content_length_n = ngx_file_size(&fi);
|
r->headers_out.content_length_n = of.size;
|
||||||
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) {
|
if (ngx_http_set_content_type(r) != NGX_OK) {
|
||||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
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);
|
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_pos = 0;
|
||||||
b->file_last = ngx_file_size(&fi);
|
b->file_last = of.size;
|
||||||
|
|
||||||
b->in_file = b->file_last ? 1: 0;
|
b->in_file = b->file_last ? 1: 0;
|
||||||
b->last_buf = (r == r->main) ? 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
|
static ngx_int_t
|
||||||
ngx_http_static_init(ngx_conf_t *cf)
|
ngx_http_static_init(ngx_conf_t *cf)
|
||||||
{
|
{
|
||||||
|
|
|
@ -605,15 +605,15 @@ void
|
||||||
sendfile(r, filename, offset = -1, bytes = 0)
|
sendfile(r, filename, offset = -1, bytes = 0)
|
||||||
CODE:
|
CODE:
|
||||||
|
|
||||||
ngx_http_request_t *r;
|
ngx_http_request_t *r;
|
||||||
char *filename;
|
char *filename;
|
||||||
int offset;
|
int offset;
|
||||||
size_t bytes;
|
size_t bytes;
|
||||||
ngx_fd_t fd;
|
ngx_int_t rc;
|
||||||
ngx_buf_t *b;
|
ngx_str_t path;
|
||||||
ngx_file_info_t fi;
|
ngx_buf_t *b;
|
||||||
ngx_pool_cleanup_t *cln;
|
ngx_open_file_info_t of;
|
||||||
ngx_pool_cleanup_file_t *clnf;
|
ngx_http_core_loc_conf_t *clcf;
|
||||||
|
|
||||||
ngx_http_perl_set_request(r);
|
ngx_http_perl_set_request(r);
|
||||||
|
|
||||||
|
@ -636,14 +636,29 @@ sendfile(r, filename, offset = -1, bytes = 0)
|
||||||
XSRETURN_EMPTY;
|
XSRETURN_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
cln = ngx_pool_cleanup_add(r->pool, sizeof(ngx_pool_cleanup_file_t));
|
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||||
if (cln == NULL) {
|
|
||||||
|
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;
|
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_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
|
||||||
ngx_open_file_n " \"%s\" failed", filename);
|
ngx_open_file_n " \"%s\" failed", filename);
|
||||||
XSRETURN_EMPTY;
|
XSRETURN_EMPTY;
|
||||||
|
@ -654,34 +669,15 @@ sendfile(r, filename, offset = -1, bytes = 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bytes == 0) {
|
if (bytes == 0) {
|
||||||
if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) {
|
bytes = of.size - offset;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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->in_file = 1;
|
||||||
|
|
||||||
b->file_pos = offset;
|
b->file_pos = offset;
|
||||||
b->file_last = offset + bytes;
|
b->file_last = offset + bytes;
|
||||||
|
|
||||||
b->file->fd = fd;
|
b->file->fd = of.fd;
|
||||||
b->file->log = r->connection->log;
|
b->file->log = r->connection->log;
|
||||||
|
|
||||||
(void) ngx_http_perl_output(r, b);
|
(void) ngx_http_perl_output(r, b);
|
||||||
|
|
|
@ -61,6 +61,8 @@ static char *ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||||
void *conf);
|
void *conf);
|
||||||
static char *ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd,
|
static char *ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||||
void *conf);
|
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,
|
static char *ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||||
void *conf);
|
void *conf);
|
||||||
static char *ngx_http_core_keepalive(ngx_conf_t *cf, ngx_command_t *cmd,
|
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,
|
0,
|
||||||
NULL },
|
NULL },
|
||||||
|
|
||||||
#if (NGX_HTTP_CACHE)
|
|
||||||
|
|
||||||
{ ngx_string("open_file_cache"),
|
{ ngx_string("open_file_cache"),
|
||||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE4,
|
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
|
||||||
ngx_http_set_cache_slot,
|
ngx_http_core_open_file_cache,
|
||||||
NGX_HTTP_LOC_CONF_OFFSET,
|
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 },
|
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
|
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->recursive_error_pages = NGX_CONF_UNSET;
|
||||||
lcf->types_hash_max_size = NGX_CONF_UNSET_UINT;
|
lcf->types_hash_max_size = NGX_CONF_UNSET_UINT;
|
||||||
lcf->types_hash_bucket_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;
|
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,
|
ngx_conf_merge_value(conf->recursive_error_pages,
|
||||||
prev->recursive_error_pages, 0);
|
prev->recursive_error_pages, 0);
|
||||||
|
|
||||||
if (conf->open_files == NULL) {
|
ngx_conf_merge_ptr_value(conf->open_file_cache,
|
||||||
conf->open_files = prev->open_files;
|
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;
|
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 *
|
static char *
|
||||||
ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||||
{
|
{
|
||||||
|
|
|
@ -290,7 +290,9 @@ struct ngx_http_core_loc_conf_s {
|
||||||
|
|
||||||
ngx_path_t *client_body_temp_path; /* client_body_temp_path */
|
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;
|
ngx_log_t *err_log;
|
||||||
|
|
||||||
|
|
|
@ -952,8 +952,10 @@ ngx_http_script_not_equal_code(ngx_http_script_engine_t *e)
|
||||||
void
|
void
|
||||||
ngx_http_script_file_code(ngx_http_script_engine_t *e)
|
ngx_http_script_file_code(ngx_http_script_engine_t *e)
|
||||||
{
|
{
|
||||||
ngx_err_t err;
|
ngx_str_t path;
|
||||||
ngx_file_info_t fi;
|
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_variable_value_t *value;
|
||||||
ngx_http_script_file_code_t *code;
|
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;
|
code = (ngx_http_script_file_code_t *) e->ip;
|
||||||
e->ip += sizeof(ngx_http_script_file_code_t);
|
e->ip += sizeof(ngx_http_script_file_code_t);
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
|
path.len = value->len - 1;
|
||||||
"http script file op %p", code->op);
|
path.data = value->data;
|
||||||
|
|
||||||
if (ngx_file_info(value->data, &fi) == -1) {
|
r = e->request;
|
||||||
err = ngx_errno;
|
|
||||||
|
|
||||||
if (err != NGX_ENOENT && err != NGX_ENOTDIR) {
|
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||||
ngx_log_error(NGX_LOG_CRIT, e->request->connection->log, err,
|
"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);
|
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) {
|
switch (code->op) {
|
||||||
case ngx_http_script_file_plain:
|
case ngx_http_script_file_plain:
|
||||||
if (ngx_is_file(&fi)) {
|
if (of.is_file) {
|
||||||
goto true;
|
goto true;
|
||||||
}
|
}
|
||||||
goto false;
|
goto false;
|
||||||
|
|
||||||
case ngx_http_script_file_not_plain:
|
case ngx_http_script_file_not_plain:
|
||||||
if (ngx_is_file(&fi)) {
|
if (of.is_file) {
|
||||||
goto false;
|
goto false;
|
||||||
}
|
}
|
||||||
goto true;
|
goto true;
|
||||||
|
|
||||||
case ngx_http_script_file_dir:
|
case ngx_http_script_file_dir:
|
||||||
if (ngx_is_dir(&fi)) {
|
if (of.is_dir) {
|
||||||
goto true;
|
goto true;
|
||||||
}
|
}
|
||||||
goto false;
|
goto false;
|
||||||
|
|
||||||
case ngx_http_script_file_not_dir:
|
case ngx_http_script_file_not_dir:
|
||||||
if (ngx_is_dir(&fi)) {
|
if (of.is_dir) {
|
||||||
goto false;
|
goto false;
|
||||||
}
|
}
|
||||||
goto true;
|
goto true;
|
||||||
|
|
||||||
case ngx_http_script_file_exists:
|
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 true;
|
||||||
}
|
}
|
||||||
goto false;
|
goto false;
|
||||||
|
|
||||||
case ngx_http_script_file_not_exists:
|
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 false;
|
||||||
}
|
}
|
||||||
goto true;
|
goto true;
|
||||||
|
|
||||||
#if (NGX_WIN32)
|
|
||||||
|
|
||||||
case ngx_http_script_file_exec:
|
case ngx_http_script_file_exec:
|
||||||
goto false;
|
if (of.is_exec) {
|
||||||
|
|
||||||
case ngx_http_script_file_not_exec:
|
|
||||||
goto true;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
case ngx_http_script_file_exec:
|
|
||||||
if (ngx_is_exec(&fi)) {
|
|
||||||
goto true;
|
goto true;
|
||||||
}
|
}
|
||||||
goto false;
|
goto false;
|
||||||
|
|
||||||
case ngx_http_script_file_not_exec:
|
case ngx_http_script_file_not_exec:
|
||||||
if (ngx_is_exec(&fi)) {
|
if (of.is_exec) {
|
||||||
goto false;
|
goto false;
|
||||||
}
|
}
|
||||||
goto true;
|
goto true;
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
false:
|
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");
|
"http script file op false");
|
||||||
|
|
||||||
*value = ngx_http_variable_null_value;
|
*value = ngx_http_variable_null_value;
|
||||||
|
|
Loading…
Reference in a new issue