mirror of
https://github.com/emikulic/darkhttpd.git
synced 2023-08-10 21:13:08 +03:00
. Do a non-blocking open and only stat once.
This commit is contained in:
parent
7abf59ea32
commit
132757b8fe
@ -1475,45 +1475,19 @@ static void process_get(struct connection *conn)
|
|||||||
debugf("uri=%s, target=%s, content-type=%s\n",
|
debugf("uri=%s, target=%s, content-type=%s\n",
|
||||||
conn->uri, target, mimetype);
|
conn->uri, target, mimetype);
|
||||||
|
|
||||||
/* stat the path - there is a potential race between this and the fopen()
|
/* open file */
|
||||||
* call, but it's better than trying to open a FIFO or a device.
|
conn->reply_fd = open(target, O_RDONLY | O_NONBLOCK);
|
||||||
*/
|
|
||||||
if (stat(target, &filestat) == -1)
|
|
||||||
{
|
|
||||||
if (errno == ENOENT)
|
|
||||||
default_reply(conn, 404, "Not Found",
|
|
||||||
"The URI you requested (%s) was not found.", conn->uri);
|
|
||||||
else
|
|
||||||
default_reply(conn, 500, "Internal Server Error",
|
|
||||||
"stat(%s) failed: %s.", conn->uri, strerror(errno));
|
|
||||||
|
|
||||||
safefree(target);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* make sure it's a regular file */
|
|
||||||
if (S_ISDIR(filestat.st_mode))
|
|
||||||
{
|
|
||||||
redirect(conn, "%s/", conn->uri);
|
|
||||||
safefree(target);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (!S_ISREG(filestat.st_mode))
|
|
||||||
{
|
|
||||||
default_reply(conn, 403, "Forbidden", "Not a regular file.");
|
|
||||||
safefree(target);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
conn->reply_fd = open(target, O_RDONLY);
|
|
||||||
safefree(target);
|
safefree(target);
|
||||||
|
|
||||||
if (conn->reply_fd == -1)
|
if (conn->reply_fd == -1)
|
||||||
{
|
{
|
||||||
/* fopen() failed */
|
/* open() failed */
|
||||||
if (errno == EACCES)
|
if (errno == EACCES)
|
||||||
default_reply(conn, 403, "Forbidden",
|
default_reply(conn, 403, "Forbidden",
|
||||||
"You don't have permission to access (%s).", conn->uri);
|
"You don't have permission to access (%s).", conn->uri);
|
||||||
|
else if (errno == ENOENT)
|
||||||
|
default_reply(conn, 404, "Not Found",
|
||||||
|
"The URI you requested (%s) was not found.", conn->uri);
|
||||||
else
|
else
|
||||||
default_reply(conn, 500, "Internal Server Error",
|
default_reply(conn, 500, "Internal Server Error",
|
||||||
"The URI you requested (%s) cannot be returned: %s.",
|
"The URI you requested (%s) cannot be returned: %s.",
|
||||||
@ -1522,7 +1496,7 @@ static void process_get(struct connection *conn)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get information on the file, again, just in case */
|
/* stat the file */
|
||||||
if (fstat(conn->reply_fd, &filestat) == -1)
|
if (fstat(conn->reply_fd, &filestat) == -1)
|
||||||
{
|
{
|
||||||
default_reply(conn, 500, "Internal Server Error",
|
default_reply(conn, 500, "Internal Server Error",
|
||||||
@ -1530,6 +1504,18 @@ static void process_get(struct connection *conn)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* make sure it's a regular file */
|
||||||
|
if (S_ISDIR(filestat.st_mode))
|
||||||
|
{
|
||||||
|
redirect(conn, "%s/", conn->uri);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (!S_ISREG(filestat.st_mode))
|
||||||
|
{
|
||||||
|
default_reply(conn, 403, "Forbidden", "Not a regular file.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
conn->reply_type = REPLY_FROMFILE;
|
conn->reply_type = REPLY_FROMFILE;
|
||||||
(void) rfc1123_date(lastmod, filestat.st_mtime);
|
(void) rfc1123_date(lastmod, filestat.st_mtime);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user