[stat_cache] no longer stat() and open() for stat
do not open file in stat_cache_get_entry() no longer stat() followed by open() and close() just for stat() callers should open() file to validate readability (and then reuse fd)
This commit is contained in:
parent
44156bbe81
commit
f56800e86a
|
@ -719,13 +719,12 @@ static int cgi_write_request(server *srv, handler_ctx *hctx, int fd) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct stat * cgi_stat(server *srv, connection *con, buffer *path, struct stat *st) {
|
||||
/* CGI might be executable even if it is not readable
|
||||
* (stat_cache_get_entry() currently checks file is readable)*/
|
||||
static struct stat * cgi_stat(server *srv, connection *con, buffer *path) {
|
||||
/* CGI might be executable even if it is not readable */
|
||||
stat_cache_entry *sce;
|
||||
return (HANDLER_ERROR != stat_cache_get_entry(srv, con, path, &sce))
|
||||
? &sce->st
|
||||
: (0 == stat(path->ptr, st)) ? st : NULL;
|
||||
: NULL;
|
||||
}
|
||||
|
||||
static int cgi_create_env(server *srv, connection *con, plugin_data *p, handler_ctx *hctx, buffer *cgi_handler) {
|
||||
|
@ -736,9 +735,7 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, handler_
|
|||
UNUSED(p);
|
||||
|
||||
if (!buffer_string_is_empty(cgi_handler)) {
|
||||
/* stat the exec file */
|
||||
struct stat st;
|
||||
if (NULL == cgi_stat(srv, con, cgi_handler, &st)) {
|
||||
if (NULL == cgi_stat(srv, con, cgi_handler)) {
|
||||
log_error_write(srv, __FILE__, __LINE__, "sbss",
|
||||
"stat for cgi-handler", cgi_handler,
|
||||
"failed:", strerror(errno));
|
||||
|
@ -910,7 +907,6 @@ static int mod_cgi_patch_connection(server *srv, connection *con, plugin_data *p
|
|||
|
||||
URIHANDLER_FUNC(cgi_is_handled) {
|
||||
plugin_data *p = p_d;
|
||||
struct stat stbuf;
|
||||
struct stat *st;
|
||||
data_string *ds;
|
||||
|
||||
|
@ -922,7 +918,7 @@ URIHANDLER_FUNC(cgi_is_handled) {
|
|||
ds = (data_string *)array_match_key_suffix(p->conf.cgi, con->physical.path);
|
||||
if (NULL == ds) return HANDLER_GO_ON;
|
||||
|
||||
st = cgi_stat(srv, con, con->physical.path, &stbuf);
|
||||
st = cgi_stat(srv, con, con->physical.path);
|
||||
if (NULL == st) return HANDLER_GO_ON;
|
||||
|
||||
if (!S_ISREG(st->st_mode)) return HANDLER_GO_ON;
|
||||
|
|
|
@ -717,7 +717,6 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
|
|||
stat_cache_entry *sce = NULL;
|
||||
stat_cache *sc;
|
||||
struct stat st;
|
||||
int fd;
|
||||
int file_ndx;
|
||||
UNUSED(con);
|
||||
|
||||
|
@ -788,34 +787,16 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* *lol*
|
||||
* - open() + fstat() on a named-pipe results in a (intended) hang.
|
||||
* - stat() if regular file + open() to see if we can read from it is better
|
||||
*
|
||||
* */
|
||||
if (-1 == stat(name->ptr, &st)) {
|
||||
return HANDLER_ERROR;
|
||||
}
|
||||
|
||||
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
/* fix broken stat/open for symlinks to reg files with appended slash on freebsd,osx */
|
||||
if (name->ptr[buffer_string_length(name) - 1] == '/') {
|
||||
errno = ENOTDIR;
|
||||
return HANDLER_ERROR;
|
||||
}
|
||||
|
||||
/* try to open the file to check if we can read it */
|
||||
#ifdef O_NONBLOCK
|
||||
fd = open(name->ptr, O_RDONLY | O_NONBLOCK, 0);
|
||||
#else
|
||||
fd = open(name->ptr, O_RDONLY, 0);
|
||||
#endif
|
||||
if (-1 == fd) {
|
||||
return HANDLER_ERROR;
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
|
||||
if (NULL == sce) {
|
||||
|
|
Loading…
Reference in New Issue