mirror of
https://github.com/nginx/nginx.git
synced 2024-11-29 12:14:27 -06:00
open_file_cache in HTTP
This commit is contained in:
parent
d92bee51ea
commit
140c7556a2
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user